Re: [syzbot] [nvme?] BUG: corrupted list in nvmet_fc_remove_port
From: Hillf Danton
Date: Sun Oct 18 2026 - 04:14:00 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
@@ -1268,20 +1268,6 @@ nvmet_fc_portentry_bind(struct nvmet_fc_
list_add_tail(&pe->pe_list, &nvmet_fc_portentry_list);
}
-static void
-nvmet_fc_portentry_unbind(struct nvmet_fc_port_entry *pe)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&nvmet_fc_tgtlock, flags);
- if (pe->tgtport) {
- nvmet_fc_tgtport_put(pe->tgtport);
- pe->tgtport->pe = NULL;
- }
- list_del(&pe->pe_list);
- spin_unlock_irqrestore(&nvmet_fc_tgtlock, flags);
-}
-
/*
* called when a targetport deregisters. Breaks the relationship
* with the nvmet port, but leaves the port_entry in place so that
@@ -2915,24 +2901,31 @@ nvmet_fc_add_port(struct nvmet_port *por
static void
nvmet_fc_remove_port(struct nvmet_port *port)
{
- struct nvmet_fc_port_entry *pe = port->priv;
+ struct nvmet_fc_port_entry *pe, *entry, *an = NULL;
struct nvmet_fc_tgtport *tgtport = NULL;
unsigned long flags;
spin_lock_irqsave(&nvmet_fc_tgtlock, flags);
- if (pe->tgtport && nvmet_fc_tgtport_get(pe->tgtport))
- tgtport = pe->tgtport;
+ pe = port->priv;
+ list_for_each_entry(entry, &nvmet_fc_portentry_list, pe_list) {
+ if (!pe)
+ break;
+ if (entry != pe)
+ continue;
+ list_del(&pe->pe_list);
+ if (pe->tgtport) {
+ pe->tgtport->pe = NULL;
+ tgtport = pe->tgtport;
+ }
+ an = pe;
+ break;
+ }
spin_unlock_irqrestore(&nvmet_fc_tgtlock, flags);
- nvmet_fc_portentry_unbind(pe);
-
+ kfree(an);
if (tgtport) {
- /* terminate any outstanding associations */
- __nvmet_fc_free_assocs(tgtport);
nvmet_fc_tgtport_put(tgtport);
}
-
- kfree(pe);
}
static void
--