netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [iptables PATCH] libiptc: Fix for segfault when renaming a chain
@ 2022-10-07 16:36 Phil Sutter
  0 siblings, 0 replies; only message in thread
From: Phil Sutter @ 2022-10-07 16:36 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Jesper Dangaard Brouer, Julien Castets

This is an odd bug: If the number of chains is right and one renames the
last one in the list, libiptc dereferences a NULL pointer. Add fix and
test case for it.

Fixes: 64ff47cde38e4 ("libiptc: fix chain rename bug in libiptc")
Reported-by: Julien Castets <castets.j@gmail.com>
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 .../testcases/chain/0006rename-segfault_0     | 19 +++++++++++++++++++
 libiptc/libiptc.c                             |  9 +++++++++
 2 files changed, 28 insertions(+)
 create mode 100755 iptables/tests/shell/testcases/chain/0006rename-segfault_0

diff --git a/iptables/tests/shell/testcases/chain/0006rename-segfault_0 b/iptables/tests/shell/testcases/chain/0006rename-segfault_0
new file mode 100755
index 0000000000000..c10a8006b56b4
--- /dev/null
+++ b/iptables/tests/shell/testcases/chain/0006rename-segfault_0
@@ -0,0 +1,19 @@
+#!/bin/bash
+#
+# Cover for a bug in libiptc:
+# - the chain 'node-98-tmp' is the last in the list sorted by name
+# - there are 81 chains in total, so three chain index buckets
+# - the last index bucket contains only the 'node-98-tmp' chain
+# => rename temporarily removes it from the bucket, leaving a NULL bucket
+#    behind which is dereferenced later when inserting the chain again with new
+#    name again
+
+(
+	echo "*filter"
+	for chain in node-1 node-10 node-101 node-102 node-104 node-107 node-11 node-12 node-13 node-14 node-15 node-16 node-17 node-18 node-19 node-2 node-20 node-21 node-22 node-23 node-25 node-26 node-27 node-28 node-29 node-3 node-30 node-31 node-32 node-33 node-34 node-36 node-37 node-39 node-4 node-40 node-41 node-42 node-43 node-44 node-45 node-46 node-47 node-48 node-49 node-5 node-50 node-51 node-53 node-54 node-55 node-56 node-57 node-58 node-59 node-6 node-60 node-61 node-62 node-63 node-64 node-65 node-66 node-68 node-69 node-7 node-70 node-71 node-74 node-75 node-76 node-8 node-80 node-81 node-86 node-89 node-9 node-92 node-93 node-95 node-98-tmp; do
+		echo ":$chain - [0:0]"
+	done
+	echo "COMMIT"
+) | $XT_MULTI iptables-restore
+$XT_MULTI iptables -E node-98-tmp node-98
+exit $?
diff --git a/libiptc/libiptc.c b/libiptc/libiptc.c
index ceeb017b39400..97823f935d1ee 100644
--- a/libiptc/libiptc.c
+++ b/libiptc/libiptc.c
@@ -606,6 +606,15 @@ static int iptcc_chain_index_delete_chain(struct chain_head *c, struct xtc_handl
 
 	if (index_ptr == &c->list) { /* Chain used as index ptr */
 
+		/* If this is the last chain in the list, its index bucket just
+		 * became empty. Adjust the size to avoid a NULL-pointer deref
+		 * later.
+		 */
+		if (next == &h->chains) {
+			h->chain_index_sz--;
+			return 0;
+		}
+
 		/* See if its possible to avoid a rebuild, by shifting
 		 * to next pointer.  Its possible if the next pointer
 		 * is located in the same index bucket.
-- 
2.34.1


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2022-10-07 16:36 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-07 16:36 [iptables PATCH] libiptc: Fix for segfault when renaming a chain Phil Sutter

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).