Netdev List
 help / color / mirror / Atom feed
* [PATCH net] dibs: fix use-after-free in dmb lookup functions
@ 2026-05-29  7:08 Rahul Chandelkar
  2026-05-29 13:11 ` Alexandra Winter
  0 siblings, 1 reply; 2+ messages in thread
From: Rahul Chandelkar @ 2026-05-29  7:08 UTC (permalink / raw)
  To: netdev; +Cc: Alexandra Winter, D. Wythe, Wenjia Zhang

From 68f633e58deb6edffa435a3b2bdc4a12a5e36daf Mon Sep 17 00:00:00 2001
From: Rahul Chandelkar <rc@rexion.ai>
Date: Fri, 29 May 2026 12:32:34 +0530
Subject: [PATCH net] dibs: fix use-after-free in dmb lookup functions

dibs_lo_attach_dmb(), dibs_lo_detach_dmb(), and dibs_lo_unregister_dmb()
all release read_lock_bh before operating on the dmb_node pointer found
during hash table lookup. A concurrent unregister on the same token can
kfree() the node in this window, causing a use-after-free when the
original caller subsequently performs refcount_inc_not_zero() or
refcount_dec_and_test() on the freed object.

Fix by performing the refcount operation while still holding read_lock_bh,
so the node cannot be freed between lookup and use. Release the lock
before any code path that may call __dibs_lo_unregister_dmb(), since that
function acquires write_lock_bh internally via hash_del().

Fixes: cb990a45d7f6 ("dibs: Define dibs loopback")
Signed-off-by: Rahul Chandelkar <rc@rexion.ai>
---
 drivers/dibs/dibs_loopback.c | 42 +++++++++++++++++-------------------
 1 file changed, 20 insertions(+), 22 deletions(-)

diff --git a/drivers/dibs/dibs_loopback.c b/drivers/dibs/dibs_loopback.c
index ec3b48cb0e87..d7c779cc0d9b 100644
--- a/drivers/dibs/dibs_loopback.c
+++ b/drivers/dibs/dibs_loopback.c
@@ -150,17 +150,21 @@ static int dibs_lo_unregister_dmb(struct dibs_dev *dibs, struct dibs_dmb *dmb)
 			break;
 		}
 	}
-	read_unlock_bh(&ldev->dmb_ht_lock);
-	if (!dmb_node)
+	if (!dmb_node) {
+		read_unlock_bh(&ldev->dmb_ht_lock);
 		return -EINVAL;
+	}
+	if (!refcount_dec_and_test(&dmb_node->refcnt)) {
+		read_unlock_bh(&ldev->dmb_ht_lock);
+		return 0;
+	}
+	read_unlock_bh(&ldev->dmb_ht_lock);
 
-	if (refcount_dec_and_test(&dmb_node->refcnt)) {
-		spin_lock_irqsave(&dibs->lock, flags);
-		dibs->dmb_clientid_arr[dmb_node->sba_idx] = NO_DIBS_CLIENT;
-		spin_unlock_irqrestore(&dibs->lock, flags);
+	spin_lock_irqsave(&dibs->lock, flags);
+	dibs->dmb_clientid_arr[dmb_node->sba_idx] = NO_DIBS_CLIENT;
+	spin_unlock_irqrestore(&dibs->lock, flags);
 
-		__dibs_lo_unregister_dmb(ldev, dmb_node);
-	}
+	__dibs_lo_unregister_dmb(ldev, dmb_node);
 	return 0;
 }
 
@@ -184,16 +188,10 @@ static int dibs_lo_attach_dmb(struct dibs_dev *dibs, struct dibs_dmb *dmb)
 			break;
 		}
 	}
-	if (!dmb_node) {
-		read_unlock_bh(&ldev->dmb_ht_lock);
-		return -EINVAL;
-	}
+	if (dmb_node && !refcount_inc_not_zero(&dmb_node->refcnt))
+		dmb_node = NULL;
 	read_unlock_bh(&ldev->dmb_ht_lock);
-
-	if (!refcount_inc_not_zero(&dmb_node->refcnt))
-		/* the dmb is being unregistered, but has
-		 * not been removed from the hash table.
-		 */
+	if (!dmb_node)
 		return -EINVAL;
 
 	/* provide dmb information */
@@ -220,14 +218,14 @@ static int dibs_lo_detach_dmb(struct dibs_dev *dibs, u64 token)
 			break;
 		}
 	}
-	if (!dmb_node) {
+	if (dmb_node && refcount_dec_and_test(&dmb_node->refcnt)) {
 		read_unlock_bh(&ldev->dmb_ht_lock);
-		return -EINVAL;
+		__dibs_lo_unregister_dmb(ldev, dmb_node);
+		return 0;
 	}
 	read_unlock_bh(&ldev->dmb_ht_lock);
-
-	if (refcount_dec_and_test(&dmb_node->refcnt))
-		__dibs_lo_unregister_dmb(ldev, dmb_node);
+	if (!dmb_node)
+		return -EINVAL;
 	return 0;
 }
 
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-05-29 13:12 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-29  7:08 [PATCH net] dibs: fix use-after-free in dmb lookup functions Rahul Chandelkar
2026-05-29 13:11 ` Alexandra Winter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox