rx-rdwr-writeproc-race-20081228
authorJeffrey Altman <jaltman@secure-endpoints.com>
Sun, 28 Dec 2008 21:04:23 +0000 (21:04 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Sun, 28 Dec 2008 21:04:23 +0000 (21:04 +0000)
LICENSE MIT
FIXES 123799

prevent rx_WriteProc() from passing a packet to rxi_PrepareSendPacket()
that has been freed and possibly allocated to another call.

src/rx/rx_rdwr.c

index 35fcce6..2c3b37b 100644 (file)
@@ -700,6 +700,13 @@ rxi_WriteProc(register struct rx_call *call, register char *buf,
     do {
        if (call->nFree == 0) {
            if (!call->error && cp) {
+                /* Clear the current packet now so that if
+                 * we are forced to wait and drop the lock 
+                 * the packet we are planning on using 
+                 * cannot be freed.
+                 */
+                cp->flags &= ~RX_PKTFLAG_CP;
+               call->currentPacket = (struct rx_packet *)0;
 #ifdef AFS_GLOBAL_RXLOCK_KERNEL
                /* Wait until TQ_BUSY is reset before adding any
                 * packets to the transmit queue
@@ -720,10 +727,9 @@ rxi_WriteProc(register struct rx_call *call, register char *buf,
                 * conn->securityMaxTrailerSize */
                hadd32(call->bytesSent, cp->length);
                rxi_PrepareSendPacket(call, cp, 0);
-               cp->flags &= ~RX_PKTFLAG_CP;
                cp->flags |= RX_PKTFLAG_TQ;
                queue_Append(&call->tq, cp);
-               cp = call->currentPacket = (struct rx_packet *)0;
+               cp = (struct rx_packet *)0;
                if (!
                    (call->
                     flags & (RX_CALL_FAST_RECOVER |