summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>2002-01-30 17:47:12 +0000
committerbde <bde@FreeBSD.org>2002-01-30 17:47:12 +0000
commit5909c8df4dc4ada0325629a022f8cb2fb883488e (patch)
tree03f73a59f0676574dc10a2f2b2d127d5a2258d3e /sys
parent2aa4b18cd1eaf39b83dacb13149fd9b9234ab9f0 (diff)
downloadFreeBSD-src-5909c8df4dc4ada0325629a022f8cb2fb883488e.zip
FreeBSD-src-5909c8df4dc4ada0325629a022f8cb2fb883488e.tar.gz
Cleaned up the 0ldSiG magic check before removing it. Just use fuword()
to fetch the magic word instead of useracc() plus a direct access. This is more efficient as well as simpler and less incorrect: - it was inefficent because useracc() takes much longer than just accessing the data using a correct access method, at least on i386's. - it was incorrect because direct access is incorrect unless the address has been mapped. This and nearby direct accesses are mostly handled better for other arches because they have to be (direct accesses don't work). - using magic in sigreturn is still fundamentally broken because false matches are possible. On i386's, a false match occurs when %eip in a new signal context happens to equal the magic value. This is not handled better for other arches.
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/amd64/machdep.c21
-rw-r--r--sys/i386/i386/machdep.c21
2 files changed, 16 insertions, 26 deletions
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index d361a27..807ab20 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -708,27 +708,22 @@ sigreturn(td, uap)
} */ *uap;
{
struct proc *p = td->td_proc;
+ struct osigcontext *oscp;
+ struct osigreturn_args *ouap;
struct trapframe *regs;
ucontext_t *ucp;
int cs, eflags;
- ucp = uap->sigcntxp;
#ifdef COMPAT_43
- if (!useracc((caddr_t)ucp, sizeof(struct osigcontext), VM_PROT_READ))
- return (EFAULT);
- if (((struct osigcontext *)ucp)->sc_trapno == 0x01d516)
- return (osigreturn(td, (struct osigreturn_args *)uap));
- /*
- * Since ucp is not an osigcontext but a ucontext_t, we have to
- * check again if all of it is accessible. A ucontext_t is
- * much larger, so instead of just checking for the pointer
- * being valid for the size of an osigcontext, now check for
- * it being valid for a whole, new-style ucontext_t.
- */
+ ouap = (struct osigreturn_args *)uap;
+ oscp = ouap->sigcntxp;
+ if (fuword(&oscp->sc_trapno) == 0x01d516)
+ return (osigreturn(td, ouap));
#endif
+
+ ucp = uap->sigcntxp;
if (!useracc((caddr_t)ucp, sizeof(*ucp), VM_PROT_READ))
return (EFAULT);
-
regs = td->td_frame;
eflags = ucp->uc_mcontext.mc_eflags;
if (eflags & PSL_VM) {
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index d361a27..807ab20 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -708,27 +708,22 @@ sigreturn(td, uap)
} */ *uap;
{
struct proc *p = td->td_proc;
+ struct osigcontext *oscp;
+ struct osigreturn_args *ouap;
struct trapframe *regs;
ucontext_t *ucp;
int cs, eflags;
- ucp = uap->sigcntxp;
#ifdef COMPAT_43
- if (!useracc((caddr_t)ucp, sizeof(struct osigcontext), VM_PROT_READ))
- return (EFAULT);
- if (((struct osigcontext *)ucp)->sc_trapno == 0x01d516)
- return (osigreturn(td, (struct osigreturn_args *)uap));
- /*
- * Since ucp is not an osigcontext but a ucontext_t, we have to
- * check again if all of it is accessible. A ucontext_t is
- * much larger, so instead of just checking for the pointer
- * being valid for the size of an osigcontext, now check for
- * it being valid for a whole, new-style ucontext_t.
- */
+ ouap = (struct osigreturn_args *)uap;
+ oscp = ouap->sigcntxp;
+ if (fuword(&oscp->sc_trapno) == 0x01d516)
+ return (osigreturn(td, ouap));
#endif
+
+ ucp = uap->sigcntxp;
if (!useracc((caddr_t)ucp, sizeof(*ucp), VM_PROT_READ))
return (EFAULT);
-
regs = td->td_frame;
eflags = ucp->uc_mcontext.mc_eflags;
if (eflags & PSL_VM) {
OpenPOWER on IntegriCloud