linux/arch/s390/kernel/compat_signal.c
<<
>>
Prefs
   1/*
   2 *    Copyright IBM Corp. 2000, 2006
   3 *    Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
   4 *               Gerhard Tonn (ton@de.ibm.com)                  
   5 *
   6 *  Copyright (C) 1991, 1992  Linus Torvalds
   7 *
   8 *  1997-11-28  Modified for POSIX.1b signals by Richard Henderson
   9 */
  10
  11#include <linux/compat.h>
  12#include <linux/sched.h>
  13#include <linux/mm.h>
  14#include <linux/smp.h>
  15#include <linux/kernel.h>
  16#include <linux/signal.h>
  17#include <linux/errno.h>
  18#include <linux/wait.h>
  19#include <linux/ptrace.h>
  20#include <linux/unistd.h>
  21#include <linux/stddef.h>
  22#include <linux/tty.h>
  23#include <linux/personality.h>
  24#include <linux/binfmts.h>
  25#include <asm/ucontext.h>
  26#include <asm/uaccess.h>
  27#include <asm/lowcore.h>
  28#include <asm/switch_to.h>
  29#include "compat_linux.h"
  30#include "compat_ptrace.h"
  31#include "entry.h"
  32
  33typedef struct 
  34{
  35        __u8 callee_used_stack[__SIGNAL_FRAMESIZE32];
  36        struct sigcontext32 sc;
  37        _sigregs32 sregs;
  38        int signo;
  39        __u32 gprs_high[NUM_GPRS];
  40        __u8 retcode[S390_SYSCALL_SIZE];
  41} sigframe32;
  42
  43typedef struct 
  44{
  45        __u8 callee_used_stack[__SIGNAL_FRAMESIZE32];
  46        __u8 retcode[S390_SYSCALL_SIZE];
  47        compat_siginfo_t info;
  48        struct ucontext32 uc;
  49        __u32 gprs_high[NUM_GPRS];
  50} rt_sigframe32;
  51
  52int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
  53{
  54        int err;
  55
  56        /* If you change siginfo_t structure, please be sure
  57           this code is fixed accordingly.
  58           It should never copy any pad contained in the structure
  59           to avoid security leaks, but must copy the generic
  60           3 ints plus the relevant union member.  
  61           This routine must convert siginfo from 64bit to 32bit as well
  62           at the same time.  */
  63        err = __put_user(from->si_signo, &to->si_signo);
  64        err |= __put_user(from->si_errno, &to->si_errno);
  65        err |= __put_user((short)from->si_code, &to->si_code);
  66        if (from->si_code < 0)
  67                err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
  68        else {
  69                switch (from->si_code >> 16) {
  70                case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
  71                case __SI_MESGQ >> 16:
  72                        err |= __put_user(from->si_int, &to->si_int);
  73                        /* fallthrough */
  74                case __SI_KILL >> 16:
  75                        err |= __put_user(from->si_pid, &to->si_pid);
  76                        err |= __put_user(from->si_uid, &to->si_uid);
  77                        break;
  78                case __SI_CHLD >> 16:
  79                        err |= __put_user(from->si_pid, &to->si_pid);
  80                        err |= __put_user(from->si_uid, &to->si_uid);
  81                        err |= __put_user(from->si_utime, &to->si_utime);
  82                        err |= __put_user(from->si_stime, &to->si_stime);
  83                        err |= __put_user(from->si_status, &to->si_status);
  84                        break;
  85                case __SI_FAULT >> 16:
  86                        err |= __put_user((unsigned long) from->si_addr,
  87                                          &to->si_addr);
  88                        break;
  89                case __SI_POLL >> 16:
  90                        err |= __put_user(from->si_band, &to->si_band);
  91                        err |= __put_user(from->si_fd, &to->si_fd);
  92                        break;
  93                case __SI_TIMER >> 16:
  94                        err |= __put_user(from->si_tid, &to->si_tid);
  95                        err |= __put_user(from->si_overrun, &to->si_overrun);
  96                        err |= __put_user(from->si_int, &to->si_int);
  97                        break;
  98                default:
  99                        break;
 100                }
 101        }
 102        return err ? -EFAULT : 0;
 103}
 104
 105int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
 106{
 107        int err;
 108        u32 tmp;
 109
 110        err = __get_user(to->si_signo, &from->si_signo);
 111        err |= __get_user(to->si_errno, &from->si_errno);
 112        err |= __get_user(to->si_code, &from->si_code);
 113
 114        if (to->si_code < 0)
 115                err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
 116        else {
 117                switch (to->si_code >> 16) {
 118                case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
 119                case __SI_MESGQ >> 16:
 120                        err |= __get_user(to->si_int, &from->si_int);
 121                        /* fallthrough */
 122                case __SI_KILL >> 16:
 123                        err |= __get_user(to->si_pid, &from->si_pid);
 124                        err |= __get_user(to->si_uid, &from->si_uid);
 125                        break;
 126                case __SI_CHLD >> 16:
 127                        err |= __get_user(to->si_pid, &from->si_pid);
 128                        err |= __get_user(to->si_uid, &from->si_uid);
 129                        err |= __get_user(to->si_utime, &from->si_utime);
 130                        err |= __get_user(to->si_stime, &from->si_stime);
 131                        err |= __get_user(to->si_status, &from->si_status);
 132                        break;
 133                case __SI_FAULT >> 16:
 134                        err |= __get_user(tmp, &from->si_addr);
 135                        to->si_addr = (void __force __user *)
 136                                (u64) (tmp & PSW32_ADDR_INSN);
 137                        break;
 138                case __SI_POLL >> 16:
 139                        err |= __get_user(to->si_band, &from->si_band);
 140                        err |= __get_user(to->si_fd, &from->si_fd);
 141                        break;
 142                case __SI_TIMER >> 16:
 143                        err |= __get_user(to->si_tid, &from->si_tid);
 144                        err |= __get_user(to->si_overrun, &from->si_overrun);
 145                        err |= __get_user(to->si_int, &from->si_int);
 146                        break;
 147                default:
 148                        break;
 149                }
 150        }
 151        return err ? -EFAULT : 0;
 152}
 153
 154static int save_sigregs32(struct pt_regs *regs, _sigregs32 __user *sregs)
 155{
 156        _sigregs32 user_sregs;
 157        int i;
 158
 159        user_sregs.regs.psw.mask = (__u32)(regs->psw.mask >> 32);
 160        user_sregs.regs.psw.mask &= PSW32_MASK_USER | PSW32_MASK_RI;
 161        user_sregs.regs.psw.mask |= PSW32_USER_BITS;
 162        user_sregs.regs.psw.addr = (__u32) regs->psw.addr |
 163                (__u32)(regs->psw.mask & PSW_MASK_BA);
 164        for (i = 0; i < NUM_GPRS; i++)
 165                user_sregs.regs.gprs[i] = (__u32) regs->gprs[i];
 166        save_access_regs(current->thread.acrs);
 167        memcpy(&user_sregs.regs.acrs, current->thread.acrs,
 168               sizeof(user_sregs.regs.acrs));
 169        save_fp_ctl(&current->thread.fp_regs.fpc);
 170        save_fp_regs(current->thread.fp_regs.fprs);
 171        memcpy(&user_sregs.fpregs, &current->thread.fp_regs,
 172               sizeof(user_sregs.fpregs));
 173        if (__copy_to_user(sregs, &user_sregs, sizeof(_sigregs32)))
 174                return -EFAULT;
 175        return 0;
 176}
 177
 178static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs)
 179{
 180        _sigregs32 user_sregs;
 181        int i;
 182
 183        /* Alwys make any pending restarted system call return -EINTR */
 184        current_thread_info()->restart_block.fn = do_no_restart_syscall;
 185
 186        if (__copy_from_user(&user_sregs, &sregs->regs, sizeof(user_sregs)))
 187                return -EFAULT;
 188
 189        if (!is_ri_task(current) && (user_sregs.regs.psw.mask & PSW32_MASK_RI))
 190                return -EINVAL;
 191
 192        /* Loading the floating-point-control word can fail. Do that first. */
 193        if (restore_fp_ctl(&user_sregs.fpregs.fpc))
 194                return -EINVAL;
 195
 196        /* Use regs->psw.mask instead of PSW_USER_BITS to preserve PER bit. */
 197        regs->psw.mask = (regs->psw.mask & ~(PSW_MASK_USER | PSW_MASK_RI)) |
 198                (__u64)(user_sregs.regs.psw.mask & PSW32_MASK_USER) << 32 |
 199                (__u64)(user_sregs.regs.psw.mask & PSW32_MASK_RI) << 32 |
 200                (__u64)(user_sregs.regs.psw.addr & PSW32_ADDR_AMODE);
 201        /* Check for invalid user address space control. */
 202        if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_HOME)
 203                regs->psw.mask = PSW_ASC_PRIMARY |
 204                        (regs->psw.mask & ~PSW_MASK_ASC);
 205        regs->psw.addr = (__u64)(user_sregs.regs.psw.addr & PSW32_ADDR_INSN);
 206        for (i = 0; i < NUM_GPRS; i++)
 207                regs->gprs[i] = (__u64) user_sregs.regs.gprs[i];
 208        memcpy(&current->thread.acrs, &user_sregs.regs.acrs,
 209               sizeof(current->thread.acrs));
 210        restore_access_regs(current->thread.acrs);
 211
 212        memcpy(&current->thread.fp_regs, &user_sregs.fpregs,
 213               sizeof(current->thread.fp_regs));
 214
 215        restore_fp_regs(current->thread.fp_regs.fprs);
 216        clear_thread_flag(TIF_SYSCALL); /* No longer in a system call */
 217        return 0;
 218}
 219
 220static int save_sigregs_gprs_high(struct pt_regs *regs, __u32 __user *uregs)
 221{
 222        __u32 gprs_high[NUM_GPRS];
 223        int i;
 224
 225        for (i = 0; i < NUM_GPRS; i++)
 226                gprs_high[i] = regs->gprs[i] >> 32;
 227        if (__copy_to_user(uregs, &gprs_high, sizeof(gprs_high)))
 228                return -EFAULT;
 229        return 0;
 230}
 231
 232static int restore_sigregs_gprs_high(struct pt_regs *regs, __u32 __user *uregs)
 233{
 234        __u32 gprs_high[NUM_GPRS];
 235        int i;
 236
 237        if (__copy_from_user(&gprs_high, uregs, sizeof(gprs_high)))
 238                return -EFAULT;
 239        for (i = 0; i < NUM_GPRS; i++)
 240                *(__u32 *)&regs->gprs[i] = gprs_high[i];
 241        return 0;
 242}
 243
 244asmlinkage long sys32_sigreturn(void)
 245{
 246        struct pt_regs *regs = task_pt_regs(current);
 247        sigframe32 __user *frame = (sigframe32 __user *)regs->gprs[15];
 248        sigset_t set;
 249
 250        if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE32))
 251                goto badframe;
 252        set_current_blocked(&set);
 253        if (restore_sigregs32(regs, &frame->sregs))
 254                goto badframe;
 255        if (restore_sigregs_gprs_high(regs, frame->gprs_high))
 256                goto badframe;
 257        return regs->gprs[2];
 258badframe:
 259        force_sig(SIGSEGV, current);
 260        return 0;
 261}
 262
 263asmlinkage long sys32_rt_sigreturn(void)
 264{
 265        struct pt_regs *regs = task_pt_regs(current);
 266        rt_sigframe32 __user *frame = (rt_sigframe32 __user *)regs->gprs[15];
 267        sigset_t set;
 268
 269        if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
 270                goto badframe;
 271        set_current_blocked(&set);
 272        if (restore_sigregs32(regs, &frame->uc.uc_mcontext))
 273                goto badframe;
 274        if (restore_sigregs_gprs_high(regs, frame->gprs_high))
 275                goto badframe;
 276        if (compat_restore_altstack(&frame->uc.uc_stack))
 277                goto badframe; 
 278        return regs->gprs[2];
 279badframe:
 280        force_sig(SIGSEGV, current);
 281        return 0;
 282}       
 283
 284/*
 285 * Set up a signal frame.
 286 */
 287
 288
 289/*
 290 * Determine which stack to use..
 291 */
 292static inline void __user *
 293get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
 294{
 295        unsigned long sp;
 296
 297        /* Default to using normal stack */
 298        sp = (unsigned long) A(regs->gprs[15]);
 299
 300        /* Overflow on alternate signal stack gives SIGSEGV. */
 301        if (on_sig_stack(sp) && !on_sig_stack((sp - frame_size) & -8UL))
 302                return (void __user *) -1UL;
 303
 304        /* This is the X/Open sanctioned signal stack switching.  */
 305        if (ka->sa.sa_flags & SA_ONSTACK) {
 306                if (! sas_ss_flags(sp))
 307                        sp = current->sas_ss_sp + current->sas_ss_size;
 308        }
 309
 310        return (void __user *)((sp - frame_size) & -8ul);
 311}
 312
 313static inline int map_signal(int sig)
 314{
 315        if (current_thread_info()->exec_domain
 316            && current_thread_info()->exec_domain->signal_invmap
 317            && sig < 32)
 318                return current_thread_info()->exec_domain->signal_invmap[sig];
 319        else
 320                return sig;
 321}
 322
 323static int setup_frame32(int sig, struct k_sigaction *ka,
 324                        sigset_t *set, struct pt_regs * regs)
 325{
 326        sigframe32 __user *frame = get_sigframe(ka, regs, sizeof(sigframe32));
 327
 328        if (frame == (void __user *) -1UL)
 329                goto give_sigsegv;
 330
 331        if (__copy_to_user(&frame->sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE32))
 332                goto give_sigsegv;
 333
 334        if (save_sigregs32(regs, &frame->sregs))
 335                goto give_sigsegv;
 336        if (save_sigregs_gprs_high(regs, frame->gprs_high))
 337                goto give_sigsegv;
 338        if (__put_user((unsigned long) &frame->sregs, &frame->sc.sregs))
 339                goto give_sigsegv;
 340
 341        /* Set up to return from userspace.  If provided, use a stub
 342           already in userspace.  */
 343        if (ka->sa.sa_flags & SA_RESTORER) {
 344                regs->gprs[14] = (__u64 __force) ka->sa.sa_restorer | PSW32_ADDR_AMODE;
 345        } else {
 346                regs->gprs[14] = (__u64 __force) frame->retcode | PSW32_ADDR_AMODE;
 347                if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn,
 348                               (u16 __force __user *)(frame->retcode)))
 349                        goto give_sigsegv;
 350        }
 351
 352        /* Set up backchain. */
 353        if (__put_user(regs->gprs[15], (unsigned int __user *) frame))
 354                goto give_sigsegv;
 355
 356        /* Set up registers for signal handler */
 357        regs->gprs[15] = (__force __u64) frame;
 358        /* Force 31 bit amode and default user address space control. */
 359        regs->psw.mask = PSW_MASK_BA |
 360                (PSW_USER_BITS & PSW_MASK_ASC) |
 361                (regs->psw.mask & ~PSW_MASK_ASC);
 362        regs->psw.addr = (__force __u64) ka->sa.sa_handler;
 363
 364        regs->gprs[2] = map_signal(sig);
 365        regs->gprs[3] = (__force __u64) &frame->sc;
 366
 367        /* We forgot to include these in the sigcontext.
 368           To avoid breaking binary compatibility, they are passed as args. */
 369        if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL ||
 370            sig == SIGTRAP || sig == SIGFPE) {
 371                /* set extra registers only for synchronous signals */
 372                regs->gprs[4] = regs->int_code & 127;
 373                regs->gprs[5] = regs->int_parm_long;
 374                regs->gprs[6] = task_thread_info(current)->last_break;
 375        }
 376
 377        /* Place signal number on stack to allow backtrace from handler.  */
 378        if (__put_user(regs->gprs[2], (int __force __user *) &frame->signo))
 379                goto give_sigsegv;
 380        return 0;
 381
 382give_sigsegv:
 383        force_sigsegv(sig, current);
 384        return -EFAULT;
 385}
 386
 387static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
 388                           sigset_t *set, struct pt_regs * regs)
 389{
 390        int err = 0;
 391        rt_sigframe32 __user *frame = get_sigframe(ka, regs, sizeof(rt_sigframe32));
 392
 393        if (frame == (void __user *) -1UL)
 394                goto give_sigsegv;
 395
 396        if (copy_siginfo_to_user32(&frame->info, info))
 397                goto give_sigsegv;
 398
 399        /* Create the ucontext.  */
 400        err |= __put_user(UC_EXTENDED, &frame->uc.uc_flags);
 401        err |= __put_user(0, &frame->uc.uc_link);
 402        err |= __compat_save_altstack(&frame->uc.uc_stack, regs->gprs[15]);
 403        err |= save_sigregs32(regs, &frame->uc.uc_mcontext);
 404        err |= save_sigregs_gprs_high(regs, frame->gprs_high);
 405        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
 406        if (err)
 407                goto give_sigsegv;
 408
 409        /* Set up to return from userspace.  If provided, use a stub
 410           already in userspace.  */
 411        if (ka->sa.sa_flags & SA_RESTORER) {
 412                regs->gprs[14] = (__u64 __force) ka->sa.sa_restorer | PSW32_ADDR_AMODE;
 413        } else {
 414                regs->gprs[14] = (__u64 __force) frame->retcode | PSW32_ADDR_AMODE;
 415                err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
 416                                  (u16 __force __user *)(frame->retcode));
 417        }
 418
 419        /* Set up backchain. */
 420        if (__put_user(regs->gprs[15], (unsigned int __force __user *) frame))
 421                goto give_sigsegv;
 422
 423        /* Set up registers for signal handler */
 424        regs->gprs[15] = (__force __u64) frame;
 425        /* Force 31 bit amode and default user address space control. */
 426        regs->psw.mask = PSW_MASK_BA |
 427                (PSW_USER_BITS & PSW_MASK_ASC) |
 428                (regs->psw.mask & ~PSW_MASK_ASC);
 429        regs->psw.addr = (__u64 __force) ka->sa.sa_handler;
 430
 431        regs->gprs[2] = map_signal(sig);
 432        regs->gprs[3] = (__force __u64) &frame->info;
 433        regs->gprs[4] = (__force __u64) &frame->uc;
 434        regs->gprs[5] = task_thread_info(current)->last_break;
 435        return 0;
 436
 437give_sigsegv:
 438        force_sigsegv(sig, current);
 439        return -EFAULT;
 440}
 441
 442/*
 443 * OK, we're invoking a handler
 444 */     
 445
 446void handle_signal32(unsigned long sig, struct k_sigaction *ka,
 447                    siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
 448{
 449        int ret;
 450
 451        /* Set up the stack frame */
 452        if (ka->sa.sa_flags & SA_SIGINFO)
 453                ret = setup_rt_frame32(sig, ka, info, oldset, regs);
 454        else
 455                ret = setup_frame32(sig, ka, oldset, regs);
 456        if (ret)
 457                return;
 458        signal_delivered(sig, info, ka, regs,
 459                                 test_thread_flag(TIF_SINGLE_STEP));
 460}
 461
 462