]> 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)
committerRuss Allbery <rra@debian.org>
Wed, 4 Nov 2009 01:29:47 +0000 (17:29 -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 0c88bb20534e6a26c6661f4cba4d8bd0b4f914ff..ae6c030d7048cebbf73db33b0282f38038b095d6 100644 (file)
@@ -299,16 +299,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.
@@ -356,16 +354,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.
@@ -832,16 +828,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.
@@ -879,16 +873,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.