netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH conntrack 1/3] conntrack: improve --secmark,--id,--zone parser
@ 2024-10-12 15:29 Pablo Neira Ayuso
  2024-10-12 15:29 ` [PATCH conntrack 2/3] conntrack: improve --mark parser Pablo Neira Ayuso
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Pablo Neira Ayuso @ 2024-10-12 15:29 UTC (permalink / raw)
  To: netfilter-devel

strtoul() is called with no error checking at all, add a helper
function to validate input is correct.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 src/conntrack.c | 34 ++++++++++++++++++++++++++++------
 1 file changed, 28 insertions(+), 6 deletions(-)

diff --git a/src/conntrack.c b/src/conntrack.c
index 9fa49869b553..f3725eefd5de 100644
--- a/src/conntrack.c
+++ b/src/conntrack.c
@@ -1213,6 +1213,25 @@ parse_parameter_mask(const char *arg, unsigned int *status, unsigned int *mask,
 		exit_error(PARAMETER_PROBLEM, "Bad parameter `%s'", arg);
 }
 
+static int parse_value(const char *str, uint32_t *ret, uint64_t max)
+{
+	char *endptr;
+	uint64_t val;
+
+	errno = 0;
+	val = strtoul(str, &endptr, 0);
+	if (endptr == str ||
+	    *endptr != '\0' ||
+	    (val == ULONG_MAX && errno == ERANGE) ||
+	    (val == 0 && errno == ERANGE) ||
+	    val > max)
+		return -1;
+
+	*ret = val;
+
+	return 0;
+}
+
 static void
 parse_u32_mask(const char *arg, struct u32_mask *m)
 {
@@ -2918,6 +2937,7 @@ static void do_parse(struct ct_cmd *ct_cmd, int argc, char *argv[])
 	struct ct_tmpl *tmpl;
 	int res = 0, partial;
 	union ct_address ad;
+	uint32_t value;
 	int c, cmd;
 
 	/* we release these objects in the exit_error() path. */
@@ -3078,17 +3098,19 @@ static void do_parse(struct ct_cmd *ct_cmd, int argc, char *argv[])
 		case 'w':
 		case '(':
 		case ')':
+			if (parse_value(optarg, &value, UINT16_MAX) < 0)
+				exit_error(OTHER_PROBLEM, "unexpected value '%s' with -%c option", optarg, c);
+
 			options |= opt2type[c];
-			nfct_set_attr_u16(tmpl->ct,
-					  opt2attr[c],
-					  strtoul(optarg, NULL, 0));
+			nfct_set_attr_u16(tmpl->ct, opt2attr[c], value);
 			break;
 		case 'i':
 		case 'c':
+			if (parse_value(optarg, &value, UINT32_MAX) < 0)
+				exit_error(OTHER_PROBLEM, "unexpected value '%s' with -%c option", optarg, c);
+
 			options |= opt2type[c];
-			nfct_set_attr_u32(tmpl->ct,
-					  opt2attr[c],
-					  strtoul(optarg, NULL, 0));
+			nfct_set_attr_u32(tmpl->ct, opt2attr[c], value);
 			break;
 		case 'm':
 			options |= opt2type[c];
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH conntrack 2/3] conntrack: improve --mark parser
  2024-10-12 15:29 [PATCH conntrack 1/3] conntrack: improve --secmark,--id,--zone parser Pablo Neira Ayuso
@ 2024-10-12 15:29 ` Pablo Neira Ayuso
  2024-10-12 15:29 ` [PATCH conntrack 3/3] tests: conntrack: missing space before option Pablo Neira Ayuso
  2024-10-12 19:57 ` [PATCH conntrack 1/3] conntrack: improve --secmark,--id,--zone parser Jeremy Sowden
  2 siblings, 0 replies; 4+ messages in thread
From: Pablo Neira Ayuso @ 2024-10-12 15:29 UTC (permalink / raw)
  To: netfilter-devel

Enhance helper function to parse mark and mask (if available), bail out
if input is not correct.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 src/conntrack.c | 36 +++++++++++++++++++++++++++++-------
 1 file changed, 29 insertions(+), 7 deletions(-)

diff --git a/src/conntrack.c b/src/conntrack.c
index f3725eefd5de..1da98697a264 100644
--- a/src/conntrack.c
+++ b/src/conntrack.c
@@ -1232,17 +1232,37 @@ static int parse_value(const char *str, uint32_t *ret, uint64_t max)
 	return 0;
 }
 
-static void
+static int
 parse_u32_mask(const char *arg, struct u32_mask *m)
 {
-	char *end;
+	uint64_t val, mask;
+	char *endptr;
+
+	val = strtoul(arg, &endptr, 0);
+	if (endptr == arg ||
+	    (*endptr != '\0' && *endptr != '/') ||
+	    (val == ULONG_MAX && errno == ERANGE) ||
+	    (val == 0 && errno == ERANGE) ||
+	    val > UINT32_MAX)
+		return -1;
 
-	m->value = (uint32_t) strtoul(arg, &end, 0);
+	m->value = val;
 
-	if (*end == '/')
-		m->mask = (uint32_t) strtoul(end+1, NULL, 0);
-	else
+	if (*endptr == '/') {
+		mask = (uint32_t) strtoul(endptr + 1, &endptr, 0);
+		if (endptr == arg ||
+		    *endptr != '\0' ||
+		    (val == ULONG_MAX && errno == ERANGE) ||
+		    (val == 0 && errno == ERANGE) ||
+		    val > UINT32_MAX)
+			return -1;
+
+		m->mask = mask;
+	} else {
 		m->mask = ~0;
+	}
+
+	return 0;
 }
 
 static int
@@ -3114,7 +3134,9 @@ static void do_parse(struct ct_cmd *ct_cmd, int argc, char *argv[])
 			break;
 		case 'm':
 			options |= opt2type[c];
-			parse_u32_mask(optarg, &tmpl->mark);
+			if (parse_u32_mask(optarg, &tmpl->mark) < 0)
+				exit_error(OTHER_PROBLEM, "unexpected value '%s' with -%c option", optarg, c);
+
 			tmpl->filter_mark_kernel.val = tmpl->mark.value;
 			tmpl->filter_mark_kernel.mask = tmpl->mark.mask;
 			tmpl->filter_mark_kernel_set = true;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH conntrack 3/3] tests: conntrack: missing space before option
  2024-10-12 15:29 [PATCH conntrack 1/3] conntrack: improve --secmark,--id,--zone parser Pablo Neira Ayuso
  2024-10-12 15:29 ` [PATCH conntrack 2/3] conntrack: improve --mark parser Pablo Neira Ayuso
@ 2024-10-12 15:29 ` Pablo Neira Ayuso
  2024-10-12 19:57 ` [PATCH conntrack 1/3] conntrack: improve --secmark,--id,--zone parser Jeremy Sowden
  2 siblings, 0 replies; 4+ messages in thread
From: Pablo Neira Ayuso @ 2024-10-12 15:29 UTC (permalink / raw)
  To: netfilter-devel

Recent updates make the conntrack parser slightly more robust. A few
test lines include:

... -w 11-s 2001:DB8::1.1.1.1 ...

where space is missing. These are typos rather than valid input.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 tests/conntrack/testsuite/09dumpopt | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/tests/conntrack/testsuite/09dumpopt b/tests/conntrack/testsuite/09dumpopt
index c1e0e6ed376d..9dcd51f81638 100644
--- a/tests/conntrack/testsuite/09dumpopt
+++ b/tests/conntrack/testsuite/09dumpopt
@@ -25,7 +25,7 @@
 # delete reverse
 -D -w 11 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ; OK
 # delete v6 conntrack
--D -w 11-s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; OK
+-D -w 11 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; OK
 # delete icmp ping request entry
 -D -w 11 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK
 # delete old entries
@@ -33,7 +33,7 @@
 # delete reverse
 -D -w 10 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ; OK
 # delete v6 conntrack
--D -w 10-s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; OK
+-D -w 10 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; OK
 # delete icmp ping request entry
 -D -w 10 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK
 #
@@ -64,7 +64,7 @@
 # delete reverse
 -D -w 11 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ; OK
 # delete v6 conntrack
--D -w 11-s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; OK
+-D -w 11 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; OK
 # delete icmp ping request entry
 -D -w 11 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK
 # delete old entries
@@ -72,7 +72,7 @@
 # delete reverse
 -D -w 10 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ; BAD
 # delete v6 conntrack
--D -w 10-s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; BAD
+-D -w 10 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; BAD
 # delete icmp ping request entry
 -D -w 10 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; BAD
 #
@@ -161,13 +161,13 @@
 # IGMP
 -D -w 10 -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p 2 ; OK
 # Some fency protocol
--D -w 10  -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p 200 ; OK
+-D -w 10 -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p 200 ; OK
 # Some fency protocol with IPv6
 -D -w 10 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p 200 ; OK
 # Delete stuff in zone 11, should succeed
 # IGMP
 -D -w 11 -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p 2 ; OK
 # Some fency protocol
--D -w 11  -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p 200 ; OK
+-D -w 11 -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p 200 ; OK
 # Some fency protocol with IPv6
 -D -w 11 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p 200 ; OK
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH conntrack 1/3] conntrack: improve --secmark,--id,--zone parser
  2024-10-12 15:29 [PATCH conntrack 1/3] conntrack: improve --secmark,--id,--zone parser Pablo Neira Ayuso
  2024-10-12 15:29 ` [PATCH conntrack 2/3] conntrack: improve --mark parser Pablo Neira Ayuso
  2024-10-12 15:29 ` [PATCH conntrack 3/3] tests: conntrack: missing space before option Pablo Neira Ayuso
@ 2024-10-12 19:57 ` Jeremy Sowden
  2 siblings, 0 replies; 4+ messages in thread
From: Jeremy Sowden @ 2024-10-12 19:57 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel

[-- Attachment #1: Type: text/plain, Size: 2563 bytes --]

On 2024-10-12, at 17:29:55 +0200, Pablo Neira Ayuso wrote:
> strtoul() is called with no error checking at all, add a helper
> function to validate input is correct.
> 
> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
> ---
>  src/conntrack.c | 34 ++++++++++++++++++++++++++++------
>  1 file changed, 28 insertions(+), 6 deletions(-)
> 
> diff --git a/src/conntrack.c b/src/conntrack.c
> index 9fa49869b553..f3725eefd5de 100644
> --- a/src/conntrack.c
> +++ b/src/conntrack.c
> @@ -1213,6 +1213,25 @@ parse_parameter_mask(const char *arg, unsigned int *status, unsigned int *mask,
>  		exit_error(PARAMETER_PROBLEM, "Bad parameter `%s'", arg);
>  }
>  
> +static int parse_value(const char *str, uint32_t *ret, uint64_t max)
> +{
> +	char *endptr;
> +	uint64_t val;
> +
> +	errno = 0;
> +	val = strtoul(str, &endptr, 0);
> +	if (endptr == str ||
> +	    *endptr != '\0' ||
> +	    (val == ULONG_MAX && errno == ERANGE) ||
> +	    (val == 0 && errno == ERANGE) ||
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

TTBOMK, this won't happen.

> +	    val > max)

Given that `*ret` is a `uint32_t`, would it make sense also to check
that `max <= UINT32_MAX`?

> +		return -1;
> +
> +	*ret = val;

> +
> +	return 0;
> +}
> +
>  static void
>  parse_u32_mask(const char *arg, struct u32_mask *m)
>  {
> @@ -2918,6 +2937,7 @@ static void do_parse(struct ct_cmd *ct_cmd, int argc, char *argv[])
>  	struct ct_tmpl *tmpl;
>  	int res = 0, partial;
>  	union ct_address ad;
> +	uint32_t value;
>  	int c, cmd;
>  
>  	/* we release these objects in the exit_error() path. */
> @@ -3078,17 +3098,19 @@ static void do_parse(struct ct_cmd *ct_cmd, int argc, char *argv[])
>  		case 'w':
>  		case '(':
>  		case ')':
> +			if (parse_value(optarg, &value, UINT16_MAX) < 0)
> +				exit_error(OTHER_PROBLEM, "unexpected value '%s' with -%c option", optarg, c);
> +
>  			options |= opt2type[c];
> -			nfct_set_attr_u16(tmpl->ct,
> -					  opt2attr[c],
> -					  strtoul(optarg, NULL, 0));
> +			nfct_set_attr_u16(tmpl->ct, opt2attr[c], value);
>  			break;
>  		case 'i':
>  		case 'c':
> +			if (parse_value(optarg, &value, UINT32_MAX) < 0)
> +				exit_error(OTHER_PROBLEM, "unexpected value '%s' with -%c option", optarg, c);
> +
>  			options |= opt2type[c];
> -			nfct_set_attr_u32(tmpl->ct,
> -					  opt2attr[c],
> -					  strtoul(optarg, NULL, 0));
> +			nfct_set_attr_u32(tmpl->ct, opt2attr[c], value);
>  			break;
>  		case 'm':
>  			options |= opt2type[c];
> -- 
> 2.30.2
> 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2024-10-12 20:29 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-12 15:29 [PATCH conntrack 1/3] conntrack: improve --secmark,--id,--zone parser Pablo Neira Ayuso
2024-10-12 15:29 ` [PATCH conntrack 2/3] conntrack: improve --mark parser Pablo Neira Ayuso
2024-10-12 15:29 ` [PATCH conntrack 3/3] tests: conntrack: missing space before option Pablo Neira Ayuso
2024-10-12 19:57 ` [PATCH conntrack 1/3] conntrack: improve --secmark,--id,--zone parser Jeremy Sowden

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).