Skip to contentSkip to conversation

nftables: validate port number in inet_service_type_parse

PATCH Applied Phil Oester 2 participants 2 messages Aug 15, 2013 – Aug 17, 2013 netfilter

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 nftables: validate port number in inet_service_type_parse

At present, nft accepts out of range port values such as in this example:

nft add rule ip filter input tcp dport 123456 accept

Attached patch adds checks for both integer overflow and 16 bit overflow, and avoids getaddrinfo call in the (common) case of digit input. Example above now produces this output:

    <cmdline>:1:36-41: Error: Service out of range
    add rule ip filter input tcp dport 123456 accept
                                       ^^^^^^

Phil

src/datatype.c +20 -7
index 55368ee..be32851 100644
@@ -11,6 +11,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <inttypes.h>
+#include <errno.h>
 #include <netdb.h>
 #include <arpa/inet.h>
 #include <linux/types.h>
@@ -500,18 +501,30 @@ static struct error_record *inet_service_type_parse(const struct expr *sym,
 {
 	struct addrinfo *ai;
 	uint16_t port;
+	uintmax_t i;
 	int err;
+	char *end;
+
+	errno = 0;
+	i = strtoumax(sym->identifier, &end, 0);
+	if (sym->identifier != end && *end == '\0') {
+		if (errno == ERANGE || i > UINT16_MAX)
+			return error(&sym->location, "Service out of range");
+
+		port = i;
+	} else {
+		err = getaddrinfo(NULL, sym->identifier, NULL, &ai);
+		if (err != 0)
+			return error(&sym->location, "Could not resolve service: %s",
+				     gai_strerror(err));
+
+		port = ((struct sockaddr_in *)ai->ai_addr)->sin_port;
+		freeaddrinfo(ai);
+	}
 
-	err = getaddrinfo(NULL, sym->identifier, NULL, &ai);
-	if (err != 0)
-		return error(&sym->location, "Could not resolve service: %s",
-			     gai_strerror(err));
-
-	port = ((struct sockaddr_in *)ai->ai_addr)->sin_port;
 	*res = constant_expr_alloc(&sym->location, &inet_service_type,
 				   BYTEORDER_BIG_ENDIAN,
 				   sizeof(port) * BITS_PER_BYTE, &port);
-	freeaddrinfo(ai);
 	return NULL;
 }
 
maintainer Applied
#1 lore raw
Quoted 11 lines · Phil Oester

At present, nft accepts out of range port values such as in this example:

nft add rule ip filter input tcp dport 123456 accept

Attached patch adds checks for both integer overflow and 16 bit overflow, and avoids getaddrinfo call in the (common) case of digit input. Example above now produces this output:

    <cmdline>:1:36-41: Error: Service out of range
    add rule ip filter input tcp dport 123456 accept
                                       ^^^^^^

Applied, thanks Phil.