OSDN Git Service

x86: switch ia32_setup_sigcontext() to unsafe_put_user()
authorAl Viro <viro@zeniv.linux.org.uk>
Sat, 15 Feb 2020 22:41:04 +0000 (17:41 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Thu, 19 Mar 2020 00:40:56 +0000 (20:40 -0400)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
arch/x86/ia32/ia32_signal.c

index 23e2c55..af673ec 100644 (file)
@@ -158,38 +158,40 @@ static int ia32_setup_sigcontext(struct sigcontext_32 __user *sc,
                                 void __user *fpstate,
                                 struct pt_regs *regs, unsigned int mask)
 {
-       int err = 0;
-
-       put_user_try {
-               put_user_ex(get_user_seg(gs), (unsigned int __user *)&sc->gs);
-               put_user_ex(get_user_seg(fs), (unsigned int __user *)&sc->fs);
-               put_user_ex(get_user_seg(ds), (unsigned int __user *)&sc->ds);
-               put_user_ex(get_user_seg(es), (unsigned int __user *)&sc->es);
-
-               put_user_ex(regs->di, &sc->di);
-               put_user_ex(regs->si, &sc->si);
-               put_user_ex(regs->bp, &sc->bp);
-               put_user_ex(regs->sp, &sc->sp);
-               put_user_ex(regs->bx, &sc->bx);
-               put_user_ex(regs->dx, &sc->dx);
-               put_user_ex(regs->cx, &sc->cx);
-               put_user_ex(regs->ax, &sc->ax);
-               put_user_ex(current->thread.trap_nr, &sc->trapno);
-               put_user_ex(current->thread.error_code, &sc->err);
-               put_user_ex(regs->ip, &sc->ip);
-               put_user_ex(regs->cs, (unsigned int __user *)&sc->cs);
-               put_user_ex(regs->flags, &sc->flags);
-               put_user_ex(regs->sp, &sc->sp_at_signal);
-               put_user_ex(regs->ss, (unsigned int __user *)&sc->ss);
-
-               put_user_ex(ptr_to_compat(fpstate), &sc->fpstate);
-
-               /* non-iBCS2 extensions.. */
-               put_user_ex(mask, &sc->oldmask);
-               put_user_ex(current->thread.cr2, &sc->cr2);
-       } put_user_catch(err);
+       if (!user_access_begin(sc, sizeof(struct sigcontext_32)))
+               return -EFAULT;
 
-       return err;
+       unsafe_put_user(get_user_seg(gs), (unsigned int __user *)&sc->gs, Efault);
+       unsafe_put_user(get_user_seg(fs), (unsigned int __user *)&sc->fs, Efault);
+       unsafe_put_user(get_user_seg(ds), (unsigned int __user *)&sc->ds, Efault);
+       unsafe_put_user(get_user_seg(es), (unsigned int __user *)&sc->es, Efault);
+
+       unsafe_put_user(regs->di, &sc->di, Efault);
+       unsafe_put_user(regs->si, &sc->si, Efault);
+       unsafe_put_user(regs->bp, &sc->bp, Efault);
+       unsafe_put_user(regs->sp, &sc->sp, Efault);
+       unsafe_put_user(regs->bx, &sc->bx, Efault);
+       unsafe_put_user(regs->dx, &sc->dx, Efault);
+       unsafe_put_user(regs->cx, &sc->cx, Efault);
+       unsafe_put_user(regs->ax, &sc->ax, Efault);
+       unsafe_put_user(current->thread.trap_nr, &sc->trapno, Efault);
+       unsafe_put_user(current->thread.error_code, &sc->err, Efault);
+       unsafe_put_user(regs->ip, &sc->ip, Efault);
+       unsafe_put_user(regs->cs, (unsigned int __user *)&sc->cs, Efault);
+       unsafe_put_user(regs->flags, &sc->flags, Efault);
+       unsafe_put_user(regs->sp, &sc->sp_at_signal, Efault);
+       unsafe_put_user(regs->ss, (unsigned int __user *)&sc->ss, Efault);
+
+       unsafe_put_user(ptr_to_compat(fpstate), &sc->fpstate, Efault);
+
+       /* non-iBCS2 extensions.. */
+       unsafe_put_user(mask, &sc->oldmask, Efault);
+       unsafe_put_user(current->thread.cr2, &sc->cr2, Efault);
+       user_access_end();
+       return 0;
+Efault:
+       user_access_end();
+       return -EFAULT;
 }
 
 /*