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: openafs-devel-1_5_61~19 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=4dadd24ba8ce72fd655e29d74801f27e9e148b01;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 --- diff --git a/src/rx/rx_rdwr.c b/src/rx/rx_rdwr.c index 61f6b2aa2..c63dc09b2 100644 --- a/src/rx/rx_rdwr.c +++ b/src/rx/rx_rdwr.c @@ -313,19 +313,17 @@ 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)) { #ifdef RXDEBUG_PACKET call->iovqc -= #endif /* RXDEBUG_PACKET */ rxi_FreePackets(0, &call->iovq); } + MUTEX_EXIT(&call->lock); + USERPRI; /* * Most common case, all of the data is in the current iovec. @@ -373,19 +371,17 @@ 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)) { #ifdef RXDEBUG_PACKET call->iovqc -= #endif /* RXDEBUG_PACKET */ rxi_FreePackets(0, &call->iovq); } + MUTEX_EXIT(&call->lock); + USERPRI; /* * Most common case, all of the data is in the current iovec. @@ -880,19 +876,17 @@ 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)) { #ifdef RXDEBUG_PACKET call->iovqc -= #endif /* RXDEBUG_PACKET */ rxi_FreePackets(0, &call->iovq); } + MUTEX_EXIT(&call->lock); + USERPRI; /* * Most common case: all of the data fits in the current iovec. @@ -930,19 +924,17 @@ rx_WriteProc32(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_IsNotEmpty(&call->iovq)) { #ifdef RXDEBUG_PACKET call->iovqc -= #endif /* RXDEBUG_PACKET */ rxi_FreePackets(0, &call->iovq); } + MUTEX_EXIT(&call->lock); + USERPRI; /* * Most common case: all of the data fits in the current iovec.