Example #1
0
asmlinkage int
sys_sigaction(int sig, const struct old_sigaction __user *act,
              struct old_sigaction __user *oact)
{
    struct k_sigaction new_ka, old_ka;
    int ret;

    if (act) {
        old_sigset_t mask;
        if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
                __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
                __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
            return -EFAULT;
        __get_user(new_ka.sa.sa_flags, &act->sa_flags);
        __get_user(mask, &act->sa_mask);
        siginitset(&new_ka.sa.sa_mask, mask);
    }

    ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);

    if (!ret && oact) {
        if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
                __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
                __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
            return -EFAULT;
        __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
        __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
    }

    return ret;
}
Example #2
0
asmlinkage int
sys_sigsuspend(old_sigset_t mask,
               unsigned long r3, unsigned long r4, unsigned long r5,
               unsigned long r6, unsigned long r7,
               struct pt_regs * regs)
{
    sigset_t saveset;

    mask &= _BLOCKABLE;
    spin_lock_irq(&current->sighand->siglock);
    saveset = current->blocked;
    siginitset(&current->blocked, mask);
    recalc_sigpending();
    spin_unlock_irq(&current->sighand->siglock);

    REF_REG_RET = -EINTR;
    while (1) {
        current->state = TASK_INTERRUPTIBLE;
        schedule();
        regs->pc += 4;    /* because sys_sigreturn decrements the pc */
        if (do_signal(regs, &saveset)) {
            /* pc now points at signal handler. Need to decrement
               it because entry.S will increment it. */
            regs->pc -= 4;
            return -EINTR;
        }
    }
}
Example #3
0
SYSCALL_DEFINE3(osf_sigaction, int, sig,
                const struct osf_sigaction __user *, act,
                struct osf_sigaction __user *, oact)
{
    struct k_sigaction new_ka, old_ka;
    int ret;

    if (act) {
        old_sigset_t mask;
        if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
                __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
                __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
                __get_user(mask, &act->sa_mask))
            return -EFAULT;
        siginitset(&new_ka.sa.sa_mask, mask);
        new_ka.ka_restorer = NULL;
    }

    ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);

    if (!ret && oact) {
        if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
                __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
                __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
                __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
            return -EFAULT;
    }

    return ret;
}
Example #4
0
/*
 * The OSF/1 sigprocmask calling sequence is different from the
 * C sigprocmask() sequence..
 */
SYSCALL_DEFINE2(osf_sigprocmask, int, how, unsigned long, newmask)
{
    sigset_t oldmask;
    sigset_t mask;
    unsigned long res;

    siginitset(&mask, newmask & _BLOCKABLE);
    res = sigprocmask(how, &mask, &oldmask);
    if (!res) {
        force_successful_syscall_return();
        res = oldmask.sig[0];
    }
    return res;
}
Example #5
0
/*
 * Atomically swap in the new signal mask, and wait for a signal.
 */
long sys_sigsuspend(int history0, int history1, old_sigset_t mask)
{
    mask &= _BLOCKABLE;
    spin_lock_irq(&current->sighand->siglock);
    current->saved_sigmask = current->blocked;
    siginitset(&current->blocked, mask);
    recalc_sigpending();
    spin_unlock_irq(&current->sighand->siglock);

    current->state = TASK_INTERRUPTIBLE;
    schedule();
    set_thread_flag(TIF_RESTORE_SIGMASK);
    return -ERESTARTNOHAND;
}
Example #6
0
/*
 * Atomically swap in the new signal mask, and wait for a signal.
 */
asmlinkage int
sys_sigsuspend(old_sigset_t mask,
               unsigned long r5, unsigned long r6, unsigned long r7,
               struct pt_regs __regs)
{
    mask &= _BLOCKABLE;
    spin_lock_irq(&current->sighand->siglock);
    current->saved_sigmask = current->blocked;
    siginitset(&current->blocked, mask);
    recalc_sigpending();
    spin_unlock_irq(&current->sighand->siglock);

    current->state = TASK_INTERRUPTIBLE;
    schedule();
    set_restore_sigmask();

    return -ERESTARTNOHAND;
}
Example #7
0
SYSCALL_DEFINE3(sigaction, int, sig, const struct sigaction __user *, act,
                struct sigaction __user *, oact)
{
    struct k_sigaction new_ka, old_ka;
    int ret;
    int err = 0;

    if (act) {
        old_sigset_t mask;

        if (!access_ok(VERIFY_READ, act, sizeof(*act)))
            return -EFAULT;
        err |= __get_user(new_ka.sa.sa_handler, &act->sa_handler);
        err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
        err |= __get_user(mask, &act->sa_mask.sig[0]);
        if (err)
            return -EFAULT;

        siginitset(&new_ka.sa.sa_mask, mask);
    }

    ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);

    if (!ret && oact) {
        if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
            return -EFAULT;
        err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
        err |= __put_user(old_ka.sa.sa_handler, &oact->sa_handler);
        err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
        err |= __put_user(0, &oact->sa_mask.sig[1]);
        err |= __put_user(0, &oact->sa_mask.sig[2]);
        err |= __put_user(0, &oact->sa_mask.sig[3]);
        if (err)
            return -EFAULT;
    }

    return ret;
}