aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2006-08-21 15:53:25 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-09-02 14:36:59 -0400
commite5b3cd42960a10c1bc3701d4f00767463c88ec9d (patch)
treef8e54261c465f51fe1ebc67facf9074f0744e385 /drivers
parent85b6c720b0931101c8bcc3a5abdc2b8514b0fb4b (diff)
[SCSI] SCSI: sanitize INQUIRY strings
Sanitize the Vendor, Product, and Revision strings contained in an INQUIRY result by setting all non-graphic or non-ASCII characters to ' '. Since the standard disallows such characters, this will affect only non-compliant devices. To help maintain backward compatibility, NUL characters are treated specially. They are taken as string terminators; they and all the following characters are set to ' '. If some valid characters get erased as a result... well, we weren't seeing them before so we haven't lost anything. The primary purpose of this change is to allow blacklist entries to match devices with illegal Vendor or Product strings. In addition, the patch updates a couple of function prototypes, giving inq_result its correct type (unsigned char *). Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/scsi_scan.c37
1 files changed, 34 insertions, 3 deletions
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index a24d3461fc78..31d05ab0b2fc 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -397,6 +397,32 @@ void scsi_target_reap(struct scsi_target *starget)
397} 397}
398 398
399/** 399/**
400 * sanitize_inquiry_string - remove non-graphical chars from an INQUIRY result string
401 * @s: INQUIRY result string to sanitize
402 * @len: length of the string
403 *
404 * Description:
405 * The SCSI spec says that INQUIRY vendor, product, and revision
406 * strings must consist entirely of graphic ASCII characters,
407 * padded on the right with spaces. Since not all devices obey
408 * this rule, we will replace non-graphic or non-ASCII characters
409 * with spaces. Exception: a NUL character is interpreted as a
410 * string terminator, so all the following characters are set to
411 * spaces.
412 **/
413static void sanitize_inquiry_string(unsigned char *s, int len)
414{
415 int terminated = 0;
416
417 for (; len > 0; (--len, ++s)) {
418 if (*s == 0)
419 terminated = 1;
420 if (terminated || *s < 0x20 || *s > 0x7e)
421 *s = ' ';
422 }
423}
424
425/**
400 * scsi_probe_lun - probe a single LUN using a SCSI INQUIRY 426 * scsi_probe_lun - probe a single LUN using a SCSI INQUIRY
401 * @sdev: scsi_device to probe 427 * @sdev: scsi_device to probe
402 * @inq_result: area to store the INQUIRY result 428 * @inq_result: area to store the INQUIRY result
@@ -410,7 +436,7 @@ void scsi_target_reap(struct scsi_target *starget)
410 * INQUIRY data is in @inq_result; the scsi_level and INQUIRY length 436 * INQUIRY data is in @inq_result; the scsi_level and INQUIRY length
411 * are copied to the scsi_device any flags value is stored in *@bflags. 437 * are copied to the scsi_device any flags value is stored in *@bflags.
412 **/ 438 **/
413static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result, 439static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
414 int result_len, int *bflags) 440 int result_len, int *bflags)
415{ 441{
416 unsigned char scsi_cmd[MAX_COMMAND_SIZE]; 442 unsigned char scsi_cmd[MAX_COMMAND_SIZE];
@@ -469,7 +495,11 @@ static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result,
469 } 495 }
470 496
471 if (result == 0) { 497 if (result == 0) {
472 response_len = (unsigned char) inq_result[4] + 5; 498 sanitize_inquiry_string(&inq_result[8], 8);
499 sanitize_inquiry_string(&inq_result[16], 16);
500 sanitize_inquiry_string(&inq_result[32], 4);
501
502 response_len = inq_result[4] + 5;
473 if (response_len > 255) 503 if (response_len > 255)
474 response_len = first_inquiry_len; /* sanity */ 504 response_len = first_inquiry_len; /* sanity */
475 505
@@ -575,7 +605,8 @@ static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result,
575 * SCSI_SCAN_NO_RESPONSE: could not allocate or setup a scsi_device 605 * SCSI_SCAN_NO_RESPONSE: could not allocate or setup a scsi_device
576 * SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized 606 * SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized
577 **/ 607 **/
578static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags) 608static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
609 int *bflags)
579{ 610{
580 /* 611 /*
581 * XXX do not save the inquiry, since it can change underneath us, 612 * XXX do not save the inquiry, since it can change underneath us,