Skip to content

Commit 6fd13d6

Browse files
andrea-parrimartinkpetersen
authored andcommitted
scsi: storvsc: Fix validation for unsolicited incoming packets
The validation on the length of incoming packets performed in storvsc_on_channel_callback() does not apply to unsolicited packets with ID of 0 sent by Hyper-V. Adjust the validation for such unsolicited packets. Link: https://lore.kernel.org/r/[email protected] Fixes: 91b1b64 ("scsi: storvsc: Validate length of incoming packet in storvsc_on_channel_callback()") Reported-by: Dexuan Cui <[email protected]> Reviewed-by: Michael Kelley <[email protected]> Reviewed-by: Haiyang Zhang <[email protected]> Signed-off-by: Andrea Parri (Microsoft) <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 187a580 commit 6fd13d6

File tree

1 file changed

+23
-9
lines changed

1 file changed

+23
-9
lines changed

drivers/scsi/storvsc_drv.c

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,11 +1285,15 @@ static void storvsc_on_channel_callback(void *context)
12851285
foreach_vmbus_pkt(desc, channel) {
12861286
struct vstor_packet *packet = hv_pkt_data(desc);
12871287
struct storvsc_cmd_request *request = NULL;
1288+
u32 pktlen = hv_pkt_datalen(desc);
12881289
u64 rqst_id = desc->trans_id;
1290+
u32 minlen = rqst_id ? sizeof(struct vstor_packet) -
1291+
stor_device->vmscsi_size_delta : sizeof(enum vstor_packet_operation);
12891292

1290-
if (hv_pkt_datalen(desc) < sizeof(struct vstor_packet) -
1291-
stor_device->vmscsi_size_delta) {
1292-
dev_err(&device->device, "Invalid packet len\n");
1293+
if (pktlen < minlen) {
1294+
dev_err(&device->device,
1295+
"Invalid pkt: id=%llu, len=%u, minlen=%u\n",
1296+
rqst_id, pktlen, minlen);
12931297
continue;
12941298
}
12951299

@@ -1302,13 +1306,23 @@ static void storvsc_on_channel_callback(void *context)
13021306
if (rqst_id == 0) {
13031307
/*
13041308
* storvsc_on_receive() looks at the vstor_packet in the message
1305-
* from the ring buffer. If the operation in the vstor_packet is
1306-
* COMPLETE_IO, then we call storvsc_on_io_completion(), and
1307-
* dereference the guest memory address. Make sure we don't call
1308-
* storvsc_on_io_completion() with a guest memory address that is
1309-
* zero if Hyper-V were to construct and send such a bogus packet.
1309+
* from the ring buffer.
1310+
*
1311+
* - If the operation in the vstor_packet is COMPLETE_IO, then
1312+
* we call storvsc_on_io_completion(), and dereference the
1313+
* guest memory address. Make sure we don't call
1314+
* storvsc_on_io_completion() with a guest memory address
1315+
* that is zero if Hyper-V were to construct and send such
1316+
* a bogus packet.
1317+
*
1318+
* - If the operation in the vstor_packet is FCHBA_DATA, then
1319+
* we call cache_wwn(), and access the data payload area of
1320+
* the packet (wwn_packet); however, there is no guarantee
1321+
* that the packet is big enough to contain such area.
1322+
* Future-proof the code by rejecting such a bogus packet.
13101323
*/
1311-
if (packet->operation == VSTOR_OPERATION_COMPLETE_IO) {
1324+
if (packet->operation == VSTOR_OPERATION_COMPLETE_IO ||
1325+
packet->operation == VSTOR_OPERATION_FCHBA_DATA) {
13121326
dev_err(&device->device, "Invalid packet with ID of 0\n");
13131327
continue;
13141328
}

0 commit comments

Comments
 (0)