* [PATCH] RDMA/irdma: publish APBVT entries after hardware setup
@ 2026-11-11 9:25 Jaeyeong Lee
2026-11-11 9:36 ` sashiko-bot
2026-11-11 15:15 ` Jacob Moroni
0 siblings, 2 replies; 3+ messages in thread
From: Jaeyeong Lee @ 2026-11-11 9:25 UTC (permalink / raw)
To: Tatyana Nikolova, linux-rdma
Cc: Jason Gunthorpe, Leon Romanovsky, Shiraz Saleem, Mustafa Ismail,
Gustavo A . R . Silva, linux-kernel, stable
irdma_add_apbvt() inserts a new entry into apbvt_hash_tbl before
sending the CQP command that creates the hardware entry. If the command
fails, the entry is freed without being removed from the hash table. A
later lookup of the same port traverses the freed entry.
Removing the entry on failure is not sufficient because another thread
can find it and increment use_cnt while the CQP command is in progress.
Serialize APBVT additions and publish new entries only after the hardware
command succeeds. Since the allocation no longer runs under apbvt_lock,
use GFP_KERNEL.
The issue was found by static analysis and confirmed with a KASAN
reproducer that forces the CQP failure and retries the same port.
BUG: KASAN: slab-use-after-free in irdma_add_apbvt+0xa0/0x280 [irdma]
Read of size 2 at addr ffff8880092d10d4 by task insmod/72
Call Trace:
irdma_add_apbvt+0xa0/0x280 [irdma]
init_module+0x232/0xff0 [irdma_apbvt_repro]
do_one_initcall+0x13d/0x340
Allocated by task 72:
irdma_add_apbvt+0xda/0x280 [irdma]
init_module+0x210/0xff0 [irdma_apbvt_repro]
Freed by task 72:
kfree+0x155/0x470
irdma_add_apbvt+0x1e9/0x280 [irdma]
init_module+0x210/0xff0 [irdma_apbvt_repro]
Fixes: 44d9e52977a1 ("RDMA/irdma: Implement device initialization definitions")
Cc: stable@vger.kernel.org
Signed-off-by: Jaeyeong Lee <lee@jaeyeong.cc>
---
drivers/infiniband/hw/irdma/cm.c | 1 +
drivers/infiniband/hw/irdma/cm.h | 3 ++-
drivers/infiniband/hw/irdma/hw.c | 28 ++++++++++++++++------------
3 files changed, 19 insertions(+), 13 deletions(-)
diff --git a/drivers/infiniband/hw/irdma/cm.c b/drivers/infiniband/hw/irdma/cm.c
index 91c0e7298283..bc30e465c670 100644
--- a/drivers/infiniband/hw/irdma/cm.c
+++ b/drivers/infiniband/hw/irdma/cm.c
@@ -3281,6 +3281,7 @@ int irdma_setup_cm_core(struct irdma_device *iwdev, u8 rdma_ver)
spin_lock_init(&cm_core->ht_lock);
spin_lock_init(&cm_core->listen_list_lock);
spin_lock_init(&cm_core->apbvt_lock);
+ mutex_init(&cm_core->apbvt_add_mutex);
switch (rdma_ver) {
case IRDMA_GEN_1:
cm_core->form_cm_frame = irdma_form_uda_cm_frame;
diff --git a/drivers/infiniband/hw/irdma/cm.h b/drivers/infiniband/hw/irdma/cm.h
index 48ee285cf745..6c5f4335f09d 100644
--- a/drivers/infiniband/hw/irdma/cm.h
+++ b/drivers/infiniband/hw/irdma/cm.h
@@ -357,7 +357,8 @@ struct irdma_cm_core {
struct workqueue_struct *event_wq;
spinlock_t ht_lock; /* protect CM node (active side) list */
spinlock_t listen_list_lock; /* protect listener list */
- spinlock_t apbvt_lock; /*serialize apbvt add/del entries*/
+ spinlock_t apbvt_lock; /* serialize APBVT entry access */
+ struct mutex apbvt_add_mutex; /* serialize APBVT hardware adds */
u64 stats_nodes_created;
u64 stats_nodes_destroyed;
u64 stats_listen_created;
diff --git a/drivers/infiniband/hw/irdma/hw.c b/drivers/infiniband/hw/irdma/hw.c
index c345cc654256..23ad18167607 100644
--- a/drivers/infiniband/hw/irdma/hw.c
+++ b/drivers/infiniband/hw/irdma/hw.c
@@ -2474,29 +2474,33 @@ struct irdma_apbvt_entry *irdma_add_apbvt(struct irdma_device *iwdev, u16 port)
struct irdma_apbvt_entry *entry;
unsigned long flags;
+ mutex_lock(&cm_core->apbvt_add_mutex);
spin_lock_irqsave(&cm_core->apbvt_lock, flags);
entry = irdma_lookup_apbvt_entry(cm_core, port);
- if (entry) {
- spin_unlock_irqrestore(&cm_core->apbvt_lock, flags);
- return entry;
- }
+ spin_unlock_irqrestore(&cm_core->apbvt_lock, flags);
+ if (entry)
+ goto out;
- entry = kzalloc_obj(*entry, GFP_ATOMIC);
- if (!entry) {
- spin_unlock_irqrestore(&cm_core->apbvt_lock, flags);
- return NULL;
- }
+ entry = kzalloc_obj(*entry, GFP_KERNEL);
+ if (!entry)
+ goto out;
entry->port = port;
entry->use_cnt = 1;
- hash_add(cm_core->apbvt_hash_tbl, &entry->hlist, entry->port);
- spin_unlock_irqrestore(&cm_core->apbvt_lock, flags);
if (irdma_cqp_manage_apbvt_cmd(iwdev, port, true)) {
kfree(entry);
- return NULL;
+ entry = NULL;
+ goto out;
}
+ spin_lock_irqsave(&cm_core->apbvt_lock, flags);
+ hash_add(cm_core->apbvt_hash_tbl, &entry->hlist, entry->port);
+ spin_unlock_irqrestore(&cm_core->apbvt_lock, flags);
+
+out:
+ mutex_unlock(&cm_core->apbvt_add_mutex);
+
return entry;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] RDMA/irdma: publish APBVT entries after hardware setup
2026-11-11 9:25 [PATCH] RDMA/irdma: publish APBVT entries after hardware setup Jaeyeong Lee
@ 2026-11-11 9:36 ` sashiko-bot
2026-11-11 15:15 ` Jacob Moroni
1 sibling, 0 replies; 3+ messages in thread
From: sashiko-bot @ 2026-11-11 9:36 UTC (permalink / raw)
To: Jaeyeong Lee, linux-rdma
> irdma_add_apbvt() inserts a new entry into apbvt_hash_tbl before
> sending the CQP command that creates the hardware entry. If the command
> fails, the entry is freed without being removed from the hash table. A
> later lookup of the same port traverses the freed entry.
>
> Removing the entry on failure is not sufficient because another thread
> can find it and increment use_cnt while the CQP command is in progress.
>
> Serialize APBVT additions and publish new entries only after the hardware
> command succeeds. Since the allocation no longer runs under apbvt_lock,
> use GFP_KERNEL.
>
> The issue was found by static analysis and confirmed with a KASAN
> reproducer that forces the CQP failure and retries the same port.
>
> [ ... ]
> init_module+0x210/0xff0 [irdma_apbvt_repro]
>
> Fixes: 44d9e52977a1 ("RDMA/irdma: Implement device initialization definitions")
> Cc: stable@vger.kernel.org
> Signed-off-by: Jaeyeong Lee <lee@jaeyeong.cc>
Sashiko has reviewed this patch and found no issues.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261111092505.3121847-1-lee@jaeyeong.cc?part=1
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] RDMA/irdma: publish APBVT entries after hardware setup
2026-11-11 9:25 [PATCH] RDMA/irdma: publish APBVT entries after hardware setup Jaeyeong Lee
2026-11-11 9:36 ` sashiko-bot
@ 2026-11-11 15:15 ` Jacob Moroni
1 sibling, 0 replies; 3+ messages in thread
From: Jacob Moroni @ 2026-11-11 15:15 UTC (permalink / raw)
To: Jaeyeong Lee
Cc: Tatyana Nikolova, linux-rdma, Jason Gunthorpe, Leon Romanovsky,
Shiraz Saleem, Mustafa Ismail, Gustavo A . R . Silva,
linux-kernel, stable
Thanks. Looks good.
> + entry = kzalloc_obj(*entry, GFP_KERNEL);
> + if (!entry)
> + goto out;
I think the GFP_KERNEL argument can be omitted here.
Reviewed-by: Jacob Moroni <jmoroni@google.com>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-11-11 15:15 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-11 9:25 [PATCH] RDMA/irdma: publish APBVT entries after hardware setup Jaeyeong Lee
2026-11-11 9:36 ` sashiko-bot
2026-11-11 15:15 ` Jacob Moroni
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox