| From 2f4843b172c2c0360ee7792ad98025fae7baefde Mon Sep 17 00:00:00 2001 |
| From: Helge Deller <deller@gmx.de> |
| Date: Thu, 22 Oct 2020 11:00:05 +0200 |
| Subject: scsi: mptfusion: Fix null pointer dereferences in mptscsih_remove() |
| |
| From: Helge Deller <deller@gmx.de> |
| |
| commit 2f4843b172c2c0360ee7792ad98025fae7baefde upstream. |
| |
| The mptscsih_remove() function triggers a kernel oops if the Scsi_Host |
| pointer (ioc->sh) is NULL, as can be seen in this syslog: |
| |
| ioc0: LSI53C1030 B2: Capabilities={Initiator,Target} |
| Begin: Waiting for root file system ... |
| scsi host2: error handler thread failed to spawn, error = -4 |
| mptspi: ioc0: WARNING - Unable to register controller with SCSI subsystem |
| Backtrace: |
| [<000000001045b7cc>] mptspi_probe+0x248/0x3d0 [mptspi] |
| [<0000000040946470>] pci_device_probe+0x1ac/0x2d8 |
| [<0000000040add668>] really_probe+0x1bc/0x988 |
| [<0000000040ade704>] driver_probe_device+0x160/0x218 |
| [<0000000040adee24>] device_driver_attach+0x160/0x188 |
| [<0000000040adef90>] __driver_attach+0x144/0x320 |
| [<0000000040ad7c78>] bus_for_each_dev+0xd4/0x158 |
| [<0000000040adc138>] driver_attach+0x4c/0x80 |
| [<0000000040adb3ec>] bus_add_driver+0x3e0/0x498 |
| [<0000000040ae0130>] driver_register+0xf4/0x298 |
| [<00000000409450c4>] __pci_register_driver+0x78/0xa8 |
| [<000000000007d248>] mptspi_init+0x18c/0x1c4 [mptspi] |
| |
| This patch adds the necessary NULL-pointer checks. Successfully tested on |
| a HP C8000 parisc workstation with buggy SCSI drives. |
| |
| Link: https://lore.kernel.org/r/20201022090005.GA9000@ls3530.fritz.box |
| Cc: <stable@vger.kernel.org> |
| Signed-off-by: Helge Deller <deller@gmx.de> |
| Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/message/fusion/mptscsih.c | 13 ++++++++----- |
| 1 file changed, 8 insertions(+), 5 deletions(-) |
| |
| --- a/drivers/message/fusion/mptscsih.c |
| +++ b/drivers/message/fusion/mptscsih.c |
| @@ -1176,8 +1176,10 @@ mptscsih_remove(struct pci_dev *pdev) |
| MPT_SCSI_HOST *hd; |
| int sz1; |
| |
| - if((hd = shost_priv(host)) == NULL) |
| - return; |
| + if (host == NULL) |
| + hd = NULL; |
| + else |
| + hd = shost_priv(host); |
| |
| mptscsih_shutdown(pdev); |
| |
| @@ -1193,14 +1195,15 @@ mptscsih_remove(struct pci_dev *pdev) |
| "Free'd ScsiLookup (%d) memory\n", |
| ioc->name, sz1)); |
| |
| - kfree(hd->info_kbuf); |
| + if (hd) |
| + kfree(hd->info_kbuf); |
| |
| /* NULL the Scsi_Host pointer |
| */ |
| ioc->sh = NULL; |
| |
| - scsi_host_put(host); |
| - |
| + if (host) |
| + scsi_host_put(host); |
| mpt_detach(pdev); |
| |
| } |