linux/arch/x86/ia32/ia32_signal.c
<<
>>
Prefs
   1/*
   2 *  linux/arch/x86_64/ia32/ia32_signal.c
   3 *
   4 *  Copyright (C) 1991, 1992  Linus Torvalds
   5 *
   6 *  1997-11-28  Modified for POSIX.1b signals by Richard Henderson
   7 *  2000-06-20  Pentium III FXSR, SSE support by Gareth Hughes
   8 *  2000-12-*   x86-64 compatibility mode signal handling by Andi Kleen
   9 */
  10
  11#include <linux/sched.h>
  12#include <linux/mm.h>
  13#include <linux/smp.h>
  14#include <linux/kernel.h>
  15#include <linux/signal.h>
  16#include <linux/errno.h>
  17#include <linux/wait.h>
  18#include <linux/ptrace.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 <asm/ucontext.h>
  25#include <asm/uaccess.h>
  26#include <asm/i387.h>
  27#include <asm/ptrace.h>
  28#include <asm/ia32_unistd.h>
  29#include <asm/user32.h>
  30#include <asm/sigcontext32.h>
  31#include <asm/proto.h>
  32#include <asm/vdso.h>
  33#include <asm/sigframe.h>
  34#include <asm/sys_ia32.h>
  35
  36#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
  37
  38#define FIX_EFLAGS      (X86_EFLAGS_AC | X86_EFLAGS_OF | \
  39                         X86_EFLAGS_DF | X86_EFLAGS_TF | X86_EFLAGS_SF | \
  40                         X86_EFLAGS_ZF | X86_EFLAGS_AF | X86_EFLAGS_PF | \
  41                         X86_EFLAGS_CF)
  42
  43void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
  44
  45int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
  46{
  47        int err = 0;
  48
  49        if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
  50                return -EFAULT;
  51
  52        put_user_try {
  53                /* If you change siginfo_t structure, please make sure that
  54                   this code is fixed accordingly.
  55                   It should never copy any pad contained in the structure
  56                   to avoid security leaks, but must copy the generic
  57                   3 ints plus the relevant union member.  */
  58                put_user_ex(from->si_signo, &to->si_signo);
  59                put_user_ex(from->si_errno, &to->si_errno);
  60                put_user_ex((short)from->si_code, &to->si_code);
  61
  62                if (from->si_code < 0) {
  63                        put_user_ex(from->si_pid, &to->si_pid);
  64                        put_user_ex(from->si_uid, &to->si_uid);
  65                        put_user_ex(ptr_to_compat(from->si_ptr), &to->si_ptr);
  66                } else {
  67                        /*
  68                         * First 32bits of unions are always present:
  69                         * si_pid === si_band === si_tid === si_addr(LS half)
  70                         */
  71                        put_user_ex(from->_sifields._pad[0],
  72                                          &to->_sifields._pad[0]);
  73                        switch (from->si_code >> 16) {
  74                        case __SI_FAULT >> 16:
  75                                break;
  76                        case __SI_CHLD >> 16:
  77                                put_user_ex(from->si_utime, &to->si_utime);
  78                                put_user_ex(from->si_stime, &to->si_stime);
  79                                put_user_ex(from->si_status, &to->si_status);
  80                                /* FALL THROUGH */
  81                        default:
  82                        case __SI_KILL >> 16:
  83                                put_user_ex(from->si_uid, &to->si_uid);
  84                                break;
  85                        case __SI_POLL >> 16:
  86                                put_user_ex(from->si_fd, &to->si_fd);
  87                                break;
  88                        case __SI_TIMER >> 16:
  89                                put_user_ex(from->si_overrun, &to->si_overrun);
  90                                put_user_ex(ptr_to_compat(from->si_ptr),
  91                                            &to->si_ptr);
  92                                break;
  93                                 /* This is not generated by the kernel as of now.  */
  94                        case __SI_RT >> 16:
  95                        case __SI_MESGQ >> 16:
  96                                put_user_ex(from->si_uid, &to->si_uid);
  97                                put_user_ex(from->si_int, &to->si_int);
  98                                break;
  99                        }
 100                }
 101        } put_user_catch(err);
 102
 103        return err;
 104}
 105
 106int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
 107{
 108        int err = 0;
 109        u32 ptr32;
 110
 111        if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
 112                return -EFAULT;
 113
 114        get_user_try {
 115                get_user_ex(to->si_signo, &from->si_signo);
 116                get_user_ex(to->si_errno, &from->si_errno);
 117                get_user_ex(to->si_code, &from->si_code);
 118
 119                get_user_ex(to->si_pid, &from->si_pid);
 120                get_user_ex(to->si_uid, &from->si_uid);
 121                get_user_ex(ptr32, &from->si_ptr);
 122                to->si_ptr = compat_ptr(ptr32);
 123        } get_user_catch(err);
 124
 125        return err;
 126}
 127
 128asmlinkage long sys32_sigsuspend(int history0, int history1, old_sigset_t mask)
 129{
 130        sigset_t blocked;
 131
 132        current->saved_sigmask = current->blocked;
 133
 134        mask &= _BLOCKABLE;
 135        siginitset(&blocked, mask);
 136        set_current_blocked(&blocked);
 137
 138        current->state = TASK_INTERRUPTIBLE;
 139        schedule();
 140
 141        set_restore_sigmask();
 142        return -ERESTARTNOHAND;
 143}
 144
 145asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *uss_ptr,
 146                                  stack_ia32_t __user *uoss_ptr,
 147                                  struct pt_regs *regs)
 148{
 149        stack_t uss, uoss;
 150        int ret, err = 0;
 151        mm_segment_t seg;
 152
 153        if (uss_ptr) {
 154                u32 ptr;
 155
 156                memset(&uss, 0, sizeof(stack_t));
 157                if (!access_ok(VERIFY_READ, uss_ptr, sizeof(stack_ia32_t)))
 158                        return -EFAULT;
 159
 160                get_user_try {
 161                        get_user_ex(ptr, &uss_ptr->ss_sp);
 162                        get_user_ex(uss.ss_flags, &uss_ptr->ss_flags);
 163                        get_user_ex(uss.ss_size, &uss_ptr->ss_size);
 164                } get_user_catch(err);
 165
 166                if (err)
 167                        return -EFAULT;
 168                uss.ss_sp = compat_ptr(ptr);
 169        }
 170        seg = get_fs();
 171        set_fs(KERNEL_DS);
 172        ret = do_sigaltstack(uss_ptr ? &uss : NULL, &uoss, regs->sp);
 173        set_fs(seg);
 174        if (ret >= 0 && uoss_ptr)  {
 175                if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(stack_ia32_t)))
 176                        return -EFAULT;
 177
 178                put_user_try {
 179                        put_user_ex(ptr_to_compat(uoss.ss_sp), &uoss_ptr->ss_sp);
 180                        put_user_ex(uoss.ss_flags, &uoss_ptr->ss_flags);
 181                        put_user_ex(uoss.ss_size, &uoss_ptr->ss_size);
 182                } put_user_catch(err);
 183
 184                if (err)
 185                        ret = -EFAULT;
 186        }
 187        return ret;
 188}
 189
 190/*
 191 * Do a signal return; undo the signal stack.
 192 */
 193#define loadsegment_gs(v)       load_gs_index(v)
 194#define loadsegment_fs(v)       loadsegment(fs, v)
 195#define loadsegment_ds(v)       loadsegment(ds, v)
 196#define loadsegment_es(v)       loadsegment(es, v)
 197
 198#define get_user_seg(seg)       ({ unsigned int v; savesegment(seg, v); v; })
 199#define set_user_seg(seg, v)    loadsegment_##seg(v)
 200
 201#define COPY(x)                 {               \
 202        get_user_ex(regs->x, &sc->x);           \
 203}
 204
 205#define GET_SEG(seg)            ({                      \
 206        unsigned short tmp;                             \
 207        get_user_ex(tmp, &sc->seg);                     \
 208        tmp;                                            \
 209})
 210
 211#define COPY_SEG_CPL3(seg)      do {                    \
 212        regs->seg = GET_SEG(seg) | 3;                   \
 213} while (0)
 214
 215#define RELOAD_SEG(seg)         {               \
 216        unsigned int pre = GET_SEG(seg);        \
 217        unsigned int cur = get_user_seg(seg);   \
 218        pre |= 3;                               \
 219        if (pre != cur)                         \
 220                set_user_seg(seg, pre);         \
 221}
 222
 223static int ia32_restore_sigcontext(struct pt_regs *regs,
 224                                   struct sigcontext_ia32 __user *sc,
 225                                   unsigned int *pax)
 226{
 227        unsigned int tmpflags, err = 0;
 228        void __user *buf;
 229        u32 tmp;
 230
 231        /* Always make any pending restarted system calls return -EINTR */
 232        current_thread_info()->restart_block.fn = do_no_restart_syscall;
 233
 234        get_user_try {
 235                /*
 236                 * Reload fs and gs if they have changed in the signal
 237                 * handler.  This does not handle long fs/gs base changes in
 238                 * the handler, but does not clobber them at least in the
 239                 * normal case.
 240                 */
 241                RELOAD_SEG(gs);
 242                RELOAD_SEG(fs);
 243                RELOAD_SEG(ds);
 244                RELOAD_SEG(es);
 245
 246                COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
 247                COPY(dx); COPY(cx); COPY(ip);
 248                /* Don't touch extended registers */
 249
 250                COPY_SEG_CPL3(cs);
 251                COPY_SEG_CPL3(ss);
 252
 253                get_user_ex(tmpflags, &sc->flags);
 254                regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
 255                /* disable syscall checks */
 256                regs->orig_ax = -1;
 257
 258                get_user_ex(tmp, &sc->fpstate);
 259                buf = compat_ptr(tmp);
 260                err |= restore_i387_xstate_ia32(buf);
 261
 262                get_user_ex(*pax, &sc->ax);
 263        } get_user_catch(err);
 264
 265        return err;
 266}
 267
 268asmlinkage long sys32_sigreturn(struct pt_regs *regs)
 269{
 270        struct sigframe_ia32 __user *frame = (struct sigframe_ia32 __user *)(regs->sp-8);
 271        sigset_t set;
 272        unsigned int ax;
 273
 274        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 275                goto badframe;
 276        if (__get_user(set.sig[0], &frame->sc.oldmask)
 277            || (_COMPAT_NSIG_WORDS > 1
 278                && __copy_from_user((((char *) &set.sig) + 4),
 279                                    &frame->extramask,
 280                                    sizeof(frame->extramask))))
 281                goto badframe;
 282
 283        sigdelsetmask(&set, ~_BLOCKABLE);
 284        set_current_blocked(&set);
 285
 286        if (ia32_restore_sigcontext(regs, &frame->sc, &ax))
 287                goto badframe;
 288        return ax;
 289
 290badframe:
 291        signal_fault(regs, frame, "32bit sigreturn");
 292        return 0;
 293}
 294
 295asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
 296{
 297        struct rt_sigframe_ia32 __user *frame;
 298        sigset_t set;
 299        unsigned int ax;
 300        struct pt_regs tregs;
 301
 302        frame = (struct rt_sigframe_ia32 __user *)(regs->sp - 4);
 303
 304        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 305                goto badframe;
 306        if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
 307                goto badframe;
 308
 309        sigdelsetmask(&set, ~_BLOCKABLE);
 310        set_current_blocked(&set);
 311
 312        if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
 313                goto badframe;
 314
 315        tregs = *regs;
 316        if (sys32_sigaltstack(&frame->uc.uc_stack, NULL, &tregs) == -EFAULT)
 317                goto badframe;
 318
 319        return ax;
 320
 321badframe:
 322        signal_fault(regs, frame, "32bit rt sigreturn");
 323        return 0;
 324}
 325
 326/*
 327 * Set up a signal frame.
 328 */
 329
 330static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
 331                                 void __user *fpstate,
 332                                 struct pt_regs *regs, unsigned int mask)
 333{
 334        int err = 0;
 335
 336        put_user_try {
 337                put_user_ex(get_user_seg(gs), (unsigned int __user *)&sc->gs);
 338                put_user_ex(get_user_seg(fs), (unsigned int __user *)&sc->fs);
 339                put_user_ex(get_user_seg(ds), (unsigned int __user *)&sc->ds);
 340                put_user_ex(get_user_seg(es), (unsigned int __user *)&sc->es);
 341
 342                put_user_ex(regs->di, &sc->di);
 343                put_user_ex(regs->si, &sc->si);
 344                put_user_ex(regs->bp, &sc->bp);
 345                put_user_ex(regs->sp, &sc->sp);
 346                put_user_ex(regs->bx, &sc->bx);
 347                put_user_ex(regs->dx, &sc->dx);
 348                put_user_ex(regs->cx, &sc->cx);
 349                put_user_ex(regs->ax, &sc->ax);
 350                put_user_ex(current->thread.trap_no, &sc->trapno);
 351                put_user_ex(current->thread.error_code, &sc->err);
 352                put_user_ex(regs->ip, &sc->ip);
 353                put_user_ex(regs->cs, (unsigned int __user *)&sc->cs);
 354                put_user_ex(regs->flags, &sc->flags);
 355                put_user_ex(regs->sp, &sc->sp_at_signal);
 356                put_user_ex(regs->ss, (unsigned int __user *)&sc->ss);
 357
 358                put_user_ex(ptr_to_compat(fpstate), &sc->fpstate);
 359
 360                /* non-iBCS2 extensions.. */
 361                put_user_ex(mask, &sc->oldmask);
 362                put_user_ex(current->thread.cr2, &sc->cr2);
 363        } put_user_catch(err);
 364
 365        return err;
 366}
 367
 368/*
 369 * Determine which stack to use..
 370 */
 371static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
 372                                 size_t frame_size,
 373                                 void **fpstate)
 374{
 375        unsigned long sp;
 376
 377        /* Default to using normal stack */
 378        sp = regs->sp;
 379
 380        /* This is the X/Open sanctioned signal stack switching.  */
 381        if (ka->sa.sa_flags & SA_ONSTACK) {
 382                if (sas_ss_flags(sp) == 0)
 383                        sp = current->sas_ss_sp + current->sas_ss_size;
 384        }
 385
 386        /* This is the legacy signal stack switching. */
 387        else if ((regs->ss & 0xffff) != __USER32_DS &&
 388                !(ka->sa.sa_flags & SA_RESTORER) &&
 389                 ka->sa.sa_restorer)
 390                sp = (unsigned long) ka->sa.sa_restorer;
 391
 392        if (used_math()) {
 393                sp = sp - sig_xstate_ia32_size;
 394                *fpstate = (struct _fpstate_ia32 *) sp;
 395                if (save_i387_xstate_ia32(*fpstate) < 0)
 396                        return (void __user *) -1L;
 397        }
 398
 399        sp -= frame_size;
 400        /* Align the stack pointer according to the i386 ABI,
 401         * i.e. so that on function entry ((sp + 4) & 15) == 0. */
 402        sp = ((sp + 4) & -16ul) - 4;
 403        return (void __user *) sp;
 404}
 405
 406int ia32_setup_frame(int sig, struct k_sigaction *ka,
 407                     compat_sigset_t *set, struct pt_regs *regs)
 408{
 409        struct sigframe_ia32 __user *frame;
 410        void __user *restorer;
 411        int err = 0;
 412        void __user *fpstate = NULL;
 413
 414        /* copy_to_user optimizes that into a single 8 byte store */
 415        static const struct {
 416                u16 poplmovl;
 417                u32 val;
 418                u16 int80;
 419        } __attribute__((packed)) code = {
 420                0xb858,          /* popl %eax ; movl $...,%eax */
 421                __NR_ia32_sigreturn,
 422                0x80cd,         /* int $0x80 */
 423        };
 424
 425        frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
 426
 427        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 428                return -EFAULT;
 429
 430        if (__put_user(sig, &frame->sig))
 431                return -EFAULT;
 432
 433        if (ia32_setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]))
 434                return -EFAULT;
 435
 436        if (_COMPAT_NSIG_WORDS > 1) {
 437                if (__copy_to_user(frame->extramask, &set->sig[1],
 438                                   sizeof(frame->extramask)))
 439                        return -EFAULT;
 440        }
 441
 442        if (ka->sa.sa_flags & SA_RESTORER) {
 443                restorer = ka->sa.sa_restorer;
 444        } else {
 445                /* Return stub is in 32bit vsyscall page */
 446                if (current->mm->context.vdso)
 447                        restorer = VDSO32_SYMBOL(current->mm->context.vdso,
 448                                                 sigreturn);
 449                else
 450                        restorer = &frame->retcode;
 451        }
 452
 453        put_user_try {
 454                put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
 455
 456                /*
 457                 * These are actually not used anymore, but left because some
 458                 * gdb versions depend on them as a marker.
 459                 */
 460                put_user_ex(*((u64 *)&code), (u64 *)frame->retcode);
 461        } put_user_catch(err);
 462
 463        if (err)
 464                return -EFAULT;
 465
 466        /* Set up registers for signal handler */
 467        regs->sp = (unsigned long) frame;
 468        regs->ip = (unsigned long) ka->sa.sa_handler;
 469
 470        /* Make -mregparm=3 work */
 471        regs->ax = sig;
 472        regs->dx = 0;
 473        regs->cx = 0;
 474
 475        loadsegment(ds, __USER32_DS);
 476        loadsegment(es, __USER32_DS);
 477
 478        regs->cs = __USER32_CS;
 479        regs->ss = __USER32_DS;
 480
 481        return 0;
 482}
 483
 484int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 485                        compat_sigset_t *set, struct pt_regs *regs)
 486{
 487        struct rt_sigframe_ia32 __user *frame;
 488        void __user *restorer;
 489        int err = 0;
 490        void __user *fpstate = NULL;
 491
 492        /* __copy_to_user optimizes that into a single 8 byte store */
 493        static const struct {
 494                u8 movl;
 495                u32 val;
 496                u16 int80;
 497                u8  pad;
 498        } __attribute__((packed)) code = {
 499                0xb8,
 500                __NR_ia32_rt_sigreturn,
 501                0x80cd,
 502                0,
 503        };
 504
 505        frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
 506
 507        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 508                return -EFAULT;
 509
 510        put_user_try {
 511                put_user_ex(sig, &frame->sig);
 512                put_user_ex(ptr_to_compat(&frame->info), &frame->pinfo);
 513                put_user_ex(ptr_to_compat(&frame->uc), &frame->puc);
 514                err |= copy_siginfo_to_user32(&frame->info, info);
 515
 516                /* Create the ucontext.  */
 517                if (cpu_has_xsave)
 518                        put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags);
 519                else
 520                        put_user_ex(0, &frame->uc.uc_flags);
 521                put_user_ex(0, &frame->uc.uc_link);
 522                put_user_ex(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
 523                put_user_ex(sas_ss_flags(regs->sp),
 524                            &frame->uc.uc_stack.ss_flags);
 525                put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
 526                err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
 527                                             regs, set->sig[0]);
 528                err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
 529
 530                if (ka->sa.sa_flags & SA_RESTORER)
 531                        restorer = ka->sa.sa_restorer;
 532                else
 533                        restorer = VDSO32_SYMBOL(current->mm->context.vdso,
 534                                                 rt_sigreturn);
 535                put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
 536
 537                /*
 538                 * Not actually used anymore, but left because some gdb
 539                 * versions need it.
 540                 */
 541                put_user_ex(*((u64 *)&code), (u64 *)frame->retcode);
 542        } put_user_catch(err);
 543
 544        if (err)
 545                return -EFAULT;
 546
 547        /* Set up registers for signal handler */
 548        regs->sp = (unsigned long) frame;
 549        regs->ip = (unsigned long) ka->sa.sa_handler;
 550
 551        /* Make -mregparm=3 work */
 552        regs->ax = sig;
 553        regs->dx = (unsigned long) &frame->info;
 554        regs->cx = (unsigned long) &frame->uc;
 555
 556        loadsegment(ds, __USER32_DS);
 557        loadsegment(es, __USER32_DS);
 558
 559        regs->cs = __USER32_CS;
 560        regs->ss = __USER32_DS;
 561
 562        return 0;
 563}
 564