root/arch/x86/ia32/ia32_signal.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ia32_restore_sigcontext
  2. COMPAT_SYSCALL_DEFINE0
  3. COMPAT_SYSCALL_DEFINE0
  4. ia32_setup_sigcontext
  5. get_sigframe
  6. ia32_setup_frame
  7. ia32_setup_rt_frame

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

/* [<][>][^][v][top][bottom][index][help] */