diff options
-rw-r--r-- | arch/x86/ia32/ia32_signal.c | 5 | ||||
-rw-r--r-- | arch/x86/kernel/signal.c | 18 | ||||
-rw-r--r-- | arch/x86/um/signal.c | 9 | ||||
-rw-r--r-- | include/linux/compat.h | 1 | ||||
-rw-r--r-- | include/linux/signal.h | 1 | ||||
-rw-r--r-- | kernel/signal.c | 16 |
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, ¤t->thread.regs, 0); | 346 | err |= copy_sc_to_user(&uc->uc_mcontext, fp, ¤t->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 | ||
649 | int compat_restore_altstack(const compat_stack_t __user *uss); | 649 | int compat_restore_altstack(const compat_stack_t __user *uss); |
650 | int __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); | |||
386 | void signals_init(void); | 386 | void signals_init(void); |
387 | 387 | ||
388 | int restore_altstack(const stack_t __user *); | 388 | int restore_altstack(const stack_t __user *); |
389 | int __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 | ||
3120 | int __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 |
3122 | asmlinkage long compat_sys_sigaltstack(const compat_stack_t __user *uss_ptr, | 3130 | asmlinkage 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 | |||
3170 | int __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 | ||