Subject: Re: 2nd review of fixes to sig_return() and LDT's
To: Chris G. Demetriou <cgd@nobozo.CS.Berkeley.EDU>
From: John Brezak <brezak@apollo.hp.com>
List: port-i386
Date: 01/08/1994 00:43:26
Ok, try this one. It eliminates the bogus force_signal() stuff and
uses trapsignal() in sigreturn() when a problem in the sigcontext is
detected. The only question I have is what T_<fault> to use. I took
a stab at it here.
*** machdep.c.orig Fri Jan 7 05:49:35 1994
--- machdep.c Sat Jan 8 00:38:52 1994
***************
*** 511,534 ****
fp = (struct sigframe *)
((caddr_t)scp - offsetof(struct sigframe, sf_sc));
! if (useracc((caddr_t)fp, sizeof(*fp), 0) == 0)
return(EINVAL);
! if (useracc((caddr_t)scp, sizeof(*scp), 0) == 0)
return(EINVAL);
/* make sure they aren't trying to do anything funny */
! if ((scp->sc_ps & PSL_MBZ) != 0 || (scp->sc_ps & PSL_MBO) != PSL_MBO)
return(EINVAL);
/* compare IOPL; we can't insist that it's always 3 or the X server
will fail */
! if ((tf->tf_eflags & PSL_IOPL) < (scp->sc_efl & PSL_IOPL))
return(EINVAL);
p->p_sigacts->ps_onstack = scp->sc_onstack & 01;
p->p_sigmask = scp->sc_mask &~
(sigmask(SIGKILL)|sigmask(SIGCONT)|sigmask(SIGSTOP));
/*
* Restore signal context.
--- 511,566 ----
fp = (struct sigframe *)
((caddr_t)scp - offsetof(struct sigframe, sf_sc));
! if (useracc((caddr_t)fp, sizeof(*fp), 0) == 0) {
! trapsignal(p, SIGBUS, T_STKFLT);
return(EINVAL);
+ }
! if (useracc((caddr_t)scp, sizeof(*scp), 0) == 0) {
! trapsignal(p, SIGBUS, T_STKFLT);
return(EINVAL);
+ }
/* make sure they aren't trying to do anything funny */
! if ((scp->sc_ps & PSL_MBZ) != 0 || (scp->sc_ps & PSL_MBO) != PSL_MBO) {
! trapsignal(p, SIGBUS, T_PROTFLT);
return(EINVAL);
+ }
/* compare IOPL; we can't insist that it's always 3 or the X server
will fail */
! if ((tf->tf_eflags & PSL_IOPL) < (scp->sc_efl & PSL_IOPL)) {
! trapsignal(p, SIGBUS, T_PROTFLT);
return(EINVAL);
+ }
p->p_sigacts->ps_onstack = scp->sc_onstack & 01;
p->p_sigmask = scp->sc_mask &~
(sigmask(SIGKILL)|sigmask(SIGCONT)|sigmask(SIGSTOP));
+
+ /*
+ * Sanity check the user's selectors and error if they
+ * are suspect.
+ */
+ #define max_ldt_sel(pcb) \
+ ((((pcb)->pcb_ldt)? \
+ (gdt_segs[GUSERLDT_SEL].ssd_limit + 1) : \
+ sizeof(ldt))/sizeof(union descriptor))
+
+ #define valid_sel(sel) \
+ (((sel) == 0) || \
+ (ISPL((sel)) == SEL_UPL && ISLDT((sel))) || \
+ (ISLDT((sel)) && IDXSEL((sel)) < max_ldt_sel((struct pcb *)(p->p_addr))))
+
+ if (scp->sc_cs&0xffff != _ucodesel || scp->sc_ss&0xffff != _udatasel ||
+ scp->sc_ds&0xffff != _udatasel || scp->sc_es&0xffff != _udatasel) {
+ if (!valid_sel(scp->sc_cs) || !valid_sel(scp->sc_ss) ||
+ !valid_sel(scp->sc_ds) || !valid_sel(scp->sc_es)) {
+ trapsignal(p, SIGBUS, T_PROTFLT);
+ return(EINVAL);
+ }
+ }
+ #undef valid_sel
/*
* Restore signal context.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
John Brezak UUCP: uunet!apollo.hp!brezak
Hewlett Packard/Apollo Internet: brezak@ch.hp.com
300 Apollo Drive Phone: (508) 436-4915
Chelmsford, Massachusetts Fax: (508) 436-5103
------------------------------------------------------------------------------