diff --git a/SOURCES/0067-segtree-Fix-segfault-when-restoring-a-huge-interval-.patch b/SOURCES/0067-segtree-Fix-segfault-when-restoring-a-huge-interval-.patch new file mode 100644 index 0000000..b5501fd --- /dev/null +++ b/SOURCES/0067-segtree-Fix-segfault-when-restoring-a-huge-interval-.patch @@ -0,0 +1,69 @@ +From 36cf5177c724540aea5a42f9dc6ef5476f86179a Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 5 Nov 2021 16:06:45 +0100 +Subject: [PATCH] segtree: Fix segfault when restoring a huge interval set + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1908127 +Upstream Status: nftables commit baecd1cf26851 + +commit baecd1cf26851a4c5b7d469206a488f14fe5b147 +Author: Phil Sutter +Date: Wed Jun 9 15:49:52 2021 +0200 + + segtree: Fix segfault when restoring a huge interval set + + Restoring a set of IPv4 prefixes with about 1.1M elements crashes nft as + set_to_segtree() exhausts the stack. Prevent this by allocating the + pointer array on heap and make sure it is freed before returning to + caller. + + With this patch in place, restoring said set succeeds with allocation of + about 3GB of memory, according to valgrind. + + Signed-off-by: Phil Sutter +--- + src/segtree.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/src/segtree.c b/src/segtree.c +index d6e3ce2..b852961 100644 +--- a/src/segtree.c ++++ b/src/segtree.c +@@ -414,10 +414,10 @@ static int set_to_segtree(struct list_head *msgs, struct set *set, + struct expr *init, struct seg_tree *tree, + bool add, bool merge) + { +- struct elementary_interval *intervals[init->size]; ++ struct elementary_interval **intervals; + struct expr *i, *next; + unsigned int n; +- int err; ++ int err = 0; + + /* We are updating an existing set with new elements, check if the new + * interval overlaps with any of the existing ones. +@@ -428,6 +428,7 @@ static int set_to_segtree(struct list_head *msgs, struct set *set, + return err; + } + ++ intervals = xmalloc_array(init->size, sizeof(intervals[0])); + n = expr_to_intervals(init, tree->keylen, intervals); + + list_for_each_entry_safe(i, next, &init->expressions, list) { +@@ -446,10 +447,11 @@ static int set_to_segtree(struct list_head *msgs, struct set *set, + for (n = 0; n < init->size; n++) { + err = ei_insert(msgs, tree, intervals[n], merge); + if (err < 0) +- return err; ++ break; + } + +- return 0; ++ xfree(intervals); ++ return err; + } + + static bool segtree_needs_first_segment(const struct set *set, +-- +2.31.1 + diff --git a/SOURCES/0068-tests-cover-baecd1cf2685-segtree-Fix-segfault-when-r.patch b/SOURCES/0068-tests-cover-baecd1cf2685-segtree-Fix-segfault-when-r.patch new file mode 100644 index 0000000..b909cfe --- /dev/null +++ b/SOURCES/0068-tests-cover-baecd1cf2685-segtree-Fix-segfault-when-r.patch @@ -0,0 +1,74 @@ +From cc6c59e683c503b461b4a80526f4bc9cbb0660bf Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 5 Nov 2021 16:06:45 +0100 +Subject: [PATCH] tests: cover baecd1cf2685 ("segtree: Fix segfault when + restoring a huge interval set") +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1908127 +Upstream Status: nftables commit d8ccad2a2b73c + +commit d8ccad2a2b73c4189934eb5fd0e3d096699b5043 +Author: Štěpán Němec +Date: Wed Oct 20 14:42:20 2021 +0200 + + tests: cover baecd1cf2685 ("segtree: Fix segfault when restoring a huge interval set") + + Test inspired by [1] with both the set and stack size reduced by the + same power of 2, to preserve the (pre-baecd1cf2685) segfault on one + hand, and make the test successfully complete (post-baecd1cf2685) in a + few seconds even on weaker hardware on the other. + + (The reason I stopped at 128kB stack size is that with 64kB I was + getting segfaults even with baecd1cf2685 applied.) + + [1] https://bugzilla.redhat.com/show_bug.cgi?id=1908127 + + Signed-off-by: Štěpán Němec + Helped-by: Phil Sutter + Signed-off-by: Phil Sutter +--- + .../sets/0068interval_stack_overflow_0 | 29 +++++++++++++++++++ + 1 file changed, 29 insertions(+) + create mode 100755 tests/shell/testcases/sets/0068interval_stack_overflow_0 + +diff --git a/tests/shell/testcases/sets/0068interval_stack_overflow_0 b/tests/shell/testcases/sets/0068interval_stack_overflow_0 +new file mode 100755 +index 0000000..134282d +--- /dev/null ++++ b/tests/shell/testcases/sets/0068interval_stack_overflow_0 +@@ -0,0 +1,29 @@ ++#!/bin/bash ++ ++set -e ++ ++ruleset_file=$(mktemp) ++ ++trap 'rm -f "$ruleset_file"' EXIT ++ ++{ ++ echo 'define big_set = {' ++ for ((i = 1; i < 255; i++)); do ++ for ((j = 1; j < 80; j++)); do ++ echo "10.0.$i.$j," ++ done ++ done ++ echo '10.1.0.0/24 }' ++} >"$ruleset_file" ++ ++cat >>"$ruleset_file" <<\EOF ++table inet test68_table { ++ set test68_set { ++ type ipv4_addr ++ flags interval ++ elements = { $big_set } ++ } ++} ++EOF ++ ++( ulimit -s 128 && "$NFT" -f "$ruleset_file" ) +-- +2.31.1 + diff --git a/SPECS/nftables.spec b/SPECS/nftables.spec index c140eeb..1f66bd6 100644 --- a/SPECS/nftables.spec +++ b/SPECS/nftables.spec @@ -1,5 +1,5 @@ %define rpmversion 0.9.3 -%define specrelease 22 +%define specrelease 23 Name: nftables Version: %{rpmversion} @@ -83,6 +83,8 @@ Patch63: 0063-parser_json-Fix-error-reporting-for-invalid-syntax.patc Patch64: 0064-parser_bison-Fix-for-implicit-declaration-of-isalnum.patch Patch65: 0065-parser_json-Fix-for-memleak-in-tcp-option-error-path.patch Patch66: 0066-json-Drop-pointless-assignment-in-exthdr_expr_json.patch +Patch67: 0067-segtree-Fix-segfault-when-restoring-a-huge-interval-.patch +Patch68: 0068-tests-cover-baecd1cf2685-segtree-Fix-segfault-when-r.patch BuildRequires: autogen BuildRequires: autoconf @@ -199,6 +201,10 @@ touch -r %{SOURCE2} $RPM_BUILD_ROOT/%{python3_sitelib}/nftables/nftables.py %{python3_sitelib}/nftables/ %changelog +* Fri Nov 05 2021 Phil Sutter [0.9.3-23.el8] +- tests: cover baecd1cf2685 ("segtree: Fix segfault when restoring a huge interval set") (Phil Sutter) [1908127] +- segtree: Fix segfault when restoring a huge interval set (Phil Sutter) [1908127] + * Wed Oct 06 2021 Phil Sutter [0.9.3-22.el8] - json: Drop pointless assignment in exthdr_expr_json() (Phil Sutter) [1999059] - parser_json: Fix for memleak in tcp option error path (Phil Sutter) [1999059]