Linux SCSI subsystem development
 help / color / mirror / Atom feed
From: Bart Van Assche <bvanassche@acm.org>
To: Brian Bunker <brian@purestorage.com>
Cc: hare@suse.de, linux-scsi@vger.kernel.org, krishna.kant@purestorage.com
Subject: Re: [PATCH v3 2/6] scsi: Protect INQUIRY sysfs attributes with mutex
Date: Sun, 3 May 2026 17:44:07 +0200	[thread overview]
Message-ID: <b584f42f-534e-4204-9fa6-92ff93ab62ad@acm.org> (raw)
In-Reply-To: <5de0e746-1a90-4a41-a36b-e56a4fcfeee6@acm.org>

On 5/2/26 6:37 PM, Bart Van Assche wrote:
> Another possibility is to change sdev->vendor, sdev->model and
> sdev->rev from pointers to fixed size strings into '\0'-terminated char
> arrays.

(replying to my own email)

How about the untested patch below?

scsi: core: Convert inquiry information

Currently the vendor, model, and revision members of struct scsi_device
are pointers to fixed-length strings that are not NUL-terminated.
Fixed-precision format specifiers (e.g., "%.8s") are required whenever
they are printed and strncmp() must be used to compare these fields.
This is error-prone.

Convert these fields to fixed-size character arrays within struct
scsi_device and remove trailing white space at initialization time.

This patch fixes a bug in the qla2xxx driver. It makes the following
code safe:

                 if (state_flags & BIT_4)
                         scmd_printk(KERN_WARNING, cp,
                             "Unsupported device '%s' found.\n",
                             cp->device->vendor);

diff --git a/drivers/hwmon/drivetemp.c b/drivers/hwmon/drivetemp.c
index 002e0660a0b8..e71b99f70076 100644
--- a/drivers/hwmon/drivetemp.c
+++ b/drivers/hwmon/drivetemp.c
@@ -306,7 +306,7 @@ static bool drivetemp_sct_avoid(struct 
drivetemp_data *st)
  	struct scsi_device *sdev = st->sdev;
  	unsigned int ctr;

-	if (!sdev->model)
+	if (!sdev->model[0])
  		return false;

  	/*
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
index fcf059bf41e8..f92ad396ac9c 100644
--- a/drivers/scsi/advansys.c
+++ b/drivers/scsi/advansys.c
@@ -7204,7 +7204,7 @@ static void AscAsyncFix(ASC_DVC_VAR *asc_dvc, 
struct scsi_device *sdev)
  	if (asc_dvc->init_sdtr & tid_bits)
  		return;

-	if ((type == TYPE_ROM) && (strncmp(sdev->vendor, "HP ", 3) == 0))
+	if (type == TYPE_ROM && strcmp(sdev->vendor, "HP") == 0)
  		asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;

  	asc_dvc->pci_fix_asyn_xfer |= tid_bits;
diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c
index 4010fdbf813c..fb59ca035843 100644
--- a/drivers/scsi/ch.c
+++ b/drivers/scsi/ch.c
@@ -408,7 +408,7 @@ ch_readconfig(scsi_changer *ch)
  				/* should not happen */
  				VPRINTK(KERN_CONT, "Huh? device not found!\n");
  			} else {
-				VPRINTK(KERN_CONT, "name: %8.8s %16.16s %4.4s\n",
+				VPRINTK(KERN_CONT, "name: %8s %16s %4s\n",
  					ch->dt[elem]->vendor,
  					ch->dt[elem]->model,
  					ch->dt[elem]->rev);
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index a1b116cd4723..bdec827b82a1 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -1262,7 +1262,7 @@ static void hpsa_show_dev_msg(const char *level, 
struct ctlr_info *h,
  	}

  	dev_printk(level, &h->pdev->dev,
-			"scsi %d:%d:%d:%d: %s %s %.8s %.16s %s SSDSmartPathCap%c En%c Exp=%d\n",
+			"scsi %d:%d:%d:%d: %s %s %s %s %s SSDSmartPathCap%c En%c Exp=%d\n",
  			h->scsi_host->host_no, dev->bus, dev->target, dev->lun,
  			description,
  			scsi_device_type(dev->devtype),
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index ef22a4228b85..242bd46df3ba 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -292,9 +292,9 @@ static struct scsi_device *scsi_alloc_sdev(struct 
scsi_target *starget,
  	if (!sdev)
  		goto out;

-	sdev->vendor = scsi_null_device_strs;
-	sdev->model = scsi_null_device_strs;
-	sdev->rev = scsi_null_device_strs;
+	strscpy(sdev->vendor, scsi_null_device_strs);
+	strscpy(sdev->model, scsi_null_device_strs);
+	strscpy(sdev->rev, scsi_null_device_strs);
  	sdev->host = shost;
  	sdev->queue_ramp_up_period = SCSI_DEFAULT_RAMP_UP_PERIOD;
  	sdev->id = starget->id;
@@ -857,6 +857,21 @@ static int scsi_probe_lun(struct scsi_device *sdev, 
unsigned char *inq_result,
  	return 0;
  }

+static void strip_trailing_spaces(char *s)
+{
+	size_t size;
+	char *end;
+
+	size = strlen(s);
+	if (!size)
+		return;
+
+	end = s + size - 1;
+	while (end >= s && isspace(*end))
+		end--;
+	*(end + 1) = '\0';
+}
+
  /**
   * scsi_add_lun - allocate and fully initialze a scsi_device
   * @sdev:	holds information to be stored in the new scsi_device
@@ -905,11 +920,17 @@ static int scsi_add_lun(struct scsi_device *sdev, 
unsigned char *inq_result,
  	if (sdev->inquiry == NULL)
  		return SCSI_SCAN_NO_RESPONSE;

-	sdev->vendor = (char *) (sdev->inquiry + 8);
-	sdev->model = (char *) (sdev->inquiry + 16);
-	sdev->rev = (char *) (sdev->inquiry + 32);
-
-	sdev->is_ata = strncmp(sdev->vendor, "ATA     ", 8) == 0;
+	memcpy(sdev->vendor, sdev->inquiry + 8, 8);
+	sdev->vendor[8] = 0;
+	strip_trailing_spaces(sdev->vendor);
+	memcpy(sdev->model, sdev->inquiry + 16, 16);
+	sdev->model[16] = 0;
+	strip_trailing_spaces(sdev->model);
+	memcpy(sdev->rev, sdev->inquiry + 32, 4);
+	sdev->rev[4] = 0;
+	strip_trailing_spaces(sdev->rev);
+
+	sdev->is_ata = strcmp(sdev->vendor, "ATA") == 0;
  	if (sdev->is_ata) {
  		/*
  		 * sata emulation layer device.  This is a hack to work around
@@ -978,7 +999,7 @@ static int scsi_add_lun(struct scsi_device *sdev, 
unsigned char *inq_result,
  	if (inq_result[7] & 0x10)
  		sdev->sdtr = 1;

-	sdev_printk(KERN_NOTICE, sdev, "%s %.8s %.16s %.4s PQ: %d "
+	sdev_printk(KERN_NOTICE, sdev, "%s %s %s %s PQ: %d "
  			"ANSI: %d%s\n", scsi_device_type(sdev->type),
  			sdev->vendor, sdev->model, sdev->rev,
  			sdev->inq_periph_qual, inq_result[2] & 0x07,
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index dfc3559e7e04..3282ad956d1f 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -648,9 +648,9 @@ static DEVICE_ATTR(field, S_IRUGO, 
sdev_show_##field, NULL);
   */
  sdev_rd_attr (type, "%d\n");
  sdev_rd_attr (scsi_level, "%d\n");
-sdev_rd_attr (vendor, "%.8s\n");
-sdev_rd_attr (model, "%.16s\n");
-sdev_rd_attr (rev, "%.4s\n");
+sdev_rd_attr (vendor, "%s\n");
+sdev_rd_attr (model, "%s\n");
+sdev_rd_attr (rev, "%s\n");
  sdev_rd_attr (cdl_supported, "%d\n");

  static ssize_t
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 2b4b2a1a8e44..b6c248e69b3a 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -2507,7 +2507,7 @@ static int sg_proc_seq_show_devstrs(struct 
seq_file *s, void *v)
  	sdp = it ? sg_lookup_dev(it->index) : NULL;
  	scsidp = sdp ? sdp->device : NULL;
  	if (sdp && scsidp && (!atomic_read(&sdp->detaching)))
-		seq_printf(s, "%8.8s\t%16.16s\t%4.4s\n",
+		seq_printf(s, "%8s\t%16s\t%4s\n",
  			   scsidp->vendor, scsidp->model, scsidp->rev);
  	else
  		seq_puts(s, "<no active device>\n");
diff --git a/drivers/target/target_core_pscsi.c 
b/drivers/target/target_core_pscsi.c
index 9ed2818c3028..1718d1620f24 100644
--- a/drivers/target/target_core_pscsi.c
+++ b/drivers/target/target_core_pscsi.c
@@ -169,14 +169,11 @@ pscsi_set_inquiry_info(struct scsi_device *sdev, 
struct t10_wwn *wwn)
  	 * Use sdev->inquiry data from drivers/scsi/scsi_scan.c:scsi_add_lun()
  	 */
  	BUILD_BUG_ON(sizeof(wwn->vendor) != INQUIRY_VENDOR_LEN + 1);
-	snprintf(wwn->vendor, sizeof(wwn->vendor),
-		 "%." __stringify(INQUIRY_VENDOR_LEN) "s", sdev->vendor);
+	strscpy(wwn->vendor, sdev->vendor);
  	BUILD_BUG_ON(sizeof(wwn->model) != INQUIRY_MODEL_LEN + 1);
-	snprintf(wwn->model, sizeof(wwn->model),
-		 "%." __stringify(INQUIRY_MODEL_LEN) "s", sdev->model);
+	strscpy(wwn->model, sdev->model);
  	BUILD_BUG_ON(sizeof(wwn->revision) != INQUIRY_REVISION_LEN + 1);
-	snprintf(wwn->revision, sizeof(wwn->revision),
-		 "%." __stringify(INQUIRY_REVISION_LEN) "s", sdev->rev);
+	strscpy(wwn->revision, sdev->rev);
  }

  static int
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 4805e40ed4d7..70315f7fdafe 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -702,7 +702,7 @@ static void ufshcd_print_host_state(struct ufs_hba *hba)
  	dev_err(hba->dev, "quirks=0x%x, dev. quirks=0x%x\n", hba->quirks,
  		hba->dev_quirks);
  	if (sdev_ufs)
-		dev_err(hba->dev, "UFS dev info: %.8s %.16s rev %.4s\n",
+		dev_err(hba->dev, "UFS dev info: %s %s rev %s\n",
  			sdev_ufs->vendor, sdev_ufs->model, sdev_ufs->rev);

  	ufshcd_print_clk_freqs(hba);
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 9c2a7bbe5891..cce4587b4b80 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -137,9 +137,9 @@ struct scsi_device {
  	struct mutex inquiry_mutex;
  	unsigned char inquiry_len;	/* valid bytes in 'inquiry' */
  	unsigned char * inquiry;	/* INQUIRY response data */
-	const char * vendor;		/* [back_compat] point into 'inquiry' ... */
-	const char * model;		/* ... after scan; point to static string */
-	const char * rev;		/* ... "nullnullnullnull" before scan */
+	char vendor[9];
+	char model[17];
+	char rev[5];

  #define SCSI_DEFAULT_VPD_LEN	255	/* default SCSI VPD page size (max) */
  	struct scsi_vpd __rcu *vpd_pg0;


  reply	other threads:[~2026-05-03 15:44 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-24 21:53 [PATCH 0/6] scsi: Support ALUA unavailable state and INQUIRY changes Brian Bunker
2026-04-24 21:53 ` [PATCH 1/6] scsi: Add INQUIRY data field definitions and accessor helpers Brian Bunker
2026-04-27  8:19   ` Hannes Reinecke
2026-04-30 15:50   ` Bart Van Assche
2026-04-24 21:53 ` [PATCH 2/6] scsi: Protect INQUIRY sysfs attributes with mutex Brian Bunker
2026-04-27  8:22   ` Hannes Reinecke
2026-04-29  1:27     ` [PATCH v2 " Brian Bunker
2026-04-29 21:06       ` Damien Le Moal
2026-04-29 21:15       ` Bart Van Assche
2026-04-29 22:49       ` [PATCH v3 " Brian Bunker
2026-04-30  6:03         ` Hannes Reinecke
2026-04-30 15:48         ` Bart Van Assche
2026-05-01 22:11           ` Brian Bunker
2026-05-02 16:37             ` Bart Van Assche
2026-05-03 15:44               ` Bart Van Assche [this message]
2026-05-04 18:36                 ` Brian Bunker
2026-05-05  8:24                   ` Bart Van Assche
2026-05-05 17:13                     ` Brian Bunker
2026-04-24 21:53 ` [PATCH 3/6] scsi: Add scsi_update_inquiry_data() for updating INQUIRY data Brian Bunker
2026-04-24 21:53 ` [PATCH 4/6] scsi: Refactor scsi_add_lun() to use scsi_update_inquiry_data() Brian Bunker
2026-04-24 21:53 ` [PATCH 5/6] scsi: Add device reprobe support to scsi_rescan_device() Brian Bunker
2026-04-24 21:53 ` [PATCH 6/6] scsi: Handle reprobe for existing devices during SCSI scan Brian Bunker

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=b584f42f-534e-4204-9fa6-92ff93ab62ad@acm.org \
    --to=bvanassche@acm.org \
    --cc=brian@purestorage.com \
    --cc=hare@suse.de \
    --cc=krishna.kant@purestorage.com \
    --cc=linux-scsi@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox