Skip to content

Commit 66a834d

Browse files
Ming Leimartinkpetersen
authored andcommitted
scsi: core: Fix error handling of scsi_host_alloc()
After device is initialized via device_initialize(), or its name is set via dev_set_name(), the device has to be freed via put_device(). Otherwise device name will be leaked because it is allocated dynamically in dev_set_name(). Fix the leak by replacing kfree() with put_device(). Since scsi_host_dev_release() properly handles IDA and kthread removal, remove special-casing these from the error handling as well. Link: https://lore.kernel.org/r/[email protected] Cc: Bart Van Assche <[email protected]> Cc: John Garry <[email protected]> Cc: Hannes Reinecke <[email protected]> Tested-by: John Garry <[email protected]> Reviewed-by: Bart Van Assche <[email protected]> Reviewed-by: John Garry <[email protected]> Reviewed-by: Hannes Reinecke <[email protected]> Signed-off-by: Ming Lei <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent e57f5cd commit 66a834d

File tree

1 file changed

+13
-10
lines changed

1 file changed

+13
-10
lines changed

drivers/scsi/hosts.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -388,8 +388,10 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
388388
mutex_init(&shost->scan_mutex);
389389

390390
index = ida_simple_get(&host_index_ida, 0, 0, GFP_KERNEL);
391-
if (index < 0)
392-
goto fail_kfree;
391+
if (index < 0) {
392+
kfree(shost);
393+
return NULL;
394+
}
393395
shost->host_no = index;
394396

395397
shost->dma_channel = 0xff;
@@ -481,7 +483,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
481483
shost_printk(KERN_WARNING, shost,
482484
"error handler thread failed to spawn, error = %ld\n",
483485
PTR_ERR(shost->ehandler));
484-
goto fail_index_remove;
486+
goto fail;
485487
}
486488

487489
shost->tmf_work_q = alloc_workqueue("scsi_tmf_%d",
@@ -490,17 +492,18 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
490492
if (!shost->tmf_work_q) {
491493
shost_printk(KERN_WARNING, shost,
492494
"failed to create tmf workq\n");
493-
goto fail_kthread;
495+
goto fail;
494496
}
495497
scsi_proc_hostdir_add(shost->hostt);
496498
return shost;
499+
fail:
500+
/*
501+
* Host state is still SHOST_CREATED and that is enough to release
502+
* ->shost_gendev. scsi_host_dev_release() will free
503+
* dev_name(&shost->shost_dev).
504+
*/
505+
put_device(&shost->shost_gendev);
497506

498-
fail_kthread:
499-
kthread_stop(shost->ehandler);
500-
fail_index_remove:
501-
ida_simple_remove(&host_index_ida, shost->host_no);
502-
fail_kfree:
503-
kfree(shost);
504507
return NULL;
505508
}
506509
EXPORT_SYMBOL(scsi_host_alloc);

0 commit comments

Comments
 (0)