diff options
| author | Kees Cook <keescook@chromium.org> | 2015-04-14 15:47:45 -0700 |
|---|---|---|
| committer | Mister Oyster <oysterized@gmail.com> | 2017-07-04 12:11:28 +0200 |
| commit | 37c2f3439e79fe8501ef9d9bf9d54b0976278b5e (patch) | |
| tree | a410fed36a857be30b599797c409b1eadb0f20a1 /arch | |
| parent | ee26c6ea4c821b5d572c0808d3d5aafb6cf8cca9 (diff) | |
x86: standardize mmap_rnd() usage
commit 82168140bc4cec7ec9bad39705518541149ff8b7 upstream.
In preparation for splitting out ET_DYN ASLR, this refactors the use of
mmap_rnd() to be used similarly to arm, and extracts the checking of
PF_RANDOMIZE.
Signed-off-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Ingo Molnar <mingo@kernel.org>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Signed-off-by: Willy Tarreau <w@1wt.eu>
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/x86/mm/mmap.c | 40 |
1 files changed, 22 insertions, 18 deletions
diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c index d4fa45822..ac5ea8584 100644 --- a/arch/x86/mm/mmap.c +++ b/arch/x86/mm/mmap.c @@ -67,22 +67,21 @@ static int mmap_is_legacy(void) static unsigned long mmap_rnd(void) { - unsigned long rnd = 0; - - /* - * 8 bits of randomness in 32bit mmaps, 20 address space bits - * 28 bits of randomness in 64bit mmaps, 40 address space bits - */ - if (current->flags & PF_RANDOMIZE) { - if (mmap_is_ia32()) - rnd = get_random_long() % (1<<8); - else - rnd = get_random_long() % (1<<28); - } + unsigned long rnd; + + if (mmap_is_ia32()) +#ifdef CONFIG_COMPAT + rnd = get_random_long() & ((1UL << mmap_rnd_compat_bits) - 1); +#else + rnd = get_random_long() & ((1UL << mmap_rnd_bits) - 1); +#endif + else + rnd = get_random_long() & ((1UL << mmap_rnd_bits) - 1); + return rnd << PAGE_SHIFT; } -static unsigned long mmap_base(void) +static unsigned long mmap_base(unsigned long rnd) { unsigned long gap = rlimit(RLIMIT_STACK); @@ -91,19 +90,19 @@ static unsigned long mmap_base(void) else if (gap > MAX_GAP) gap = MAX_GAP; - return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd()); + return PAGE_ALIGN(TASK_SIZE - gap - rnd); } /* * Bottom-up (legacy) layout on X86_32 did not support randomization, X86_64 * does, but not when emulating X86_32 */ -static unsigned long mmap_legacy_base(void) +static unsigned long mmap_legacy_base(unsigned long rnd) { if (mmap_is_ia32()) return TASK_UNMAPPED_BASE; else - return TASK_UNMAPPED_BASE + mmap_rnd(); + return TASK_UNMAPPED_BASE + rnd; } /* @@ -112,14 +111,19 @@ static unsigned long mmap_legacy_base(void) */ void arch_pick_mmap_layout(struct mm_struct *mm) { - mm->mmap_legacy_base = mmap_legacy_base(); - mm->mmap_base = mmap_base(); + unsigned long random_factor = 0UL; + + if (current->flags & PF_RANDOMIZE) + random_factor = mmap_rnd(); + + mm->mmap_legacy_base = mmap_legacy_base(random_factor); if (mmap_is_legacy()) { mm->mmap_base = mm->mmap_legacy_base; mm->get_unmapped_area = arch_get_unmapped_area; mm->unmap_area = arch_unmap_area; } else { + mm->mmap_base = mmap_base(random_factor); mm->get_unmapped_area = arch_get_unmapped_area_topdown; mm->unmap_area = arch_unmap_area_topdown; } |
