summaryrefslogtreecommitdiff
path: root/usr/src/lib
diff options
context:
space:
mode:
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));