@@ -978,7 +978,8 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len,
{
const unsigned char *d;
const unsigned char *vpd = NULL;
- int len = -ENODATA, vpd_type, vpd_len, prio = -1, i, naa_prio;
+ size_t len, vpd_len, i;
+ int vpd_type, prio = -1, naa_prio;
d = in + 4;
while (d < in + in_len) {
@@ -1048,17 +1049,20 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len,
if (prio <= 0)
return -ENODATA;
+ /* Need space at least for one digit */
+ else if (out_len <= 1)
+ return 0;
+ len = 0;
vpd_type = vpd[1] & 0xf;
vpd_len = vpd[3];
vpd += 4;
if (vpd_type == 0x2 || vpd_type == 0x3) {
- int i;
+ size_t i;
- assert(out_len >= 2);
len = sprintf(out, "%d", vpd_type);
if (2 * vpd_len >= out_len - len) {
- condlog(1, "%s: WWID overflow, type %d, %d/%lu bytes required",
+ condlog(1, "%s: WWID overflow, type %d, %lu/%lu bytes required",
__func__, vpd_type,
2 * vpd_len + len + 1, out_len);
vpd_len = (out_len - len - 1) / 2;
@@ -1066,6 +1070,10 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len,
for (i = 0; i < vpd_len; i++)
len += sprintf(out + len,
"%02x", vpd[i]);
+ } else if (vpd_type == 0x8 && vpd_len < 4) {
+ condlog(1, "%s: VPD length %lu too small for designator type 8",
+ __func__, vpd_len);
+ return -EINVAL;
} else if (vpd_type == 0x8) {
if (!memcmp("eui.", vpd, 4))
out[0] = '2';
@@ -1079,7 +1087,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len,
while (len > 2 && vpd[len - 2] == '\0')
--len;
if (len > out_len - 1) {
- condlog(1, "%s: WWID overflow, type 8/%c, %d/%lu bytes required",
+ condlog(1, "%s: WWID overflow, type 8/%c, %lu/%lu bytes required",
__func__, out[0], len + 1, out_len);
len = out_len - 1;
}
@@ -1096,15 +1104,14 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len,
} else if (vpd_type == 0x1) {
const unsigned char *p;
- int p_len;
+ size_t p_len;
out[0] = '1';
len = 1;
- p = vpd;
while ((p = memchr(vpd, ' ', vpd_len))) {
p_len = p - vpd;
if (len + p_len > out_len - 1) {
- condlog(1, "%s: WWID overflow, type 1, %d/%lu bytes required",
+ condlog(1, "%s: WWID overflow, type 1, %lu/%lu bytes required",
__func__, len + p_len, out_len);
p_len = out_len - len - 1;
}
@@ -1130,7 +1137,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len,
p_len = vpd_len;
if (p_len > 0 && len < out_len - 1) {
if (len + p_len > out_len - 1) {
- condlog(1, "%s: WWID overflow, type 1, %d/%lu bytes required",
+ condlog(1, "%s: WWID overflow, type 1, %lu/%lu bytes required",
__func__, len + p_len + 1, out_len);
p_len = out_len - len - 1;
}