Esempio n. 1
0
/*
 * These syscalls are unncessary because it is next to impossible to
 * find 4.3BSD binaries built for i386.  The current libc has routines
 * which fake the 4.3BSD family of signal syscalls, so anything built
 * from source won't be using these.
 *
 * This file is provided for educational purposes only.  The osigvec()
 * syscall is probably broken because the current signal code uses
 * a different signal trampoline.
 *
 * MPALMOSTSAFE
 */
int
sys_osigvec(struct osigvec_args *uap)
{
	struct sigvec vec;
	struct sigaction nsa, osa;
	struct sigaction *nsap, *osap;
	int error;

	if (uap->signum <= 0 || uap->signum >= ONSIG)
		return (EINVAL);
	nsap = (uap->nsv != NULL) ? &nsa : NULL;
	osap = (uap->osv != NULL) ? &osa : NULL;
	if (nsap) {
		error = copyin(uap->nsv, &vec, sizeof(vec));
		if (error)
			return (error);
		nsap->sa_handler = vec.sv_handler;
		OSIG2SIG(vec.sv_mask, nsap->sa_mask);
		nsap->sa_flags = vec.sv_flags;
		nsap->sa_flags ^= SA_RESTART;	/* opposite of SV_INTERRUPT */
	}

	error = kern_sigaction(uap->signum, nsap, osap);

	if (osap && !error) {
		vec.sv_handler = osap->sa_handler;
		SIG2OSIG(osap->sa_mask, vec.sv_mask);
		vec.sv_flags = osap->sa_flags;
		vec.sv_flags &= ~SA_NOCLDWAIT;
		vec.sv_flags ^= SA_RESTART;
		error = copyout(&vec, uap->osv, sizeof(vec));
	}
	return (error);
}
Esempio n. 2
0
/*
 * MPSAFE
 */
int
sys_osigsetmask(struct osigsetmask_args *uap)
{
	struct lwp *lp = curthread->td_lwp;
	sigset_t set;

	OSIG2SIG(uap->mask, set);
	SIG_CANTMASK(set);
	crit_enter();
	SIG2OSIG(lp->lwp_sigmask, uap->sysmsg_iresult);
	SIGSETLO(lp->lwp_sigmask, set);
	crit_exit();
	return (0);
}
Esempio n. 3
0
static void
ia32_osendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
{
	struct ia32_sigframe3 sf, *fp;
	struct proc *p;
	struct thread *td;
	struct sigacts *psp;
	struct trapframe *regs;
	int sig;
	int oonstack;

	td = curthread;
	p = td->td_proc;
	PROC_LOCK_ASSERT(p, MA_OWNED);
	sig = ksi->ksi_signo;
	psp = p->p_sigacts;
	mtx_assert(&psp->ps_mtx, MA_OWNED);
	regs = td->td_frame;
	oonstack = sigonstack(regs->tf_rsp);

	/* Allocate space for the signal handler context. */
	if ((td->td_pflags & TDP_ALTSTACK) && !oonstack &&
	    SIGISMEMBER(psp->ps_sigonstack, sig)) {
		fp = (struct ia32_sigframe3 *)(td->td_sigstk.ss_sp +
		    td->td_sigstk.ss_size - sizeof(sf));
		td->td_sigstk.ss_flags |= SS_ONSTACK;
	} else
		fp = (struct ia32_sigframe3 *)regs->tf_rsp - 1;

	/* Translate the signal if appropriate. */
	if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
		sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];

	/* Build the argument list for the signal handler. */
	sf.sf_signum = sig;
	sf.sf_scp = (register_t)&fp->sf_siginfo.si_sc;
	if (SIGISMEMBER(psp->ps_siginfo, sig)) {
		/* Signal handler installed with SA_SIGINFO. */
		sf.sf_arg2 = (register_t)&fp->sf_siginfo;
		sf.sf_siginfo.si_signo = sig;
		sf.sf_siginfo.si_code = ksi->ksi_code;
		sf.sf_ah = (uintptr_t)catcher;
	} else {
		/* Old FreeBSD-style arguments. */
		sf.sf_arg2 = ksi->ksi_code;
		sf.sf_addr = (register_t)ksi->ksi_addr;
		sf.sf_ah = (uintptr_t)catcher;
	}
	mtx_unlock(&psp->ps_mtx);
	PROC_UNLOCK(p);

	/* Save most if not all of trap frame. */
	sf.sf_siginfo.si_sc.sc_eax = regs->tf_rax;
	sf.sf_siginfo.si_sc.sc_ebx = regs->tf_rbx;
	sf.sf_siginfo.si_sc.sc_ecx = regs->tf_rcx;
	sf.sf_siginfo.si_sc.sc_edx = regs->tf_rdx;
	sf.sf_siginfo.si_sc.sc_esi = regs->tf_rsi;
	sf.sf_siginfo.si_sc.sc_edi = regs->tf_rdi;
	sf.sf_siginfo.si_sc.sc_cs = regs->tf_cs;
	sf.sf_siginfo.si_sc.sc_ds = regs->tf_ds;
	sf.sf_siginfo.si_sc.sc_ss = regs->tf_ss;
	sf.sf_siginfo.si_sc.sc_es = regs->tf_es;
	sf.sf_siginfo.si_sc.sc_fs = regs->tf_fs;
	sf.sf_siginfo.si_sc.sc_gs = regs->tf_gs;
	sf.sf_siginfo.si_sc.sc_isp = regs->tf_rsp;

	/* Build the signal context to be used by osigreturn(). */
	sf.sf_siginfo.si_sc.sc_onstack = (oonstack) ? 1 : 0;
	SIG2OSIG(*mask, sf.sf_siginfo.si_sc.sc_mask);
	sf.sf_siginfo.si_sc.sc_esp = regs->tf_rsp;
	sf.sf_siginfo.si_sc.sc_ebp = regs->tf_rbp;
	sf.sf_siginfo.si_sc.sc_eip = regs->tf_rip;
	sf.sf_siginfo.si_sc.sc_eflags = regs->tf_rflags;
	sf.sf_siginfo.si_sc.sc_trapno = regs->tf_trapno;
	sf.sf_siginfo.si_sc.sc_err = regs->tf_err;

	/*
	 * Copy the sigframe out to the user's stack.
	 */
	if (copyout(&sf, fp, sizeof(*fp)) != 0) {
#ifdef DEBUG
		printf("process %ld has trashed its stack\n", (long)p->p_pid);
#endif
		PROC_LOCK(p);
		sigexit(td, SIGILL);
	}

	regs->tf_rsp = (uintptr_t)fp;
	regs->tf_rip = p->p_sysent->sv_psstrings - sz_ia32_osigcode;
	regs->tf_rflags &= ~(PSL_T | PSL_D);
	regs->tf_cs = _ucode32sel;
	regs->tf_ds = _udatasel;
	regs->tf_es = _udatasel;
	regs->tf_fs = _udatasel;
	regs->tf_ss = _udatasel;
	set_pcb_flags(td->td_pcb, PCB_FULL_IRET);
	PROC_LOCK(p);
	mtx_lock(&psp->ps_mtx);
}