diff mbox series

[iptables,3/3] xshared: fix crash when -4/-6 follows a restore command

Message ID 20261002124916.2264622-3-phil@nwl.cc
State New
Headers show
Series [iptables,1/3] extensions: libxt_conntrack: Fix inverted ctstate translation | expand

Commit Message

Phil Sutter Oct. 2, 2026, 12:49 p.m. UTC
From: Evgeniy Gorbanyov <esgor@altlinux.org>

iptables-restore returns early on -6, and ip6tables-restore on -4, so
a rule for the other family is ignored. A command already parsed on
that line is still executed. replace_entry() then dereferences NULL
address pointers because post_parse() never ran.

Clear the command before returning so the line is dropped.

Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1864
Signed-off-by: Evgeniy Gorbanyov <esgor@altlinux.org>
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 .../0019-family-flag-after-command_0          | 29 +++++++++++++++++++
 iptables/xshared.c                            |  8 +++--
 2 files changed, 35 insertions(+), 2 deletions(-)
 create mode 100755 iptables/tests/shell/testcases/ipt-restore/0019-family-flag-after-command_0
diff mbox series

Patch

diff --git a/iptables/tests/shell/testcases/ipt-restore/0019-family-flag-after-command_0 b/iptables/tests/shell/testcases/ipt-restore/0019-family-flag-after-command_0
new file mode 100755
index 0000000000000..4e1bed1e984fe
--- /dev/null
+++ b/iptables/tests/shell/testcases/ipt-restore/0019-family-flag-after-command_0
@@ -0,0 +1,29 @@ 
+#!/bin/bash
+
+# -4/-6 during restore skips the whole line. If the flag appears after a
+# command has already been parsed, that command must be discarded.
+# Otherwise iptables-restore executes it without post_parse() and crashes
+# on NULL address pointers in replace_entry.
+
+set -e
+
+$XT_MULTI iptables-restore <<EOF
+*filter
+-A FORWARD -m comment --comment keep -j ACCEPT
+-R FORWARD 1 -6 -m comment --comment gone -j DROP
+-F FORWARD -6
+COMMIT
+EOF
+
+EXPECT='-A FORWARD -m comment --comment keep -j ACCEPT'
+diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables -S | grep -v '^-P')
+
+$XT_MULTI ip6tables-restore <<EOF
+*filter
+-A FORWARD -m comment --comment keep -j ACCEPT
+-R FORWARD 1 -4 -m comment --comment gone -j DROP
+-F FORWARD -4
+COMMIT
+EOF
+
+diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI ip6tables -S | grep -v '^-P')
diff --git a/iptables/xshared.c b/iptables/xshared.c
index 263dcc32e5eb1..bb3da97be9fd3 100644
--- a/iptables/xshared.c
+++ b/iptables/xshared.c
@@ -1903,8 +1903,10 @@  void do_parse(int argc, char *argv[],
 			if (args->family == AF_INET)
 				break;
 
-			if (p->restore && args->family == AF_INET6)
+			if (p->restore && args->family == AF_INET6) {
+				p->command = CMD_NONE;
 				return;
+			}
 
 			exit_tryhelp(2, p->line);
 
@@ -1912,8 +1914,10 @@  void do_parse(int argc, char *argv[],
 			if (args->family == AF_INET6)
 				break;
 
-			if (p->restore && args->family == AF_INET)
+			if (p->restore && args->family == AF_INET) {
+				p->command = CMD_NONE;
 				return;
+			}
 
 			exit_tryhelp(2, p->line);