staging: r8188eu: fix NULL check for rcu pointer

Message ID 20230131090057.241779-1-martin@kaiser.cx
State New
Headers
Series staging: r8188eu: fix NULL check for rcu pointer |

Commit Message

Martin Kaiser Jan. 31, 2023, 9 a.m. UTC
  Fix the NULL check for padapter->pnetdev->rx_handler_data.

The current code calls rcu_dereference while it holds the rcu read lock
and checks the pointer after releasing the lock. An rcu pointer may only be
used between calls to rcu_read_lock and rcu_read_unlock.

Replace the check with rcu_access_pointer. My understanding is that this
function returns the value of the pointer and needs no locking. We can
then check the pointer but we must not dereference it.

Signed-off-by: Martin Kaiser <martin@kaiser.cx>
---
 drivers/staging/r8188eu/core/rtw_xmit.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)
  

Comments

Greg KH Jan. 31, 2023, 3:09 p.m. UTC | #1
On Tue, Jan 31, 2023 at 10:00:57AM +0100, Martin Kaiser wrote:
> Fix the NULL check for padapter->pnetdev->rx_handler_data.
> 
> The current code calls rcu_dereference while it holds the rcu read lock
> and checks the pointer after releasing the lock. An rcu pointer may only be
> used between calls to rcu_read_lock and rcu_read_unlock.
> 
> Replace the check with rcu_access_pointer. My understanding is that this
> function returns the value of the pointer and needs no locking. We can
> then check the pointer but we must not dereference it.
> 
> Signed-off-by: Martin Kaiser <martin@kaiser.cx>

What commit id does this fix?

thanks,

greg k-h
  
Dan Carpenter Jan. 31, 2023, 3:19 p.m. UTC | #2
[ Resending because my email setup is crap and silently eats my out
  going mail. ]

On Tue, Jan 31, 2023 at 10:00:57AM +0100, Martin Kaiser wrote:
> Fix the NULL check for padapter->pnetdev->rx_handler_data.
> 
> The current code calls rcu_dereference while it holds the rcu read lock
> and checks the pointer after releasing the lock. An rcu pointer may only be
> used between calls to rcu_read_lock and rcu_read_unlock.
> 
> Replace the check with rcu_access_pointer. My understanding is that this
> function returns the value of the pointer and needs no locking. We can
> then check the pointer but we must not dereference it.
> 
> Signed-off-by: Martin Kaiser <martin@kaiser.cx>

This patch is fine but it's a clean up and not a fix.  The original code
doesn't dereference "br_port".  I guess the new code is faster and
especially if you have lockdep enabled, so maybe in that sense it is a
fix.

regards,
dan carpenter
  
Martin Kaiser Jan. 31, 2023, 5:16 p.m. UTC | #3
Hello Greg and all,

Thus wrote Greg Kroah-Hartman (gregkh@linuxfoundation.org):

> On Tue, Jan 31, 2023 at 10:00:57AM +0100, Martin Kaiser wrote:
> > Fix the NULL check for padapter->pnetdev->rx_handler_data.

> > The current code calls rcu_dereference while it holds the rcu read lock
> > and checks the pointer after releasing the lock. An rcu pointer may only be
> > used between calls to rcu_read_lock and rcu_read_unlock.

> > Replace the check with rcu_access_pointer. My understanding is that this
> > function returns the value of the pointer and needs no locking. We can
> > then check the pointer but we must not dereference it.

> > Signed-off-by: Martin Kaiser <martin@kaiser.cx>

> What commit id does this fix?

the code that checks br_port has been around since the driver was
imported into staging.

If the patch is considered as a fix, it should have

Fixes: 15865124feed ("staging: r8188eu: introduce new core dir for RTL8188eu driver")

Best regards,

   Martin
  
Martin Kaiser Jan. 31, 2023, 5:23 p.m. UTC | #4
Hello Dan and all,

Thus wrote Dan Carpenter (error27@gmail.com):

> This patch is fine but it's a clean up and not a fix.  The original code
> doesn't dereference "br_port".  I guess the new code is faster and
> especially if you have lockdep enabled, so maybe in that sense it is a
> fix.

ok, I see. The br_port pointer may no longer be valid after rcu_unlock
but we can still check it for NULL at that time without dereferencing it.

Thanks for the clarification,
Martin
  
Dan Carpenter Feb. 1, 2023, 5:06 a.m. UTC | #5
On Tue, Jan 31, 2023 at 06:16:13PM +0100, Martin Kaiser wrote:
> Hello Greg and all,
> 
> Thus wrote Greg Kroah-Hartman (gregkh@linuxfoundation.org):
> 
> > On Tue, Jan 31, 2023 at 10:00:57AM +0100, Martin Kaiser wrote:
> > > Fix the NULL check for padapter->pnetdev->rx_handler_data.
> 
> > > The current code calls rcu_dereference while it holds the rcu read lock
> > > and checks the pointer after releasing the lock. An rcu pointer may only be
> > > used between calls to rcu_read_lock and rcu_read_unlock.
> 
> > > Replace the check with rcu_access_pointer. My understanding is that this
> > > function returns the value of the pointer and needs no locking. We can
> > > then check the pointer but we must not dereference it.
> 
> > > Signed-off-by: Martin Kaiser <martin@kaiser.cx>
> 
> > What commit id does this fix?
> 
> the code that checks br_port has been around since the driver was
> imported into staging.
> 
> If the patch is considered as a fix, it should have
> 
> Fixes: 15865124feed ("staging: r8188eu: introduce new core dir for RTL8188eu driver")

I don't think it is a fix as we discuss later in the thread.

But if it were then it's still really useful to record that.  I normally
don't record when Fixes are from before the git era because one time,
ten years ago, one person said not to do that.  But really even there I
personally think Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") is useful.

It tells the tools how far to backport things.  It tells us if most of
our bugs come from the very start or if we're introducing them later.

regards,
dan carpenter
  

Patch

diff --git a/drivers/staging/r8188eu/core/rtw_xmit.c b/drivers/staging/r8188eu/core/rtw_xmit.c
index 91f92ec5ef69..18941320e70e 100644
--- a/drivers/staging/r8188eu/core/rtw_xmit.c
+++ b/drivers/staging/r8188eu/core/rtw_xmit.c
@@ -1631,18 +1631,14 @@  s32 rtw_xmit(struct adapter *padapter, struct sk_buff **ppkt)
 	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
 	struct xmit_frame *pxmitframe = NULL;
 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
-	void *br_port = NULL;
 	s32 res;
 
 	pxmitframe = rtw_alloc_xmitframe(pxmitpriv);
 	if (!pxmitframe)
 		return -1;
 
-	rcu_read_lock();
-	br_port = rcu_dereference(padapter->pnetdev->rx_handler_data);
-	rcu_read_unlock();
-
-	if (br_port && check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE)) {
+	if (rcu_access_pointer(padapter->pnetdev->rx_handler_data) &&
+	    check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE)) {
 		res = rtw_br_client_tx(padapter, ppkt);
 		if (res == -1) {
 			rtw_free_xmitframe(pxmitpriv, pxmitframe);