]>
Commit | Line | Data |
---|---|---|
3dcc8d3b | 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
e74c0f31 WB |
2 | From: Paolo Bonzini <pbonzini@redhat.com> |
3 | Date: Thu, 1 Jun 2017 17:26:14 +0200 | |
3dcc8d3b | 4 | Subject: [PATCH] megasas: always store SCSIRequest* into MegasasCmd |
e74c0f31 WB |
5 | |
6 | This ensures that the request is unref'ed properly, and avoids a | |
7 | segmentation fault in the new qtest testcase that is added. | |
8 | This is CVE-2017-9503. | |
9 | ||
10 | Reported-by: Zhangyanyu <zyy4013@stu.ouc.edu.cn> | |
11 | Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> | |
12 | --- | |
13 | hw/scsi/megasas.c | 31 ++++++++++++++++--------------- | |
14 | 1 file changed, 16 insertions(+), 15 deletions(-) | |
15 | ||
16 | diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c | |
ddbcf45e | 17 | index 135662df31..734fdaef90 100644 |
e74c0f31 WB |
18 | --- a/hw/scsi/megasas.c |
19 | +++ b/hw/scsi/megasas.c | |
ddbcf45e | 20 | @@ -609,6 +609,9 @@ static void megasas_reset_frames(MegasasState *s) |
e74c0f31 WB |
21 | static void megasas_abort_command(MegasasCmd *cmd) |
22 | { | |
23 | /* Never abort internal commands. */ | |
24 | + if (cmd->dcmd_opcode != -1) { | |
25 | + return; | |
26 | + } | |
27 | if (cmd->req != NULL) { | |
28 | scsi_req_cancel(cmd->req); | |
29 | } | |
ddbcf45e | 30 | @@ -1017,7 +1020,6 @@ static int megasas_pd_get_info_submit(SCSIDevice *sdev, int lun, |
e74c0f31 WB |
31 | uint64_t pd_size; |
32 | uint16_t pd_id = ((sdev->id & 0xFF) << 8) | (lun & 0xFF); | |
33 | uint8_t cmdbuf[6]; | |
34 | - SCSIRequest *req; | |
35 | size_t len, resid; | |
36 | ||
37 | if (!cmd->iov_buf) { | |
ddbcf45e | 38 | @@ -1026,8 +1028,8 @@ static int megasas_pd_get_info_submit(SCSIDevice *sdev, int lun, |
e74c0f31 WB |
39 | info->inquiry_data[0] = 0x7f; /* Force PQual 0x3, PType 0x1f */ |
40 | info->vpd_page83[0] = 0x7f; | |
41 | megasas_setup_inquiry(cmdbuf, 0, sizeof(info->inquiry_data)); | |
42 | - req = scsi_req_new(sdev, cmd->index, lun, cmdbuf, cmd); | |
43 | - if (!req) { | |
44 | + cmd->req = scsi_req_new(sdev, cmd->index, lun, cmdbuf, cmd); | |
45 | + if (!cmd->req) { | |
46 | trace_megasas_dcmd_req_alloc_failed(cmd->index, | |
47 | "PD get info std inquiry"); | |
48 | g_free(cmd->iov_buf); | |
ddbcf45e | 49 | @@ -1036,26 +1038,26 @@ static int megasas_pd_get_info_submit(SCSIDevice *sdev, int lun, |
e74c0f31 WB |
50 | } |
51 | trace_megasas_dcmd_internal_submit(cmd->index, | |
52 | "PD get info std inquiry", lun); | |
53 | - len = scsi_req_enqueue(req); | |
54 | + len = scsi_req_enqueue(cmd->req); | |
55 | if (len > 0) { | |
56 | cmd->iov_size = len; | |
57 | - scsi_req_continue(req); | |
58 | + scsi_req_continue(cmd->req); | |
59 | } | |
60 | return MFI_STAT_INVALID_STATUS; | |
61 | } else if (info->inquiry_data[0] != 0x7f && info->vpd_page83[0] == 0x7f) { | |
62 | megasas_setup_inquiry(cmdbuf, 0x83, sizeof(info->vpd_page83)); | |
63 | - req = scsi_req_new(sdev, cmd->index, lun, cmdbuf, cmd); | |
64 | - if (!req) { | |
65 | + cmd->req = scsi_req_new(sdev, cmd->index, lun, cmdbuf, cmd); | |
66 | + if (!cmd->req) { | |
67 | trace_megasas_dcmd_req_alloc_failed(cmd->index, | |
68 | "PD get info vpd inquiry"); | |
69 | return MFI_STAT_FLASH_ALLOC_FAIL; | |
70 | } | |
71 | trace_megasas_dcmd_internal_submit(cmd->index, | |
72 | "PD get info vpd inquiry", lun); | |
73 | - len = scsi_req_enqueue(req); | |
74 | + len = scsi_req_enqueue(cmd->req); | |
75 | if (len > 0) { | |
76 | cmd->iov_size = len; | |
77 | - scsi_req_continue(req); | |
78 | + scsi_req_continue(cmd->req); | |
79 | } | |
80 | return MFI_STAT_INVALID_STATUS; | |
81 | } | |
ddbcf45e | 82 | @@ -1217,7 +1219,6 @@ static int megasas_ld_get_info_submit(SCSIDevice *sdev, int lun, |
e74c0f31 WB |
83 | struct mfi_ld_info *info = cmd->iov_buf; |
84 | size_t dcmd_size = sizeof(struct mfi_ld_info); | |
85 | uint8_t cdb[6]; | |
86 | - SCSIRequest *req; | |
87 | ssize_t len, resid; | |
88 | uint16_t sdev_id = ((sdev->id & 0xFF) << 8) | (lun & 0xFF); | |
89 | uint64_t ld_size; | |
ddbcf45e | 90 | @@ -1226,8 +1227,8 @@ static int megasas_ld_get_info_submit(SCSIDevice *sdev, int lun, |
e74c0f31 WB |
91 | cmd->iov_buf = g_malloc0(dcmd_size); |
92 | info = cmd->iov_buf; | |
93 | megasas_setup_inquiry(cdb, 0x83, sizeof(info->vpd_page83)); | |
94 | - req = scsi_req_new(sdev, cmd->index, lun, cdb, cmd); | |
95 | - if (!req) { | |
96 | + cmd->req = scsi_req_new(sdev, cmd->index, lun, cdb, cmd); | |
97 | + if (!cmd->req) { | |
98 | trace_megasas_dcmd_req_alloc_failed(cmd->index, | |
99 | "LD get info vpd inquiry"); | |
100 | g_free(cmd->iov_buf); | |
ddbcf45e | 101 | @@ -1236,10 +1237,10 @@ static int megasas_ld_get_info_submit(SCSIDevice *sdev, int lun, |
e74c0f31 WB |
102 | } |
103 | trace_megasas_dcmd_internal_submit(cmd->index, | |
104 | "LD get info vpd inquiry", lun); | |
105 | - len = scsi_req_enqueue(req); | |
106 | + len = scsi_req_enqueue(cmd->req); | |
107 | if (len > 0) { | |
108 | cmd->iov_size = len; | |
109 | - scsi_req_continue(req); | |
110 | + scsi_req_continue(cmd->req); | |
111 | } | |
112 | return MFI_STAT_INVALID_STATUS; | |
113 | } | |
ddbcf45e | 114 | @@ -1851,7 +1852,7 @@ static void megasas_command_complete(SCSIRequest *req, uint32_t status, |
e74c0f31 WB |
115 | return; |
116 | } | |
117 | ||
118 | - if (cmd->req == NULL) { | |
119 | + if (cmd->dcmd_opcode != -1) { | |
120 | /* | |
121 | * Internal command complete | |
122 | */ | |
123 | -- | |
124 | 2.11.0 | |
125 |