diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-14 11:47:26 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-14 11:47:26 -0500 |
commit | c1e0d97d3d63d5173baf8c39a13dc5c25b031bd4 (patch) | |
tree | 4bf35b974326f1f17de4ea3d17b65aa44811da01 /arch/s390 | |
parent | 7f5db6a8022e8d4bb92b3d638068d2c2a9c9b59b (diff) | |
parent | 51120c2cc70fc241721b8016f4eff575e7d6aa30 (diff) |
Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6:
[S390] MAINTAINERS: Update zcrypt driver entry
[S390] Randomize PIEs
[S390] Randomise the brk region
[S390] Add is_32bit_task() helper function
[S390] Randomize lower bits of stack address
[S390] Randomize mmap start address
[S390] Rearrange mmap.c
[S390] Enable flexible mmap layout for 64 bit processes
[S390] vdso: dont map at mmap_base
[S390] reduce miminum gap between stack and mmap_base
[S390] mmap: consider stack address randomization
[S390] Update default configuration
[S390] cio: path_event overindication after resume
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/defconfig | 16 | ||||
-rw-r--r-- | arch/s390/include/asm/compat.h | 2 | ||||
-rw-r--r-- | arch/s390/include/asm/elf.h | 9 | ||||
-rw-r--r-- | arch/s390/include/asm/system.h | 2 | ||||
-rw-r--r-- | arch/s390/include/asm/thread_info.h | 6 | ||||
-rw-r--r-- | arch/s390/kernel/process.c | 38 | ||||
-rw-r--r-- | arch/s390/kernel/vdso.c | 4 | ||||
-rw-r--r-- | arch/s390/mm/mmap.c | 49 |
8 files changed, 101 insertions, 25 deletions
diff --git a/arch/s390/defconfig b/arch/s390/defconfig index d79697157ac0..29c82c640a88 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig | |||
@@ -5,10 +5,21 @@ CONFIG_AUDIT=y | |||
5 | CONFIG_RCU_TRACE=y | 5 | CONFIG_RCU_TRACE=y |
6 | CONFIG_IKCONFIG=y | 6 | CONFIG_IKCONFIG=y |
7 | CONFIG_IKCONFIG_PROC=y | 7 | CONFIG_IKCONFIG_PROC=y |
8 | CONFIG_CGROUPS=y | ||
9 | CONFIG_CPUSETS=y | ||
10 | CONFIG_CGROUP_CPUACCT=y | ||
11 | CONFIG_RESOURCE_COUNTERS=y | ||
12 | CONFIG_CGROUP_MEM_RES_CTLR=y | ||
13 | CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y | ||
14 | CONFIG_CGROUP_SCHED=y | ||
15 | CONFIG_RT_GROUP_SCHED=y | ||
16 | CONFIG_BLK_CGROUP=y | ||
8 | CONFIG_BLK_DEV_INITRD=y | 17 | CONFIG_BLK_DEV_INITRD=y |
9 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | 18 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set |
10 | CONFIG_PERF_EVENTS=y | 19 | # CONFIG_COMPAT_BRK is not set |
11 | CONFIG_SLAB=y | 20 | CONFIG_SLAB=y |
21 | CONFIG_PROFILING=y | ||
22 | CONFIG_OPROFILE=y | ||
12 | CONFIG_KPROBES=y | 23 | CONFIG_KPROBES=y |
13 | CONFIG_MODULES=y | 24 | CONFIG_MODULES=y |
14 | CONFIG_MODULE_UNLOAD=y | 25 | CONFIG_MODULE_UNLOAD=y |
@@ -19,7 +30,9 @@ CONFIG_HIGH_RES_TIMERS=y | |||
19 | CONFIG_PREEMPT=y | 30 | CONFIG_PREEMPT=y |
20 | CONFIG_MEMORY_HOTPLUG=y | 31 | CONFIG_MEMORY_HOTPLUG=y |
21 | CONFIG_MEMORY_HOTREMOVE=y | 32 | CONFIG_MEMORY_HOTREMOVE=y |
33 | CONFIG_KSM=y | ||
22 | CONFIG_BINFMT_MISC=m | 34 | CONFIG_BINFMT_MISC=m |
35 | CONFIG_CMM=m | ||
23 | CONFIG_HZ_100=y | 36 | CONFIG_HZ_100=y |
24 | CONFIG_KEXEC=y | 37 | CONFIG_KEXEC=y |
25 | CONFIG_PM=y | 38 | CONFIG_PM=y |
@@ -105,6 +118,7 @@ CONFIG_DEBUG_LIST=y | |||
105 | CONFIG_DEBUG_NOTIFIERS=y | 118 | CONFIG_DEBUG_NOTIFIERS=y |
106 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | 119 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set |
107 | CONFIG_KPROBES_SANITY_TEST=y | 120 | CONFIG_KPROBES_SANITY_TEST=y |
121 | CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y | ||
108 | CONFIG_CPU_NOTIFIER_ERROR_INJECT=m | 122 | CONFIG_CPU_NOTIFIER_ERROR_INJECT=m |
109 | CONFIG_LATENCYTOP=y | 123 | CONFIG_LATENCYTOP=y |
110 | CONFIG_SYSCTL_SYSCALL_CHECK=y | 124 | CONFIG_SYSCTL_SYSCALL_CHECK=y |
diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h index a875c2f542e1..da359ca6fe55 100644 --- a/arch/s390/include/asm/compat.h +++ b/arch/s390/include/asm/compat.h | |||
@@ -169,7 +169,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) | |||
169 | 169 | ||
170 | static inline int is_compat_task(void) | 170 | static inline int is_compat_task(void) |
171 | { | 171 | { |
172 | return test_thread_flag(TIF_31BIT); | 172 | return is_32bit_task(); |
173 | } | 173 | } |
174 | 174 | ||
175 | #else | 175 | #else |
diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h index 354d42616c7e..10c029cfcc7d 100644 --- a/arch/s390/include/asm/elf.h +++ b/arch/s390/include/asm/elf.h | |||
@@ -161,7 +161,9 @@ extern unsigned int vdso_enabled; | |||
161 | use of this is to invoke "./ld.so someprog" to test out a new version of | 161 | use of this is to invoke "./ld.so someprog" to test out a new version of |
162 | the loader. We need to make sure that it is out of the way of the program | 162 | the loader. We need to make sure that it is out of the way of the program |
163 | that it will "exec", and that there is sufficient room for the brk. */ | 163 | that it will "exec", and that there is sufficient room for the brk. */ |
164 | #define ELF_ET_DYN_BASE (STACK_TOP / 3 * 2) | 164 | |
165 | extern unsigned long randomize_et_dyn(unsigned long base); | ||
166 | #define ELF_ET_DYN_BASE (randomize_et_dyn(STACK_TOP / 3 * 2)) | ||
165 | 167 | ||
166 | /* This yields a mask that user programs can use to figure out what | 168 | /* This yields a mask that user programs can use to figure out what |
167 | instruction set this CPU supports. */ | 169 | instruction set this CPU supports. */ |
@@ -206,6 +208,8 @@ do { \ | |||
206 | current->mm->context.noexec == 0; \ | 208 | current->mm->context.noexec == 0; \ |
207 | }) | 209 | }) |
208 | 210 | ||
211 | #define STACK_RND_MASK 0x7ffUL | ||
212 | |||
209 | #define ARCH_DLINFO \ | 213 | #define ARCH_DLINFO \ |
210 | do { \ | 214 | do { \ |
211 | if (vdso_enabled) \ | 215 | if (vdso_enabled) \ |
@@ -218,4 +222,7 @@ struct linux_binprm; | |||
218 | #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 | 222 | #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 |
219 | int arch_setup_additional_pages(struct linux_binprm *, int); | 223 | int arch_setup_additional_pages(struct linux_binprm *, int); |
220 | 224 | ||
225 | extern unsigned long arch_randomize_brk(struct mm_struct *mm); | ||
226 | #define arch_randomize_brk arch_randomize_brk | ||
227 | |||
221 | #endif | 228 | #endif |
diff --git a/arch/s390/include/asm/system.h b/arch/s390/include/asm/system.h index 6710b0eac165..8f8d759f6a7b 100644 --- a/arch/s390/include/asm/system.h +++ b/arch/s390/include/asm/system.h | |||
@@ -449,7 +449,7 @@ extern void (*_machine_restart)(char *command); | |||
449 | extern void (*_machine_halt)(void); | 449 | extern void (*_machine_halt)(void); |
450 | extern void (*_machine_power_off)(void); | 450 | extern void (*_machine_power_off)(void); |
451 | 451 | ||
452 | #define arch_align_stack(x) (x) | 452 | extern unsigned long arch_align_stack(unsigned long sp); |
453 | 453 | ||
454 | static inline int tprot(unsigned long addr) | 454 | static inline int tprot(unsigned long addr) |
455 | { | 455 | { |
diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h index ebc77091466f..ad1382f7932e 100644 --- a/arch/s390/include/asm/thread_info.h +++ b/arch/s390/include/asm/thread_info.h | |||
@@ -118,6 +118,12 @@ static inline struct thread_info *current_thread_info(void) | |||
118 | #define _TIF_SINGLE_STEP (1<<TIF_FREEZE) | 118 | #define _TIF_SINGLE_STEP (1<<TIF_FREEZE) |
119 | #define _TIF_FREEZE (1<<TIF_FREEZE) | 119 | #define _TIF_FREEZE (1<<TIF_FREEZE) |
120 | 120 | ||
121 | #ifdef CONFIG_64BIT | ||
122 | #define is_32bit_task() (test_thread_flag(TIF_31BIT)) | ||
123 | #else | ||
124 | #define is_32bit_task() (1) | ||
125 | #endif | ||
126 | |||
121 | #endif /* __KERNEL__ */ | 127 | #endif /* __KERNEL__ */ |
122 | 128 | ||
123 | #define PREEMPT_ACTIVE 0x4000000 | 129 | #define PREEMPT_ACTIVE 0x4000000 |
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 6ba42222b542..a895e69379f7 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c | |||
@@ -30,9 +30,11 @@ | |||
30 | #include <linux/tick.h> | 30 | #include <linux/tick.h> |
31 | #include <linux/elfcore.h> | 31 | #include <linux/elfcore.h> |
32 | #include <linux/kernel_stat.h> | 32 | #include <linux/kernel_stat.h> |
33 | #include <linux/personality.h> | ||
33 | #include <linux/syscalls.h> | 34 | #include <linux/syscalls.h> |
34 | #include <linux/compat.h> | 35 | #include <linux/compat.h> |
35 | #include <linux/kprobes.h> | 36 | #include <linux/kprobes.h> |
37 | #include <linux/random.h> | ||
36 | #include <asm/compat.h> | 38 | #include <asm/compat.h> |
37 | #include <asm/uaccess.h> | 39 | #include <asm/uaccess.h> |
38 | #include <asm/pgtable.h> | 40 | #include <asm/pgtable.h> |
@@ -332,3 +334,39 @@ unsigned long get_wchan(struct task_struct *p) | |||
332 | } | 334 | } |
333 | return 0; | 335 | return 0; |
334 | } | 336 | } |
337 | |||
338 | unsigned long arch_align_stack(unsigned long sp) | ||
339 | { | ||
340 | if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) | ||
341 | sp -= get_random_int() & ~PAGE_MASK; | ||
342 | return sp & ~0xf; | ||
343 | } | ||
344 | |||
345 | static inline unsigned long brk_rnd(void) | ||
346 | { | ||
347 | /* 8MB for 32bit, 1GB for 64bit */ | ||
348 | if (is_32bit_task()) | ||
349 | return (get_random_int() & 0x7ffUL) << PAGE_SHIFT; | ||
350 | else | ||
351 | return (get_random_int() & 0x3ffffUL) << PAGE_SHIFT; | ||
352 | } | ||
353 | |||
354 | unsigned long arch_randomize_brk(struct mm_struct *mm) | ||
355 | { | ||
356 | unsigned long ret = PAGE_ALIGN(mm->brk + brk_rnd()); | ||
357 | |||
358 | if (ret < mm->brk) | ||
359 | return mm->brk; | ||
360 | return ret; | ||
361 | } | ||
362 | |||
363 | unsigned long randomize_et_dyn(unsigned long base) | ||
364 | { | ||
365 | unsigned long ret = PAGE_ALIGN(base + brk_rnd()); | ||
366 | |||
367 | if (!(current->flags & PF_RANDOMIZE)) | ||
368 | return base; | ||
369 | if (ret < base) | ||
370 | return base; | ||
371 | return ret; | ||
372 | } | ||
diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c index e3150dd2fe74..f438d74dedbd 100644 --- a/arch/s390/kernel/vdso.c +++ b/arch/s390/kernel/vdso.c | |||
@@ -203,7 +203,6 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) | |||
203 | if (!uses_interp) | 203 | if (!uses_interp) |
204 | return 0; | 204 | return 0; |
205 | 205 | ||
206 | vdso_base = mm->mmap_base; | ||
207 | #ifdef CONFIG_64BIT | 206 | #ifdef CONFIG_64BIT |
208 | vdso_pagelist = vdso64_pagelist; | 207 | vdso_pagelist = vdso64_pagelist; |
209 | vdso_pages = vdso64_pages; | 208 | vdso_pages = vdso64_pages; |
@@ -233,8 +232,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) | |||
233 | * fail and end up putting it elsewhere. | 232 | * fail and end up putting it elsewhere. |
234 | */ | 233 | */ |
235 | down_write(&mm->mmap_sem); | 234 | down_write(&mm->mmap_sem); |
236 | vdso_base = get_unmapped_area(NULL, vdso_base, | 235 | vdso_base = get_unmapped_area(NULL, 0, vdso_pages << PAGE_SHIFT, 0, 0); |
237 | vdso_pages << PAGE_SHIFT, 0, 0); | ||
238 | if (IS_ERR_VALUE(vdso_base)) { | 236 | if (IS_ERR_VALUE(vdso_base)) { |
239 | rc = vdso_base; | 237 | rc = vdso_base; |
240 | goto out_up; | 238 | goto out_up; |
diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c index 869efbaed3ea..c9a9f7f18188 100644 --- a/arch/s390/mm/mmap.c +++ b/arch/s390/mm/mmap.c | |||
@@ -27,17 +27,44 @@ | |||
27 | #include <linux/personality.h> | 27 | #include <linux/personality.h> |
28 | #include <linux/mm.h> | 28 | #include <linux/mm.h> |
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/random.h> | ||
30 | #include <asm/pgalloc.h> | 31 | #include <asm/pgalloc.h> |
31 | #include <asm/compat.h> | 32 | #include <asm/compat.h> |
32 | 33 | ||
34 | static unsigned long stack_maxrandom_size(void) | ||
35 | { | ||
36 | if (!(current->flags & PF_RANDOMIZE)) | ||
37 | return 0; | ||
38 | if (current->personality & ADDR_NO_RANDOMIZE) | ||
39 | return 0; | ||
40 | return STACK_RND_MASK << PAGE_SHIFT; | ||
41 | } | ||
42 | |||
33 | /* | 43 | /* |
34 | * Top of mmap area (just below the process stack). | 44 | * Top of mmap area (just below the process stack). |
35 | * | 45 | * |
36 | * Leave an at least ~128 MB hole. | 46 | * Leave at least a ~32 MB hole. |
37 | */ | 47 | */ |
38 | #define MIN_GAP (128*1024*1024) | 48 | #define MIN_GAP (32*1024*1024) |
39 | #define MAX_GAP (STACK_TOP/6*5) | 49 | #define MAX_GAP (STACK_TOP/6*5) |
40 | 50 | ||
51 | static inline int mmap_is_legacy(void) | ||
52 | { | ||
53 | if (current->personality & ADDR_COMPAT_LAYOUT) | ||
54 | return 1; | ||
55 | if (rlimit(RLIMIT_STACK) == RLIM_INFINITY) | ||
56 | return 1; | ||
57 | return sysctl_legacy_va_layout; | ||
58 | } | ||
59 | |||
60 | static unsigned long mmap_rnd(void) | ||
61 | { | ||
62 | if (!(current->flags & PF_RANDOMIZE)) | ||
63 | return 0; | ||
64 | /* 8MB randomization for mmap_base */ | ||
65 | return (get_random_int() & 0x7ffUL) << PAGE_SHIFT; | ||
66 | } | ||
67 | |||
41 | static inline unsigned long mmap_base(void) | 68 | static inline unsigned long mmap_base(void) |
42 | { | 69 | { |
43 | unsigned long gap = rlimit(RLIMIT_STACK); | 70 | unsigned long gap = rlimit(RLIMIT_STACK); |
@@ -46,22 +73,8 @@ static inline unsigned long mmap_base(void) | |||
46 | gap = MIN_GAP; | 73 | gap = MIN_GAP; |
47 | else if (gap > MAX_GAP) | 74 | else if (gap > MAX_GAP) |
48 | gap = MAX_GAP; | 75 | gap = MAX_GAP; |
49 | 76 | gap &= PAGE_MASK; | |
50 | return STACK_TOP - (gap & PAGE_MASK); | 77 | return STACK_TOP - stack_maxrandom_size() - mmap_rnd() - gap; |
51 | } | ||
52 | |||
53 | static inline int mmap_is_legacy(void) | ||
54 | { | ||
55 | #ifdef CONFIG_64BIT | ||
56 | /* | ||
57 | * Force standard allocation for 64 bit programs. | ||
58 | */ | ||
59 | if (!is_compat_task()) | ||
60 | return 1; | ||
61 | #endif | ||
62 | return sysctl_legacy_va_layout || | ||
63 | (current->personality & ADDR_COMPAT_LAYOUT) || | ||
64 | rlimit(RLIMIT_STACK) == RLIM_INFINITY; | ||
65 | } | 78 | } |
66 | 79 | ||
67 | #ifndef CONFIG_64BIT | 80 | #ifndef CONFIG_64BIT |