lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <yq1tuek347m.fsf@ca-mkp.ca.oracle.com>
Date:   Mon, 03 Jan 2022 16:28:35 -0500
From:   "Martin K. Petersen" <martin.petersen@...cle.com>
To:     "Maciej W. Rozycki" <macro@...am.me.uk>
Cc:     Douglas Gilbert <dgilbert@...erlog.com>,
        Khalid Aziz <khalid@...ehiking.org>,
        "James E.J. Bottomley" <jejb@...ux.ibm.com>,
        "Martin K. Petersen" <martin.petersen@...cle.com>,
        Christoph Hellwig <hch@....de>, Nix <nix@...eri.org.uk>,
        linux-scsi@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: Re: [PATCH v3 3/3] scsi: Set allocation length to 255 for ATA
 Information VPD page


Maciej,

>  So I do have all the reasons to conclude this value has indeed been 
> arbitrarily chosen, don't I?

The SAT spec defines the contents of the first part of the page. The
trailing 512 bytes are defined in the ATA spec.

> If you insist that the value of 64 stay, then please come up with a
> suitable macro name to define along with SCSI_VPD_PG_LEN that reflects
> the meaning of 64 in this context and I'll be happy to update 3/3
> accordingly, but please explain why the value of 64 is any better than
> 255 here and the inconsistency with the buffer size justified.

Can please you try the following patch?

-- 
Martin K. Petersen	Oracle Linux Engineering

Subject: [PATCH] scsi: core: Request VPD page header before fetching full page

We currently default to 255 bytes when fetching for VPD pages during
discovery. However, we have had a few devices that are known to wedge if
the requested buffer exceeds a certain size. See commit af73623f5f10
("[SCSI] sd: Reduce buffer size for vpd request") which works around one
example of this problem in the SCSI disk driver.

With commit d188b0675b21 ("scsi: core: Add sysfs attributes for VPD pages
0h and 89h") we now risk triggering the same issue in the generic midlayer
code.

The problem with the ATA VPD page in particular is that the SCSI portion of
the page is trailed by 512 bytes of verbatim ATA Identify Device
information.  However, not all controllers actually provide the additional
512 bytes and will lock up if one asks for more than the 64 bytes
containing the SCSI protocol fields.

Instead of picking a new, somewhat arbitrary, number of bytes for the
default VPD buffer size, first fetch the 4-byte header for each page. The
header contains the size of the page as far as the device is concerned. Use
this reported size to allocate the permanent VPD buffer and then proceed to
fetch the full page up to a 1K limit.

Signed-off-by: Martin K. Petersen <martin.petersen@...cle.com>
Fixes: d188b0675b21 ("scsi: core: Add sysfs attributes for VPD pages 0h and 89h")

diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 211aace69c22..d45c4d7526d5 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -384,7 +384,13 @@ EXPORT_SYMBOL_GPL(scsi_get_vpd_page);
 static struct scsi_vpd *scsi_get_vpd_buf(struct scsi_device *sdev, u8 page)
 {
 	struct scsi_vpd *vpd_buf;
-	int vpd_len = SCSI_VPD_PG_LEN, result;
+	int vpd_len, result;
+	unsigned char vpd_header[SCSI_VPD_HEADER_SIZE];
+
+	result = scsi_vpd_inquiry(sdev, vpd_header, page, SCSI_VPD_HEADER_SIZE);
+	if (result < SCSI_VPD_HEADER_SIZE || result > SCSI_VPD_MAX_SIZE)
+		return NULL;
+	vpd_len = result;
 
 retry_pg:
 	vpd_buf = kmalloc(sizeof(*vpd_buf) + vpd_len, GFP_KERNEL);
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index d1c6fc83b1e3..6d6c44e8da08 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -100,6 +100,11 @@ struct scsi_vpd {
 	unsigned char	data[];
 };
 
+enum scsi_vpd_parameters {
+	SCSI_VPD_HEADER_SIZE = 4,
+	SCSI_VPD_MAX_SIZE = 1024,
+};
+
 struct scsi_device {
 	struct Scsi_Host *host;
 	struct request_queue *request_queue;
@@ -141,7 +146,6 @@ struct scsi_device {
 	const char * model;		/* ... after scan; point to static string */
 	const char * rev;		/* ... "nullnullnullnull" before scan */
 
-#define SCSI_VPD_PG_LEN                255
 	struct scsi_vpd __rcu *vpd_pg0;
 	struct scsi_vpd __rcu *vpd_pg83;
 	struct scsi_vpd __rcu *vpd_pg80;

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ