Commit 8e89a356 authored by Kees Cook's avatar Kees Cook Committed by Linus Torvalds

s390: standardize mmap_rnd() usage

In preparation for splitting out ET_DYN ASLR, this refactors the use of
mmap_rnd() to be used similarly to arm and x86, and extracts the
checking of PF_RANDOMIZE.
Signed-off-by: default avatarKees Cook <keescook@chromium.org>
Acked-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Reviewed-by: default avatarIngo Molnar <mingo@kernel.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent ed632274
...@@ -62,20 +62,18 @@ static inline int mmap_is_legacy(void) ...@@ -62,20 +62,18 @@ static inline int mmap_is_legacy(void)
static unsigned long mmap_rnd(void) static unsigned long mmap_rnd(void)
{ {
if (!(current->flags & PF_RANDOMIZE))
return 0;
if (is_32bit_task()) if (is_32bit_task())
return (get_random_int() & 0x7ff) << PAGE_SHIFT; return (get_random_int() & 0x7ff) << PAGE_SHIFT;
else else
return (get_random_int() & mmap_rnd_mask) << PAGE_SHIFT; return (get_random_int() & mmap_rnd_mask) << PAGE_SHIFT;
} }
static unsigned long mmap_base_legacy(void) static unsigned long mmap_base_legacy(unsigned long rnd)
{ {
return TASK_UNMAPPED_BASE + mmap_rnd(); return TASK_UNMAPPED_BASE + rnd;
} }
static inline unsigned long mmap_base(void) static inline unsigned long mmap_base(unsigned long rnd)
{ {
unsigned long gap = rlimit(RLIMIT_STACK); unsigned long gap = rlimit(RLIMIT_STACK);
...@@ -84,7 +82,7 @@ static inline unsigned long mmap_base(void) ...@@ -84,7 +82,7 @@ static inline unsigned long mmap_base(void)
else if (gap > MAX_GAP) else if (gap > MAX_GAP)
gap = MAX_GAP; gap = MAX_GAP;
gap &= PAGE_MASK; gap &= PAGE_MASK;
return STACK_TOP - stack_maxrandom_size() - mmap_rnd() - gap; return STACK_TOP - stack_maxrandom_size() - rnd - gap;
} }
unsigned long unsigned long
...@@ -187,7 +185,11 @@ unsigned long randomize_et_dyn(void) ...@@ -187,7 +185,11 @@ unsigned long randomize_et_dyn(void)
if (!is_32bit_task()) if (!is_32bit_task())
/* Align to 4GB */ /* Align to 4GB */
base &= ~((1UL << 32) - 1); base &= ~((1UL << 32) - 1);
return base + mmap_rnd();
if (current->flags & PF_RANDOMIZE)
base += mmap_rnd();
return base;
} }
#ifndef CONFIG_64BIT #ifndef CONFIG_64BIT
...@@ -198,15 +200,20 @@ unsigned long randomize_et_dyn(void) ...@@ -198,15 +200,20 @@ unsigned long randomize_et_dyn(void)
*/ */
void arch_pick_mmap_layout(struct mm_struct *mm) void arch_pick_mmap_layout(struct mm_struct *mm)
{ {
unsigned long random_factor = 0UL;
if (current->flags & PF_RANDOMIZE)
random_factor = mmap_rnd();
/* /*
* Fall back to the standard layout if the personality * Fall back to the standard layout if the personality
* bit is set, or if the expected stack growth is unlimited: * bit is set, or if the expected stack growth is unlimited:
*/ */
if (mmap_is_legacy()) { if (mmap_is_legacy()) {
mm->mmap_base = mmap_base_legacy(); mm->mmap_base = mmap_base_legacy(random_factor);
mm->get_unmapped_area = arch_get_unmapped_area; mm->get_unmapped_area = arch_get_unmapped_area;
} else { } else {
mm->mmap_base = mmap_base(); mm->mmap_base = mmap_base(random_factor);
mm->get_unmapped_area = arch_get_unmapped_area_topdown; mm->get_unmapped_area = arch_get_unmapped_area_topdown;
} }
} }
...@@ -273,15 +280,20 @@ s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr, ...@@ -273,15 +280,20 @@ s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr,
*/ */
void arch_pick_mmap_layout(struct mm_struct *mm) void arch_pick_mmap_layout(struct mm_struct *mm)
{ {
unsigned long random_factor = 0UL;
if (current->flags & PF_RANDOMIZE)
random_factor = mmap_rnd();
/* /*
* Fall back to the standard layout if the personality * Fall back to the standard layout if the personality
* bit is set, or if the expected stack growth is unlimited: * bit is set, or if the expected stack growth is unlimited:
*/ */
if (mmap_is_legacy()) { if (mmap_is_legacy()) {
mm->mmap_base = mmap_base_legacy(); mm->mmap_base = mmap_base_legacy(random_factor);
mm->get_unmapped_area = s390_get_unmapped_area; mm->get_unmapped_area = s390_get_unmapped_area;
} else { } else {
mm->mmap_base = mmap_base(); mm->mmap_base = mmap_base(random_factor);
mm->get_unmapped_area = s390_get_unmapped_area_topdown; mm->get_unmapped_area = s390_get_unmapped_area_topdown;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment