-
Notifications
You must be signed in to change notification settings - Fork 57
Description
Issue
The stack's lower bits are randomized when randomize_va_space is not 0
regardless of the ADDR_NO_RANDOMIZE personality.
This is inconvenient when debugging software. It requires to turn off
ASLR on the whole system to have deterministic stack addresses.
Test
This can be tested with the following code :
void main()
{
int a;
printf("%p\n", &a);
}On linux-hardened
$ for i in {1..5}; do ./a.out; done
0x73a0feb8e134
0x7d5c898ca584
0x7f2a18026ae4
0x7ff12a7c2e14
0x791eeca04c04
$ for i in {1..5}; do setarch $(uname -m) -R ./a.out; done
0x7fffffffd204
0x7fffffffd304
0x7fffffffde24
0x7fffffffd4c4
0x7fffffffd564
# sysctl -w kernel.randomize_va_space=0
$ for i in {1..5}; do ./a.out; done
0x7fffffffe084
0x7fffffffe084
0x7fffffffe084
0x7fffffffe084
0x7fffffffe084
On a vanilla kernel
$ for i in {1..5}; do ./a.out; done
0x7ffe5ed5cc3c
0x7ffefeaca9bc
0x7ffe8e5b28bc
0x7ffd8144582c
0x7ffd4a0247ec
$ for i in {1..5}; do setarch $(uname -m) -R ./a.out; done`
0x7fffffffe42c
0x7fffffffe42c
0x7fffffffe42c
0x7fffffffe42c
0x7fffffffe42c
Root cause
setup_arg_pages in fs/exec.c calls arch_align_stack (unless
CONFIG_STACK_GROWS_UP is set).
arch_align_stack checks both randomize_va_space and ADDR_NO_RANDOMIZE :
if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
sp -= get_random_int() % 8192;This results in the lower bits of the stack being randomized in both linux and
linux-hardened.
Commit 533d2e0 randomizes the stack a second
time. This code, only checks for randomize_va_space:
if (randomize_va_space)
bprm->p ^= get_random_int() & ~PAGE_MASK;I assume this commit exists since arch_align_stack is not defined for every
architecture. Only x86, aarch64, ppc, s390, mips and um. (most notably: arm
does not)
cf. arch/um/kernel/process.c:
/*
* Only x86 and x86_64 have an arch_align_stack().
* All other arches have "#define arch_align_stack(x) (x)"
* in their asm/exec.h
*/Can we check the ADDR_NO_RANDOMIZE personality before xoring the stack pointer
with a random value?