diff mbox

[v2] scsi: qla2xxx: Fix an integer overflow in sysfs code

Message ID BY2PR07MB23426AD1AC3C646124E8FBBE939C0@BY2PR07MB2342.namprd07.prod.outlook.com (mailing list archive)
State Not Applicable
Headers show

Commit Message

Carnuccio, Joe Aug. 30, 2017, 5:08 p.m. UTC
good catch, thanks; I'll propagate this to our various OOB drivers.


-----Original Message-----
From: Dan Carpenter [mailto:dan.carpenter@oracle.com] 
Sent: Wednesday, August 30, 2017 6:31 AM
To: Dept-Eng QLA2xxx Upstream <qla2xxx-upstream@cavium.com>; shqking <shqking@gmail.com>; Carnuccio, Joe <Joe.Carnuccio@cavium.com>
Cc: James E.J. Bottomley <jejb@linux.vnet.ibm.com>; Martin K. Petersen <martin.petersen@oracle.com>; linux-scsi@vger.kernel.org; security@kernel.org
Subject: [PATCH v2] scsi: qla2xxx: Fix an integer overflow in sysfs code

The value of "size" comes from the user.  When we add "start + size"
it could lead to an integer overflow bug.

It means we vmalloc() a lot more memory than we had intended.  I believe that on 64 bit systems vmalloc() can succeed even if we ask it to allocate huge 4GB buffers.  So we would get memory corruption and likely a crash when we call ha->isp_ops->write_optrom() and ->read_optrom().

Only root can trigger this bug.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=194061

Cc: stable@vger.kernel.org
Fixes: b7cc176c9eb3 ("[SCSI] qla2xxx: Allow region-based flash-part accesses.")
Reported-by: shqking <shqking@gmail.com>
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
---
v2: Add stable and the URL for bugzila

 		}
 
 		ha->optrom_region_start = start;
-		ha->optrom_region_size = start + size > ha->optrom_size ?
-		    ha->optrom_size - start : size;
+		ha->optrom_region_size = start + size;
 
 		ha->optrom_state = QLA_SWRITING;
 		ha->optrom_buffer = vmalloc(ha->optrom_region_size);
diff mbox

Patch

diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 75c4b312645e..9ce28c4f9812 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -318,6 +318,8 @@  qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj,
 		return -EINVAL;
 	if (start > ha->optrom_size)
 		return -EINVAL;
+	if (size > ha->optrom_size - start)
+		size = ha->optrom_size - start;
 
 	mutex_lock(&ha->optrom_mutex);
 	switch (val) {
@@ -343,8 +345,7 @@  qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj,
 		}
 
 		ha->optrom_region_start = start;
-		ha->optrom_region_size = start + size > ha->optrom_size ?
-		    ha->optrom_size - start : size;
+		ha->optrom_region_size = start + size;
 
 		ha->optrom_state = QLA_SREADING;
 		ha->optrom_buffer = vmalloc(ha->optrom_region_size); @@ -417,8 +418,7 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj,