Permalink
Browse files

3220 noncompliant devices break sd-config-list

  • Loading branch information...
1 parent 33df475 commit eacb69c551f77c92b70401884e7f213b13d3ad81 @wesolows wesolows committed Sep 24, 2012
Showing with 53 additions and 15 deletions.
  1. +53 −15 usr/src/uts/common/io/scsi/targets/sd.c
@@ -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;
@@ -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

0 comments on commit eacb69c

Please sign in to comment.