Re: [syzbot] [nvme?] BUG: corrupted list in nvmet_fc_remove_port
From: Hillf Danton
Date: Sat Oct 17 2026 - 03:31:51 EST
> Date: Sun, 11 Oct 2026 10:32:37 -0700 [thread overview]
> Hello,
>
> syzbot found the following issue on:
>
> HEAD commit: a5ebb76233b7 Merge tag 'edac_urgent_for_v7.3_rc7' of git:/..
> git tree: upstream
> console+strace: https://syzkaller.appspot.com/x/log.txt?x=1494923e580000
> kernel config: https://syzkaller.appspot.com/x/.config?x=df4bbab1c2172b9f
> dashboard link: https://syzkaller.appspot.com/bug?extid=c98b21427617af7f547a
> syz repro: https://syzkaller.appspot.com/x/repro.syz?x=126a0f15580000
> C reproducer: https://syzkaller.appspot.com/x/repro.c?x=166a0f15580000
#syz test
--- x/drivers/nvme/target/fc.c
+++ y/drivers/nvme/target/fc.c
@@ -113,6 +113,7 @@ struct nvmet_fc_tgtport {
struct nvmet_fc_port_entry *pe;
struct kref ref;
u32 max_sg_cnt;
+ int assoc_freed;
};
struct nvmet_fc_port_entry {
@@ -1271,9 +1272,17 @@ nvmet_fc_portentry_bind(struct nvmet_fc_
static void
nvmet_fc_portentry_unbind(struct nvmet_fc_port_entry *pe)
{
+ struct nvmet_fc_port_entry *entry;
unsigned long flags;
spin_lock_irqsave(&nvmet_fc_tgtlock, flags);
+ list_for_each_entry(entry, &nvmet_fc_portentry_list, pe_list) {
+ if (entry == pe)
+ goto out;
+ }
+ spin_unlock_irqrestore(&nvmet_fc_tgtlock, flags);
+ return;
+out:
if (pe->tgtport) {
nvmet_fc_tgtport_put(pe->tgtport);
pe->tgtport->pe = NULL;
@@ -1475,6 +1484,9 @@ __nvmet_fc_free_assocs(struct nvmet_fc_t
{
struct nvmet_fc_tgt_assoc *assoc;
+ if (tgtport->assoc_freed)
+ return;
+ tgtport->assoc_freed = 1;
rcu_read_lock();
list_for_each_entry_rcu(assoc, &tgtport->assoc_list, a_list) {
if (!nvmet_fc_tgt_a_get(assoc))
@@ -1643,8 +1655,10 @@ nvmet_fc_unregister_targetport(struct nv
nvmet_fc_portentry_unbind_tgt(tgtport);
+ spin_lock_irqsave(&nvmet_fc_tgtlock, flags);
/* terminate any outstanding associations */
__nvmet_fc_free_assocs(tgtport);
+ spin_unlock_irqrestore(&nvmet_fc_tgtlock, flags);
flush_workqueue(nvmet_wq);
@@ -2927,8 +2941,10 @@ nvmet_fc_remove_port(struct nvmet_port *
nvmet_fc_portentry_unbind(pe);
if (tgtport) {
+ spin_lock_irqsave(&nvmet_fc_tgtlock, flags);
/* terminate any outstanding associations */
__nvmet_fc_free_assocs(tgtport);
+ spin_unlock_irqrestore(&nvmet_fc_tgtlock, flags);
nvmet_fc_tgtport_put(tgtport);
}
--