linux/drivers/scsi/snic
Chen Changcheng 12e67eb89e scsi: snic: Fix SCSI host leak on workqueue allocation failure
In snic_add_host(), if scsi_add_host() succeeds but
alloc_ordered_workqueue() fails, the function returns -ENOMEM with
shost->work_q left as NULL. The caller's error path then calls
snic_del_host(), which returns early when !shost->work_q without calling
scsi_remove_host(). The Scsi_Host remains registered in sysfs as a zombie
device even after the probe has failed. This causes:

 - The leaked host remains visible in /sys/class/scsi_host/ after probe
   failure, with state "running".

 - Subsequent SCSI host numbering is permanently shifted (the leaked host
   ID from ida_alloc() is never reclaimed).

 - Memory leak: the Scsi_Host allocation can never be freed because
   device_add() took a reference that can only be released by device_del()
   inside scsi_remove_host().

Fix by adding scsi_remove_host() in the workqueue allocation failure path
inside snic_add_host(), undoing the successful scsi_add_host() before
returning the error. This is cleaner than modifying snic_del_host() because
snic_del_host() is called from a shared error label that also serves paths
where snic_add_host() was never invoked.

Reproducer (requires no real SNIC hardware):

 - Build CONFIG_SCSI_SNIC=y (built-in)

 - Add snic.test_mode=1 snic.inject_wq_fail=1 to kernel cmdline

 - Boot with a PCI device matching the snic driver (e.g. QEMU edu device,
   PCI ID 0x1234:0x11e8, temporarily added to the driver's PCI ID table)

Before the fix:

  # /sys/class/scsi_host/ contains a zombie host0:
  $ cat /sys/class/scsi_host/host0/proc_name
  snic_scsi
  $ cat /sys/class/scsi_host/host0/state
  running
  # ata_piix gets host1, host2 (host0 stuck):
  scsi host1: ata_piix
  scsi host2: ata_piix

After the fix:

  # host0 is properly freed and reused by ata_piix:
  scsi host0: ata_piix
  scsi host1: ata_piix
  # No zombie host in /sys/class/scsi_host/

Signed-off-by: Chen Changcheng <chenchangcheng@kylinos.cn>
Acked-by: Narsimhulu Musini <nmusini@cisco.com>
Link: https://patch.msgid.link/20260727073438.209673-1-chenchangcheng@kylinos.cn
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
2026-08-23 22:34:58 -04:00
..
cq_desc.h
cq_enet_desc.h
Makefile
snic_attrs.c
snic_ctl.c
snic_debugfs.c scsi: snic: Switch to use %ptSp 2025-11-19 12:30:11 +01:00
snic_disc.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
snic_disc.h
snic_fwint.h
snic_io.c
snic_io.h
snic_isr.c
snic_main.c scsi: snic: Fix SCSI host leak on workqueue allocation failure 2026-08-23 22:34:58 -04:00
snic_res.c
snic_res.h
snic_scsi.c scsi: Change the return type of the .queuecommand() callback 2026-01-23 21:32:34 -05:00
snic_stats.h
snic_trc.c scsi: snic: Switch to use %ptSp 2025-11-19 12:30:11 +01:00
snic_trc.h
snic.h scsi: Change the return type of the .queuecommand() callback 2026-01-23 21:32:34 -05:00
vnic_cq_fw.h
vnic_cq.c
vnic_cq.h
vnic_dev.c scsi: snic: vnic_dev: Remove dead store in vnic_dev_discover_res() 2026-05-14 21:33:17 -04:00
vnic_dev.h
vnic_devcmd.h
vnic_intr.c
vnic_intr.h
vnic_resource.h
vnic_snic.h
vnic_stats.h
vnic_wq.c
vnic_wq.h
wq_enet_desc.h