From 5ea18ea8c0c99f2c71a5eaf32f4fbf6339ce8cc7 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Tue, 11 Feb 2020 16:52:59 +0100 Subject: [PATCH] xtables-restore: fix for --noflush and empty lines Lookahead buffer used for cache requirements estimate in restore --noflush separates individual lines with nul-chars. Two consecutive nul-chars are interpreted as end of buffer and remaining buffer content is skipped. Sadly, reading an empty line (i.e., one containing a newline character only) caused double nul-chars to appear in buffer as well, leading to premature stop when reading cached lines from buffer. To fix that, make use of xtables_restore_parse_line() skipping empty lines without calling strtok() and just leave the newline character in place. A more intuitive approach, namely skipping empty lines while buffering, is deliberately not chosen as that would cause wrong values in 'line' variable. Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1400 Fixes: 09cb517949e69 ("xtables-restore: Improve performance of --noflush operation") Signed-off-by: Phil Sutter Acked-by: Arturo Borrero Gonzalez (cherry picked from commit 8e76391096f12212985c401ee83a67990aa27a29) Signed-off-by: Phil Sutter --- .../ipt-restore/0011-noflush-empty-line_0 | 16 ++++++++++++++++ iptables/xtables-restore.c | 8 +++++--- 2 files changed, 21 insertions(+), 3 deletions(-) create mode 100755 iptables/tests/shell/testcases/ipt-restore/0011-noflush-empty-line_0 diff --git a/iptables/tests/shell/testcases/ipt-restore/0011-noflush-empty-line_0 b/iptables/tests/shell/testcases/ipt-restore/0011-noflush-empty-line_0 new file mode 100755 index 0000000000000..bea1a690bb624 --- /dev/null +++ b/iptables/tests/shell/testcases/ipt-restore/0011-noflush-empty-line_0 @@ -0,0 +1,16 @@ +#!/bin/bash -e + +# make sure empty lines won't break --noflush + +cat <in)) { size_t blen = strlen(buffer); - /* drop trailing newline; xtables_restore_parse_line() + /* Drop trailing newline; xtables_restore_parse_line() * uses strtok() which replaces them by nul-characters, * causing unpredictable string delimiting in - * preload_buffer */ - if (buffer[blen - 1] == '\n') + * preload_buffer. + * Unless this is an empty line which would fold into a + * spurious EoB indicator (double nul-char). */ + if (buffer[blen - 1] == '\n' && blen > 1) buffer[blen - 1] = '\0'; else blen++; -- 2.24.1