[PATCH] scsi: target: use kref_get_unless_zero() in core_get_se_deve_from_rtpi()

Yifei Gao <[email protected]> Tue, 4 Aug 2026 21:37:25 +0000
Newsgroups gmane.linux.kernel,gmane.linux.scsi,gmane.linux.scsi.target.devel,gmane.linux.kernel.stable
Message-ID <[email protected]>
core_get_se_deve_from_rtpi() iterates nacl->lun_entry_hlist under
rcu_read_lock() and takes a plain kref_get() on deve->pr_kref for the
matching entry. The disable path, core_disable_device_list_for_node(),
unhashes the entry, drops the final reference, waits for pr_comp and
frees it via call_rcu() while holding lun_entry_mutex, which the reader
does not hold. A reader racing that path can revive the kref after it has
reached zero, defeating the pr_comp completion barrier and leading to a
use-after-free.

Use kref_get_unless_zero() and skip entries whose refcount has already
dropped to zero.

Fixes: 29a05deebf6c ("target: Convert se_node_acl->device_list[] to RCU hlist")
Cc: [email protected]
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Yifei Gao <[email protected]>
---
 drivers/target/target_core_device.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index 9db2201aa553..bff97c6efffb 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -220,7 +220,8 @@ struct se_dev_entry *core_get_se_deve_from_rtpi(
 		if (lun->lun_tpg->tpg_rtpi != rtpi)
 			continue;
 
-		kref_get(&deve->pr_kref);
+		if (!kref_get_unless_zero(&deve->pr_kref))
+			continue;
 		rcu_read_unlock();
 
 		return deve;
-- 
2.43.0