diff options
Diffstat (limited to 'usr/src/lib')
-rw-r--r-- | usr/src/lib/fm/libdiskstatus/common/ds_scsi_uscsi.c | 25 |
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)); |