]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
nft-restore: Fix for deletion of new, referenced rule
authorPhil Sutter <phil@nwl.cc>
Tue, 28 Feb 2023 17:09:25 +0000 (18:09 +0100)
committerPhil Sutter <phil@nwl.cc>
Wed, 1 Mar 2023 19:15:45 +0000 (20:15 +0100)
Combining multiple corner-cases here:

* Insert a rule before another new one which is not the first. Triggers
  NFTNL_RULE_ID assignment of the latter.

* Delete the referenced new rule in the same batch again. Causes
  overwriting of the previously assigned RULE_ID.

Consequently, iptables-nft-restore fails during *insert*, because the
reference is dangling.

Reported-by: Eric Garver <eric@garver.life>
Fixes: 760b35b46e4cc ("nft: Fix for add and delete of same rule in single batch")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Tested-by: Eric Garver <eric@garver.life>
iptables/nft.c
iptables/tests/shell/testcases/ipt-restore/0003-restore-ordering_0

index 63468cf3b134431bbdeb690f5ed1e108563ef307..5896fd410ca78e6b0cb8bfe73a25e55c13ad37f3 100644 (file)
@@ -2343,7 +2343,8 @@ static int __nft_rule_del(struct nft_handle *h, struct nftnl_rule *r)
 
        nftnl_rule_list_del(r);
 
-       if (!nftnl_rule_get_u64(r, NFTNL_RULE_HANDLE))
+       if (!nftnl_rule_get_u64(r, NFTNL_RULE_HANDLE) &&
+           !nftnl_rule_get_u32(r, NFTNL_RULE_ID))
                nftnl_rule_set_u32(r, NFTNL_RULE_ID, ++h->rule_id);
 
        obj = batch_rule_add(h, NFT_COMPAT_RULE_DELETE, r);
index 3f1d229e915ff6ab043fd7faed17e2758b2c6591..5482b7ea17298950fcdc572d7411a1c8b105e7aa 100755 (executable)
@@ -123,3 +123,19 @@ EXPECT='-A FORWARD -m comment --comment "rule 1" -j ACCEPT
 -A FORWARD -m comment --comment "rule 3" -j ACCEPT'
 
 diff -u -Z <(echo -e "$EXPECT") <(ipt_show)
+
+# test adding, referencing and deleting the same rule in a batch
+
+$XT_MULTI iptables-restore <<EOF
+*filter
+-A FORWARD -m comment --comment "first rule" -j ACCEPT
+-A FORWARD -m comment --comment "referenced rule" -j ACCEPT
+-I FORWARD 2 -m comment --comment "referencing rule" -j ACCEPT
+-D FORWARD -m comment --comment "referenced rule" -j ACCEPT
+COMMIT
+EOF
+
+EXPECT='-A FORWARD -m comment --comment "first rule" -j ACCEPT
+-A FORWARD -m comment --comment "referencing rule" -j ACCEPT'
+
+diff -u -Z <(echo -e "$EXPECT") <(ipt_show)