]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
Protect rx_call iovq from simultaneous attempts to empty it
authorJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 27 Jul 2009 16:54:16 +0000 (12:54 -0400)
committerDerrick Brashear <shadow|account-1000005@unknown>
Mon, 2 Nov 2009 18:47:29 +0000 (10:47 -0800)
The iovq queue is not safe to clear without holding the call lock.

FIXES 125110

LICENSE BSD

Reviewed-on: http://gerrit.openafs.org/242
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Hans-Werner Paulsen <hans@MPA-Garching.MPG.DE>
Tested-by: Jeffrey Altman <jaltman@openafs.org>
Reviewed-by: Jeffrey Altman <jaltman@openafs.org>
(cherry picked from commit 4dadd24ba8ce72fd655e29d74801f27e9e148b01)
Change-Id: Ifdb1f420f07f9c55d56fe24899e3a040a77db6a9
Reviewed-on: http://gerrit.openafs.org/763
Tested-by: Andrew Deason <adeason@sinenomine.net>
src/rx/rx_rdwr.c

index 3b82279af92b5e99c3bfa0c50b552a99709f1489..8f8e8ba9a940224f358b93cd95521f6fbd5c3aab 100644 (file)
@@ -297,16 +297,14 @@ rx_ReadProc(struct rx_call *call, char *buf, int nbytes)
     char *tcurpos;
     SPLVAR;
 
-    /*
-     * Free any packets from the last call to ReadvProc/WritevProc.
-     * We do not need the lock because the receiver threads only
-     * touch the iovq when the RX_CALL_IOVEC_WAIT flag is set, and the
-     * RX_CALL_IOVEC_WAIT is always cleared before returning from
-     * ReadvProc/WritevProc.
-     */
+    /* Free any packets from the last call to ReadvProc/WritevProc */
+    NETPRI;
+    MUTEX_ENTER(&call->lock);
     if (!queue_IsEmpty(&call->iovq)) {
         rxi_FreePackets(0, &call->iovq);
     }
+    MUTEX_EXIT(&call->lock);
+    USERPRI;
 
     /*
      * Most common case, all of the data is in the current iovec.
@@ -354,16 +352,14 @@ rx_ReadProc32(struct rx_call *call, afs_int32 * value)
     char *tcurpos;
     SPLVAR;
 
-    /*
-     * Free any packets from the last call to ReadvProc/WritevProc.
-     * We do not need the lock because the receiver threads only
-     * touch the iovq when the RX_CALL_IOVEC_WAIT flag is set, and the
-     * RX_CALL_IOVEC_WAIT is always cleared before returning from
-     * ReadvProc/WritevProc.
-     */
+    /* Free any packets from the last call to ReadvProc/WritevProc */
+    NETPRI;
+    MUTEX_ENTER(&call->lock);
     if (!queue_IsEmpty(&call->iovq)) {
        rxi_FreePackets(0, &call->iovq);
     }
+    MUTEX_EXIT(&call->lock);
+    USERPRI;
 
     /*
      * Most common case, all of the data is in the current iovec.
@@ -830,16 +826,14 @@ rx_WriteProc(struct rx_call *call, char *buf, int nbytes)
     char *tcurpos;
     SPLVAR;
 
-    /*
-     * Free any packets from the last call to ReadvProc/WritevProc.
-     * We do not need the lock because the receiver threads only
-     * touch the iovq when the RX_CALL_IOVEC_WAIT flag is set, and the
-     * RX_CALL_IOVEC_WAIT is always cleared before returning from
-     * ReadvProc/WritevProc.
-     */
+    /* Free any packets from the last call to ReadvProc/WritevProc */
+    NETPRI;
+    MUTEX_ENTER(&call->lock);
     if (queue_IsNotEmpty(&call->iovq)) {
        rxi_FreePackets(0, &call->iovq);
     }
+    MUTEX_EXIT(&call->lock);
+    USERPRI;
 
     /*
      * Most common case: all of the data fits in the current iovec.
@@ -877,16 +871,14 @@ rx_WriteProc32(register struct rx_call *call, register afs_int32 * value)
     char *tcurpos;
     SPLVAR;
 
-    /*
-     * Free any packets from the last call to ReadvProc/WritevProc.
-     * We do not need the lock because the receiver threads only
-     * touch the iovq when the RX_CALL_IOVEC_WAIT flag is set, and the
-     * RX_CALL_IOVEC_WAIT is always cleared before returning from
-     * ReadvProc/WritevProc.
-     */
+    /* Free any packets from the last call to ReadvProc/WritevProc */
+    NETPRI;
+    MUTEX_ENTER(&call->lock);
     if (queue_IsNotEmpty(&call->iovq)) {
        rxi_FreePackets(0, &call->iovq);
     }
+    MUTEX_EXIT(&call->lock);
+    USERPRI;
 
     /*
      * Most common case: all of the data fits in the current iovec.