Blame SOURCES/0069-libmultipath-cleanup-add_feature.patch

e71b65
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
e71b65
From: Benjamin Marzinski <bmarzins@redhat.com>
e71b65
Date: Fri, 7 Oct 2022 12:35:38 -0500
e71b65
Subject: [PATCH] libmultipath: cleanup add_feature
e71b65
e71b65
add_feature() didn't correctly handle feature strings that used
e71b65
whitespace other than spaces, which the kernel allows. It also didn't
e71b65
allow adding features with multiple tokens. When it looked to see if the
e71b65
feature string to be added already existed, it didn't check if the match
e71b65
was part of a larger token. Finally, it did unnecessary work.  By using
e71b65
asprintf() to create the string, the function can be signifcantly
e71b65
simplified.
e71b65
e71b65
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
e71b65
Reviewed-by: Martin Wilck <mwilck@suse.com>
e71b65
---
e71b65
 libmultipath/structs.c | 49 +++++++++++++++++++++---------------------
e71b65
 1 file changed, 24 insertions(+), 25 deletions(-)
e71b65
e71b65
diff --git a/libmultipath/structs.c b/libmultipath/structs.c
e71b65
index 83906ffe..5dfa86a8 100644
e71b65
--- a/libmultipath/structs.c
e71b65
+++ b/libmultipath/structs.c
e71b65
@@ -608,23 +608,33 @@ int add_feature(char **f, const char *n)
e71b65
 {
e71b65
 	int c = 0, d, l;
e71b65
 	char *e, *t;
e71b65
+	const char *p;
e71b65
 
e71b65
 	if (!f)
e71b65
 		return 1;
e71b65
 
e71b65
 	/* Nothing to do */
e71b65
-	if (!n || *n == '0')
e71b65
+	if (!n || *n == '\0')
e71b65
 		return 0;
e71b65
 
e71b65
-	if (strchr(n, ' ') != NULL) {
e71b65
-		condlog(0, "internal error: feature \"%s\" contains spaces", n);
e71b65
+	l = strlen(n);
e71b65
+	if (isspace(*n) || isspace(*(n + l - 1))) {
e71b65
+		condlog(0, "internal error: feature \"%s\" has leading or trailing spaces", n);
e71b65
 		return 1;
e71b65
 	}
e71b65
 
e71b65
+	p = n;
e71b65
+	d = 1;
e71b65
+	while (*p != '\0') {
e71b65
+		if (isspace(*p) && !isspace(*(p + 1)) && *(p + 1) != '\0')
e71b65
+			d++;
e71b65
+		p++;
e71b65
+	}
e71b65
+
e71b65
 	/* default feature is null */
e71b65
 	if(!*f)
e71b65
 	{
e71b65
-		l = asprintf(&t, "1 %s", n);
e71b65
+		l = asprintf(&t, "%0d %s", d, n);
e71b65
 		if(l == -1)
e71b65
 			return 1;
e71b65
 
e71b65
@@ -633,35 +643,24 @@ int add_feature(char **f, const char *n)
e71b65
 	}
e71b65
 
e71b65
 	/* Check if feature is already present */
e71b65
-	if (strstr(*f, n))
e71b65
-		return 0;
e71b65
+	e = *f;
e71b65
+	while ((e = strstr(e, n)) != NULL) {
e71b65
+		if (isspace(*(e - 1)) &&
e71b65
+		    (isspace(*(e + l)) || *(e + l) == '\0'))
e71b65
+			return 0;
e71b65
+		e += l;
e71b65
+	}
e71b65
 
e71b65
 	/* Get feature count */
e71b65
 	c = strtoul(*f, &e, 10);
e71b65
-	if (*f == e || (*e != ' ' && *e != '\0')) {
e71b65
+	if (*f == e || (!isspace(*e) && *e != '\0')) {
e71b65
 		condlog(0, "parse error in feature string \"%s\"", *f);
e71b65
 		return 1;
e71b65
 	}
e71b65
-
e71b65
-	/* Add 1 digit and 1 space */
e71b65
-	l = strlen(e) + strlen(n) + 2;
e71b65
-
e71b65
-	c++;
e71b65
-	/* Check if we need more digits for feature count */
e71b65
-	for (d = c; d >= 10; d /= 10)
e71b65
-		l++;
e71b65
-
e71b65
-	t = MALLOC(l + 1);
e71b65
-	if (!t)
e71b65
+	c += d;
e71b65
+	if (asprintf(&t, "%0d%s %s", c, e, n) < 0)
e71b65
 		return 1;
e71b65
 
e71b65
-	/* e: old feature string with leading space, or "" */
e71b65
-	if (*e == ' ')
e71b65
-		while (*(e + 1) == ' ')
e71b65
-			e++;
e71b65
-
e71b65
-	snprintf(t, l + 1, "%0d%s %s", c, e, n);
e71b65
-
e71b65
 	FREE(*f);
e71b65
 	*f = t;
e71b65