^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * linux/arch/x86_64/ia32/ia32_signal.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 1991, 1992 Linus Torvalds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * 2000-06-20 Pentium III FXSR, SSE support by Gareth Hughes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * 2000-12-* x86-64 compatibility mode signal handling by Andi Kleen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/sched/task_stack.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/personality.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/compat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/binfmts.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/syscalls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <asm/ucontext.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <asm/fpu/internal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <asm/fpu/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <asm/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <asm/ia32_unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <asm/user32.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <uapi/asm/sigcontext.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <asm/proto.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <asm/vdso.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <asm/sigframe.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <asm/sighandling.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <asm/smap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static inline void reload_segments(struct sigcontext_32 *sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) unsigned int cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) savesegment(gs, cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) if ((sc->gs | 0x03) != cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) load_gs_index(sc->gs | 0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) savesegment(fs, cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) if ((sc->fs | 0x03) != cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) loadsegment(fs, sc->fs | 0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) savesegment(ds, cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) if ((sc->ds | 0x03) != cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) loadsegment(ds, sc->ds | 0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) savesegment(es, cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) if ((sc->es | 0x03) != cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) loadsegment(es, sc->es | 0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * Do a signal return; undo the signal stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static int ia32_restore_sigcontext(struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct sigcontext_32 __user *usc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct sigcontext_32 sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /* Always make any pending restarted system calls return -EINTR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) current->restart_block.fn = do_no_restart_syscall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (unlikely(copy_from_user(&sc, usc, sizeof(sc))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /* Get only the ia32 registers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) regs->bx = sc.bx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) regs->cx = sc.cx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) regs->dx = sc.dx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) regs->si = sc.si;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) regs->di = sc.di;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) regs->bp = sc.bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) regs->ax = sc.ax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) regs->sp = sc.sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) regs->ip = sc.ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /* Get CS/SS and force CPL3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) regs->cs = sc.cs | 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) regs->ss = sc.ss | 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) regs->flags = (regs->flags & ~FIX_EFLAGS) | (sc.flags & FIX_EFLAGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /* disable syscall checks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) regs->orig_ax = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * Reload fs and gs if they have changed in the signal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * handler. This does not handle long fs/gs base changes in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * the handler, but does not clobber them at least in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * normal case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) reload_segments(&sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return fpu__restore_sig(compat_ptr(sc.fpstate), 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) COMPAT_SYSCALL_DEFINE0(sigreturn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct pt_regs *regs = current_pt_regs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct sigframe_ia32 __user *frame = (struct sigframe_ia32 __user *)(regs->sp-8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) sigset_t set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (!access_ok(frame, sizeof(*frame)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (__get_user(set.sig[0], &frame->sc.oldmask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) || __get_user(((__u32 *)&set)[1], &frame->extramask[0]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) set_current_blocked(&set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (ia32_restore_sigcontext(regs, &frame->sc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) return regs->ax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) badframe:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) signal_fault(regs, frame, "32bit sigreturn");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) COMPAT_SYSCALL_DEFINE0(rt_sigreturn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct pt_regs *regs = current_pt_regs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct rt_sigframe_ia32 __user *frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) sigset_t set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) frame = (struct rt_sigframe_ia32 __user *)(regs->sp - 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (!access_ok(frame, sizeof(*frame)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (__get_user(set.sig[0], (__u64 __user *)&frame->uc.uc_sigmask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) set_current_blocked(&set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (compat_restore_altstack(&frame->uc.uc_stack))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return regs->ax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) badframe:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) signal_fault(regs, frame, "32bit rt sigreturn");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * Set up a signal frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define get_user_seg(seg) ({ unsigned int v; savesegment(seg, v); v; })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static __always_inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) __unsafe_setup_sigcontext32(struct sigcontext_32 __user *sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) void __user *fpstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct pt_regs *regs, unsigned int mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) unsafe_put_user(get_user_seg(gs), (unsigned int __user *)&sc->gs, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) unsafe_put_user(get_user_seg(fs), (unsigned int __user *)&sc->fs, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) unsafe_put_user(get_user_seg(ds), (unsigned int __user *)&sc->ds, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) unsafe_put_user(get_user_seg(es), (unsigned int __user *)&sc->es, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) unsafe_put_user(regs->di, &sc->di, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) unsafe_put_user(regs->si, &sc->si, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) unsafe_put_user(regs->bp, &sc->bp, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) unsafe_put_user(regs->sp, &sc->sp, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) unsafe_put_user(regs->bx, &sc->bx, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) unsafe_put_user(regs->dx, &sc->dx, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) unsafe_put_user(regs->cx, &sc->cx, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) unsafe_put_user(regs->ax, &sc->ax, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) unsafe_put_user(current->thread.trap_nr, &sc->trapno, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) unsafe_put_user(current->thread.error_code, &sc->err, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) unsafe_put_user(regs->ip, &sc->ip, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) unsafe_put_user(regs->cs, (unsigned int __user *)&sc->cs, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) unsafe_put_user(regs->flags, &sc->flags, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) unsafe_put_user(regs->sp, &sc->sp_at_signal, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) unsafe_put_user(regs->ss, (unsigned int __user *)&sc->ss, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) unsafe_put_user(ptr_to_compat(fpstate), &sc->fpstate, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /* non-iBCS2 extensions.. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) unsafe_put_user(mask, &sc->oldmask, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) unsafe_put_user(current->thread.cr2, &sc->cr2, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) Efault:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) #define unsafe_put_sigcontext32(sc, fp, regs, set, label) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (__unsafe_setup_sigcontext32(sc, fp, regs, set->sig[0])) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) goto label; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) } while(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * Determine which stack to use..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) size_t frame_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) void __user **fpstate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) unsigned long sp, fx_aligned, math_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /* Default to using normal stack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) sp = regs->sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) /* This is the X/Open sanctioned signal stack switching. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (ksig->ka.sa.sa_flags & SA_ONSTACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) sp = sigsp(sp, ksig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /* This is the legacy signal stack switching. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) else if (regs->ss != __USER32_DS &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) !(ksig->ka.sa.sa_flags & SA_RESTORER) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) ksig->ka.sa.sa_restorer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) sp = (unsigned long) ksig->ka.sa.sa_restorer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) sp = fpu__alloc_mathframe(sp, 1, &fx_aligned, &math_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) *fpstate = (struct _fpstate_32 __user *) sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (copy_fpstate_to_sigframe(*fpstate, (void __user *)fx_aligned,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) math_size) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) return (void __user *) -1L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) sp -= frame_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) /* Align the stack pointer according to the i386 ABI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * i.e. so that on function entry ((sp + 4) & 15) == 0. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) sp = ((sp + 4) & -16ul) - 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return (void __user *) sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) int ia32_setup_frame(int sig, struct ksignal *ksig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) compat_sigset_t *set, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) struct sigframe_ia32 __user *frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) void __user *restorer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) void __user *fp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) /* copy_to_user optimizes that into a single 8 byte store */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static const struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) u16 poplmovl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) u16 int80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) } __attribute__((packed)) code = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 0xb858, /* popl %eax ; movl $...,%eax */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) __NR_ia32_sigreturn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 0x80cd, /* int $0x80 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) frame = get_sigframe(ksig, regs, sizeof(*frame), &fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (ksig->ka.sa.sa_flags & SA_RESTORER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) restorer = ksig->ka.sa.sa_restorer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) /* Return stub is in 32bit vsyscall page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (current->mm->context.vdso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) restorer = current->mm->context.vdso +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) vdso_image_32.sym___kernel_sigreturn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) restorer = &frame->retcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (!user_access_begin(frame, sizeof(*frame)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) unsafe_put_user(sig, &frame->sig, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) unsafe_put_sigcontext32(&frame->sc, fp, regs, set, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) unsafe_put_user(set->sig[1], &frame->extramask[0], Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) unsafe_put_user(ptr_to_compat(restorer), &frame->pretcode, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * These are actually not used anymore, but left because some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * gdb versions depend on them as a marker.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) unsafe_put_user(*((u64 *)&code), (u64 __user *)frame->retcode, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) user_access_end();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) /* Set up registers for signal handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) regs->sp = (unsigned long) frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) regs->ip = (unsigned long) ksig->ka.sa.sa_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) /* Make -mregparm=3 work */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) regs->ax = sig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) regs->dx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) regs->cx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) loadsegment(ds, __USER32_DS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) loadsegment(es, __USER32_DS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) regs->cs = __USER32_CS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) regs->ss = __USER32_DS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) Efault:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) user_access_end();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) int ia32_setup_rt_frame(int sig, struct ksignal *ksig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) compat_sigset_t *set, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) struct rt_sigframe_ia32 __user *frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) void __user *restorer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) void __user *fp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /* unsafe_put_user optimizes that into a single 8 byte store */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) static const struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) u8 movl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) u16 int80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) u8 pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) } __attribute__((packed)) code = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 0xb8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) __NR_ia32_rt_sigreturn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 0x80cd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) frame = get_sigframe(ksig, regs, sizeof(*frame), &fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (!user_access_begin(frame, sizeof(*frame)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) unsafe_put_user(sig, &frame->sig, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) unsafe_put_user(ptr_to_compat(&frame->info), &frame->pinfo, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) unsafe_put_user(ptr_to_compat(&frame->uc), &frame->puc, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) /* Create the ucontext. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (static_cpu_has(X86_FEATURE_XSAVE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) unsafe_put_user(UC_FP_XSTATE, &frame->uc.uc_flags, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) unsafe_put_user(0, &frame->uc.uc_flags, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) unsafe_put_user(0, &frame->uc.uc_link, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) unsafe_compat_save_altstack(&frame->uc.uc_stack, regs->sp, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (ksig->ka.sa.sa_flags & SA_RESTORER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) restorer = ksig->ka.sa.sa_restorer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) restorer = current->mm->context.vdso +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) vdso_image_32.sym___kernel_rt_sigreturn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) unsafe_put_user(ptr_to_compat(restorer), &frame->pretcode, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) * Not actually used anymore, but left because some gdb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) * versions need it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) unsafe_put_user(*((u64 *)&code), (u64 __user *)frame->retcode, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) unsafe_put_sigcontext32(&frame->uc.uc_mcontext, fp, regs, set, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) unsafe_put_user(*(__u64 *)set, (__u64 *)&frame->uc.uc_sigmask, Efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) user_access_end();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (__copy_siginfo_to_user32(&frame->info, &ksig->info))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) /* Set up registers for signal handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) regs->sp = (unsigned long) frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) regs->ip = (unsigned long) ksig->ka.sa.sa_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) /* Make -mregparm=3 work */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) regs->ax = sig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) regs->dx = (unsigned long) &frame->info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) regs->cx = (unsigned long) &frame->uc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) loadsegment(ds, __USER32_DS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) loadsegment(es, __USER32_DS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) regs->cs = __USER32_CS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) regs->ss = __USER32_DS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) Efault:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) user_access_end();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }