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:
parent
62ee6508dd
commit
7bf85edf58
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user