File CVE-2017-9503-qemuu-megasas-always-store-SCSIRequest-into-MegasasCmd.patch of Package xen.5424
This ensures that the request is unref'ed properly, and avoids a
segmentation fault in the new qtest testcase that is added.
Reported-by: Zhangyanyu <address@hidden>
Signed-off-by: Paolo Bonzini <address@hidden>
---
hw/scsi/megasas.c | 31 ++++++++++++++++---------------
tests/megasas-test.c | 35 +++++++++++++++++++++++++++++++++++
2 files changed, 51 insertions(+), 15 deletions(-)
Index: xen-4.5.5-testing/tools/qemu-xen-dir-remote/hw/scsi/megasas.c
===================================================================
--- xen-4.5.5-testing.orig/tools/qemu-xen-dir-remote/hw/scsi/megasas.c
+++ xen-4.5.5-testing/tools/qemu-xen-dir-remote/hw/scsi/megasas.c
@@ -567,6 +567,9 @@ static void megasas_reset_frames(Megasas
static void megasas_abort_command(MegasasCmd *cmd)
{
+ if (cmd->dcmd_opcode != -1) {
+ return;
+ }
if (cmd->req) {
scsi_req_cancel(cmd->req);
cmd->req = NULL;
@@ -970,7 +973,6 @@ static int megasas_pd_get_info_submit(SC
uint64_t pd_size;
uint16_t sdev_id = ((sdev->id & 0xFF) >> 8) | (lun & 0xFF);
uint8_t cmdbuf[6];
- SCSIRequest *req;
size_t len, resid;
if (!cmd->iov_buf) {
@@ -980,8 +982,8 @@ static int megasas_pd_get_info_submit(SC
info->inquiry_data[0] = 0x7f; /* Force PQual 0x3, PType 0x1f */
info->vpd_page83[0] = 0x7f;
megasas_setup_inquiry(cmdbuf, 0, sizeof(info->inquiry_data));
- req = scsi_req_new(sdev, cmd->index, lun, cmdbuf, cmd);
- if (!req) {
+ cmd->req = scsi_req_new(sdev, cmd->index, lun, cmdbuf, cmd);
+ if (!cmd->req) {
trace_megasas_dcmd_req_alloc_failed(cmd->index,
"PD get info std inquiry");
g_free(cmd->iov_buf);
@@ -990,26 +992,26 @@ static int megasas_pd_get_info_submit(SC
}
trace_megasas_dcmd_internal_submit(cmd->index,
"PD get info std inquiry", lun);
- len = scsi_req_enqueue(req);
+ len = scsi_req_enqueue(cmd->req);
if (len > 0) {
cmd->iov_size = len;
- scsi_req_continue(req);
+ scsi_req_continue(cmd->req);
}
return MFI_STAT_INVALID_STATUS;
} else if (info->inquiry_data[0] != 0x7f && info->vpd_page83[0] == 0x7f) {
megasas_setup_inquiry(cmdbuf, 0x83, sizeof(info->vpd_page83));
- req = scsi_req_new(sdev, cmd->index, lun, cmdbuf, cmd);
- if (!req) {
+ cmd->req = scsi_req_new(sdev, cmd->index, lun, cmdbuf, cmd);
+ if (!cmd->req) {
trace_megasas_dcmd_req_alloc_failed(cmd->index,
"PD get info vpd inquiry");
return MFI_STAT_FLASH_ALLOC_FAIL;
}
trace_megasas_dcmd_internal_submit(cmd->index,
"PD get info vpd inquiry", lun);
- len = scsi_req_enqueue(req);
+ len = scsi_req_enqueue(cmd->req);
if (len > 0) {
cmd->iov_size = len;
- scsi_req_continue(req);
+ scsi_req_continue(cmd->req);
}
return MFI_STAT_INVALID_STATUS;
}
@@ -1132,7 +1134,6 @@ static int megasas_ld_get_info_submit(SC
struct mfi_ld_info *info = cmd->iov_buf;
size_t dcmd_size = sizeof(struct mfi_ld_info);
uint8_t cdb[6];
- SCSIRequest *req;
ssize_t len, resid;
BlockConf *conf = &sdev->conf;
uint16_t sdev_id = ((sdev->id & 0xFF) >> 8) | (lun & 0xFF);
@@ -1143,8 +1144,8 @@ static int megasas_ld_get_info_submit(SC
memset(cmd->iov_buf, 0x0, dcmd_size);
info = cmd->iov_buf;
megasas_setup_inquiry(cdb, 0x83, sizeof(info->vpd_page83));
- req = scsi_req_new(sdev, cmd->index, lun, cdb, cmd);
- if (!req) {
+ cmd->req = scsi_req_new(sdev, cmd->index, lun, cdb, cmd);
+ if (!cmd->req) {
trace_megasas_dcmd_req_alloc_failed(cmd->index,
"LD get info vpd inquiry");
g_free(cmd->iov_buf);
@@ -1153,10 +1154,10 @@ static int megasas_ld_get_info_submit(SC
}
trace_megasas_dcmd_internal_submit(cmd->index,
"LD get info vpd inquiry", lun);
- len = scsi_req_enqueue(req);
+ len = scsi_req_enqueue(cmd->req);
if (len > 0) {
cmd->iov_size = len;
- scsi_req_continue(req);
+ scsi_req_continue(cmd->req);
}
return MFI_STAT_INVALID_STATUS;
}
@@ -1761,7 +1762,7 @@ static void megasas_command_complete(SCS
trace_megasas_command_complete(cmd->index, status, resid);
- if (cmd->req != req) {
+ if (cmd->dcmd_opcode != -1) {
/*
* Internal command complete
*/