Blame SOURCES/netlabelctl-addr_parse_fix.patch

380d7b
netlabelctl: add additional validation code to the network address parser
380d7b
380d7b
From: Paul Moore <pmoore@redhat.com>
380d7b
380d7b
It is possible to use network masks with non-integer values or integer
380d7b
values greater than the size of the network address, this patch fixes
380d7b
this.
380d7b
380d7b
Signed-off-by: Paul Moore <pmoore@redhat.com>
380d7b
---
380d7b
 netlabelctl/main.c |   39 ++++++++++++++++++++++++++++++++++++---
380d7b
 1 file changed, 36 insertions(+), 3 deletions(-)
380d7b
380d7b
diff --git a/netlabelctl/main.c b/netlabelctl/main.c
380d7b
index 4479bbf..6c4ab7f 100644
380d7b
--- a/netlabelctl/main.c
380d7b
+++ b/netlabelctl/main.c
380d7b
@@ -210,7 +210,30 @@ void nlctl_addr_print(const struct nlbl_netaddr *addr)
380d7b
 }
380d7b
 
380d7b
 /**
380d7b
- * Add a domain mapping to NetLabel
380d7b
+ * Parse an unsigned interger number
380d7b
+ * @param str the number string
380d7b
+ * @param num pointer to number to return
380d7b
+ *
380d7b
+ * Parse an unsigned integer number string and returns the value in @num.
380d7b
+ * Returns zero on success, negative values on failure.
380d7b
+ *
380d7b
+ */
380d7b
+static int _nlctl_num_parse(char *str, uint32_t *num)
380d7b
+{
380d7b
+	char *spot = str;
380d7b
+
380d7b
+	while (*spot != '\0') {
380d7b
+		if (*spot < '0' || *spot > '9')
380d7b
+			return -EINVAL;
380d7b
+		spot++;
380d7b
+	}
380d7b
+
380d7b
+	*num = atoi(str);
380d7b
+	return 0;
380d7b
+}
380d7b
+
380d7b
+/**
380d7b
+ * Parse a network address/mask pair
380d7b
  * @param addr_str the IP address/mask in string format
380d7b
  * @param addr the IP address/mask in native NetLabel format
380d7b
  *
380d7b
@@ -240,7 +263,12 @@ int nlctl_addr_parse(char *addr_str, struct nlbl_netaddr *addr)
380d7b
 	ret_val = inet_pton(AF_INET, addr_str, &addr->addr.v4);
380d7b
 	if (ret_val > 0) {
380d7b
 		addr->type = AF_INET;
380d7b
-		iter_a = (mask ? atoi(mask) : 32);
380d7b
+		if (mask != NULL) {
380d7b
+			ret_val = _nlctl_num_parse(mask, &iter_a);
380d7b
+			if (ret_val < 0 || iter_a > 32)
380d7b
+				return -EINVAL;
380d7b
+		} else
380d7b
+			iter_a = 32;
380d7b
 		for (; iter_a > 0; iter_a--) {
380d7b
 			addr->mask.v4.s_addr >>= 1;
380d7b
 			addr->mask.v4.s_addr |= 0x80000000;
380d7b
@@ -253,7 +281,12 @@ int nlctl_addr_parse(char *addr_str, struct nlbl_netaddr *addr)
380d7b
 	ret_val = inet_pton(AF_INET6, addr_str, &addr->addr.v6);
380d7b
 	if (ret_val > 0) {
380d7b
 		addr->type = AF_INET6;
380d7b
-		iter_a = (mask ? atoi(mask) : 128);
380d7b
+		if (mask != NULL) {
380d7b
+			ret_val = _nlctl_num_parse(mask, &iter_a);
380d7b
+			if (ret_val < 0 || iter_a > 128)
380d7b
+				return -EINVAL;
380d7b
+		} else
380d7b
+			iter_a = 128;
380d7b
 		for (iter_b = 0; iter_a > 0 && iter_b < 4; iter_b++) {
380d7b
 			for (; iter_a > 0 &&
380d7b
 			       addr->mask.v6.s6_addr32[iter_b] < 0xffffffff;