All of lore.kernel.org
 help / color / mirror / Atom feed
* [iptables PATCH 1/3] ebtables: Clone extensions before modifying them
@ 2024-11-05 20:35 Phil Sutter
  2024-11-05 20:35 ` [iptables PATCH 2/3] ebtables: Simplify ebt_add_{match,watcher} Phil Sutter
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Phil Sutter @ 2024-11-05 20:35 UTC (permalink / raw)
  To: netfilter-devel

Upon identifying an extension option, ebt_command_default() would have
the extension parse the option prior to creating a copy for attaching to
the iptables_command_state object. After copying, the (modified)
initial extension's data was cleared.

This somewhat awkward process breaks with among match which increases
match_size if needed (but never reduces it). This change is not undone,
hence leaks into following instances. This in turn is problematic with
ebtables-restore only (as multiple rules are parsed) and specifically
when deleting rules as the potentially over-sized match_size won't match
the one parsed from the kernel.

A workaround would be to make bramong_parse() realloc the match also if
new size is smaller than the old one. This patch attempts a proper fix
though, by making ebt_command_default() copy the extension first and
parsing the option into the copy afterwards.

No Fixes tag: Prior to commit 24bb57d3f52ac ("ebtables: Support for
guided option parser"), ebtables relied upon the extension's parser
return code instead of checking option_offset, so copying the extension
opportunistically wasn't feasible.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 iptables/nft-bridge.h |  8 ++++----
 iptables/xtables-eb.c | 16 ++++++++++------
 2 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/iptables/nft-bridge.h b/iptables/nft-bridge.h
index 13b077fc4fbf3..54b473ebff6b0 100644
--- a/iptables/nft-bridge.h
+++ b/iptables/nft-bridge.h
@@ -108,10 +108,10 @@ static inline const char *ebt_target_name(unsigned int verdict)
 })								\
 
 void ebt_cs_clean(struct iptables_command_state *cs);
-void ebt_add_match(struct xtables_match *m,
-			  struct iptables_command_state *cs);
-void ebt_add_watcher(struct xtables_target *watcher,
-                     struct iptables_command_state *cs);
+struct xtables_match *ebt_add_match(struct xtables_match *m,
+				    struct iptables_command_state *cs);
+struct xtables_target *ebt_add_watcher(struct xtables_target *watcher,
+				       struct iptables_command_state *cs);
 int ebt_command_default(struct iptables_command_state *cs,
 			struct xtables_globals *unused, bool ebt_invert);
 
diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c
index 658cf4b98c04d..06386cd90830c 100644
--- a/iptables/xtables-eb.c
+++ b/iptables/xtables-eb.c
@@ -367,8 +367,8 @@ static void ebt_load_match_extensions(void)
 	ebt_load_watcher("nflog");
 }
 
-void ebt_add_match(struct xtables_match *m,
-		   struct iptables_command_state *cs)
+struct xtables_match *ebt_add_match(struct xtables_match *m,
+				    struct iptables_command_state *cs)
 {
 	struct xtables_rule_match **rule_matches = &cs->matches;
 	struct xtables_match *newm;
@@ -397,10 +397,12 @@ void ebt_add_match(struct xtables_match *m,
 	for (matchp = &cs->match_list; *matchp; matchp = &(*matchp)->next)
 		;
 	*matchp = newnode;
+
+	return newm;
 }
 
-void ebt_add_watcher(struct xtables_target *watcher,
-		     struct iptables_command_state *cs)
+struct xtables_target *ebt_add_watcher(struct xtables_target *watcher,
+				       struct iptables_command_state *cs)
 {
 	struct ebt_match *newnode, **matchp;
 	struct xtables_target *clone;
@@ -425,6 +427,8 @@ void ebt_add_watcher(struct xtables_target *watcher,
 	for (matchp = &cs->match_list; *matchp; matchp = &(*matchp)->next)
 		;
 	*matchp = newnode;
+
+	return clone;
 }
 
 int ebt_command_default(struct iptables_command_state *cs,
@@ -476,8 +480,8 @@ int ebt_command_default(struct iptables_command_state *cs,
 		if (cs->c < m->option_offset ||
 		    cs->c >= m->option_offset + XT_OPTION_OFFSET_SCALE)
 			continue;
+		m = ebt_add_match(m, cs);
 		xtables_option_mpcall(cs->c, cs->argv, ebt_invert, m, &cs->eb);
-		ebt_add_match(m, cs);
 		return 0;
 	}
 
@@ -491,8 +495,8 @@ int ebt_command_default(struct iptables_command_state *cs,
 		if (cs->c < t->option_offset ||
 		    cs->c >= t->option_offset + XT_OPTION_OFFSET_SCALE)
 			continue;
+		t = ebt_add_watcher(t, cs);
 		xtables_option_tpcall(cs->c, cs->argv, ebt_invert, t, &cs->eb);
-		ebt_add_watcher(t, cs);
 		return 0;
 	}
 	if (cs->c == ':')
-- 
2.47.0


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

* [iptables PATCH 2/3] ebtables: Simplify ebt_add_{match,watcher}
  2024-11-05 20:35 [iptables PATCH 1/3] ebtables: Clone extensions before modifying them Phil Sutter
@ 2024-11-05 20:35 ` Phil Sutter
  2024-11-05 20:35 ` [iptables PATCH 3/3] tests: shell: Test ebtables-restore deleting among matches Phil Sutter
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Phil Sutter @ 2024-11-05 20:35 UTC (permalink / raw)
  To: netfilter-devel

Now that extension options are parsed after these functions return, no
modifications need to be carried over to the clone and undone in the
original.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 iptables/xtables-eb.c | 20 +++++---------------
 1 file changed, 5 insertions(+), 15 deletions(-)

diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c
index 06386cd90830c..86c33b4e7dcb6 100644
--- a/iptables/xtables-eb.c
+++ b/iptables/xtables-eb.c
@@ -371,23 +371,17 @@ struct xtables_match *ebt_add_match(struct xtables_match *m,
 				    struct iptables_command_state *cs)
 {
 	struct xtables_rule_match **rule_matches = &cs->matches;
-	struct xtables_match *newm;
 	struct ebt_match *newnode, **matchp;
-	struct xt_entry_match *m2;
+	struct xtables_match *newm;
 
 	newm = xtables_find_match(m->name, XTF_LOAD_MUST_SUCCEED, rule_matches);
 	if (newm == NULL)
 		xtables_error(OTHER_PROBLEM,
 			      "Unable to add match %s", m->name);
 
-	m2 = xtables_calloc(1, newm->m->u.match_size);
-	memcpy(m2, newm->m, newm->m->u.match_size);
-	memset(newm->m->data, 0, newm->size);
+	newm->m = xtables_calloc(1, m->m->u.match_size);
+	memcpy(newm->m, m->m, m->m->u.match_size);
 	xs_init_match(newm);
-	newm->m = m2;
-
-	newm->mflags = m->mflags;
-	m->mflags = 0;
 
 	/* glue code for watchers */
 	newnode = xtables_calloc(1, sizeof(struct ebt_match));
@@ -409,17 +403,13 @@ struct xtables_target *ebt_add_watcher(struct xtables_target *watcher,
 
 	clone = xtables_malloc(sizeof(struct xtables_target));
 	memcpy(clone, watcher, sizeof(struct xtables_target));
-	clone->udata = NULL;
-	clone->tflags = watcher->tflags;
 	clone->next = clone;
+	clone->udata = NULL;
+	xs_init_target(clone);
 
 	clone->t = xtables_calloc(1, watcher->t->u.target_size);
 	memcpy(clone->t, watcher->t, watcher->t->u.target_size);
 
-	memset(watcher->t->data, 0, watcher->size);
-	xs_init_target(watcher);
-	watcher->tflags = 0;
-
 
 	newnode = xtables_calloc(1, sizeof(struct ebt_match));
 	newnode->u.watcher = clone;
-- 
2.47.0


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

* [iptables PATCH 3/3] tests: shell: Test ebtables-restore deleting among matches
  2024-11-05 20:35 [iptables PATCH 1/3] ebtables: Clone extensions before modifying them Phil Sutter
  2024-11-05 20:35 ` [iptables PATCH 2/3] ebtables: Simplify ebt_add_{match,watcher} Phil Sutter
@ 2024-11-05 20:35 ` Phil Sutter
  2024-11-05 22:03 ` [iptables PATCH 1/3] ebtables: Clone extensions before modifying them Florian Westphal
  2024-11-05 23:03 ` Phil Sutter
  3 siblings, 0 replies; 5+ messages in thread
From: Phil Sutter @ 2024-11-05 20:35 UTC (permalink / raw)
  To: netfilter-devel

Rules containing among match would spuriously fail to compare if there
was a previous rule with larger among match payload.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 .../ebtables/0012-restore-delete-among_0       | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)
 create mode 100755 iptables/tests/shell/testcases/ebtables/0012-restore-delete-among_0

diff --git a/iptables/tests/shell/testcases/ebtables/0012-restore-delete-among_0 b/iptables/tests/shell/testcases/ebtables/0012-restore-delete-among_0
new file mode 100755
index 0000000000000..165745e169f89
--- /dev/null
+++ b/iptables/tests/shell/testcases/ebtables/0012-restore-delete-among_0
@@ -0,0 +1,18 @@
+#!/bin/bash -e
+
+case "$XT_MULTI" in
+*xtables-nft-multi)
+	;;
+*)
+	echo "skip $XT_MULTI"
+	exit 0
+	;;
+esac
+
+RULESET='*filter
+-A FORWARD --among-dst de:ad:0:be:ee:ff,c0:ff:ee:0:ba:be
+-A FORWARD --among-dst de:ad:0:be:ee:ff'
+
+$XT_MULTI ebtables-restore <<< "$RULESET"
+echo "$RULESET" | sed -e 's/-A/-D/' | $XT_MULTI ebtables-restore --noflush
+
-- 
2.47.0


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

* Re: [iptables PATCH 1/3] ebtables: Clone extensions before modifying them
  2024-11-05 20:35 [iptables PATCH 1/3] ebtables: Clone extensions before modifying them Phil Sutter
  2024-11-05 20:35 ` [iptables PATCH 2/3] ebtables: Simplify ebt_add_{match,watcher} Phil Sutter
  2024-11-05 20:35 ` [iptables PATCH 3/3] tests: shell: Test ebtables-restore deleting among matches Phil Sutter
@ 2024-11-05 22:03 ` Florian Westphal
  2024-11-05 23:03 ` Phil Sutter
  3 siblings, 0 replies; 5+ messages in thread
From: Florian Westphal @ 2024-11-05 22:03 UTC (permalink / raw)
  To: Phil Sutter; +Cc: netfilter-devel

Phil Sutter <phil@nwl.cc> wrote:
> Upon identifying an extension option, ebt_command_default() would have
> the extension parse the option prior to creating a copy for attaching to
> the iptables_command_state object. After copying, the (modified)
> initial extension's data was cleared.

Patches look good to me, thanks for adding test cases.

Acked-by: Florian Westphal <fw@strlen.de>

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

* Re: [iptables PATCH 1/3] ebtables: Clone extensions before modifying them
  2024-11-05 20:35 [iptables PATCH 1/3] ebtables: Clone extensions before modifying them Phil Sutter
                   ` (2 preceding siblings ...)
  2024-11-05 22:03 ` [iptables PATCH 1/3] ebtables: Clone extensions before modifying them Florian Westphal
@ 2024-11-05 23:03 ` Phil Sutter
  3 siblings, 0 replies; 5+ messages in thread
From: Phil Sutter @ 2024-11-05 23:03 UTC (permalink / raw)
  To: netfilter-devel

On Tue, Nov 05, 2024 at 09:35:41PM +0100, Phil Sutter wrote:
> Upon identifying an extension option, ebt_command_default() would have
> the extension parse the option prior to creating a copy for attaching to
> the iptables_command_state object. After copying, the (modified)
> initial extension's data was cleared.
> 
> This somewhat awkward process breaks with among match which increases
> match_size if needed (but never reduces it). This change is not undone,
> hence leaks into following instances. This in turn is problematic with
> ebtables-restore only (as multiple rules are parsed) and specifically
> when deleting rules as the potentially over-sized match_size won't match
> the one parsed from the kernel.
> 
> A workaround would be to make bramong_parse() realloc the match also if
> new size is smaller than the old one. This patch attempts a proper fix
> though, by making ebt_command_default() copy the extension first and
> parsing the option into the copy afterwards.
> 
> No Fixes tag: Prior to commit 24bb57d3f52ac ("ebtables: Support for
> guided option parser"), ebtables relied upon the extension's parser
> return code instead of checking option_offset, so copying the extension
> opportunistically wasn't feasible.
> 
> Signed-off-by: Phil Sutter <phil@nwl.cc>

Series applied.

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

end of thread, other threads:[~2024-11-05 23:03 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-05 20:35 [iptables PATCH 1/3] ebtables: Clone extensions before modifying them Phil Sutter
2024-11-05 20:35 ` [iptables PATCH 2/3] ebtables: Simplify ebt_add_{match,watcher} Phil Sutter
2024-11-05 20:35 ` [iptables PATCH 3/3] tests: shell: Test ebtables-restore deleting among matches Phil Sutter
2024-11-05 22:03 ` [iptables PATCH 1/3] ebtables: Clone extensions before modifying them Florian Westphal
2024-11-05 23:03 ` Phil Sutter

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.