Accepting request 391950 from home:hreinecke:branches:Base:System
- sg_inq,sg_vpd: Safe VPD page access (bsc#945094) * Add 0001-sg_vpd-sg_inq-Safe-VPD-page-access.patch OBS-URL: https://build.opensuse.org/request/show/391950 OBS-URL: https://build.opensuse.org/package/show/Base:System/sg3_utils?expand=0&rev=59
This commit is contained in:
parent
be7de41c1d
commit
e54f9d0a84
296
0001-sg_vpd-sg_inq-Safe-VPD-page-access.patch
Normal file
296
0001-sg_vpd-sg_inq-Safe-VPD-page-access.patch
Normal file
@ -0,0 +1,296 @@
|
||||
From 199fde9fa26d62cb19af502b99d0100247aff97b Mon Sep 17 00:00:00 2001
|
||||
From: Hannes Reinecke <hare@suse.de>
|
||||
Date: Thu, 28 Apr 2016 14:22:38 +0200
|
||||
Subject: [PATCH] sg_vpd, sg_inq: Safe VPD page access
|
||||
|
||||
Check VPD page 0x0 before trying to access individual VPD pages.
|
||||
Non-conformant drives are know to crash when blindly issuing
|
||||
a VPD request; checking page 0x0 should avoid that.
|
||||
The check can be suppressed by using the new option '--force'
|
||||
|
||||
Signed-off-by: Hannes Reinecke <hare@suse.com>
|
||||
---
|
||||
doc/sg_inq.8 | 20 +++++++++++++-------
|
||||
doc/sg_vpd.8 | 7 ++++++-
|
||||
src/sg_inq.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++--
|
||||
src/sg_vpd.c | 31 ++++++++++++++++++++++++++++---
|
||||
4 files changed, 94 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/doc/sg_inq.8 b/doc/sg_inq.8
|
||||
index 11b4c16..db3ee30 100644
|
||||
--- a/doc/sg_inq.8
|
||||
+++ b/doc/sg_inq.8
|
||||
@@ -5,16 +5,17 @@ sg_inq \- issue SCSI INQUIRY command and/or decode its response
|
||||
.B sg_inq
|
||||
[\fI\-\-ata\fR] [\fI\-\-block=0|1\fR] [\fI\-\-cmddt\fR]
|
||||
[\fI\-\-descriptors\fR] [\fI\-\-export\fR] [\fI\-\-extended\fR]
|
||||
-[\fI\-\-help\fR] [\fI\-\-hex\fR] [\fI\-\-id\fR] [\fI\-\-inhex=FN\fR]
|
||||
-[\fI\-\-len=LEN\fR] [\fI\-\-maxlen=LEN\fR] [\fI\-\-page=PG\fR]
|
||||
-[\fI\-\-raw\fR] [\fI\-\-vendor\fR] [\fI\-\-verbose\fR]
|
||||
+[\fI\-\-force\fR] [\fI\-\-help\fR] [\fI\-\-hex\fR] [\fI\-\-id\fR]
|
||||
+[\fI\-\-inhex=FN\fR] [\fI\-\-len=LEN\fR] [\fI\-\-maxlen=LEN\fR]
|
||||
+[\fI\-\-page=PG\fR] [\fI\-\-raw\fR] [\fI\-\-vendor\fR] [\fI\-\-verbose\fR]
|
||||
[\fI\-\-version\fR] [\fI\-\-vpd\fR] \fIDEVICE\fR
|
||||
.PP
|
||||
.B sg_inq
|
||||
-[\fI\-36\fR] [\fI\-a\fR] [\fI\-A\fR] [\fI\-b\fR] [\fI\-\-B=0|1\fR] [\fI\-c\fR]
|
||||
-[\fI\-cl\fR] [\fI\-d\fR] [\fI\-e\fR] [\fI\-h\fR] [\fI\-H\fR] [\fI\-i\fR]
|
||||
-[\fI\-I=FN\fR] [\fI\-l=LEN\fR] [\fI\-m\fR] [\fI\-M\fR] [\fI\-o=OPCODE_PG\fR]
|
||||
-[\fI\-p=VPD_PG\fR] [\fI\-P\fR] [\fI\-r\fR] [\fI\-s\fR] [\fI\-u\fR] [\fI\-v\fR]
|
||||
+[\fI\-36\fR] [\fI\-a\fR] [\fI\-A\fR] [\fI\-b\fR] [\fI\-\-B=0|1\fR]
|
||||
+[\fI\-c\fR] [\fI\-cl\fR] [\fI\-d\fR] [\fI\-e\fR] [\fI\-f\fR]
|
||||
+[\fI\-h\fR] [\fI\-H\fR] [\fI\-i\fR] [\fI\-I=FN\fR] [\fI\-l=LEN\fR]
|
||||
+[\fI\-m\fR] [\fI\-M\fR] [\fI\-o=OPCODE_PG\fR] [\fI\-p=VPD_PG\fR]
|
||||
+[\fI\-P\fR] [\fI\-r\fR] [\fI\-s\fR] [\fI\-u\fR] [\fI\-v\fR]
|
||||
[\fI\-V\fR] [\fI\-x\fR] [\fI\-36\fR] [\fI\-?\fR] \fIDEVICE\fR
|
||||
.SH DESCRIPTION
|
||||
.\" Add any additional description here
|
||||
@@ -94,6 +95,11 @@ if any.
|
||||
\fB\-e\fR
|
||||
see entry below for \fI\-\-vpd\fR.
|
||||
.TP
|
||||
+\fB\-f\fR, \fB\-\-force\fR
|
||||
+skip checking of VPD page 0x0 (SUPPORTED VPD PAGES) before accessing
|
||||
+the individual VPD page. This is know to crash certain USB devices,
|
||||
+so use with care.
|
||||
+.TP
|
||||
\fB\-u\fR, \fB\-\-export\fR
|
||||
prints out information obtained from the device. The output can be
|
||||
modified by selecting a VPD page with \fIPG\fR (from
|
||||
diff --git a/doc/sg_vpd.8 b/doc/sg_vpd.8
|
||||
index 4e3e15d..0aacc08 100644
|
||||
--- a/doc/sg_vpd.8
|
||||
+++ b/doc/sg_vpd.8
|
||||
@@ -6,7 +6,7 @@ sg_vpd \- fetch SCSI VPD page and/or decode its response
|
||||
[\fI\-\-all\fR] [\fI\-\-enumerate\fR] [\fI\-\-help\fR] [\fI\-\-hex\fR]
|
||||
[\fI\-\-ident\fR] [\fI\-\-inhex=FN\fR] [\fI\-\-long\fR] [\fI\-\-maxlen=LEN\fR]
|
||||
[\fI\-\-page=PG\fR] [\fI\-\-quiet\fR] [\fI\-\-raw\fR] [\fI\-\-vendor=VP\fR]
|
||||
-[\fI\-\-verbose\fR] [\fI\-\-version\fR] [\fIDEVICE\fR]
|
||||
+[\fI\-\-force\fR] [\fI\-\-verbose\fR] [\fI\-\-version\fR] [\fIDEVICE\fR]
|
||||
.SH DESCRIPTION
|
||||
.\" Add any additional description here
|
||||
.PP
|
||||
@@ -60,6 +60,11 @@ summary lines of all VPD pages whose number matches \fIPG\fR. May be used
|
||||
with \fI\-\-vendor=VP\fR to restrict output to known vendor specific pages
|
||||
for vendor/product \fIVP\fR.
|
||||
.TP
|
||||
+\fB\-f\fR, \fB\-\-force\fR
|
||||
+skip checking of VPD page 0x0 (SUPPORTED VPD PAGES) before accessing
|
||||
+the individual VPD page. This is know to crash certain USB devices,
|
||||
+so use with care.
|
||||
+.TP
|
||||
\fB\-h\fR, \fB\-\-help\fR
|
||||
outputs the usage message summarizing command line options then exits.
|
||||
Ignores \fIDEVICE\fR if given.
|
||||
diff --git a/src/sg_inq.c b/src/sg_inq.c
|
||||
index e4bcfd3..24c0ced 100644
|
||||
--- a/src/sg_inq.c
|
||||
+++ b/src/sg_inq.c
|
||||
@@ -192,6 +192,7 @@ static struct option long_options[] = {
|
||||
{"descriptors", no_argument, 0, 'd'},
|
||||
{"export", no_argument, 0, 'u'},
|
||||
{"extended", no_argument, 0, 'x'},
|
||||
+ {"force", no_argument, 0, 'f'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"hex", no_argument, 0, 'H'},
|
||||
{"id", no_argument, 0, 'i'},
|
||||
@@ -217,6 +218,7 @@ struct opts_t {
|
||||
int do_cmddt;
|
||||
int do_descriptors;
|
||||
int do_export;
|
||||
+ int do_force;
|
||||
int do_help;
|
||||
int do_hex;
|
||||
int do_raw;
|
||||
@@ -279,6 +281,7 @@ usage()
|
||||
" only supported for VPD pages 0x80 and 0x83\n"
|
||||
" --extended|-E|-x decode extended INQUIRY data VPD page "
|
||||
"(0x86)\n"
|
||||
+ " --force|-f skip VPD page 0 checking\n"
|
||||
" --help|-h print usage message then exit\n"
|
||||
" --hex|-H output response in hex\n"
|
||||
" --id|-i decode device identification VPD page "
|
||||
@@ -400,10 +403,10 @@ cl_new_process(struct opts_t * op, int argc, char * argv[])
|
||||
|
||||
#ifdef SG_LIB_LINUX
|
||||
#ifdef SG_SCSI_STRINGS
|
||||
- c = getopt_long(argc, argv, "aB:cdeEhHiI:l:m:NOp:rsuvVx",
|
||||
+ c = getopt_long(argc, argv, "aB:cdeEfhHiI:l:m:NOp:rsuvVx",
|
||||
long_options, &option_index);
|
||||
#else
|
||||
- c = getopt_long(argc, argv, "B:cdeEhHiI:l:m:p:rsuvVx", long_options,
|
||||
+ c = getopt_long(argc, argv, "B:cdeEfhHiI:l:m:p:rsuvVx", long_options,
|
||||
&option_index);
|
||||
#endif /* SG_SCSI_STRINGS */
|
||||
#else /* SG_LIB_LINUX */
|
||||
@@ -452,6 +455,9 @@ cl_new_process(struct opts_t * op, int argc, char * argv[])
|
||||
++op->do_vpd;
|
||||
op->page_num = VPD_EXT_INQ;
|
||||
break;
|
||||
+ case 'f':
|
||||
+ ++op->do_force;
|
||||
+ break;
|
||||
case 'h':
|
||||
++op->do_help;
|
||||
break;
|
||||
@@ -584,6 +590,9 @@ cl_old_process(struct opts_t * op, int argc, char * argv[])
|
||||
case 'e':
|
||||
++op->do_vpd;
|
||||
break;
|
||||
+ case 'f':
|
||||
+ ++op->do_force;
|
||||
+ break;
|
||||
case 'h':
|
||||
case 'H':
|
||||
++op->do_hex;
|
||||
@@ -1234,6 +1243,32 @@ decode_supported_vpd(unsigned char * buff, int len, int do_hex)
|
||||
}
|
||||
}
|
||||
|
||||
+static bool
|
||||
+vpd_page_is_supported(unsigned char * buff, int len, int pg)
|
||||
+{
|
||||
+ int vpd, k, rlen;
|
||||
+ bool supported = false;
|
||||
+
|
||||
+ if (len < 4)
|
||||
+ return false;
|
||||
+
|
||||
+ rlen = buff[3] + 4;
|
||||
+ if (rlen > len)
|
||||
+ pr2serr("Supported VPD pages VPD page truncated, indicates %d, got "
|
||||
+ "%d\n", rlen, len);
|
||||
+ else
|
||||
+ len = rlen;
|
||||
+
|
||||
+ for (k = 0; k < len - 4; ++k) {
|
||||
+ vpd = buff[4 + k];
|
||||
+ if(vpd == pg) {
|
||||
+ supported = true;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ return supported;
|
||||
+}
|
||||
+
|
||||
/* ASCII Information VPD pages (page numbers: 0x1 to 0x7f) */
|
||||
static void
|
||||
decode_ascii_inf(unsigned char * buff, int len, int do_hex)
|
||||
@@ -3454,6 +3489,15 @@ vpd_decode(int sg_fd, const struct opts_t * op, int inhex_len)
|
||||
mxlen = op->resp_len;
|
||||
else
|
||||
mxlen = inhex_len;
|
||||
+ if (sg_fd != -1 && !op->do_force && pn != VPD_SUPPORTED_VPDS) {
|
||||
+ res = vpd_fetch_page_from_dev(sg_fd, rp, 0, mxlen, vb, &len);
|
||||
+ if (res)
|
||||
+ goto out;
|
||||
+ if (!vpd_page_is_supported(rp, len, pn)) {
|
||||
+ res = SG_LIB_CAT_ILLEGAL_REQ;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
switch (pn) {
|
||||
case VPD_SUPPORTED_VPDS:
|
||||
if (!op->do_raw && (op->do_hex < 2))
|
||||
@@ -3747,6 +3791,7 @@ vpd_decode(int sg_fd, const struct opts_t * op, int inhex_len)
|
||||
return vpd_mainly_hex(sg_fd, op, inhex_len);
|
||||
}
|
||||
}
|
||||
+out:
|
||||
if (res) {
|
||||
char b[80];
|
||||
|
||||
diff --git a/src/sg_vpd.c b/src/sg_vpd.c
|
||||
index 831b0aa..530dd85 100644
|
||||
--- a/src/sg_vpd.c
|
||||
+++ b/src/sg_vpd.c
|
||||
@@ -45,6 +45,7 @@ static const char * version_str = "1.14 20160217"; /* spc5r08 + sbc4r10 */
|
||||
struct opts_t {
|
||||
int do_all;
|
||||
int do_enum;
|
||||
+ int do_force;
|
||||
int do_hex;
|
||||
int num_vpd;
|
||||
int do_ident;
|
||||
@@ -151,6 +152,7 @@ static void decode_transport_id(const char * leadin, unsigned char * ucp,
|
||||
static struct option long_options[] = {
|
||||
{"all", no_argument, 0, 'a'},
|
||||
{"enumerate", no_argument, 0, 'e'},
|
||||
+ {"force", no_argument, 0, 'f'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"hex", no_argument, 0, 'H'},
|
||||
{"ident", no_argument, 0, 'i'},
|
||||
@@ -231,7 +233,7 @@ static struct svpd_values_name_t standard_vpd_pg[] = {
|
||||
static void
|
||||
usage()
|
||||
{
|
||||
- pr2serr("Usage: sg_vpd [--all] [--enumerate] [--help] [--hex] "
|
||||
+ pr2serr("Usage: sg_vpd [--all] [--enumerate] [--force] [--help] [--hex] "
|
||||
"[--ident]\n"
|
||||
" [--inhex=FN] [--long] [--maxlen=LEN] "
|
||||
"[--page=PG] [--quiet]\n"
|
||||
@@ -244,6 +246,7 @@ usage()
|
||||
" --enumerate|-e enumerate known VPD pages names (ignore "
|
||||
"DEVICE),\n"
|
||||
" can be used with --page=num to search\n"
|
||||
+ " --force|-f skip VPD page 0 checking\n"
|
||||
" --help|-h output this usage message then exit\n"
|
||||
" --hex|-H output page in ASCII hexadecimal\n"
|
||||
" --ident|-i output device identification VPD page, "
|
||||
@@ -3034,7 +3037,7 @@ static int
|
||||
svpd_decode_t10(int sg_fd, struct opts_t * op, int subvalue, int off)
|
||||
{
|
||||
int len, pdt, num, k, resid, alloc_len, pn, vb, allow_name, long_notquiet;
|
||||
- int res = 0;
|
||||
+ int res = 0, vpd_supported = 0;
|
||||
char b[48];
|
||||
const struct svpd_values_name_t * vnp;
|
||||
char obuff[DEF_ALLOC_LEN];
|
||||
@@ -3049,6 +3052,25 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, int subvalue, int off)
|
||||
else
|
||||
allow_name = 1;
|
||||
rp = rsp_buff + off;
|
||||
+ if (sg_fd != -1 && !op->do_force &&
|
||||
+ pn != VPD_NO_RATHER_STD_INQ &&
|
||||
+ pn != VPD_SUPPORTED_VPDS) {
|
||||
+ res = vpd_fetch_page_from_dev(sg_fd, rp, 0, op->maxlen, vb, &len);
|
||||
+ if (res)
|
||||
+ return res;
|
||||
+
|
||||
+ num = rp[3];
|
||||
+ if (num > (len - 4))
|
||||
+ num = (len - 4);
|
||||
+ for (k = 0; k < num; ++k) {
|
||||
+ if (pn == rp[4 + k]) {
|
||||
+ vpd_supported = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ if (!vpd_supported)
|
||||
+ return SG_LIB_CAT_ILLEGAL_REQ;
|
||||
+ }
|
||||
switch(pn) {
|
||||
case VPD_NO_RATHER_STD_INQ: /* -2 (want standard inquiry response) */
|
||||
if (sg_fd >= 0) {
|
||||
@@ -3772,7 +3794,7 @@ main(int argc, char * argv[])
|
||||
while (1) {
|
||||
int option_index = 0;
|
||||
|
||||
- c = getopt_long(argc, argv, "aehHiI:lm:M:p:qrvV", long_options,
|
||||
+ c = getopt_long(argc, argv, "aefhHiI:lm:M:p:qrvV", long_options,
|
||||
&option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
@@ -3784,6 +3806,9 @@ main(int argc, char * argv[])
|
||||
case 'e':
|
||||
++op->do_enum;
|
||||
break;
|
||||
+ case 'f':
|
||||
+ ++op->do_force;
|
||||
+ break;
|
||||
case 'h':
|
||||
case '?':
|
||||
usage();
|
||||
--
|
||||
2.6.6
|
||||
|
@ -1,3 +1,9 @@
|
||||
-------------------------------------------------------------------
|
||||
Thu Apr 28 14:38:24 CEST 2016 - hare@suse.de
|
||||
|
||||
- sg_inq,sg_vpd: Safe VPD page access (bsc#945094)
|
||||
* Add 0001-sg_vpd-sg_inq-Safe-VPD-page-access.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Feb 18 09:41:03 CET 2016 - hare@suse.de
|
||||
|
||||
|
@ -28,6 +28,7 @@ Url: http://sg.danny.cz/sg/sg3_utils.html
|
||||
Source: http://sg.danny.cz/sg/p/%name-%version.tar.xz
|
||||
Source1: 40-usb-blacklist.rules
|
||||
Patch1: sgut-libversioning.diff
|
||||
Patch2: 0001-sg_vpd-sg_inq-Safe-VPD-page-access.patch
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
BuildRequires: libtool
|
||||
BuildRequires: udev
|
||||
@ -84,6 +85,7 @@ applications that want to make use of libsgutils.
|
||||
%prep
|
||||
%setup -q
|
||||
%patch1 -p1
|
||||
%patch2 -p1
|
||||
|
||||
%build
|
||||
autoreconf -fi
|
||||
|
Loading…
x
Reference in New Issue
Block a user