diff options
| author | ragge <ragge@NetBSD.org> | 2002-11-14 20:30:40 +0000 |
|---|---|---|
| committer | ragge <ragge@NetBSD.org> | 2002-11-14 20:30:40 +0000 |
| commit | adca0d86b218c0844ae8d82bc13d7bd877bb286e (patch) | |
| tree | 611b892068be77f746ce1b216c4c01b718e4ae0b | |
| parent | 6c24ccfd1fb3e08d2941c969468e88353d4f5c80 (diff) | |
Fix for a problem where an user can crash the machine via sigreturn(),
noticed by and fix from Miod Vallat <miod@openbsd.org>.
Miod's OpenBSD log message:
> Don't uvm_useracc the user sigcontext in sys_sigreturn and then access
> the user addresses directly from the kernel. copyin is faster and can
> correctly deal properly with mappings that uvm_useracc thinks are
> correct but will fault anyway (to figure out how to generate such
> mappings is left as en excercise for the reader).
>
> Blatantly stolen from art@'s similar fix to sparc.
| -rw-r--r-- | sys/arch/vax/vax/machdep.c | 56 |
1 files changed, 29 insertions, 27 deletions
diff --git a/sys/arch/vax/vax/machdep.c b/sys/arch/vax/vax/machdep.c index a07dfa82812..4d452a43dc1 100644 --- a/sys/arch/vax/vax/machdep.c +++ b/sys/arch/vax/vax/machdep.c @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.129 2002/09/28 09:53:08 ragge Exp $ */ +/* $NetBSD: machdep.c,v 1.130 2002/11/14 20:30:40 ragge Exp $ */ /* * Copyright (c) 2002, Hugh Graham. @@ -354,33 +354,34 @@ compat_13_sys_sigreturn(p, v, retval) syscallarg(struct sigcontext13 *) sigcntxp; } */ *uap = v; struct trapframe *scf; - struct sigcontext13 *cntx; + struct sigcontext13 *ucntx; + struct sigcontext13 ksc; sigset_t mask; scf = p->p_addr->u_pcb.framep; - cntx = SCARG(uap, sigcntxp); - if (uvm_useracc((caddr_t)cntx, sizeof (*cntx), B_READ) == 0) + ucntx = SCARG(uap, sigcntxp); + if (copyin((caddr_t)ucntx, (caddr_t)&ksc, sizeof(struct sigcontext))) return EINVAL; /* Compatibility mode? */ - if ((cntx->sc_ps & (PSL_IPL | PSL_IS)) || - ((cntx->sc_ps & (PSL_U | PSL_PREVU)) != (PSL_U | PSL_PREVU)) || - (cntx->sc_ps & PSL_CM)) { + if ((ksc.sc_ps & (PSL_IPL | PSL_IS)) || + ((ksc.sc_ps & (PSL_U | PSL_PREVU)) != (PSL_U | PSL_PREVU)) || + (ksc.sc_ps & PSL_CM)) { return (EINVAL); } - if (cntx->sc_onstack & SS_ONSTACK) + if (ksc.sc_onstack & SS_ONSTACK) p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK; else p->p_sigctx.ps_sigstk.ss_flags &= ~SS_ONSTACK; - native_sigset13_to_sigset(&cntx->sc_mask, &mask); + native_sigset13_to_sigset(&ksc.sc_mask, &mask); (void) sigprocmask1(p, SIG_SETMASK, &mask, 0); - scf->fp = cntx->sc_fp; - scf->ap = cntx->sc_ap; - scf->pc = cntx->sc_pc; - scf->sp = cntx->sc_sp; - scf->psl = cntx->sc_ps; + scf->fp = ksc.sc_fp; + scf->ap = ksc.sc_ap; + scf->pc = ksc.sc_pc; + scf->sp = ksc.sc_sp; + scf->psl = ksc.sc_ps; return (EJUSTRETURN); } #endif @@ -395,31 +396,32 @@ sys___sigreturn14(p, v, retval) syscallarg(struct sigcontext *) sigcntxp; } */ *uap = v; struct trapframe *scf; - struct sigcontext *cntx; + struct sigcontext *ucntx; + struct sigcontext ksc; scf = p->p_addr->u_pcb.framep; - cntx = SCARG(uap, sigcntxp); + ucntx = SCARG(uap, sigcntxp); - if (uvm_useracc((caddr_t)cntx, sizeof (*cntx), B_READ) == 0) + if (copyin((caddr_t)ucntx, (caddr_t)&ksc, sizeof(struct sigcontext))) return EINVAL; /* Compatibility mode? */ - if ((cntx->sc_ps & (PSL_IPL | PSL_IS)) || - ((cntx->sc_ps & (PSL_U | PSL_PREVU)) != (PSL_U | PSL_PREVU)) || - (cntx->sc_ps & PSL_CM)) { + if ((ksc.sc_ps & (PSL_IPL | PSL_IS)) || + ((ksc.sc_ps & (PSL_U | PSL_PREVU)) != (PSL_U | PSL_PREVU)) || + (ksc.sc_ps & PSL_CM)) { return (EINVAL); } - if (cntx->sc_onstack & 01) + if (ksc.sc_onstack & SS_ONSTACK) p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK; else p->p_sigctx.ps_sigstk.ss_flags &= ~SS_ONSTACK; /* Restore signal mask. */ - (void) sigprocmask1(p, SIG_SETMASK, &cntx->sc_mask, 0); + (void) sigprocmask1(p, SIG_SETMASK, &ksc.sc_mask, 0); - scf->fp = cntx->sc_fp; - scf->ap = cntx->sc_ap; - scf->pc = cntx->sc_pc; - scf->sp = cntx->sc_sp; - scf->psl = cntx->sc_ps; + scf->fp = ksc.sc_fp; + scf->ap = ksc.sc_ap; + scf->pc = ksc.sc_pc; + scf->sp = ksc.sc_sp; + scf->psl = ksc.sc_ps; return (EJUSTRETURN); } |
