Skip site navigation (1)Skip section navigation (2)
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>