Skip to content

Commit bdb854f

Browse files
gkennedy12gregkh
authored andcommitted
scsi: scsi_debug: Fix type in min_t to avoid stack OOB
commit 36e07d7 upstream. Change min_t() to use type "u32" instead of type "int" to avoid stack out of bounds. With min_t() type "int" the values get sign extended and the larger value gets used causing stack out of bounds. BUG: KASAN: stack-out-of-bounds in memcpy include/linux/fortify-string.h:191 [inline] BUG: KASAN: stack-out-of-bounds in sg_copy_buffer+0x1de/0x240 lib/scatterlist.c:976 Read of size 127 at addr ffff888072607128 by task syz-executor.7/18707 CPU: 1 PID: 18707 Comm: syz-executor.7 Not tainted 5.15.0-syzk #1 Hardware name: Red Hat KVM, BIOS 1.13.0-2 Call Trace: __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x89/0xb5 lib/dump_stack.c:106 print_address_description.constprop.9+0x28/0x160 mm/kasan/report.c:256 __kasan_report mm/kasan/report.c:442 [inline] kasan_report.cold.14+0x7d/0x117 mm/kasan/report.c:459 check_region_inline mm/kasan/generic.c:183 [inline] kasan_check_range+0x1a3/0x210 mm/kasan/generic.c:189 memcpy+0x23/0x60 mm/kasan/shadow.c:65 memcpy include/linux/fortify-string.h:191 [inline] sg_copy_buffer+0x1de/0x240 lib/scatterlist.c:976 sg_copy_from_buffer+0x33/0x40 lib/scatterlist.c:1000 fill_from_dev_buffer.part.34+0x82/0x130 drivers/scsi/scsi_debug.c:1162 fill_from_dev_buffer drivers/scsi/scsi_debug.c:1888 [inline] resp_readcap16+0x365/0x3b0 drivers/scsi/scsi_debug.c:1887 schedule_resp+0x4d8/0x1a70 drivers/scsi/scsi_debug.c:5478 scsi_debug_queuecommand+0x8c9/0x1ec0 drivers/scsi/scsi_debug.c:7533 scsi_dispatch_cmd drivers/scsi/scsi_lib.c:1520 [inline] scsi_queue_rq+0x16b0/0x2d40 drivers/scsi/scsi_lib.c:1699 blk_mq_dispatch_rq_list+0xb9b/0x2700 block/blk-mq.c:1639 __blk_mq_sched_dispatch_requests+0x28f/0x590 block/blk-mq-sched.c:325 blk_mq_sched_dispatch_requests+0x105/0x190 block/blk-mq-sched.c:358 __blk_mq_run_hw_queue+0xe5/0x150 block/blk-mq.c:1761 __blk_mq_delay_run_hw_queue+0x4f8/0x5c0 block/blk-mq.c:1838 blk_mq_run_hw_queue+0x18d/0x350 block/blk-mq.c:1891 blk_mq_sched_insert_request+0x3db/0x4e0 block/blk-mq-sched.c:474 blk_execute_rq_nowait+0x16b/0x1c0 block/blk-exec.c:62 sg_common_write.isra.18+0xeb3/0x2000 drivers/scsi/sg.c:836 sg_new_write.isra.19+0x570/0x8c0 drivers/scsi/sg.c:774 sg_ioctl_common+0x14d6/0x2710 drivers/scsi/sg.c:939 sg_ioctl+0xa2/0x180 drivers/scsi/sg.c:1165 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:874 [inline] __se_sys_ioctl fs/ioctl.c:860 [inline] __x64_sys_ioctl+0x19d/0x220 fs/ioctl.c:860 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3a/0x80 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x44/0xae Link: https://lore.kernel.org/r/[email protected] Reported-by: syzkaller <[email protected]> Acked-by: Douglas Gilbert <[email protected]> Signed-off-by: George Kennedy <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent aa1f912 commit bdb854f

File tree

1 file changed

+19
-15
lines changed

1 file changed

+19
-15
lines changed

Diff for: drivers/scsi/scsi_debug.c

+19-15
Original file line numberDiff line numberDiff line change
@@ -1188,7 +1188,7 @@ static int p_fill_from_dev_buffer(struct scsi_cmnd *scp, const void *arr,
11881188
__func__, off_dst, scsi_bufflen(scp), act_len,
11891189
scsi_get_resid(scp));
11901190
n = scsi_bufflen(scp) - (off_dst + act_len);
1191-
scsi_set_resid(scp, min_t(int, scsi_get_resid(scp), n));
1191+
scsi_set_resid(scp, min_t(u32, scsi_get_resid(scp), n));
11921192
return 0;
11931193
}
11941194

@@ -1561,7 +1561,8 @@ static int resp_inquiry(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
15611561
unsigned char pq_pdt;
15621562
unsigned char *arr;
15631563
unsigned char *cmd = scp->cmnd;
1564-
int alloc_len, n, ret;
1564+
u32 alloc_len, n;
1565+
int ret;
15651566
bool have_wlun, is_disk, is_zbc, is_disk_zbc;
15661567

15671568
alloc_len = get_unaligned_be16(cmd + 3);
@@ -1584,7 +1585,8 @@ static int resp_inquiry(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
15841585
kfree(arr);
15851586
return check_condition_result;
15861587
} else if (0x1 & cmd[1]) { /* EVPD bit set */
1587-
int lu_id_num, port_group_id, target_dev_id, len;
1588+
int lu_id_num, port_group_id, target_dev_id;
1589+
u32 len;
15881590
char lu_id_str[6];
15891591
int host_no = devip->sdbg_host->shost->host_no;
15901592

@@ -1675,9 +1677,9 @@ static int resp_inquiry(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
16751677
kfree(arr);
16761678
return check_condition_result;
16771679
}
1678-
len = min(get_unaligned_be16(arr + 2) + 4, alloc_len);
1680+
len = min_t(u32, get_unaligned_be16(arr + 2) + 4, alloc_len);
16791681
ret = fill_from_dev_buffer(scp, arr,
1680-
min(len, SDEBUG_MAX_INQ_ARR_SZ));
1682+
min_t(u32, len, SDEBUG_MAX_INQ_ARR_SZ));
16811683
kfree(arr);
16821684
return ret;
16831685
}
@@ -1713,7 +1715,7 @@ static int resp_inquiry(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
17131715
}
17141716
put_unaligned_be16(0x2100, arr + n); /* SPL-4 no version claimed */
17151717
ret = fill_from_dev_buffer(scp, arr,
1716-
min_t(int, alloc_len, SDEBUG_LONG_INQ_SZ));
1718+
min_t(u32, alloc_len, SDEBUG_LONG_INQ_SZ));
17171719
kfree(arr);
17181720
return ret;
17191721
}
@@ -1728,8 +1730,8 @@ static int resp_requests(struct scsi_cmnd *scp,
17281730
unsigned char *cmd = scp->cmnd;
17291731
unsigned char arr[SCSI_SENSE_BUFFERSIZE]; /* assume >= 18 bytes */
17301732
bool dsense = !!(cmd[1] & 1);
1731-
int alloc_len = cmd[4];
1732-
int len = 18;
1733+
u32 alloc_len = cmd[4];
1734+
u32 len = 18;
17331735
int stopped_state = atomic_read(&devip->stopped);
17341736

17351737
memset(arr, 0, sizeof(arr));
@@ -1773,7 +1775,7 @@ static int resp_requests(struct scsi_cmnd *scp,
17731775
arr[7] = 0xa;
17741776
}
17751777
}
1776-
return fill_from_dev_buffer(scp, arr, min_t(int, len, alloc_len));
1778+
return fill_from_dev_buffer(scp, arr, min_t(u32, len, alloc_len));
17771779
}
17781780

17791781
static int resp_start_stop(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
@@ -2311,7 +2313,8 @@ static int resp_mode_sense(struct scsi_cmnd *scp,
23112313
{
23122314
int pcontrol, pcode, subpcode, bd_len;
23132315
unsigned char dev_spec;
2314-
int alloc_len, offset, len, target_dev_id;
2316+
u32 alloc_len, offset, len;
2317+
int target_dev_id;
23152318
int target = scp->device->id;
23162319
unsigned char *ap;
23172320
unsigned char arr[SDEBUG_MAX_MSENSE_SZ];
@@ -2467,7 +2470,7 @@ static int resp_mode_sense(struct scsi_cmnd *scp,
24672470
arr[0] = offset - 1;
24682471
else
24692472
put_unaligned_be16((offset - 2), arr + 0);
2470-
return fill_from_dev_buffer(scp, arr, min_t(int, alloc_len, offset));
2473+
return fill_from_dev_buffer(scp, arr, min_t(u32, alloc_len, offset));
24712474
}
24722475

24732476
#define SDEBUG_MAX_MSELECT_SZ 512
@@ -2582,7 +2585,8 @@ static int resp_ie_l_pg(unsigned char *arr)
25822585
static int resp_log_sense(struct scsi_cmnd *scp,
25832586
struct sdebug_dev_info *devip)
25842587
{
2585-
int ppc, sp, pcode, subpcode, alloc_len, len, n;
2588+
int ppc, sp, pcode, subpcode;
2589+
u32 alloc_len, len, n;
25862590
unsigned char arr[SDEBUG_MAX_LSENSE_SZ];
25872591
unsigned char *cmd = scp->cmnd;
25882592

@@ -2652,9 +2656,9 @@ static int resp_log_sense(struct scsi_cmnd *scp,
26522656
mk_sense_invalid_fld(scp, SDEB_IN_CDB, 3, -1);
26532657
return check_condition_result;
26542658
}
2655-
len = min_t(int, get_unaligned_be16(arr + 2) + 4, alloc_len);
2659+
len = min_t(u32, get_unaligned_be16(arr + 2) + 4, alloc_len);
26562660
return fill_from_dev_buffer(scp, arr,
2657-
min_t(int, len, SDEBUG_MAX_INQ_ARR_SZ));
2661+
min_t(u32, len, SDEBUG_MAX_INQ_ARR_SZ));
26582662
}
26592663

26602664
static inline bool sdebug_dev_is_zoned(struct sdebug_dev_info *devip)
@@ -4409,7 +4413,7 @@ static int resp_report_zones(struct scsi_cmnd *scp,
44094413
put_unaligned_be64(sdebug_capacity - 1, arr + 8);
44104414

44114415
rep_len = (unsigned long)desc - (unsigned long)arr;
4412-
ret = fill_from_dev_buffer(scp, arr, min_t(int, alloc_len, rep_len));
4416+
ret = fill_from_dev_buffer(scp, arr, min_t(u32, alloc_len, rep_len));
44134417

44144418
fini:
44154419
read_unlock(macc_lckp);

0 commit comments

Comments
 (0)