Allow disabling ASLR via DISABLE_ASLR environment variable

* VMAddressSpace: Add randomizingEnabled property.
* VMUserAddressSpace: Randomize addresses only when randomizingEnabled
  property is set.
* create_team_arg(): Check, if the team's environment contains
  "DISABLE_ASLR=1". Set the team's address space property
  randomizingEnabled accordingly in load_image_internal() and
  exec_team().
This commit is contained in:
Ingo Weinhold 2013-12-01 02:51:12 +01:00
parent 62ee6508dd
commit 7bf85edf58
5 changed files with 44 additions and 17 deletions

View File

@ -61,6 +61,11 @@ public:
void IncrementChangeCount()
{ fChangeCount++; }
inline bool IsRandomizingEnabled() const
{ return fRandomizingEnabled; }
inline void SetRandomizingEnabled(bool enabled)
{ fRandomizingEnabled = enabled; }
inline AreaIterator GetAreaIterator();
VMAddressSpace*& HashTableLink() { return fHashTableLink; }
@ -143,6 +148,7 @@ protected:
int32 fFaultCount;
int32 fChangeCount;
VMTranslationMap* fTranslationMap;
bool fRandomizingEnabled;
bool fDeleting;
static VMAddressSpace* sKernelAddressSpace;
};

View File

@ -78,10 +78,13 @@ struct team_arg {
uint32 arg_count;
uint32 env_count;
mode_t umask;
uint32 flags;
port_id error_port;
uint32 error_token;
};
#define TEAM_ARGS_FLAG_NO_ASLR 0x01
namespace {
@ -1482,15 +1485,24 @@ create_team_arg(struct team_arg** _teamArg, const char* path, char** flatArgs,
}
// copy the args over
teamArg->flat_args = flatArgs;
teamArg->flat_args_size = flatArgsSize;
teamArg->arg_count = argCount;
teamArg->env_count = envCount;
teamArg->flags = 0;
teamArg->umask = umask;
teamArg->error_port = port;
teamArg->error_token = token;
// determine the flags from the environment
const char* const* env = flatArgs + argCount + 1;
for (int32 i = 0; i < envCount; i++) {
if (strcmp(env[i], "DISABLE_ASLR=1") == 0) {
teamArg->flags |= TEAM_ARGS_FLAG_NO_ASLR;
break;
}
}
*_teamArg = teamArg;
return B_OK;
}
@ -1763,6 +1775,9 @@ load_image_internal(char**& _flatArgs, size_t flatArgsSize, int32 argCount,
if (status != B_OK)
goto err2;
team->address_space->SetRandomizingEnabled(
(teamArgs->flags & TEAM_ARGS_FLAG_NO_ASLR) == 0);
// create the user data area
status = create_team_user_data(team);
if (status != B_OK)
@ -1934,10 +1949,13 @@ exec_team(const char* path, char**& _flatArgs, size_t flatArgsSize,
delete_realtime_sem_context(team->realtime_sem_context);
team->realtime_sem_context = NULL;
// update ASLR
team->address_space->SetRandomizingEnabled(
(teamArgs->flags & TEAM_ARGS_FLAG_NO_ASLR) == 0);
status = create_team_user_data(team);
if (status != B_OK) {
// creating the user data failed -- we're toast
// TODO: We should better keep the old user area in the first place.
free_team_arg(teamArgs);
exit_thread(status);
return status;

View File

@ -89,6 +89,7 @@ VMAddressSpace::VMAddressSpace(team_id id, addr_t base, size_t size,
fFaultCount(0),
fChangeCount(0),
fTranslationMap(NULL),
fRandomizingEnabled(true),
fDeleting(false)
{
rw_lock_init(&fLock, name);

View File

@ -52,14 +52,6 @@ is_valid_spot(addr_t base, addr_t alignedBase, addr_t size, addr_t limit)
}
static inline bool
is_randomized(uint32 addressSpec)
{
return addressSpec == B_RANDOMIZED_ANY_ADDRESS
|| addressSpec == B_RANDOMIZED_BASE_ADDRESS;
}
static inline bool
is_base_address_spec(uint32 addressSpec)
{
@ -422,6 +414,15 @@ VMUserAddressSpace::Dump() const
}
inline bool
VMUserAddressSpace::_IsRandomized(uint32 addressSpec) const
{
return fRandomizingEnabled
&& (addressSpec == B_RANDOMIZED_ANY_ADDRESS
|| addressSpec == B_RANDOMIZED_BASE_ADDRESS);
}
addr_t
VMUserAddressSpace::_RandomizeAddress(addr_t start, addr_t end,
size_t alignment, bool initial)
@ -567,7 +568,7 @@ VMUserAddressSpace::_InsertAreaSlot(addr_t start, addr_t size, addr_t end,
start = align_address(start, alignment);
if (addressSpec == B_RANDOMIZED_BASE_ADDRESS) {
if (fRandomizingEnabled && addressSpec == B_RANDOMIZED_BASE_ADDRESS) {
originalStart = start;
start = _RandomizeAddress(start, end - size + 1, alignment, true);
}
@ -603,7 +604,7 @@ second_chance:
? end : std::min(next->Base() - 1, end);
if (is_valid_spot(start, alignedBase, size, nextBase)) {
addr_t rangeEnd = std::min(nextBase - size + 1, end);
if (is_randomized(addressSpec)) {
if (_IsRandomized(addressSpec)) {
alignedBase = _RandomizeAddress(alignedBase, rangeEnd,
alignment);
}
@ -626,7 +627,7 @@ second_chance:
if (is_valid_spot(last->Base() + (last->Size() - 1),
alignedBase, size, nextBase)) {
addr_t rangeEnd = std::min(nextBase - size + 1, end);
if (is_randomized(addressSpec)) {
if (_IsRandomized(addressSpec)) {
alignedBase = _RandomizeAddress(alignedBase,
rangeEnd, alignment);
}
@ -648,7 +649,7 @@ second_chance:
if (next == NULL && is_valid_spot(last->Base() + (last->Size() - 1),
alignedBase, size, end)) {
if (is_randomized(addressSpec)) {
if (_IsRandomized(addressSpec)) {
alignedBase = _RandomizeAddress(alignedBase, end - size + 1,
alignment);
}
@ -660,7 +661,7 @@ second_chance:
} else if (is_base_address_spec(addressSpec)) {
// we didn't find a free spot in the requested range, so we'll
// try again without any restrictions
if (!is_randomized(addressSpec)) {
if (!_IsRandomized(addressSpec)) {
start = USER_BASE_ANY;
addressSpec = B_ANY_ADDRESS;
} else if (start == originalStart) {
@ -706,7 +707,7 @@ second_chance:
&& next->Size() >= size) {
addr_t rangeEnd = std::min(
next->Base() + next->Size() - size, end);
if (is_randomized(addressSpec)) {
if (_IsRandomized(addressSpec)) {
alignedBase = _RandomizeAddress(next->Base(),
rangeEnd, alignment);
}
@ -728,7 +729,7 @@ second_chance:
// reserved area, and the reserved area will be resized
// to make space
if (is_randomized(addressSpec)) {
if (_IsRandomized(addressSpec)) {
addr_t alignedNextBase = align_address(next->Base(),
alignment);

View File

@ -53,6 +53,7 @@ public:
virtual void Dump() const;
private:
inline bool _IsRandomized(uint32 addressSpec) const;
static addr_t _RandomizeAddress(addr_t start, addr_t end,
size_t alignment, bool initial = false);