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