diff options
author | Kees Cook <keescook@chromium.org> | 2015-04-14 18:47:57 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-14 19:49:05 -0400 |
commit | 8e89a356feb6f196824a72101861d931a97ac2d2 (patch) | |
tree | a094206d40c115021bd0bc0f795091cee63b420f /arch/s390/mm | |
parent | ed6322746afb74c2509e2f3a6464182793b16eb9 (diff) |
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>
Diffstat (limited to 'arch/s390/mm')
-rw-r--r-- | arch/s390/mm/mmap.c | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c index 179a2c20b01f..db57078075c5 100644 --- a/arch/s390/mm/mmap.c +++ b/arch/s390/mm/mmap.c | |||
@@ -62,20 +62,18 @@ static inline int mmap_is_legacy(void) | |||
62 | 62 | ||
63 | static unsigned long mmap_rnd(void) | 63 | static unsigned long mmap_rnd(void) |
64 | { | 64 | { |
65 | if (!(current->flags & PF_RANDOMIZE)) | ||
66 | return 0; | ||
67 | if (is_32bit_task()) | 65 | if (is_32bit_task()) |
68 | return (get_random_int() & 0x7ff) << PAGE_SHIFT; | 66 | return (get_random_int() & 0x7ff) << PAGE_SHIFT; |
69 | else | 67 | else |
70 | return (get_random_int() & mmap_rnd_mask) << PAGE_SHIFT; | 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 | unsigned long gap = rlimit(RLIMIT_STACK); | 78 | unsigned long gap = rlimit(RLIMIT_STACK); |
81 | 79 | ||
@@ -84,7 +82,7 @@ static inline unsigned long mmap_base(void) | |||
84 | else if (gap > MAX_GAP) | 82 | else if (gap > MAX_GAP) |
85 | gap = MAX_GAP; | 83 | gap = MAX_GAP; |
86 | gap &= PAGE_MASK; | 84 | gap &= PAGE_MASK; |
87 | return STACK_TOP - stack_maxrandom_size() - mmap_rnd() - gap; | 85 | return STACK_TOP - stack_maxrandom_size() - rnd - gap; |
88 | } | 86 | } |
89 | 87 | ||
90 | unsigned long | 88 | unsigned long |
@@ -187,7 +185,11 @@ unsigned long randomize_et_dyn(void) | |||
187 | if (!is_32bit_task()) | 185 | if (!is_32bit_task()) |
188 | /* Align to 4GB */ | 186 | /* Align to 4GB */ |
189 | base &= ~((1UL << 32) - 1); | 187 | base &= ~((1UL << 32) - 1); |
190 | return base + mmap_rnd(); | 188 | |
189 | if (current->flags & PF_RANDOMIZE) | ||
190 | base += mmap_rnd(); | ||
191 | |||
192 | return base; | ||
191 | } | 193 | } |
192 | 194 | ||
193 | #ifndef CONFIG_64BIT | 195 | #ifndef CONFIG_64BIT |
@@ -198,15 +200,20 @@ unsigned long randomize_et_dyn(void) | |||
198 | */ | 200 | */ |
199 | void arch_pick_mmap_layout(struct mm_struct *mm) | 201 | void arch_pick_mmap_layout(struct mm_struct *mm) |
200 | { | 202 | { |
203 | unsigned long random_factor = 0UL; | ||
204 | |||
205 | if (current->flags & PF_RANDOMIZE) | ||
206 | random_factor = mmap_rnd(); | ||
207 | |||
201 | /* | 208 | /* |
202 | * Fall back to the standard layout if the personality | 209 | * Fall back to the standard layout if the personality |
203 | * bit is set, or if the expected stack growth is unlimited: | 210 | * bit is set, or if the expected stack growth is unlimited: |
204 | */ | 211 | */ |
205 | if (mmap_is_legacy()) { | 212 | if (mmap_is_legacy()) { |
206 | mm->mmap_base = mmap_base_legacy(); | 213 | mm->mmap_base = mmap_base_legacy(random_factor); |
207 | mm->get_unmapped_area = arch_get_unmapped_area; | 214 | mm->get_unmapped_area = arch_get_unmapped_area; |
208 | } else { | 215 | } else { |
209 | mm->mmap_base = mmap_base(); | 216 | mm->mmap_base = mmap_base(random_factor); |
210 | mm->get_unmapped_area = arch_get_unmapped_area_topdown; | 217 | mm->get_unmapped_area = arch_get_unmapped_area_topdown; |
211 | } | 218 | } |
212 | } | 219 | } |
@@ -273,15 +280,20 @@ s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr, | |||
273 | */ | 280 | */ |
274 | void arch_pick_mmap_layout(struct mm_struct *mm) | 281 | void arch_pick_mmap_layout(struct mm_struct *mm) |
275 | { | 282 | { |
283 | unsigned long random_factor = 0UL; | ||
284 | |||
285 | if (current->flags & PF_RANDOMIZE) | ||
286 | random_factor = mmap_rnd(); | ||
287 | |||
276 | /* | 288 | /* |
277 | * Fall back to the standard layout if the personality | 289 | * Fall back to the standard layout if the personality |
278 | * bit is set, or if the expected stack growth is unlimited: | 290 | * bit is set, or if the expected stack growth is unlimited: |
279 | */ | 291 | */ |
280 | if (mmap_is_legacy()) { | 292 | if (mmap_is_legacy()) { |
281 | mm->mmap_base = mmap_base_legacy(); | 293 | mm->mmap_base = mmap_base_legacy(random_factor); |
282 | mm->get_unmapped_area = s390_get_unmapped_area; | 294 | mm->get_unmapped_area = s390_get_unmapped_area; |
283 | } else { | 295 | } else { |
284 | mm->mmap_base = mmap_base(); | 296 | mm->mmap_base = mmap_base(random_factor); |
285 | mm->get_unmapped_area = s390_get_unmapped_area_topdown; | 297 | mm->get_unmapped_area = s390_get_unmapped_area_topdown; |
286 | } | 298 | } |
287 | } | 299 | } |