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:
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user