Subject: Re: 2nd review of fixes to sig_return() and LDT's
To: John Brezak <brezak@apollo.hp.com>
From: Chris G. Demetriou <cgd@nobozo.CS.Berkeley.EDU>
List: port-i386
Date: 01/07/1994 21:58:27
[ as John tries to find a gun...  8-]

Basically, the first four cases are explicitly covered by the
interface described by sigreturn(), and also work the same
way on N other architectures.  They *must* return the proper
error codes, and *not* do anything else.

The final case, that of the bogus LDTs, is the only one that
*can* be handled differently.  Since a bogus LDT either means
a serious problem, or an (obvious) attempt to breach security,
the process trying it should be signalled, if possible.

comments follow the chunks that they comment on.  The above bit
is what i've been trying to say, but i think i've made a little
mess of it.

> --- 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);
> +       }

can't access something on the stack.  man page says "return EFAULT."
(i.e. don't signal)

> !       if (useracc((caddr_t)scp, sizeof(*scp), 0) == 0) {
> !               trapsignal(p, SIGBUS, T_STKFLT);
>                 return(EINVAL);
> +       }

can't access something on the stack.  man page says "return EFAULT."
(i.e. don't signal)

>         /* 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);
> +       }

The process status longword is invalid.  man page says "return EINVAL."
(i.e. don't signal)

>         /* 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);
> +       }

The process status longword is would raise the process's privilege.
man page says "return EINVAL." (i.e. don't signal)

>         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

Man page doesn't cover this case.

They're trying to do something "strange and evil" to the CPU.
Strange and evil processes must be stopped!  But, if they're stopped,
they can be restarted.  So... HIT IT WITH A BUS!  8-)



chris

------------------------------------------------------------------------------