Skip to content

Stack's lower bits are randomized despite ADDR_NO_RANDOMIZE #52

@XeR

Description

@XeR

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinggood first issueGood for newcomers

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions