Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Kees Cook <keescook@chromium.org>
Acked-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Reviewed-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Kees Cook and committed by
Linus Torvalds
8e89a356 ed632274

+23 -11
+23 -11
arch/s390/mm/mmap.c
··· 62 62 63 63 static unsigned long mmap_rnd(void) 64 64 { 65 - if (!(current->flags & PF_RANDOMIZE)) 66 - return 0; 67 65 if (is_32bit_task()) 68 66 return (get_random_int() & 0x7ff) << PAGE_SHIFT; 69 67 else 70 68 return (get_random_int() & mmap_rnd_mask) << PAGE_SHIFT; 71 69 } 72 70 73 - static unsigned long mmap_base_legacy(void) 71 + static unsigned long mmap_base_legacy(unsigned long rnd) 74 72 { 75 - return TASK_UNMAPPED_BASE + mmap_rnd(); 73 + return TASK_UNMAPPED_BASE + rnd; 76 74 } 77 75 78 - static inline unsigned long mmap_base(void) 76 + static inline unsigned long mmap_base(unsigned long rnd) 79 77 { 80 78 unsigned long gap = rlimit(RLIMIT_STACK); 81 79 ··· 82 84 else if (gap > MAX_GAP) 83 85 gap = MAX_GAP; 84 86 gap &= PAGE_MASK; 85 - return STACK_TOP - stack_maxrandom_size() - mmap_rnd() - gap; 87 + return STACK_TOP - stack_maxrandom_size() - rnd - gap; 86 88 } 87 89 88 90 unsigned long ··· 185 187 if (!is_32bit_task()) 186 188 /* Align to 4GB */ 187 189 base &= ~((1UL << 32) - 1); 188 - return base + mmap_rnd(); 190 + 191 + if (current->flags & PF_RANDOMIZE) 192 + base += mmap_rnd(); 193 + 194 + return base; 189 195 } 190 196 191 197 #ifndef CONFIG_64BIT ··· 200 198 */ 201 199 void arch_pick_mmap_layout(struct mm_struct *mm) 202 200 { 201 + unsigned long random_factor = 0UL; 202 + 203 + if (current->flags & PF_RANDOMIZE) 204 + random_factor = mmap_rnd(); 205 + 203 206 /* 204 207 * Fall back to the standard layout if the personality 205 208 * bit is set, or if the expected stack growth is unlimited: 206 209 */ 207 210 if (mmap_is_legacy()) { 208 - mm->mmap_base = mmap_base_legacy(); 211 + mm->mmap_base = mmap_base_legacy(random_factor); 209 212 mm->get_unmapped_area = arch_get_unmapped_area; 210 213 } else { 211 - mm->mmap_base = mmap_base(); 214 + mm->mmap_base = mmap_base(random_factor); 212 215 mm->get_unmapped_area = arch_get_unmapped_area_topdown; 213 216 } 214 217 } ··· 280 273 */ 281 274 void arch_pick_mmap_layout(struct mm_struct *mm) 282 275 { 276 + unsigned long random_factor = 0UL; 277 + 278 + if (current->flags & PF_RANDOMIZE) 279 + random_factor = mmap_rnd(); 280 + 283 281 /* 284 282 * Fall back to the standard layout if the personality 285 283 * bit is set, or if the expected stack growth is unlimited: 286 284 */ 287 285 if (mmap_is_legacy()) { 288 - mm->mmap_base = mmap_base_legacy(); 286 + mm->mmap_base = mmap_base_legacy(random_factor); 289 287 mm->get_unmapped_area = s390_get_unmapped_area; 290 288 } else { 291 - mm->mmap_base = mmap_base(); 289 + mm->mmap_base = mmap_base(random_factor); 292 290 mm->get_unmapped_area = s390_get_unmapped_area_topdown; 293 291 } 294 292 }