lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:   Wed,  8 Feb 2023 10:41:03 +0800
From:   Jiasheng Jiang <jiasheng@...as.ac.cn>
To:     linuxdrivers@...otech.com, jejb@...ux.ibm.com,
        martin.petersen@...cle.com
Cc:     linux-scsi@...r.kernel.org, linux-kernel@...r.kernel.org,
        Jiasheng Jiang <jiasheng@...as.ac.cn>
Subject: [PATCH] scsi: esas2r: Add missing check and destroy for create_singlethread_workqueue

Add the check for the return value of the create_singlethread_workqueue
in order to avoid NULL pointer dereference.
Moreover, the allocated "a->fw_event_q" should be destroyed when
esas2r_init_adapter fails later in order to avoid memory leak.
It is better to use goto label to remove duplicate error handling code.

Fixes: 26780d9e12ed ("[SCSI] esas2r: ATTO Technology ExpressSAS 6G SAS/SATA RAID Adapter Driver")
Signed-off-by: Jiasheng Jiang <jiasheng@...as.ac.cn>
---
 drivers/scsi/esas2r/esas2r_init.c | 30 ++++++++++++++++++------------
 1 file changed, 18 insertions(+), 12 deletions(-)

diff --git a/drivers/scsi/esas2r/esas2r_init.c b/drivers/scsi/esas2r/esas2r_init.c
index c1a5ab662dc8..820530639517 100644
--- a/drivers/scsi/esas2r/esas2r_init.c
+++ b/drivers/scsi/esas2r/esas2r_init.c
@@ -272,14 +272,14 @@ int esas2r_init_adapter(struct Scsi_Host *host, struct pci_dev *pcid,
 		esas2r_log(ESAS2R_LOG_CRIT,
 			   "tried to init invalid adapter index %u!",
 			   index);
-		return 0;
+		goto error_exit;
 	}
 
 	if (esas2r_adapters[index]) {
 		esas2r_log(ESAS2R_LOG_CRIT,
 			   "tried to init existing adapter index %u!",
 			   index);
-		return 0;
+		goto error_exit;
 	}
 
 	a = (struct esas2r_adapter *)host->hostdata;
@@ -294,8 +294,7 @@ int esas2r_init_adapter(struct Scsi_Host *host, struct pci_dev *pcid,
 
 	if (!dma64 && dma_set_mask_and_coherent(&pcid->dev, DMA_BIT_MASK(32))) {
 		esas2r_log(ESAS2R_LOG_CRIT, "failed to set DMA mask");
-		esas2r_kill_adapter(index);
-		return 0;
+		goto error_kill_adapter;
 	}
 
 	esas2r_log_dev(ESAS2R_LOG_INFO, &pcid->dev,
@@ -314,6 +313,10 @@ int esas2r_init_adapter(struct Scsi_Host *host, struct pci_dev *pcid,
 	snprintf(a->fw_event_q_name, ESAS2R_KOBJ_NAME_LEN, "esas2r/%d",
 		 a->index);
 	a->fw_event_q = create_singlethread_workqueue(a->fw_event_q_name);
+	if (!a->fw_event_q) {
+		esas2r_log(ESAS2R_LOG_CRIT, "failed to allocate workqueue");
+		goto error_kill_adapter;
+	}
 
 	init_waitqueue_head(&a->buffered_ioctl_waiter);
 	init_waitqueue_head(&a->nvram_waiter);
@@ -338,8 +341,7 @@ int esas2r_init_adapter(struct Scsi_Host *host, struct pci_dev *pcid,
 		if (!alloc_vda_req(a, last_request)) {
 			esas2r_log(ESAS2R_LOG_CRIT,
 				   "failed to allocate a VDA request!");
-			esas2r_kill_adapter(index);
-			return 0;
+			goto error_destroy_workqueue;
 		}
 	}
 
@@ -350,8 +352,7 @@ int esas2r_init_adapter(struct Scsi_Host *host, struct pci_dev *pcid,
 
 	if (esas2r_map_regions(a) != 0) {
 		esas2r_log(ESAS2R_LOG_CRIT, "could not map PCI regions!");
-		esas2r_kill_adapter(index);
-		return 0;
+		goto error_destroy_workqueue;
 	}
 
 	a->index = index;
@@ -379,8 +380,7 @@ int esas2r_init_adapter(struct Scsi_Host *host, struct pci_dev *pcid,
 		esas2r_log(ESAS2R_LOG_CRIT,
 			   "failed to allocate %d bytes of consistent memory!",
 			   a->uncached_size);
-		esas2r_kill_adapter(index);
-		return 0;
+		goto error_destroy_workqueue;
 	}
 
 	a->uncached_phys = bus_addr;
@@ -397,8 +397,7 @@ int esas2r_init_adapter(struct Scsi_Host *host, struct pci_dev *pcid,
 					&next_uncached)) {
 		esas2r_log(ESAS2R_LOG_CRIT,
 			   "failed to initialize adapter structure (2)!");
-		esas2r_kill_adapter(index);
-		return 0;
+		goto error_destroy_workqueue;
 	}
 
 	tasklet_init(&a->tasklet,
@@ -430,6 +429,13 @@ int esas2r_init_adapter(struct Scsi_Host *host, struct pci_dev *pcid,
 		     a, a->disable_cnt);
 
 	return 1;
+
+error_destroy_workqueue:
+	destroy_workqueue(a->fw_event_q);
+error_kill_adapter:
+	esas2r_kill_adapter(index);
+error_exit:
+	return 0;
 }
 
 static void esas2r_adapter_power_down(struct esas2r_adapter *a,
-- 
2.25.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ