FreeBSD/sys/i386/linux/linux_sysvec.c
/*
 * System call to cleanup state after a signal
 * has been taken.  Reset signal mask and
 * stack state from context left by sendsig (above).
 * Return to previous pc and psl as specified by
 * context left by sendsig. Check carefully to
 * make sure that the user has not modified the
 * psl to gain improper privileges or to cause
 * a machine fault.
 */
System call to cleanup state after a signal
has been taken.  Reset signal mask and
stack state from context left by sendsig (above).
Return to previous pc and psl as specified by
context left by sendsig. Check carefully to
make sure that the user has not modified the
psl to gain improper privileges or to cause
a machine fault.
System call to cleanup state after a signal has been taken . Reset signal mask and stack state from context left by sendsig ( above ) . Return to previous pc and psl as specified by context left by sendsig . Check carefully to make sure that the user has not modified the psl to gain improper privileges or to cause a machine fault .
int
linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args)
{
	struct l_sigframe frame;
	struct trapframe *regs;
	l_sigset_t lmask;
	sigset_t bmask;
	int eflags;
	ksiginfo_t ksi;
	regs = td->td_frame;
#ifdef DEBUG
	if (ldebug(sigreturn))
		printf(ARGS(sigreturn, "%p"), (void *)args->sfp);
#endif
	if (copyin(args->sfp, &frame, sizeof(frame)) != 0)
		return (EFAULT);
#define	EFLAGS_SECURE(ef, oef)	((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0)
	eflags = frame.sf_sc.sc_eflags;
	if (!EFLAGS_SECURE(eflags, regs->tf_eflags))
		return (EINVAL);
#define	CS_SECURE(cs)	(ISPL(cs) == SEL_UPL)
	if (!CS_SECURE(frame.sf_sc.sc_cs)) {
		ksiginfo_init_trap(&ksi);
		ksi.ksi_signo = SIGBUS;
		ksi.ksi_code = BUS_OBJERR;
		ksi.ksi_trapno = T_PROTFLT;
		ksi.ksi_addr = (void *)regs->tf_eip;
		trapsignal(td, &ksi);
		return (EINVAL);
	}
	lmask.__mask = frame.sf_sc.sc_mask;
	linux_to_bsd_sigset(&lmask, &bmask);
	kern_sigprocmask(td, SIG_SETMASK, &bmask, NULL, 0);
	regs->tf_fs     = frame.sf_sc.sc_fs;
	regs->tf_es     = frame.sf_sc.sc_es;
	regs->tf_ds     = frame.sf_sc.sc_ds;
	regs->tf_edi    = frame.sf_sc.sc_edi;
	regs->tf_esi    = frame.sf_sc.sc_esi;
	regs->tf_ebp    = frame.sf_sc.sc_ebp;
	regs->tf_ebx    = frame.sf_sc.sc_ebx;
	regs->tf_edx    = frame.sf_sc.sc_edx;
	regs->tf_ecx    = frame.sf_sc.sc_ecx;
	regs->tf_eax    = frame.sf_sc.sc_eax;
	regs->tf_eip    = frame.sf_sc.sc_eip;
	regs->tf_cs     = frame.sf_sc.sc_cs;
	regs->tf_eflags = eflags;
	regs->tf_esp    = frame.sf_sc.sc_esp_at_signal;
	regs->tf_ss     = frame.sf_sc.sc_ss;
	return (EJUSTRETURN);
}
int linux_sigreturn ( struct thread * td , struct linux_sigreturn_args * args ) { struct l_sigframe frame ; struct trapframe * regs ; l_sigset_t lmask ; sigset_t bmask ; int eflags ; ksiginfo_t ksi ; regs = td -> td_frame ; #ifdef DEBUG if ( ldebug ( sigreturn ) ) printf ( ARGS ( sigreturn , " " ) , ( void * ) args -> sfp ) ; #endif if ( copyin ( args -> sfp , & frame , sizeof ( frame ) ) != 0 ) return ( EFAULT ) ; #define EFLAGS_SECURE ( ef , oef ) 	((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0) eflags = frame . sf_sc . sc_eflags ; if ( ! EFLAGS_SECURE ( eflags , regs -> tf_eflags ) ) return ( EINVAL ) ; #define CS_SECURE ( cs ) 	(ISPL(cs) == SEL_UPL) if ( ! CS_SECURE ( frame . sf_sc . sc_cs ) ) { ksiginfo_init_trap ( & ksi ) ; ksi . ksi_signo = SIGBUS ; ksi . ksi_code = BUS_OBJERR ; ksi . ksi_trapno = T_PROTFLT ; ksi . ksi_addr = ( void * ) regs -> tf_eip ; trapsignal ( td , & ksi ) ; return ( EINVAL ) ; } lmask . __mask = frame . sf_sc . sc_mask ; linux_to_bsd_sigset ( & lmask , & bmask ) ; kern_sigprocmask ( td , SIG_SETMASK , & bmask , NULL , 0 ) ; regs -> tf_fs = frame . sf_sc . sc_fs ; regs -> tf_es = frame . sf_sc . sc_es ; regs -> tf_ds = frame . sf_sc . sc_ds ; regs -> tf_edi = frame . sf_sc . sc_edi ; regs -> tf_esi = frame . sf_sc . sc_esi ; regs -> tf_ebp = frame . sf_sc . sc_ebp ; regs -> tf_ebx = frame . sf_sc . sc_ebx ; regs -> tf_edx = frame . sf_sc . sc_edx ; regs -> tf_ecx = frame . sf_sc . sc_ecx ; regs -> tf_eax = frame . sf_sc . sc_eax ; regs -> tf_eip = frame . sf_sc . sc_eip ; regs -> tf_cs = frame . sf_sc . sc_cs ; regs -> tf_eflags = eflags ; regs -> tf_esp = frame . sf_sc . sc_esp_at_signal ; regs -> tf_ss = frame . sf_sc . sc_ss ; return ( EJUSTRETURN ) ; }
System call to cleanup state after a signal
 has been taken.
System call to cleanup state after a signal has been taken .
/*
	 * The trampoline code hands us the sigframe.
	 * It is unsafe to keep track of it ourselves, in the event that a
	 * program jumps out of a signal handler.
	 */ /*
	 * Check for security violations.
	 */ /*
	 * Don't allow users to load a valid privileged %cs.  Let the
	 * hardware check for invalid selectors, excess privilege in
	 * other selectors, invalid %eip's and invalid %esp's.
	 */ /*
	 * Restore signal context.
	 */ /* %gs was restored by the trampoline. */