提交 e5b3cd42 编写于 作者: A Alan Stern 提交者: James Bottomley

[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: NAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: NJames Bottomley <James.Bottomley@SteelEye.com>
上级 85b6c720
......@@ -396,6 +396,32 @@ void scsi_target_reap(struct scsi_target *starget)
return;
}
/**
* sanitize_inquiry_string - remove non-graphical chars from an INQUIRY result string
* @s: INQUIRY result string to sanitize
* @len: length of the string
*
* Description:
* The SCSI spec says that INQUIRY vendor, product, and revision
* strings must consist entirely of graphic ASCII characters,
* padded on the right with spaces. Since not all devices obey
* this rule, we will replace non-graphic or non-ASCII characters
* with spaces. Exception: a NUL character is interpreted as a
* string terminator, so all the following characters are set to
* spaces.
**/
static void sanitize_inquiry_string(unsigned char *s, int len)
{
int terminated = 0;
for (; len > 0; (--len, ++s)) {
if (*s == 0)
terminated = 1;
if (terminated || *s < 0x20 || *s > 0x7e)
*s = ' ';
}
}
/**
* scsi_probe_lun - probe a single LUN using a SCSI INQUIRY
* @sdev: scsi_device to probe
......@@ -410,7 +436,7 @@ void scsi_target_reap(struct scsi_target *starget)
* INQUIRY data is in @inq_result; the scsi_level and INQUIRY length
* are copied to the scsi_device any flags value is stored in *@bflags.
**/
static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result,
static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
int result_len, int *bflags)
{
unsigned char scsi_cmd[MAX_COMMAND_SIZE];
......@@ -469,7 +495,11 @@ static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result,
}
if (result == 0) {
response_len = (unsigned char) inq_result[4] + 5;
sanitize_inquiry_string(&inq_result[8], 8);
sanitize_inquiry_string(&inq_result[16], 16);
sanitize_inquiry_string(&inq_result[32], 4);
response_len = inq_result[4] + 5;
if (response_len > 255)
response_len = first_inquiry_len; /* sanity */
......@@ -575,7 +605,8 @@ static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result,
* SCSI_SCAN_NO_RESPONSE: could not allocate or setup a scsi_device
* SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized
**/
static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags)
static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
int *bflags)
{
/*
* XXX do not save the inquiry, since it can change underneath us,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册