libmultipath: fix length issues in get_vpd_sgio
authorBenjamin Marzinski <bmarzins@redhat.com>
Tue, 9 Oct 2018 23:03:04 +0000 (18:03 -0500)
committerChristophe Varoqui <christophe.varoqui@opensvc.com>
Wed, 10 Oct 2018 06:09:31 +0000 (08:09 +0200)
When get_vpd_sgio() finds out that the vpd info needed to be truncated
to fit in the buffer, it doesn't trucate the size as well,  which allows
it to overwrite the buffer. Also, in once len is set to -ENODATA,
get_vpd_sgio() should exit, instead of using the negative len in
memcpy(). Found by coverity.

Reviewed-by: Martin Wilck <mwilck@suse.com>
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
libmultipath/discovery.c

index f973d4b..301093f 100644 (file)
@@ -1116,17 +1116,21 @@ get_vpd_sgio (int fd, int pg, char * str, int maxlen)
                return -ENODATA;
        }
        buff_len = get_unaligned_be16(&buff[2]) + 4;
-       if (buff_len > 4096)
+       if (buff_len > 4096) {
                condlog(3, "vpd pg%02x page truncated", pg);
-
+               buff_len = 4096;
+       }
        if (pg == 0x80)
                len = parse_vpd_pg80(buff, str, maxlen);
        else if (pg == 0x83)
                len = parse_vpd_pg83(buff, buff_len, str, maxlen);
        else if (pg == 0xc9 && maxlen >= 8) {
-               len = buff_len < 8 ? -ENODATA :
-                       (buff_len <= maxlen ? buff_len : maxlen);
-               memcpy (str, buff, len);
+               if (buff_len < 8)
+                       len = -ENODATA;
+               else {
+                       len = (buff_len <= maxlen)? buff_len : maxlen;
+                       memcpy (str, buff, len);
+               }
        } else
                len = -ENOSYS;