Ticket #1934: 0002-Fix-handling-multiple-designators-in-VPD-page.patch

File 0002-Fix-handling-multiple-designators-in-VPD-page.patch, 4.4 KB (added by Ross Lagerwall, 26 hours ago)
  • scsicmds.cpp

    From fe74cffdd670221283dd86834c867dea71e6132a Mon Sep 17 00:00:00 2001
    From: Ross Lagerwall <ross.lagerwall@citrix.com>
    Date: Fri, 21 Feb 2025 12:40:52 +0000
    Subject: [PATCH 2/2] Fix handling multiple designators in VPD page
    
    A VPD 0x83 page may have both an EUI-64 designator as well as an NAA
    designator. The code attempts to put them in the same buffer which
    results in a weird concatenated, truncated id like this:
    0x600a098038313577792450384a4a62750x2450384a4a62750000a09838313
    
    Instead, prefer NAA, then EUI-64, then SCSI name string. Also guard
    against the same designator appearing multiple times.
    
    Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
    ---
     scsicmds.cpp | 33 +++++++++++++++++++++++++--------
     1 file changed, 25 insertions(+), 8 deletions(-)
    
    diff --git a/scsicmds.cpp b/scsicmds.cpp
    index e5e26851685a..ecae021cf6e4 100644
    a b scsi_vpd_dev_id_iter(const unsigned char * initial_desig_desc, int page_len,  
    740740    return (k == page_len) ? -1 : -2;
    741741}
    742742
    743 /* Decode VPD page 0x83 logical unit designator into a string. If both
    744  * numeric address and SCSI name string present, prefer the former.
     743/* Decode VPD page 0x83 logical unit designator into a string. If multiple
     744 * designators are present, the order of preference is NAA, EUI-64, SCSI name
     745 * string.
    745746 * Returns 0 on success, -1 on error with error string in s. */
    746747int
    747748scsi_decode_lu_dev_id(const unsigned char * b, int blen, char * s, int slen,
    scsi_decode_lu_dev_id(const unsigned char * b, int blen, char * s, int slen,  
    758759#define SLEN(a, b) ((a) > (b) ? ((a) - (b)) : 0)
    759760    s[0] = '\0';
    760761    int si = 0;
    761     int have_scsi_ns = 0;
     762    int have_scsi_ns = 0, have_eui_64 = 0, have_naa = 0;
    762763    int off = -1;
    763764    int u;
    764765    while ((u = scsi_vpd_dev_id_iter(b, blen, &off, -1, -1, -1)) == 0) {
    scsi_decode_lu_dev_id(const unsigned char * b, int blen, char * s, int slen,  
    787788                snprintf(s+si, SLEN(slen, si), "error: EUI-64 length");
    788789                return -1;
    789790            }
     791            if (have_eui_64) {
     792                snprintf(s+si, SLEN(slen, si), "error: Duplicate EUI-64 designator");
     793                return -1;
     794            }
     795            if (have_naa)
     796                continue;
    790797            if (have_scsi_ns)
    791798                si = 0;
    792799            si += snprintf(s+si, SLEN(slen, si), "0x");
    793800            for (int m = 0; m < i_len; ++m)
    794801                si += snprintf(s+si, SLEN(slen, si), "%02x", (unsigned int)ip[m]);
     802            have_eui_64++;
    795803            break;
    796804        case 3: /* NAA */
    797805            if (1 != c_set) {
    scsi_decode_lu_dev_id(const unsigned char * b, int blen, char * s, int slen,  
    803811                snprintf(s+si, SLEN(slen, si), "error: unexpected NAA");
    804812                return -1;
    805813            }
    806             if (have_scsi_ns)
     814            if (have_naa) {
     815                snprintf(s+si, SLEN(slen, si), "error: Duplicate NAA designator");
     816                return -1;
     817            }
     818            if (have_eui_64 || have_scsi_ns)
    807819                si = 0;
    808820            if (2 == naa) {             /* NAA IEEE Extended */
    809821                if (8 != i_len) {
    scsi_decode_lu_dev_id(const unsigned char * b, int blen, char * s, int slen,  
    831843                for (int m = 0; m < 16; ++m)
    832844                    si += snprintf(s+si, SLEN(slen, si), "%02x", (unsigned int)ip[m]);
    833845            }
     846            have_naa++;
    834847            break;
    835848        case 4: /* Relative target port */
    836849        case 5: /* (primary) Target port group */
    scsi_decode_lu_dev_id(const unsigned char * b, int blen, char * s, int slen,  
    842855                snprintf(s+si, SLEN(slen, si), "error: SCSI name string");
    843856                return -1;
    844857            }
    845             /* does %s print out UTF-8 ok?? */
    846             if (si == 0) {
    847                 si += snprintf(s+si, SLEN(slen, si), "%s", (const char *)ip);
    848                 ++have_scsi_ns;
     858            if (have_scsi_ns) {
     859                snprintf(s+si, SLEN(slen, si), "error: Duplicate SCSI name string designator");
     860                return -1;
    849861            }
     862            if (have_eui_64 || have_naa)
     863                continue;
     864            /* does %s print out UTF-8 ok?? */
     865            si += snprintf(s+si, SLEN(slen, si), "%s", (const char *)ip);
     866            ++have_scsi_ns;
    850867            break;
    851868        default: /* reserved */
    852869            break;