aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-05-15 16:06:06 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-05-15 16:06:06 -0400
commit4b470f120817a16ea28da6141ea6e3a3040b297b (patch)
tree8550d22831fb39fee6c758a5904c37ec81b9e2f7
parentbe5e32fc2e4b23ab443213f0c1b01cbc7ba645dc (diff)
parentd045c77c1a69703143a36169c224429c48b9eecd (diff)
Merge branch 'parisc-4.1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux
Pull parisc fixes from Helge Deller: "One important patch which fixes crashes due to stack randomization on architectures where the stack grows upwards (currently parisc and metag only). This bug went unnoticed on parisc since kernel 3.14 where the flexible mmap memory layout support was added by commit 9dabf60dc4ab. The changes in fs/exec.c are inside an #ifdef CONFIG_STACK_GROWSUP section and will not affect other platforms. The other two patches rename args of the kthread_arg() function and fixes a printk output" * 'parisc-4.1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux: parisc,metag: Fix crashes due to stack randomization on stack-grows-upwards architectures parisc: copy_thread(): rename 'arg' argument to 'kthread_arg' parisc: %pf is only for function pointers
-rw-r--r--arch/parisc/include/asm/elf.h4
-rw-r--r--arch/parisc/kernel/process.c10
-rw-r--r--arch/parisc/kernel/sys_parisc.c3
-rw-r--r--drivers/parisc/superio.c2
-rw-r--r--fs/exec.c3
5 files changed, 17 insertions, 5 deletions
diff --git a/arch/parisc/include/asm/elf.h b/arch/parisc/include/asm/elf.h
index 3391d061eccc..78c9fd32c554 100644
--- a/arch/parisc/include/asm/elf.h
+++ b/arch/parisc/include/asm/elf.h
@@ -348,6 +348,10 @@ struct pt_regs; /* forward declaration... */
348 348
349#define ELF_HWCAP 0 349#define ELF_HWCAP 0
350 350
351#define STACK_RND_MASK (is_32bit_task() ? \
352 0x7ff >> (PAGE_SHIFT - 12) : \
353 0x3ffff >> (PAGE_SHIFT - 12))
354
351struct mm_struct; 355struct mm_struct;
352extern unsigned long arch_randomize_brk(struct mm_struct *); 356extern unsigned long arch_randomize_brk(struct mm_struct *);
353#define arch_randomize_brk arch_randomize_brk 357#define arch_randomize_brk arch_randomize_brk
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index 8a488c22a99f..809905a811ed 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -181,9 +181,12 @@ int dump_task_fpu (struct task_struct *tsk, elf_fpregset_t *r)
181 return 1; 181 return 1;
182} 182}
183 183
184/*
185 * Copy architecture-specific thread state
186 */
184int 187int
185copy_thread(unsigned long clone_flags, unsigned long usp, 188copy_thread(unsigned long clone_flags, unsigned long usp,
186 unsigned long arg, struct task_struct *p) 189 unsigned long kthread_arg, struct task_struct *p)
187{ 190{
188 struct pt_regs *cregs = &(p->thread.regs); 191 struct pt_regs *cregs = &(p->thread.regs);
189 void *stack = task_stack_page(p); 192 void *stack = task_stack_page(p);
@@ -195,11 +198,10 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
195 extern void * const child_return; 198 extern void * const child_return;
196 199
197 if (unlikely(p->flags & PF_KTHREAD)) { 200 if (unlikely(p->flags & PF_KTHREAD)) {
201 /* kernel thread */
198 memset(cregs, 0, sizeof(struct pt_regs)); 202 memset(cregs, 0, sizeof(struct pt_regs));
199 if (!usp) /* idle thread */ 203 if (!usp) /* idle thread */
200 return 0; 204 return 0;
201
202 /* kernel thread */
203 /* Must exit via ret_from_kernel_thread in order 205 /* Must exit via ret_from_kernel_thread in order
204 * to call schedule_tail() 206 * to call schedule_tail()
205 */ 207 */
@@ -215,7 +217,7 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
215#else 217#else
216 cregs->gr[26] = usp; 218 cregs->gr[26] = usp;
217#endif 219#endif
218 cregs->gr[25] = arg; 220 cregs->gr[25] = kthread_arg;
219 } else { 221 } else {
220 /* user thread */ 222 /* user thread */
221 /* usp must be word aligned. This also prevents users from 223 /* usp must be word aligned. This also prevents users from
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
index e1ffea2f9a0b..5aba01ac457f 100644
--- a/arch/parisc/kernel/sys_parisc.c
+++ b/arch/parisc/kernel/sys_parisc.c
@@ -77,6 +77,9 @@ static unsigned long mmap_upper_limit(void)
77 if (stack_base > STACK_SIZE_MAX) 77 if (stack_base > STACK_SIZE_MAX)
78 stack_base = STACK_SIZE_MAX; 78 stack_base = STACK_SIZE_MAX;
79 79
80 /* Add space for stack randomization. */
81 stack_base += (STACK_RND_MASK << PAGE_SHIFT);
82
80 return PAGE_ALIGN(STACK_TOP - stack_base); 83 return PAGE_ALIGN(STACK_TOP - stack_base);
81} 84}
82 85
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c
index 8be2096c8423..deeaed544222 100644
--- a/drivers/parisc/superio.c
+++ b/drivers/parisc/superio.c
@@ -348,7 +348,7 @@ int superio_fixup_irq(struct pci_dev *pcidev)
348 BUG(); 348 BUG();
349 return -1; 349 return -1;
350 } 350 }
351 printk("superio_fixup_irq(%s) ven 0x%x dev 0x%x from %pf\n", 351 printk(KERN_DEBUG "superio_fixup_irq(%s) ven 0x%x dev 0x%x from %ps\n",
352 pci_name(pcidev), 352 pci_name(pcidev),
353 pcidev->vendor, pcidev->device, 353 pcidev->vendor, pcidev->device,
354 __builtin_return_address(0)); 354 __builtin_return_address(0));
diff --git a/fs/exec.c b/fs/exec.c
index 49a1c61433b7..1977c2a553ac 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -659,6 +659,9 @@ int setup_arg_pages(struct linux_binprm *bprm,
659 if (stack_base > STACK_SIZE_MAX) 659 if (stack_base > STACK_SIZE_MAX)
660 stack_base = STACK_SIZE_MAX; 660 stack_base = STACK_SIZE_MAX;
661 661
662 /* Add space for stack randomization. */
663 stack_base += (STACK_RND_MASK << PAGE_SHIFT);
664
662 /* Make sure we didn't let the argument array grow too large. */ 665 /* Make sure we didn't let the argument array grow too large. */
663 if (vma->vm_end - vma->vm_start > stack_base) 666 if (vma->vm_end - vma->vm_start > stack_base)
664 return -ENOMEM; 667 return -ENOMEM;