From 14d361253ec7a7b1756c193c091acc119d6fcb43 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Mon, 27 Jul 2009 12:54:16 -0400 Subject: [PATCH] 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 --- src/rx/rx_rdwr.c | 48 ++++++++++++++++++++---------------------------- 1 file changed, 20 insertions(+), 28 deletions(-) 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. -- 2.39.5