FROMLIST: scsi: ufs: Fix memory corruption by ufshcd_read_desc_param()
Running the following commands on my test setup triggers stack corruption:
cd /sys/devices/platform/14700000.ufs/host0/target0:0:0 &&
for f in $(ls */unit_descriptor/hpb_pinned_region_start_offset | sort); do
grep -aH . $f
done
The above commands trigger stack corruption because these commands
assign the value 37 to the variable 'param_offset' and the value 35 to
'buff_len'. The following code changes param_size from 2 into 254 since
'param_size' has type u8:
if (param_offset + param_size > buff_len)
param_size = buff_len - param_offset;
The next statement triggers stack corruption since 'param_read_buf'
points at a two-byte stack array:
memcpy(param_read_buf, &desc_buf[param_offset], param_size);
With this patch applied, the output of the above command on my test
setup is as follows:
0:0:0:0/unit_descriptor/hpb_pinned_region_start_offset:0x0000
0:0:0:1/unit_descriptor/hpb_pinned_region_start_offset:0x0000
0:0:0:2/unit_descriptor/hpb_pinned_region_start_offset:0x0000
0:0:0:3/unit_descriptor/hpb_pinned_region_start_offset:0x0000
grep: 0:0:0:49456/unit_descriptor/hpb_pinned_region_start_offset: Invalid argument
grep: 0:0:0:49476/unit_descriptor/hpb_pinned_region_start_offset: Invalid argument
grep: 0:0:0:49488/unit_descriptor/hpb_pinned_region_start_offset: Invalid argument
Link: https://lore.kernel.org/linux-scsi/20210719231127.869088-1-bvanassche@acm.org/T/#u
Bug: 194045295
Change-Id: I305c15b20f3ac3d6e3e97592566fcc51058195bb
Signed-off-by: Bart Van Assche <bvanassche@google.com>
This commit is contained in:
@@ -3393,9 +3393,11 @@ int ufshcd_read_desc_param(struct ufs_hba *hba,
|
||||
|
||||
if (is_kmalloc) {
|
||||
/* Make sure we don't copy more data than available */
|
||||
if (param_offset + param_size > buff_len)
|
||||
param_size = buff_len - param_offset;
|
||||
memcpy(param_read_buf, &desc_buf[param_offset], param_size);
|
||||
if (param_offset >= buff_len)
|
||||
ret = -EINVAL;
|
||||
else
|
||||
memcpy(param_read_buf, &desc_buf[param_offset],
|
||||
min_t(u32, param_size, buff_len - param_offset));
|
||||
}
|
||||
out:
|
||||
if (is_kmalloc)
|
||||
|
||||
Reference in New Issue
Block a user