|
@@ -52,6 +52,16 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
|
|
return do_sigaltstack(uss, uoss, regs->sp);
|
|
return do_sigaltstack(uss, uoss, regs->sp);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#define COPY(x) { \
|
|
|
|
+ err |= __get_user(regs->x, &sc->x); \
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#define COPY_SEG_STRICT(seg) { \
|
|
|
|
+ unsigned short tmp; \
|
|
|
|
+ err |= __get_user(tmp, &sc->seg); \
|
|
|
|
+ regs->seg = tmp | 3; \
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* Do a signal return; undo the signal stack.
|
|
* Do a signal return; undo the signal stack.
|
|
*/
|
|
*/
|
|
@@ -64,8 +74,6 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
|
|
/* Always make any pending restarted system calls return -EINTR */
|
|
/* Always make any pending restarted system calls return -EINTR */
|
|
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
|
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
|
|
|
|
|
-#define COPY(x) (err |= __get_user(regs->x, &sc->x))
|
|
|
|
-
|
|
|
|
COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
|
|
COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
|
|
COPY(dx); COPY(cx); COPY(ip);
|
|
COPY(dx); COPY(cx); COPY(ip);
|
|
COPY(r8);
|
|
COPY(r8);
|
|
@@ -80,11 +88,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
|
|
/* Kernel saves and restores only the CS segment register on signals,
|
|
/* Kernel saves and restores only the CS segment register on signals,
|
|
* which is the bare minimum needed to allow mixed 32/64-bit code.
|
|
* which is the bare minimum needed to allow mixed 32/64-bit code.
|
|
* App's signal handler can save/restore other segments if needed. */
|
|
* App's signal handler can save/restore other segments if needed. */
|
|
- {
|
|
|
|
- unsigned cs;
|
|
|
|
- err |= __get_user(cs, &sc->cs);
|
|
|
|
- regs->cs = cs | 3; /* Force into user mode */
|
|
|
|
- }
|
|
|
|
|
|
+ COPY_SEG_STRICT(cs);
|
|
|
|
|
|
{
|
|
{
|
|
unsigned int tmpflags;
|
|
unsigned int tmpflags;
|