diff options
author | Robert Mustacchi <rm@joyent.com> | 2019-01-29 23:21:24 +0000 |
---|---|---|
committer | Robert Mustacchi <rm@joyent.com> | 2019-06-05 00:47:31 +0000 |
commit | 0e35cc03de180a2fdef6c639e43b43824f85c65b (patch) | |
tree | c097f9da8e73f789f07b2c984ea4f02a93083542 /usr/src/lib | |
parent | 0222d5accac6e2a33600db46cd235825f511de93 (diff) | |
download | illumos-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.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)); |