Bug 194061

Summary: integer overflow in linux/drivers/scsi/qla2xxx/qla_attr.c:346
Product: Drivers Reporter: shqking (shqking)
Component: OtherAssignee: drivers_other
Status: NEW ---    
Severity: high    
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: Linux 4.10-rc7 Subsystem:
Regression: No Bisected commit-id:

Description shqking 2017-02-06 09:30:48 UTC
Hello.

An potential integer overflow is found in linux/drivers/scsi/qla2xxx/qla_attr.c:346.

346 ha->optrom_region_size = start + size > ha->optrom_size ?
347 ha->optrom_size - start : size;

The intention of the conditional expression at line 346 is to guarantee that the result, i.e. "has->optrom_region_size", is no bigger than "ha->optrom_size - start".

It is a fact that "start" is less than "ha->optrom_size" due to the check at line 319.
However, there is no range check for "size".
An integer overflow for "start + size" would occur, if "size" is set as a very big integer.

For example, assume that "start" is 2, "size" is 0xffffffff and "ha->optrom_size" is 100, "start + size" overflows to 1, invalidating the security check at line 346 and causing the result ("ha->optrom_region_size") to hold the big integer 0xffffffff.
This would further lead to huge memory allocation at line 350 and buffer overflow at line 373. 

A possible workaround is to add an overflow check at line 346, like below:
  ha->optrom_region_size = (start + size < start || start + size > ha->optrom_size) ? ha->optrom_size - start : size;

Thanks.