Blame SOURCES/0007-libmultipath-fix-sgio_get_vpd-looping.patch

8444ee
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
8444ee
From: Benjamin Marzinski <bmarzins@redhat.com>
8444ee
Date: Fri, 1 Nov 2019 10:33:04 -0500
8444ee
Subject: [PATCH] libmultipath: fix sgio_get_vpd looping
8444ee
8444ee
If do_inq returns a page with a length that is less than maxlen, but
8444ee
larger than DEFAULT_SGIO_LEN, this function will loop forever. Also
8444ee
if do_inq returns with a length equal to or greater than maxlen,
8444ee
sgio_get_vpd will exit immediately, even if it hasn't read the entire
8444ee
page.  Fix these issues, modify the tests to verify the new behavior.
8444ee
8444ee
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
8444ee
---
8444ee
 libmultipath/discovery.c | 12 +++---
8444ee
 tests/vpd.c              | 84 ++++++++++++++++++++++++----------------
8444ee
 2 files changed, 57 insertions(+), 39 deletions(-)
8444ee
8444ee
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
8444ee
index 72f455e8..3c72a80a 100644
8444ee
--- a/libmultipath/discovery.c
8444ee
+++ b/libmultipath/discovery.c
8444ee
@@ -870,6 +870,7 @@ static int
8444ee
 sgio_get_vpd (unsigned char * buff, int maxlen, int fd, int pg)
8444ee
 {
8444ee
 	int len = DEFAULT_SGIO_LEN;
8444ee
+	int rlen;
8444ee
 
8444ee
 	if (fd < 0) {
8444ee
 		errno = EBADF;
8444ee
@@ -877,12 +878,11 @@ sgio_get_vpd (unsigned char * buff, int maxlen, int fd, int pg)
8444ee
 	}
8444ee
 retry:
8444ee
 	if (0 == do_inq(fd, 0, 1, pg, buff, len)) {
8444ee
-		len = get_unaligned_be16(&buff[2]) + 4;
8444ee
-		if (len >= maxlen)
8444ee
-			return len;
8444ee
-		if (len > DEFAULT_SGIO_LEN)
8444ee
-			goto retry;
8444ee
-		return len;
8444ee
+		rlen = get_unaligned_be16(&buff[2]) + 4;
8444ee
+		if (rlen <= len || len >= maxlen)
8444ee
+			return rlen;
8444ee
+		len = (rlen < maxlen)? rlen : maxlen;
8444ee
+		goto retry;
8444ee
 	}
8444ee
 	return -1;
8444ee
 }
8444ee
diff --git a/tests/vpd.c b/tests/vpd.c
8444ee
index d9f80eaa..4dbce010 100644
8444ee
--- a/tests/vpd.c
8444ee
+++ b/tests/vpd.c
8444ee
@@ -306,7 +306,7 @@ static int create_vpd83(unsigned char *buf, size_t bufsiz, const char *id,
8444ee
 	default:
8444ee
 		break;
8444ee
 	}
8444ee
-	put_unaligned_be16(n, buf + 2);
8444ee
+	put_unaligned_be16(bufsiz, buf + 2);
8444ee
 	return n + 4;
8444ee
 }
8444ee
 
8444ee
@@ -429,6 +429,8 @@ static void test_vpd_vnd_ ## len ## _ ## wlen(void **state)             \
8444ee
 	free(exp_wwid);							\
8444ee
 	will_return(__wrap_ioctl, n);					\
8444ee
 	will_return(__wrap_ioctl, vt->vpdbuf);				\
8444ee
+	will_return(__wrap_ioctl, n);					\
8444ee
+	will_return(__wrap_ioctl, vt->vpdbuf);				\
8444ee
 	ret = get_vpd_sgio(10, 0x83, vt->wwid, wlen);			\
8444ee
 	assert_correct_wwid("test_vpd_vnd_" #len "_" #wlen,		\
8444ee
 			    exp_len, ret, '1', 0, false,		\
8444ee
@@ -459,6 +461,8 @@ static void test_vpd_str_ ## typ ## _ ## len ## _ ## wlen(void **state) \
8444ee
 		exp_len = wlen - 1;					\
8444ee
 	will_return(__wrap_ioctl, n);					\
8444ee
 	will_return(__wrap_ioctl, vt->vpdbuf);				\
8444ee
+	will_return(__wrap_ioctl, n);					\
8444ee
+	will_return(__wrap_ioctl, vt->vpdbuf);				\
8444ee
 	ret = get_vpd_sgio(10, 0x83, vt->wwid, wlen);			\
8444ee
 	assert_correct_wwid("test_vpd_str_" #typ "_" #len "_" #wlen,	\
8444ee
 			    exp_len, ret, byte0[type], 0,		\
8444ee
@@ -496,6 +500,8 @@ static void test_vpd_naa_ ## naa ## _ ## wlen(void **state)             \
8444ee
 			 3, naa, 0);					\
8444ee
 	will_return(__wrap_ioctl, n);					\
8444ee
 	will_return(__wrap_ioctl, vt->vpdbuf);				\
8444ee
+	will_return(__wrap_ioctl, n);					\
8444ee
+	will_return(__wrap_ioctl, vt->vpdbuf);				\
8444ee
 	ret = get_vpd_sgio(10, 0x83, vt->wwid, wlen);			\
8444ee
 	assert_correct_wwid("test_vpd_naa_" #naa "_" #wlen,		\
8444ee
 			    exp_len, ret, '3', '0' + naa, true,		\
8444ee
@@ -506,22 +512,26 @@ static void test_vpd_naa_ ## naa ## _ ## wlen(void **state)             \
8444ee
  * test_vpd_eui_LEN_WLEN() - test code for VPD 83, EUI64
8444ee
  * @LEN:	EUI64 length (8, 12, or 16)
8444ee
  * @WLEN:	WWID buffer size
8444ee
+ * @SML:	Use small VPD page size
8444ee
  */
8444ee
-#define make_test_vpd_eui(len, wlen)					\
8444ee
-static void test_vpd_eui_ ## len ## _ ## wlen(void **state)             \
8444ee
+#define make_test_vpd_eui(len, wlen, sml)				\
8444ee
+static void test_vpd_eui_ ## len ## _ ## wlen ## _ ## sml(void **state)	\
8444ee
 {									\
8444ee
 	struct vpdtest *vt = *state;                                    \
8444ee
 	int n, ret;							\
8444ee
 	/* returned size is always uneven */				\
8444ee
 	int exp_len = wlen > 2 * len + 1 ? 2 * len + 1 :		\
8444ee
 		wlen % 2 == 0 ? wlen - 1 : wlen - 2;			\
8444ee
+	int bufsize = sml ? 255 : sizeof(vt->vpdbuf);			\
8444ee
 									\
8444ee
-	n = create_vpd83(vt->vpdbuf, sizeof(vt->vpdbuf), test_id,	\
8444ee
+	n = create_vpd83(vt->vpdbuf, bufsize, test_id,			\
8444ee
 			 2, 0, len);					\
8444ee
 	will_return(__wrap_ioctl, n);					\
8444ee
 	will_return(__wrap_ioctl, vt->vpdbuf);				\
8444ee
+	will_return(__wrap_ioctl, n);					\
8444ee
+	will_return(__wrap_ioctl, vt->vpdbuf);				\
8444ee
 	ret = get_vpd_sgio(10, 0x83, vt->wwid, wlen);			\
8444ee
-	assert_correct_wwid("test_vpd_eui_" #len "_" #wlen,		\
8444ee
+	assert_correct_wwid("test_vpd_eui_" #len "_" #wlen "_" #sml,	\
8444ee
 			    exp_len, ret, '2', 0, true,			\
8444ee
 			    test_id, vt->wwid);				\
8444ee
 }
8444ee
@@ -603,25 +613,30 @@ make_test_vpd_vnd(20, 10);
8444ee
 make_test_vpd_vnd(10, 10);
8444ee
 
8444ee
 /* EUI64 tests */
8444ee
+/* small vpd page test */
8444ee
+make_test_vpd_eui(8, 32, 1);
8444ee
+make_test_vpd_eui(12, 32, 1);
8444ee
+make_test_vpd_eui(16, 40, 1);
8444ee
+
8444ee
 /* 64bit, WWID size: 18 */
8444ee
-make_test_vpd_eui(8, 32);
8444ee
-make_test_vpd_eui(8, 18);
8444ee
-make_test_vpd_eui(8, 17);
8444ee
-make_test_vpd_eui(8, 16);
8444ee
-make_test_vpd_eui(8, 10);
8444ee
+make_test_vpd_eui(8, 32, 0);
8444ee
+make_test_vpd_eui(8, 18, 0);
8444ee
+make_test_vpd_eui(8, 17, 0);
8444ee
+make_test_vpd_eui(8, 16, 0);
8444ee
+make_test_vpd_eui(8, 10, 0);
8444ee
 
8444ee
 /* 96 bit, WWID size: 26 */
8444ee
-make_test_vpd_eui(12, 32);
8444ee
-make_test_vpd_eui(12, 26);
8444ee
-make_test_vpd_eui(12, 25);
8444ee
-make_test_vpd_eui(12, 20);
8444ee
-make_test_vpd_eui(12, 10);
8444ee
+make_test_vpd_eui(12, 32, 0);
8444ee
+make_test_vpd_eui(12, 26, 0);
8444ee
+make_test_vpd_eui(12, 25, 0);
8444ee
+make_test_vpd_eui(12, 20, 0);
8444ee
+make_test_vpd_eui(12, 10, 0);
8444ee
 
8444ee
 /* 128 bit, WWID size: 34 */
8444ee
-make_test_vpd_eui(16, 40);
8444ee
-make_test_vpd_eui(16, 34);
8444ee
-make_test_vpd_eui(16, 33);
8444ee
-make_test_vpd_eui(16, 20);
8444ee
+make_test_vpd_eui(16, 40, 0);
8444ee
+make_test_vpd_eui(16, 34, 0);
8444ee
+make_test_vpd_eui(16, 33, 0);
8444ee
+make_test_vpd_eui(16, 20, 0);
8444ee
 
8444ee
 /* NAA IEEE registered extended (36), WWID size: 34 */
8444ee
 make_test_vpd_naa(6, 40);
8444ee
@@ -722,20 +737,23 @@ static int test_vpd(void)
8444ee
 		cmocka_unit_test(test_vpd_vnd_19_20),
8444ee
 		cmocka_unit_test(test_vpd_vnd_20_10),
8444ee
 		cmocka_unit_test(test_vpd_vnd_10_10),
8444ee
-		cmocka_unit_test(test_vpd_eui_8_32),
8444ee
-		cmocka_unit_test(test_vpd_eui_8_18),
8444ee
-		cmocka_unit_test(test_vpd_eui_8_17),
8444ee
-		cmocka_unit_test(test_vpd_eui_8_16),
8444ee
-		cmocka_unit_test(test_vpd_eui_8_10),
8444ee
-		cmocka_unit_test(test_vpd_eui_12_32),
8444ee
-		cmocka_unit_test(test_vpd_eui_12_26),
8444ee
-		cmocka_unit_test(test_vpd_eui_12_25),
8444ee
-		cmocka_unit_test(test_vpd_eui_12_20),
8444ee
-		cmocka_unit_test(test_vpd_eui_12_10),
8444ee
-		cmocka_unit_test(test_vpd_eui_16_40),
8444ee
-		cmocka_unit_test(test_vpd_eui_16_34),
8444ee
-		cmocka_unit_test(test_vpd_eui_16_33),
8444ee
-		cmocka_unit_test(test_vpd_eui_16_20),
8444ee
+		cmocka_unit_test(test_vpd_eui_8_32_1),
8444ee
+		cmocka_unit_test(test_vpd_eui_12_32_1),
8444ee
+		cmocka_unit_test(test_vpd_eui_16_40_1),
8444ee
+		cmocka_unit_test(test_vpd_eui_8_32_0),
8444ee
+		cmocka_unit_test(test_vpd_eui_8_18_0),
8444ee
+		cmocka_unit_test(test_vpd_eui_8_17_0),
8444ee
+		cmocka_unit_test(test_vpd_eui_8_16_0),
8444ee
+		cmocka_unit_test(test_vpd_eui_8_10_0),
8444ee
+		cmocka_unit_test(test_vpd_eui_12_32_0),
8444ee
+		cmocka_unit_test(test_vpd_eui_12_26_0),
8444ee
+		cmocka_unit_test(test_vpd_eui_12_25_0),
8444ee
+		cmocka_unit_test(test_vpd_eui_12_20_0),
8444ee
+		cmocka_unit_test(test_vpd_eui_12_10_0),
8444ee
+		cmocka_unit_test(test_vpd_eui_16_40_0),
8444ee
+		cmocka_unit_test(test_vpd_eui_16_34_0),
8444ee
+		cmocka_unit_test(test_vpd_eui_16_33_0),
8444ee
+		cmocka_unit_test(test_vpd_eui_16_20_0),
8444ee
 		cmocka_unit_test(test_vpd_naa_6_40),
8444ee
 		cmocka_unit_test(test_vpd_naa_6_34),
8444ee
 		cmocka_unit_test(test_vpd_naa_6_33),
8444ee
-- 
8444ee
2.17.2
8444ee