From: Jeffrey Altman Date: Mon, 27 Jul 2009 16:54:16 +0000 (-0400) Subject: Protect rx_call iovq from simultaneous attempts to empty it X-Git-Tag: debian/1.4.11+dfsg-5~8 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=14d361253ec7a7b1756c193c091acc119d6fcb43;p=packages%2Fo%2Fopenafs.git Protect rx_call iovq from simultaneous attempts to empty it 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 Tested-by: Hans-Werner Paulsen Tested-by: Jeffrey Altman Reviewed-by: Jeffrey Altman (cherry picked from commit 4dadd24ba8ce72fd655e29d74801f27e9e148b01) Change-Id: Ifdb1f420f07f9c55d56fe24899e3a040a77db6a9 Reviewed-on: http://gerrit.openafs.org/763 Tested-by: Andrew Deason --- diff --git a/src/rx/rx_rdwr.c b/src/rx/rx_rdwr.c index 0c88bb205..ae6c030d7 100644 --- a/src/rx/rx_rdwr.c +++ b/src/rx/rx_rdwr.c @@ -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.