Another race condition fixed in RFS
Todd Brunhoff
toddb at tekcrl.UUCP
Sat Aug 23 03:53:26 AEST 1986
Bill Sommerfeld <wesommer at athena.mit.edu> has done another marvelous job
of finding another crash condition and providing the fix. These are
his paraphrased comments followed by the diffs.
When sleeping in rmt_getmsg, waiting to grab the
connection, you didn't check to see if rp->close is true every time
you wake up..
Imagine the following scenario:
(watching this with debug set to 0xc00 helps)
A: goes into the sleep waiting for the connection (on &rp->r_recver)
B: does random remote i/o and sees the connection break in getmsg
B: calls rmt_shutdown, sets rp->r_close to true, wakes up
&rp->r_recver,
B: returns error code from remoteio
A: wakes up, grabs the connection
A: drops right into rmt_uio where it attempts to access the socket
A: falls down dead in sorecieve with a protection fault (scribbled
socket).
This fix also means that when there are multiple processes using a
connection, and the connection dies, *ALL* of them wake up with error
messages (not just the one which happened to be active at the time).
This is a feature!
RCS file: RCS/rmt_io.c,v
retrieving revision 2.6
diff -c -r2.6 rmt_io.c
*** /tmp/,RCSt1014402 Fri Aug 22 10:49:55 1986
--- rmt_io.c Fri Aug 22 10:41:54 1986
***************
*** 11,17
* may be copied, modified or used in any way, without fee, provided this
* notice remains an unaltered part of the software.
*
! * $Header: rmt_io.c,v 2.6 86/08/08 14:39:13 toddb Exp $
*
* $Log: rmt_io.c,v $
* Revision 2.6 86/08/08 14:39:13 toddb
--- 11,17 -----
* may be copied, modified or used in any way, without fee, provided this
* notice remains an unaltered part of the software.
*
! * $Header: rmt_io.c,v 2.7 86/08/22 10:37:11 toddb Exp $
*
* $Log: rmt_io.c,v $
* Revision 2.7 86/08/22 10:37:11 toddb
***************
*** 14,19
* $Header: rmt_io.c,v 2.6 86/08/08 14:39:13 toddb Exp $
*
* $Log: rmt_io.c,v $
* Revision 2.6 86/08/08 14:39:13 toddb
* Removed unnecessary printf from rmt_closehost().
*
--- 14,26 -----
* $Header: rmt_io.c,v 2.7 86/08/22 10:37:11 toddb Exp $
*
* $Log: rmt_io.c,v $
+ * Revision 2.7 86/08/22 10:37:11 toddb
+ * While waiting for the use of the socket, the code in rmt_getmsg()
+ * neglected to check whether the connection was closed or closing.
+ * This meant that if it did close while a process was waiting, the
+ * process would begin to use an invalid socket. Fix by
+ * wesommer at athena.mit.edu.
+ *
* Revision 2.6 86/08/08 14:39:13 toddb
* Removed unnecessary printf from rmt_closehost().
*
***************
*** 435,441
* that we are the recipient of this message. In fact,
* the message may have already arrived.
*/
! while (rp->r_recver != u.u_procp->p_pid && rp->r_recver != -1)
sleep((caddr_t)&rp->r_recver, PZERO+1);
if (rp->r_recver == u.u_procp->p_pid && rp->r_received) {
auio.uio_resid = 0;
--- 442,450 -----
* that we are the recipient of this message. In fact,
* the message may have already arrived.
*/
! while (rp->r_recver != u.u_procp->p_pid
! && rp->r_recver != -1
! && ! rp->r_close)
sleep((caddr_t)&rp->r_recver, PZERO+1);
if (rp->r_close)
break;
***************
*** 437,442
*/
while (rp->r_recver != u.u_procp->p_pid && rp->r_recver != -1)
sleep((caddr_t)&rp->r_recver, PZERO+1);
if (rp->r_recver == u.u_procp->p_pid && rp->r_received) {
auio.uio_resid = 0;
break;
--- 446,453 -----
&& rp->r_recver != -1
&& ! rp->r_close)
sleep((caddr_t)&rp->r_recver, PZERO+1);
+ if (rp->r_close)
+ break;
if (rp->r_recver == u.u_procp->p_pid && rp->r_received) {
auio.uio_resid = 0;
break;
More information about the Comp.sources.bugs
mailing list