aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/ia32/ia32_signal.c5
-rw-r--r--arch/x86/kernel/signal.c18
-rw-r--r--arch/x86/um/signal.c9
-rw-r--r--include/linux/compat.h1
-rw-r--r--include/linux/signal.h1
-rw-r--r--kernel/signal.c16
6 files changed, 25 insertions, 25 deletions
diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c
index a866411a2fcc..a1daf4a65009 100644
--- a/arch/x86/ia32/ia32_signal.c
+++ b/arch/x86/ia32/ia32_signal.c
@@ -467,10 +467,7 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
467 else 467 else
468 put_user_ex(0, &frame->uc.uc_flags); 468 put_user_ex(0, &frame->uc.uc_flags);
469 put_user_ex(0, &frame->uc.uc_link); 469 put_user_ex(0, &frame->uc.uc_link);
470 put_user_ex(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); 470 err |= __compat_save_altstack(&frame->uc.uc_stack, regs->sp);
471 put_user_ex(sas_ss_flags(regs->sp),
472 &frame->uc.uc_stack.ss_flags);
473 put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
474 471
475 if (ka->sa.sa_flags & SA_RESTORER) 472 if (ka->sa.sa_flags & SA_RESTORER)
476 restorer = ka->sa.sa_restorer; 473 restorer = ka->sa.sa_restorer;
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index b17ed37c61a2..a6c8a347b8c6 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -363,10 +363,7 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
363 else 363 else
364 put_user_ex(0, &frame->uc.uc_flags); 364 put_user_ex(0, &frame->uc.uc_flags);
365 put_user_ex(0, &frame->uc.uc_link); 365 put_user_ex(0, &frame->uc.uc_link);
366 put_user_ex(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); 366 err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
367 put_user_ex(sas_ss_flags(regs->sp),
368 &frame->uc.uc_stack.ss_flags);
369 put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
370 367
371 /* Set up to return from userspace. */ 368 /* Set up to return from userspace. */
372 restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn); 369 restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
@@ -413,7 +410,6 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
413 struct rt_sigframe __user *frame; 410 struct rt_sigframe __user *frame;
414 void __user *fp = NULL; 411 void __user *fp = NULL;
415 int err = 0; 412 int err = 0;
416 struct task_struct *me = current;
417 413
418 frame = get_sigframe(ka, regs, sizeof(struct rt_sigframe), &fp); 414 frame = get_sigframe(ka, regs, sizeof(struct rt_sigframe), &fp);
419 415
@@ -432,10 +428,7 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
432 else 428 else
433 put_user_ex(0, &frame->uc.uc_flags); 429 put_user_ex(0, &frame->uc.uc_flags);
434 put_user_ex(0, &frame->uc.uc_link); 430 put_user_ex(0, &frame->uc.uc_link);
435 put_user_ex(me->sas_ss_sp, &frame->uc.uc_stack.ss_sp); 431 err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
436 put_user_ex(sas_ss_flags(regs->sp),
437 &frame->uc.uc_stack.ss_flags);
438 put_user_ex(me->sas_ss_size, &frame->uc.uc_stack.ss_size);
439 432
440 /* Set up to return from userspace. If provided, use a stub 433 /* Set up to return from userspace. If provided, use a stub
441 already in userspace. */ 434 already in userspace. */
@@ -502,10 +495,7 @@ static int x32_setup_rt_frame(int sig, struct k_sigaction *ka,
502 else 495 else
503 put_user_ex(0, &frame->uc.uc_flags); 496 put_user_ex(0, &frame->uc.uc_flags);
504 put_user_ex(0, &frame->uc.uc_link); 497 put_user_ex(0, &frame->uc.uc_link);
505 put_user_ex(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); 498 err |= __compat_save_altstack(&frame->uc.uc_stack, regs->sp);
506 put_user_ex(sas_ss_flags(regs->sp),
507 &frame->uc.uc_stack.ss_flags);
508 put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
509 put_user_ex(0, &frame->uc.uc__pad0); 499 put_user_ex(0, &frame->uc.uc__pad0);
510 500
511 if (ka->sa.sa_flags & SA_RESTORER) { 501 if (ka->sa.sa_flags & SA_RESTORER) {
@@ -651,7 +641,7 @@ long sys_rt_sigreturn(struct pt_regs *regs)
651 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax)) 641 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
652 goto badframe; 642 goto badframe;
653 643
654 if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT) 644 if (restore_altstack(&frame->uc.uc_stack))
655 goto badframe; 645 goto badframe;
656 646
657 return ax; 647 return ax;
diff --git a/arch/x86/um/signal.c b/arch/x86/um/signal.c
index bdaa08cfbcf4..71cef48ea5cd 100644
--- a/arch/x86/um/signal.c
+++ b/arch/x86/um/signal.c
@@ -342,9 +342,7 @@ static int copy_ucontext_to_user(struct ucontext __user *uc,
342{ 342{
343 int err = 0; 343 int err = 0;
344 344
345 err |= put_user(current->sas_ss_sp, &uc->uc_stack.ss_sp); 345 err |= __save_altstack(&uc->uc_stack, sp);
346 err |= put_user(sas_ss_flags(sp), &uc->uc_stack.ss_flags);
347 err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size);
348 err |= copy_sc_to_user(&uc->uc_mcontext, fp, &current->thread.regs, 0); 346 err |= copy_sc_to_user(&uc->uc_mcontext, fp, &current->thread.regs, 0);
349 err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set)); 347 err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set));
350 return err; 348 return err;
@@ -529,10 +527,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
529 /* Create the ucontext. */ 527 /* Create the ucontext. */
530 err |= __put_user(0, &frame->uc.uc_flags); 528 err |= __put_user(0, &frame->uc.uc_flags);
531 err |= __put_user(0, &frame->uc.uc_link); 529 err |= __put_user(0, &frame->uc.uc_link);
532 err |= __put_user(me->sas_ss_sp, &frame->uc.uc_stack.ss_sp); 530 err |= __save_altstack(&frame->uc.uc_stack, PT_REGS_SP(regs));
533 err |= __put_user(sas_ss_flags(PT_REGS_SP(regs)),
534 &frame->uc.uc_stack.ss_flags);
535 err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size);
536 err |= copy_sc_to_user(&frame->uc.uc_mcontext, &frame->fpstate, regs, 531 err |= copy_sc_to_user(&frame->uc.uc_mcontext, &frame->fpstate, regs,
537 set->sig[0]); 532 set->sig[0]);
538 err |= __put_user(&frame->fpstate, &frame->uc.uc_mcontext.fpstate); 533 err |= __put_user(&frame->fpstate, &frame->uc.uc_mcontext.fpstate);
diff --git a/include/linux/compat.h b/include/linux/compat.h
index cb5637e2ee2c..334813307ec1 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -647,6 +647,7 @@ asmlinkage long compat_sys_sigaltstack(const compat_stack_t __user *uss_ptr,
647 compat_stack_t __user *uoss_ptr); 647 compat_stack_t __user *uoss_ptr);
648 648
649int compat_restore_altstack(const compat_stack_t __user *uss); 649int compat_restore_altstack(const compat_stack_t __user *uss);
650int __compat_save_altstack(compat_stack_t __user *, unsigned long);
650#endif 651#endif
651 652
652#else 653#else
diff --git a/include/linux/signal.h b/include/linux/signal.h
index 5969522136fe..0a89ffc48466 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -386,5 +386,6 @@ int unhandled_signal(struct task_struct *tsk, int sig);
386void signals_init(void); 386void signals_init(void);
387 387
388int restore_altstack(const stack_t __user *); 388int restore_altstack(const stack_t __user *);
389int __save_altstack(stack_t __user *, unsigned long);
389 390
390#endif /* _LINUX_SIGNAL_H */ 391#endif /* _LINUX_SIGNAL_H */
diff --git a/kernel/signal.c b/kernel/signal.c
index aee85bd76b8a..f072513302c3 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -3117,6 +3117,14 @@ int restore_altstack(const stack_t __user *uss)
3117 return err == -EFAULT ? err : 0; 3117 return err == -EFAULT ? err : 0;
3118} 3118}
3119 3119
3120int __save_altstack(stack_t __user *uss, unsigned long sp)
3121{
3122 struct task_struct *t = current;
3123 return __put_user((void __user *)t->sas_ss_sp, &uss->ss_sp) |
3124 __put_user(sas_ss_flags(sp), &uss->ss_flags) |
3125 __put_user(t->sas_ss_size, &uss->ss_size);
3126}
3127
3120#ifdef CONFIG_COMPAT 3128#ifdef CONFIG_COMPAT
3121#ifdef CONFIG_GENERIC_SIGALTSTACK 3129#ifdef CONFIG_GENERIC_SIGALTSTACK
3122asmlinkage long compat_sys_sigaltstack(const compat_stack_t __user *uss_ptr, 3130asmlinkage long compat_sys_sigaltstack(const compat_stack_t __user *uss_ptr,
@@ -3158,6 +3166,14 @@ int compat_restore_altstack(const compat_stack_t __user *uss)
3158 /* squash all but -EFAULT for now */ 3166 /* squash all but -EFAULT for now */
3159 return err == -EFAULT ? err : 0; 3167 return err == -EFAULT ? err : 0;
3160} 3168}
3169
3170int __compat_save_altstack(compat_stack_t __user *uss, unsigned long sp)
3171{
3172 struct task_struct *t = current;
3173 return __put_user(ptr_to_compat((void __user *)t->sas_ss_sp), &uss->ss_sp) |
3174 __put_user(sas_ss_flags(sp), &uss->ss_flags) |
3175 __put_user(t->sas_ss_size, &uss->ss_size);
3176}
3161#endif 3177#endif
3162#endif 3178#endif
3163 3179