[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 2/4] hw/scsi/megasas: Assert cdb_len is valid in megasas_handl
From: |
Philippe Mathieu-Daudé |
Subject: |
[PATCH v2 2/4] hw/scsi/megasas: Assert cdb_len is valid in megasas_handle_scsi() |
Date: |
Tue, 1 Dec 2020 20:10:24 +0100 |
cdb_len can not be zero... (or less than 6) here, else we have a
out-of-bound read first in scsi_cdb_length():
71 int scsi_cdb_length(uint8_t *buf)
72 {
73 int cdb_len;
74
75 switch (buf[0] >> 5) {
76 case 0:
77 cdb_len = 6;
78 break;
Then another out-of-bound read when the size returned by
scsi_cdb_length() is used.
Figured out after reviewing:
https://www.mail-archive.com/qemu-devel@nongnu.org/msg757937.html
And reproduced fuzzing:
qemu-fuzz-i386: hw/scsi/megasas.c:1679: int megasas_handle_scsi(MegasasState
*, MegasasCmd *, int):
Assertion `len > 0 && cdb_len >= len' failed.
==1689590== ERROR: libFuzzer: deadly signal
#8 0x7f7a5d918e75 in __assert_fail (/lib64/libc.so.6+0x34e75)
#9 0x55a1b95cf6d4 in megasas_handle_scsi hw/scsi/megasas.c:1679:5
#10 0x55a1b95cf6d4 in megasas_handle_frame hw/scsi/megasas.c:1975:24
#11 0x55a1b95cf6d4 in megasas_mmio_write hw/scsi/megasas.c:2132:9
#12 0x55a1b981972e in memory_region_write_accessor softmmu/memory.c:491:5
#13 0x55a1b981972e in access_with_adjusted_size softmmu/memory.c:552:18
#14 0x55a1b981972e in memory_region_dispatch_write
softmmu/memory.c:1501:16
#15 0x55a1b97f0ab0 in flatview_write_continue softmmu/physmem.c:2759:23
#16 0x55a1b97ec3f2 in flatview_write softmmu/physmem.c:2799:14
#17 0x55a1b97ec3f2 in address_space_write softmmu/physmem.c:2891:18
#18 0x55a1b985c7cd in cpu_outw softmmu/ioport.c:70:5
#19 0x55a1b99577ac in qtest_process_command softmmu/qtest.c:481:13
Inspired-by: Daniele Buono <dbuono@linux.vnet.ibm.com>
Inspired-by: Alexander Bulekov <alxndr@bu.edu>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
hw/scsi/megasas.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index 1a5fc5857db..f5ad4425b5b 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -1667,6 +1667,7 @@ static int megasas_handle_scsi(MegasasState *s,
MegasasCmd *cmd,
{
uint8_t *cdb;
int target_id, lun_id, cdb_len;
+ int len = -1;
bool is_write;
struct SCSIDevice *sdev = NULL;
bool is_logical = (frame_cmd == MFI_CMD_LD_SCSI_IO);
@@ -1676,6 +1677,10 @@ static int megasas_handle_scsi(MegasasState *s,
MegasasCmd *cmd,
lun_id = cmd->frame->header.lun_id;
cdb_len = cmd->frame->header.cdb_len;
+ if (cdb_len > 0) {
+ len = scsi_cdb_length(cdb);
+ }
+ assert(len > 0 && cdb_len >= len);
if (is_logical) {
if (target_id >= MFI_MAX_LD || lun_id != 0) {
trace_megasas_scsi_target_not_present(
--
2.26.2
[PATCH v2 3/4] tests/qtest/fuzz-test: Add test_megasas_cdb_len_zero() reproducer, Philippe Mathieu-Daudé, 2020/12/01
[RFC PATCH v2 4/4] hw/scsi/megasas: Have incorrect cdb return MFI_STAT_ABORT_NOT_POSSIBLE, Philippe Mathieu-Daudé, 2020/12/01