Skip to content

Commit

Permalink
3220 noncompliant devices break sd-config-list
Browse files Browse the repository at this point in the history
  • Loading branch information
Keith M Wesolowski committed Sep 25, 2012
1 parent 33df475 commit eacb69c
Showing 1 changed file with 53 additions and 15 deletions.
68 changes: 53 additions & 15 deletions usr/src/uts/common/io/scsi/targets/sd.c
Expand Up @@ -4447,8 +4447,10 @@ sd_sdconf_id_match(struct sd_lun *un, char *id, int idlen)
struct scsi_inquiry *sd_inq;
int rval = SD_SUCCESS;
char *p;
int inq_vidlen, inq_pidlen;
int chk_vidlen, chk_pidlen;
int has_tail = 0;
static const int VSZ = sizeof (sd_inq->inq_vid);
static const int PSZ = sizeof (sd_inq->inq_pid);

ASSERT(un != NULL);
sd_inq = un->un_sd->sd_inq;
Expand All @@ -4463,22 +4465,58 @@ sd_sdconf_id_match(struct sd_lun *un, char *id, int idlen)
* buffer, and some broken devices violate SPC 4.3.1 and return
* fields with null bytes in them.
*/
for (p = sd_inq->inq_vid; *p != '\0' && p - sd_inq->inq_vid < 8; ++p)
;
inq_vidlen = p - sd_inq->inq_vid;
chk_vidlen = MIN(idlen, inq_vidlen);
chk_vidlen = MIN(VSZ, idlen);
p = id + chk_vidlen - 1;
while (*p == ' ' && chk_vidlen > 0) {
--p;
--chk_vidlen;
}

for (p = sd_inq->inq_pid; *p != '\0' && p - sd_inq->inq_pid < 16; ++p)
;
inq_pidlen = p - sd_inq->inq_pid;
if (idlen > 8)
chk_pidlen = MIN(idlen - 8, inq_pidlen);
else
chk_pidlen = 0;
/*
* If it's all spaces, check the whole thing.
*/
if (chk_vidlen == 0)
chk_vidlen = MIN(VSZ, idlen);

if (idlen > VSZ) {
chk_pidlen = idlen - VSZ;
p = id + idlen - 1;
while (*p == ' ' && chk_pidlen > 0) {
--p;
--chk_pidlen;
}
if (chk_pidlen == 0)
chk_pidlen = MIN(PSZ, idlen - VSZ);
}

/*
* There's one more thing we need to do here. If the user specified
* an ID with trailing spaces, we need to make sure the inquiry
* vid/pid has only spaces or NULs after the check length; otherwise, it
* can't match.
*/
if (idlen > chk_vidlen && chk_vidlen < VSZ) {
for (p = sd_inq->inq_vid + chk_vidlen;
p < sd_inq->inq_vid + VSZ; ++p) {
if (*p != ' ' && *p != '\0') {
++has_tail;
break;
}
}
}
if (idlen > chk_pidlen + VSZ && chk_pidlen < PSZ) {
for (p = sd_inq->inq_pid + chk_pidlen;
p < sd_inq->inq_pid + PSZ; ++p) {
if (*p != ' ' && *p != '\0') {
++has_tail;
break;
}
}
}

if (strncasecmp(sd_inq->inq_vid, id, chk_vidlen) != 0 ||
(idlen > 8 &&
strncasecmp(sd_inq->inq_pid, id + 8, chk_pidlen) != 0)) {
if (has_tail || strncasecmp(sd_inq->inq_vid, id, chk_vidlen) != 0 ||
(idlen > VSZ &&
strncasecmp(sd_inq->inq_pid, id + VSZ, chk_pidlen) != 0)) {
/*
* The user id string is compared to the inquiry vid/pid
* using a case insensitive comparison and ignoring
Expand Down

0 comments on commit eacb69c

Please sign in to comment.