summaryrefslogtreecommitdiff
path: root/usr/src/lib
diff options
context:
space:
mode:
authorRobert Mustacchi <rm@joyent.com>2019-01-29 23:21:24 +0000
committerRobert Mustacchi <rm@joyent.com>2019-06-05 00:47:31 +0000
commit0e35cc03de180a2fdef6c639e43b43824f85c65b (patch)
treec097f9da8e73f789f07b2c984ea4f02a93083542 /usr/src/lib
parent0222d5accac6e2a33600db46cd235825f511de93 (diff)
downloadillumos-joyent-0e35cc03de180a2fdef6c639e43b43824f85c65b.tar.gz
10939 libdiskstatus trusts disk mode sense data to its death
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com> Reviewed by: Rob Johnston <rob.johnston@joyent.com> Reviewed by: Toomas Soome <tsoome@me.com> Reviewed by: Gergő Doma <domag02@gmail.com> Reviewed by: Andy Fiddaman <andy@omniosce.org> Approved by: Dan McDonald <danmcd@joyent.com>
Diffstat (limited to 'usr/src/lib')
-rw-r--r--usr/src/lib/fm/libdiskstatus/common/ds_scsi_uscsi.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/usr/src/lib/fm/libdiskstatus/common/ds_scsi_uscsi.c b/usr/src/lib/fm/libdiskstatus/common/ds_scsi_uscsi.c
index 81f62ad0cf..1c73c959ea 100644
--- a/usr/src/lib/fm/libdiskstatus/common/ds_scsi_uscsi.c
+++ b/usr/src/lib/fm/libdiskstatus/common/ds_scsi_uscsi.c
@@ -22,10 +22,9 @@
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright (c) 2019, Joyent, Inc.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* This file contains routines for sending and receiving SCSI commands. The
* higher level logic is contained in ds_scsi.c.
@@ -99,7 +98,7 @@ static slist_t mode_select_strings[] = {
};
static slist_t sensekey_strings[] = {
- { "No sense error", KEY_NO_SENSE },
+ { "No sense error", KEY_NO_SENSE },
{ "Recoverable error", KEY_RECOVERABLE_ERROR },
{ "Not ready error", KEY_NOT_READY },
{ "Medium error", KEY_MEDIUM_ERROR },
@@ -1244,6 +1243,19 @@ uscsi_mode_sense(int fd, int page_code, int page_control, caddr_t page_data,
*/
hdr = (struct mode_header *)mode_sense_buf;
(void) memset((caddr_t)header, 0, sizeof (struct scsi_ms_header));
+
+ /*
+ * Check to see if we have a valid header length. We've occasionally
+ * seen hardware return zero here, even though they filled in the media
+ * type.
+ */
+ if (hdr->length == 0) {
+ dprintf("\nMode sense page 0x%x: has header length for zero\n",
+ page_code);
+ ddump("Mode sense:", mode_sense_buf, nbytes);
+ return (-1);
+ }
+
if (hdr->bdesc_length != sizeof (struct block_descriptor) &&
hdr->bdesc_length != 0) {
dprintf("\nMode sense page 0x%x: block descriptor "
@@ -1259,6 +1271,13 @@ uscsi_mode_sense(int fd, int page_code, int page_control, caddr_t page_data,
if (page_code == MODEPAGE_ALLPAGES) {
/* special case */
+ if ((hdr->length + sizeof (header->ms_header.length)) <
+ (MODE_HEADER_LENGTH + hdr->bdesc_length)) {
+ dprintf("\nHeader length would spiral into a "
+ "negative bcopy\n");
+ return (-1);
+ }
+
(void) memcpy(page_data, (caddr_t)pg,
(hdr->length + sizeof (header->ms_header.length)) -
(MODE_HEADER_LENGTH + hdr->bdesc_length));