Esempio n. 1
0
static void
sendsig_siginfo(const ksiginfo_t *ksi, const sigset_t *mask)
{
	struct lwp *l = curlwp;
	struct proc *p = l->l_proc;
	struct sigacts *ps = p->p_sigacts;
	struct trapframe *tf = l->l_md.md_regs;
	int sig = ksi->ksi_signo, error;
	sig_t catcher = SIGACTION(p, sig).sa_handler;
	struct sigframe_siginfo *fp, frame;
	int onstack;

	switch (ps->sa_sigdesc[sig].sd_vers) {
	case 0:		/* FALLTHROUGH */ /* handled by sendsig_sigcontext */
	case 1:		/* FALLTHROUGH */ /* handled by sendsig_sigcontext */
	default:	/* unknown version */
		printf("sendsig_siginfo: bad version %d\n",
		       ps->sa_sigdesc[sig].sd_vers);
		sigexit(l, SIGILL);
		/* NOTREACHED */
	case 2:
		break;
	}

	fp = getframe(l, sig, &onstack);
	--fp;

	frame.sf_si._info = ksi->ksi_info;
	frame.sf_uc.uc_link = l->l_ctxlink;
	frame.sf_uc.uc_sigmask = *mask;
	frame.sf_uc.uc_flags = _UC_SIGMASK;
	frame.sf_uc.uc_flags |= (l->l_sigstk.ss_flags & SS_ONSTACK)
		? _UC_SETSTACK : _UC_CLRSTACK;
	memset(&frame.sf_uc.uc_stack, 0, sizeof(frame.sf_uc.uc_stack));
	sendsig_reset(l, sig);
	mutex_exit(p->p_lock);
	cpu_getmcontext(l, &frame.sf_uc.uc_mcontext, &frame.sf_uc.uc_flags);
	error = copyout(&frame, fp, sizeof(frame));
	mutex_enter(p->p_lock);

	if (error != 0) {
		/*
		 * Process has trashed its stack; give it an illegal
		 * instruction to halt it in its tracks.
		 */
		sigexit(l, SIGILL);
		/* NOTREACHED */
	}

	tf->tf_r4 = sig;		/* "signum" argument for handler */
	tf->tf_r5 = (int)&fp->sf_si;	/* "sip" argument for handler */
	tf->tf_r6 = (int)&fp->sf_uc;	/* "ucp" argument for handler */
 	tf->tf_spc = (int)catcher;
	tf->tf_r15 = (int)fp;
	tf->tf_pr = (int)ps->sa_sigdesc[sig].sd_tramp;

	/* Remember if we're now on the signal stack. */
	if (onstack)
		l->l_sigstk.ss_flags |= SS_ONSTACK;
}
Esempio n. 2
0
static vaddr_t
setupstack_siginfo3(const ksiginfo_t *ksi, const sigset_t *mask, int vers,
	struct lwp *l, struct trapframe *tf, vaddr_t sp, int onstack,
	vaddr_t handler)
{
	struct trampoline3 tramp;
	ucontext_t uc;

	/*
	 * Arguments given to the signal handler.
	 */
	tramp.narg = 3;
	tramp.sig = ksi->ksi_signo;
	sp -= sizeof(uc);		tramp.ucp = sp;
	sp -= sizeof(siginfo_t);	tramp.sip = sp;
	sp -= sizeof(tramp);

	/* Save register context.  */
	uc.uc_flags = _UC_SIGMASK;
	uc.uc_sigmask = *mask;
	uc.uc_link = NULL;
	memset(&uc.uc_stack, 0, sizeof(uc.uc_stack));
	cpu_getmcontext(l, &uc.uc_mcontext, &uc.uc_flags);

	tf->fp = handler;

	/* Copy the context to the stack.  */
	if (copyout(&uc, (char *)tramp.ucp, sizeof(uc)) != 0 ||
	    copyout(&ksi->ksi_info, (char *)tramp.sip, sizeof(ksi->ksi_info)) != 0 ||
	    copyout(&tramp, (char *)sp, sizeof(tramp)) != 0)
		sigexit(l, SIGILL);

	return sp;
};
Esempio n. 3
0
void
sendsig_siginfo(const ksiginfo_t *ksi, const sigset_t *mask)
{
	struct lwp * const l = curlwp;
	struct proc * const p = l->l_proc;
	struct trapframe * const tf = l->l_md.md_utf;
	struct sigaltstack * const ss = &l->l_sigstk;
	const struct sigact_sigdesc * const sd =
	    &p->p_sigacts->sa_sigdesc[ksi->ksi_signo];

	const uintptr_t handler = (uintptr_t) sd->sd_sigact.sa_handler;
	const bool onstack_p = (ss->ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0
	    && (sd->sd_sigact.sa_flags & SA_ONSTACK) != 0;

	vaddr_t sp;

	sp = onstack_p ? ((vaddr_t)ss->ss_sp + ss->ss_size) & -16 : tf->tf_sp;

	sp -= sizeof(ucontext_t);
	const vaddr_t ucp = sp;

	sp -= roundup(sizeof(siginfo_t), 16);
	const vaddr_t sip = sp;

	ucontext_t uc;
	memset(&uc, 0, sizeof(uc));
	uc.uc_flags = _UC_SIGMASK;
	uc.uc_sigmask = *mask;
	uc.uc_link = l->l_ctxlink;
	sendsig_reset(l, ksi->ksi_signo);
	mutex_exit(p->p_lock);
	cpu_getmcontext(l, &uc.uc_mcontext, &uc.uc_flags);

	/*
	 * Copy the siginfo and ucontext onto the user's stack.
	 */
	int error = copyout(&ksi->ksi_info, (void *)sip, sizeof(ksi->ksi_info));
	if (error == 0) {
		error = copyout(&uc, (void *)ucp, sizeof(uc));
	}

	mutex_enter(p->p_lock);

	if (error || sd->sd_vers != 2) {
		/*
		 * Thread has trashed its stack.  Blow it away.
		 */
		if (error == 0) {
			printf("pid %d.%d(%s): %p(sig %d): bad version %d\n",
			    p->p_pid, l->l_lid, p->p_comm, __func__,
			    ksi->ksi_signo, sd->sd_vers);
		}
		sigexit(l, SIGILL);
		/* NOTREACHED */
	}

	tf->tf_reg[0] = ksi->ksi_signo;
	tf->tf_reg[1] = sip;
	tf->tf_reg[2] = ucp;
	tf->tf_reg[28] = ucp;	/* put in a callee saved register */

	tf->tf_sp = sp;
	tf->tf_lr = sd->sd_tramp;
	tf->tf_pc = handler;

	/*
	 * Remember if we'ere now on the signal stack.
	 */
	if (onstack_p)
		ss->ss_flags |= SS_ONSTACK;
}