From bdb4f98aeb9d383504a3adb0df92cd345884d86c 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 3b82279af..8f8e8ba9a 100644 --- a/src/rx/rx_rdwr.c +++ b/src/rx/rx_rdwr.c @@ -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. -- 2.39.5