]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
new helpers: __save_altstack/__compat_save_altstack, switch x86 and um to those
authorAl Viro <viro@zeniv.linux.org.uk>
Tue, 20 Nov 2012 19:24:26 +0000 (14:24 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Wed, 19 Dec 2012 23:07:41 +0000 (18:07 -0500)
note that they are relying on access_ok() already checked by caller.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
arch/x86/ia32/ia32_signal.c
arch/x86/kernel/signal.c
arch/x86/um/signal.c
include/linux/compat.h
include/linux/signal.h
kernel/signal.c

index a866411a2fccd930cda4f29f5eef941bbb46b87e..a1daf4a6500926a1305415a6eb4eaba53db6b31f 100644 (file)
@@ -467,10 +467,7 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                else
                        put_user_ex(0, &frame->uc.uc_flags);
                put_user_ex(0, &frame->uc.uc_link);
-               put_user_ex(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
-               put_user_ex(sas_ss_flags(regs->sp),
-                           &frame->uc.uc_stack.ss_flags);
-               put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+               err |= __compat_save_altstack(&frame->uc.uc_stack, regs->sp);
 
                if (ka->sa.sa_flags & SA_RESTORER)
                        restorer = ka->sa.sa_restorer;
index b17ed37c61a218d156a8eb33ea8986fd40faec16..a6c8a347b8c64041790b01900ec134502c00260b 100644 (file)
@@ -363,10 +363,7 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                else
                        put_user_ex(0, &frame->uc.uc_flags);
                put_user_ex(0, &frame->uc.uc_link);
-               put_user_ex(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
-               put_user_ex(sas_ss_flags(regs->sp),
-                           &frame->uc.uc_stack.ss_flags);
-               put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+               err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
 
                /* Set up to return from userspace.  */
                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,
        struct rt_sigframe __user *frame;
        void __user *fp = NULL;
        int err = 0;
-       struct task_struct *me = current;
 
        frame = get_sigframe(ka, regs, sizeof(struct rt_sigframe), &fp);
 
@@ -432,10 +428,7 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                else
                        put_user_ex(0, &frame->uc.uc_flags);
                put_user_ex(0, &frame->uc.uc_link);
-               put_user_ex(me->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
-               put_user_ex(sas_ss_flags(regs->sp),
-                           &frame->uc.uc_stack.ss_flags);
-               put_user_ex(me->sas_ss_size, &frame->uc.uc_stack.ss_size);
+               err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
 
                /* Set up to return from userspace.  If provided, use a stub
                   already in userspace.  */
@@ -502,10 +495,7 @@ static int x32_setup_rt_frame(int sig, struct k_sigaction *ka,
                else
                        put_user_ex(0, &frame->uc.uc_flags);
                put_user_ex(0, &frame->uc.uc_link);
-               put_user_ex(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
-               put_user_ex(sas_ss_flags(regs->sp),
-                           &frame->uc.uc_stack.ss_flags);
-               put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+               err |= __compat_save_altstack(&frame->uc.uc_stack, regs->sp);
                put_user_ex(0, &frame->uc.uc__pad0);
 
                if (ka->sa.sa_flags & SA_RESTORER) {
@@ -651,7 +641,7 @@ long sys_rt_sigreturn(struct pt_regs *regs)
        if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
                goto badframe;
 
-       if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT)
+       if (restore_altstack(&frame->uc.uc_stack))
                goto badframe;
 
        return ax;
index bdaa08cfbcf4bc38eecc3ec57e34c5b0e62ecf2c..71cef48ea5cd5b84abb1216d24ff04b18911eaec 100644 (file)
@@ -342,9 +342,7 @@ static int copy_ucontext_to_user(struct ucontext __user *uc,
 {
        int err = 0;
 
-       err |= put_user(current->sas_ss_sp, &uc->uc_stack.ss_sp);
-       err |= put_user(sas_ss_flags(sp), &uc->uc_stack.ss_flags);
-       err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size);
+       err |= __save_altstack(&uc->uc_stack, sp);
        err |= copy_sc_to_user(&uc->uc_mcontext, fp, &current->thread.regs, 0);
        err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set));
        return err;
@@ -529,10 +527,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
        /* Create the ucontext.  */
        err |= __put_user(0, &frame->uc.uc_flags);
        err |= __put_user(0, &frame->uc.uc_link);
-       err |= __put_user(me->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
-       err |= __put_user(sas_ss_flags(PT_REGS_SP(regs)),
-                         &frame->uc.uc_stack.ss_flags);
-       err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size);
+       err |= __save_altstack(&frame->uc.uc_stack, PT_REGS_SP(regs));
        err |= copy_sc_to_user(&frame->uc.uc_mcontext, &frame->fpstate, regs,
                               set->sig[0]);
        err |= __put_user(&frame->fpstate, &frame->uc.uc_mcontext.fpstate);
index cb5637e2ee2c518793b1b17a7da60f9b2d437e9a..334813307ec10fc5c87607870243d5685689011e 100644 (file)
@@ -647,6 +647,7 @@ asmlinkage long compat_sys_sigaltstack(const compat_stack_t __user *uss_ptr,
                                       compat_stack_t __user *uoss_ptr);
 
 int compat_restore_altstack(const compat_stack_t __user *uss);
+int __compat_save_altstack(compat_stack_t __user *, unsigned long);
 #endif
 
 #else
index 5969522136fee0985f42334a237ab2dc56adcefd..0a89ffc4846669c7bfa5f6289e8563decb84c520 100644 (file)
@@ -386,5 +386,6 @@ int unhandled_signal(struct task_struct *tsk, int sig);
 void signals_init(void);
 
 int restore_altstack(const stack_t __user *);
+int __save_altstack(stack_t __user *, unsigned long);
 
 #endif /* _LINUX_SIGNAL_H */
index aee85bd76b8ad59cb1388d3c32b4fd4a65d4ec63..f072513302c3915301ddf41e72c5d9f72257fb41 100644 (file)
@@ -3117,6 +3117,14 @@ int restore_altstack(const stack_t __user *uss)
        return err == -EFAULT ? err : 0;
 }
 
+int __save_altstack(stack_t __user *uss, unsigned long sp)
+{
+       struct task_struct *t = current;
+       return  __put_user((void __user *)t->sas_ss_sp, &uss->ss_sp) |
+               __put_user(sas_ss_flags(sp), &uss->ss_flags) |
+               __put_user(t->sas_ss_size, &uss->ss_size);
+}
+
 #ifdef CONFIG_COMPAT
 #ifdef CONFIG_GENERIC_SIGALTSTACK
 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)
        /* squash all but -EFAULT for now */
        return err == -EFAULT ? err : 0;
 }
+
+int __compat_save_altstack(compat_stack_t __user *uss, unsigned long sp)
+{
+       struct task_struct *t = current;
+       return  __put_user(ptr_to_compat((void __user *)t->sas_ss_sp), &uss->ss_sp) |
+               __put_user(sas_ss_flags(sp), &uss->ss_flags) |
+               __put_user(t->sas_ss_size, &uss->ss_size);
+}
 #endif
 #endif