asmlinkage long sys32_sigreturn(struct pt_regs *regs) { sigframe32 __user *frame = (sigframe32 __user *)regs->gprs[15]; sigset_t set; if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) goto badframe; if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE32)) goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); if (restore_sigregs32(regs, &frame->sregs)) goto badframe; return regs->gprs[2]; badframe: force_sig(SIGSEGV, current); return 0; }
asmlinkage long sys32_sigreturn(void) { struct pt_regs *regs = task_pt_regs(current); sigframe32 __user *frame = (sigframe32 __user *)regs->gprs[15]; sigset_t set; if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE32)) goto badframe; set_current_blocked(&set); if (restore_sigregs32(regs, &frame->sregs)) goto badframe; if (restore_sigregs_gprs_high(regs, frame->gprs_high)) goto badframe; return regs->gprs[2]; badframe: force_sig(SIGSEGV, current); return 0; }
asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs) { rt_sigframe32 __user *frame = (rt_sigframe32 __user *)regs->gprs[15]; sigset_t set; stack_t st; __u32 ss_sp; int err; mm_segment_t old_fs = get_fs(); if (verify_area(VERIFY_READ, frame, sizeof(*frame))) goto badframe; if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); if (restore_sigregs32(regs, &frame->uc.uc_mcontext)) goto badframe; err = __get_user(ss_sp, &frame->uc.uc_stack.ss_sp); st.ss_sp = (void *) A((unsigned long)ss_sp); err |= __get_user(st.ss_size, &frame->uc.uc_stack.ss_size); err |= __get_user(st.ss_flags, &frame->uc.uc_stack.ss_flags); if (err) goto badframe; /* It is more difficult to avoid calling this function than to call it and ignore errors. */ set_fs (KERNEL_DS); do_sigaltstack((stack_t __user *)&st, NULL, regs->gprs[15]); set_fs (old_fs); return regs->gprs[2]; badframe: force_sig(SIGSEGV, current); return 0; }
asmlinkage long sys32_rt_sigreturn(void) { struct pt_regs *regs = task_pt_regs(current); rt_sigframe32 __user *frame = (rt_sigframe32 __user *)regs->gprs[15]; sigset_t set; if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) goto badframe; set_current_blocked(&set); if (restore_sigregs32(regs, &frame->uc.uc_mcontext)) goto badframe; if (restore_sigregs_gprs_high(regs, frame->gprs_high)) goto badframe; if (compat_restore_altstack(&frame->uc.uc_stack)) goto badframe; return regs->gprs[2]; badframe: force_sig(SIGSEGV, current); return 0; }
asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs) { rt_sigframe32 __user *frame = (rt_sigframe32 __user *)regs->gprs[15]; sigset_t set; stack_t st; __u32 ss_sp; int err; mm_segment_t old_fs = get_fs(); if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) goto badframe; if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); if (restore_sigregs32(regs, &frame->uc.uc_mcontext)) goto badframe; err = __get_user(ss_sp, &frame->uc.uc_stack.ss_sp); st.ss_sp = compat_ptr(ss_sp); err |= __get_user(st.ss_size, &frame->uc.uc_stack.ss_size); err |= __get_user(st.ss_flags, &frame->uc.uc_stack.ss_flags); if (err) goto badframe; set_fs (KERNEL_DS); do_sigaltstack((stack_t __force __user *)&st, NULL, regs->gprs[15]); set_fs (old_fs); return regs->gprs[2]; badframe: force_sig(SIGSEGV, current); return 0; }