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:50 +01:00
parent 62ee6508dd
commit 7bf85edf58
5 changed files with 44 additions and 17 deletions
@@ -61,6 +61,11 @@ public:
void IncrementChangeCount() void IncrementChangeCount()
{ fChangeCount++; } { fChangeCount++; }
inline bool IsRandomizingEnabled() const
{ return fRandomizingEnabled; }
inline void SetRandomizingEnabled(bool enabled)
{ fRandomizingEnabled = enabled; }
inline AreaIterator GetAreaIterator(); inline AreaIterator GetAreaIterator();
VMAddressSpace*& HashTableLink() { return fHashTableLink; } VMAddressSpace*& HashTableLink() { return fHashTableLink; }
@@ -143,6 +148,7 @@ protected:
int32 fFaultCount; int32 fFaultCount;
int32 fChangeCount; int32 fChangeCount;
VMTranslationMap* fTranslationMap; VMTranslationMap* fTranslationMap;
bool fRandomizingEnabled;
bool fDeleting; bool fDeleting;
static VMAddressSpace* sKernelAddressSpace; static VMAddressSpace* sKernelAddressSpace;
}; };
+20 -2
View File
@@ -78,10 +78,13 @@ struct team_arg {
uint32 arg_count; uint32 arg_count;
uint32 env_count; uint32 env_count;
mode_t umask; mode_t umask;
uint32 flags;
port_id error_port; port_id error_port;
uint32 error_token; uint32 error_token;
}; };
#define TEAM_ARGS_FLAG_NO_ASLR 0x01
namespace { namespace {
@@ -1482,15 +1485,24 @@ create_team_arg(struct team_arg** _teamArg, const char* path, char** flatArgs,
} }
// copy the args over // copy the args over
teamArg->flat_args = flatArgs; teamArg->flat_args = flatArgs;
teamArg->flat_args_size = flatArgsSize; teamArg->flat_args_size = flatArgsSize;
teamArg->arg_count = argCount; teamArg->arg_count = argCount;
teamArg->env_count = envCount; teamArg->env_count = envCount;
teamArg->flags = 0;
teamArg->umask = umask; teamArg->umask = umask;
teamArg->error_port = port; teamArg->error_port = port;
teamArg->error_token = token; 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; *_teamArg = teamArg;
return B_OK; return B_OK;
} }
@@ -1763,6 +1775,9 @@ load_image_internal(char**& _flatArgs, size_t flatArgsSize, int32 argCount,
if (status != B_OK) if (status != B_OK)
goto err2; goto err2;
team->address_space->SetRandomizingEnabled(
(teamArgs->flags & TEAM_ARGS_FLAG_NO_ASLR) == 0);
// create the user data area // create the user data area
status = create_team_user_data(team); status = create_team_user_data(team);
if (status != B_OK) 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); delete_realtime_sem_context(team->realtime_sem_context);
team->realtime_sem_context = NULL; 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); status = create_team_user_data(team);
if (status != B_OK) { if (status != B_OK) {
// creating the user data failed -- we're toast // 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); free_team_arg(teamArgs);
exit_thread(status); exit_thread(status);
return status; return status;
+1
View File
@@ -89,6 +89,7 @@ VMAddressSpace::VMAddressSpace(team_id id, addr_t base, size_t size,
fFaultCount(0), fFaultCount(0),
fChangeCount(0), fChangeCount(0),
fTranslationMap(NULL), fTranslationMap(NULL),
fRandomizingEnabled(true),
fDeleting(false) fDeleting(false)
{ {
rw_lock_init(&fLock, name); rw_lock_init(&fLock, name);
+16 -15
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 static inline bool
is_base_address_spec(uint32 addressSpec) 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 addr_t
VMUserAddressSpace::_RandomizeAddress(addr_t start, addr_t end, VMUserAddressSpace::_RandomizeAddress(addr_t start, addr_t end,
size_t alignment, bool initial) 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); start = align_address(start, alignment);
if (addressSpec == B_RANDOMIZED_BASE_ADDRESS) { if (fRandomizingEnabled && addressSpec == B_RANDOMIZED_BASE_ADDRESS) {
originalStart = start; originalStart = start;
start = _RandomizeAddress(start, end - size + 1, alignment, true); start = _RandomizeAddress(start, end - size + 1, alignment, true);
} }
@@ -603,7 +604,7 @@ second_chance:
? end : std::min(next->Base() - 1, end); ? end : std::min(next->Base() - 1, end);
if (is_valid_spot(start, alignedBase, size, nextBase)) { if (is_valid_spot(start, alignedBase, size, nextBase)) {
addr_t rangeEnd = std::min(nextBase - size + 1, end); addr_t rangeEnd = std::min(nextBase - size + 1, end);
if (is_randomized(addressSpec)) { if (_IsRandomized(addressSpec)) {
alignedBase = _RandomizeAddress(alignedBase, rangeEnd, alignedBase = _RandomizeAddress(alignedBase, rangeEnd,
alignment); alignment);
} }
@@ -626,7 +627,7 @@ second_chance:
if (is_valid_spot(last->Base() + (last->Size() - 1), if (is_valid_spot(last->Base() + (last->Size() - 1),
alignedBase, size, nextBase)) { alignedBase, size, nextBase)) {
addr_t rangeEnd = std::min(nextBase - size + 1, end); addr_t rangeEnd = std::min(nextBase - size + 1, end);
if (is_randomized(addressSpec)) { if (_IsRandomized(addressSpec)) {
alignedBase = _RandomizeAddress(alignedBase, alignedBase = _RandomizeAddress(alignedBase,
rangeEnd, alignment); rangeEnd, alignment);
} }
@@ -648,7 +649,7 @@ second_chance:
if (next == NULL && is_valid_spot(last->Base() + (last->Size() - 1), if (next == NULL && is_valid_spot(last->Base() + (last->Size() - 1),
alignedBase, size, end)) { alignedBase, size, end)) {
if (is_randomized(addressSpec)) { if (_IsRandomized(addressSpec)) {
alignedBase = _RandomizeAddress(alignedBase, end - size + 1, alignedBase = _RandomizeAddress(alignedBase, end - size + 1,
alignment); alignment);
} }
@@ -660,7 +661,7 @@ second_chance:
} else if (is_base_address_spec(addressSpec)) { } else if (is_base_address_spec(addressSpec)) {
// we didn't find a free spot in the requested range, so we'll // we didn't find a free spot in the requested range, so we'll
// try again without any restrictions // try again without any restrictions
if (!is_randomized(addressSpec)) { if (!_IsRandomized(addressSpec)) {
start = USER_BASE_ANY; start = USER_BASE_ANY;
addressSpec = B_ANY_ADDRESS; addressSpec = B_ANY_ADDRESS;
} else if (start == originalStart) { } else if (start == originalStart) {
@@ -706,7 +707,7 @@ second_chance:
&& next->Size() >= size) { && next->Size() >= size) {
addr_t rangeEnd = std::min( addr_t rangeEnd = std::min(
next->Base() + next->Size() - size, end); next->Base() + next->Size() - size, end);
if (is_randomized(addressSpec)) { if (_IsRandomized(addressSpec)) {
alignedBase = _RandomizeAddress(next->Base(), alignedBase = _RandomizeAddress(next->Base(),
rangeEnd, alignment); rangeEnd, alignment);
} }
@@ -728,7 +729,7 @@ second_chance:
// reserved area, and the reserved area will be resized // reserved area, and the reserved area will be resized
// to make space // to make space
if (is_randomized(addressSpec)) { if (_IsRandomized(addressSpec)) {
addr_t alignedNextBase = align_address(next->Base(), addr_t alignedNextBase = align_address(next->Base(),
alignment); alignment);
@@ -53,6 +53,7 @@ public:
virtual void Dump() const; virtual void Dump() const;
private: private:
inline bool _IsRandomized(uint32 addressSpec) const;
static addr_t _RandomizeAddress(addr_t start, addr_t end, static addr_t _RandomizeAddress(addr_t start, addr_t end,
size_t alignment, bool initial = false); size_t alignment, bool initial = false);