|
|
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;
|