hrev46463 adds 1 changeset to branch 'master' old head: 62ee6508ddd34131547eba18142631404d7816fb new head: 7bf85edf58b140433802e19e992d32f0a824b702 overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=7bf85ed+%5E62ee650 ---------------------------------------------------------------------------- 7bf85ed: 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(). [ Ingo Weinhold <ingo_weinhold@xxxxxx> ] ---------------------------------------------------------------------------- Revision: hrev46463 Commit: 7bf85edf58b140433802e19e992d32f0a824b702 URL: http://cgit.haiku-os.org/haiku/commit/?id=7bf85ed Author: Ingo Weinhold <ingo_weinhold@xxxxxx> Date: Sun Dec 1 01:51:12 2013 UTC ---------------------------------------------------------------------------- 5 files changed, 44 insertions(+), 17 deletions(-) headers/private/kernel/vm/VMAddressSpace.h | 6 +++++ src/system/kernel/team.cpp | 22 ++++++++++++++++-- src/system/kernel/vm/VMAddressSpace.cpp | 1 + src/system/kernel/vm/VMUserAddressSpace.cpp | 31 +++++++++++++------------ src/system/kernel/vm/VMUserAddressSpace.h | 1 + ---------------------------------------------------------------------------- diff --git a/headers/private/kernel/vm/VMAddressSpace.h b/headers/private/kernel/vm/VMAddressSpace.h index d26e53b..28127ec 100644 --- a/headers/private/kernel/vm/VMAddressSpace.h +++ b/headers/private/kernel/vm/VMAddressSpace.h @@ -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; }; diff --git a/src/system/kernel/team.cpp b/src/system/kernel/team.cpp index a9e9115..615d107 100644 --- a/src/system/kernel/team.cpp +++ b/src/system/kernel/team.cpp @@ -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; diff --git a/src/system/kernel/vm/VMAddressSpace.cpp b/src/system/kernel/vm/VMAddressSpace.cpp index 46f3e12..cb61239 100644 --- a/src/system/kernel/vm/VMAddressSpace.cpp +++ b/src/system/kernel/vm/VMAddressSpace.cpp @@ -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); diff --git a/src/system/kernel/vm/VMUserAddressSpace.cpp b/src/system/kernel/vm/VMUserAddressSpace.cpp index 5c24b94..53249de 100644 --- a/src/system/kernel/vm/VMUserAddressSpace.cpp +++ b/src/system/kernel/vm/VMUserAddressSpace.cpp @@ -53,14 +53,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) { return addressSpec == B_BASE_ADDRESS @@ -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); diff --git a/src/system/kernel/vm/VMUserAddressSpace.h b/src/system/kernel/vm/VMUserAddressSpace.h index 0aa4261..bb26ca9 100644 --- a/src/system/kernel/vm/VMUserAddressSpace.h +++ b/src/system/kernel/vm/VMUserAddressSpace.h @@ -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);