Date: Mon, 21 Jan 2002 12:10:57 -0500 (EST) From: Andrew Gallatin <gallatin@cs.duke.edu> To: Bernd Walter <ticso@cicely8.cicely.de> Cc: freebsd-alpha@FreeBSD.ORG Subject: Re: 4.5-RC panic Message-ID: <15436.19361.398632.413668@grasshopper.cs.duke.edu> In-Reply-To: <20020121172920.U58301@cicely8.cicely.de> References: <20020121035556.D58301@cicely8.cicely.de> <15436.8686.765933.505738@grasshopper.cs.duke.edu> <20020121172920.U58301@cicely8.cicely.de>
next in thread | previous in thread | raw e-mail | index | archive | help
Bernd Walter writes:
>
> I did not follow the -stable commits regulary so I can't say.
> The box has some memory load so I wouldn't be surprised if the complete
> tcsh was swapped.
>
> > Can you disassemble this and see if its faulting on the call or the return?
>
> int
> sigreturn(struct proc *p,
> struct sigreturn_args /* {
> ucontext_t *sigcntxp;
> } */ *uap)
> {
> fffffc00004d0354: 09 04 f0 47 mov a0,s0
> ucontext_t uc, *ucp;
> struct pcb *pcb;
> unsigned long val;
>
> if (((struct osigcontext*)uap->sigcntxp)->sc_regs[R_ZERO] == 0xACEDBADE)
Directly deref'ing a user pointer inside the kernel looks pretty bad
to me. It makes sense you'd panic if tcsh was swapped out. It looks
like this bug is over 2 years old..
Can you reproduce this?
I've appended an untested patch to try. Please check over my pointer arith..
Drew
Index: machdep.c
===================================================================
RCS file: /home/ncvs/src/sys/alpha/alpha/machdep.c,v
retrieving revision 1.68.2.15
diff -u -r1.68.2.15 machdep.c
--- machdep.c 13 Dec 2001 19:18:00 -0000 1.68.2.15
+++ machdep.c 21 Jan 2002 17:02:11 -0000
@@ -1570,9 +1570,6 @@
struct pcb *pcb;
unsigned long val;
- if (((struct osigcontext*)uap->sigcntxp)->sc_regs[R_ZERO] == 0xACEDBADE)
- return osigreturn(p, (struct osigreturn_args *)uap);
-
ucp = uap->sigcntxp;
pcb = &p->p_addr->u_pcb;
@@ -1582,10 +1579,24 @@
#endif
/*
- * Fetch the entire context structure at once for speed.
+ * Fetch the context structure in 2 chunks:
+ * First get just sizeof(struct osigcontext) bytes in
+ * case this is an osigreturn
+ */
+ if (copyin((caddr_t)ucp, (caddr_t)&uc, sizeof(struct osigcontext)))
+ return (EFAULT);
+
+ if (((struct osigcontext*)ucp)->sc_regs[R_ZERO] == 0xACEDBADE)
+ return osigreturn(p, (struct osigreturn_args *)uap);
+
+ /*
+ * Now get the rest of it
*/
- if (copyin((caddr_t)ucp, (caddr_t)&uc, sizeof(ucontext_t)))
+ if (copyin((caddr_t)ucp + sizeof(struct osigcontext),
+ (caddr_t)&uc + sizeof(struct osigcontext),
+ sizeof(ucontext_t) - sizeof(struct osigcontext)))
return (EFAULT);
+
/*
* Restore the user-supplied information
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-alpha" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?15436.19361.398632.413668>
