1From 26ecdf53960658771c0fc582f72a4025e2887f75 Mon Sep 17 00:00:00 2001 2From: Phil Sutter <phil@nwl.cc> 3Date: Tue, 18 Jan 2022 22:39:08 +0100 4Subject: xshared: Fix response to unprivileged users 5 6Expected behaviour in both variants is: 7 8* Print help without error, append extension help if -m and/or -j 9 options are present 10* Indicate lack of permissions in an error message for anything else 11 12With iptables-nft, this was broken basically from day 1. Shared use of 13do_parse() then somewhat broke legacy: it started complaining about 14inability to create a lock file. 15 16Fix this by making iptables-nft assume extension revision 0 is present 17if permissions don't allow to verify. This is consistent with legacy. 18 19Second part is to exit directly after printing help - this avoids having 20to make the following code "nop-aware" to prevent privileged actions. 21 22Conflict: NA 23Reference: 24https://git.netfilter.org/iptables/commit/?id=26ecdf53960658771c0fc582f72a4025e2887f75 25Signed-off-by: Phil Sutter <phil@nwl.cc> 26Reviewed-by: Florian Westphal <fw@strlen.de> 27--- 28 iptables/nft.c | 5 ++ 29 .../testcases/iptables/0008-unprivileged_0 | 59 +++++++++++++++++++ 30 iptables/xtables.c | 2 +- 31 3 files changed, 65 insertions(+), 1 deletion(-) 32 create mode 100644 iptables/tests/shell/testcases/iptables/0008-unprivileged_0 33 34diff --git a/iptables/nft.c b/iptables/nft.c 35index bde4ca7..c9a4940 100644 36--- a/iptables/nft.c 37+++ b/iptables/nft.c 38@@ -3245,6 +3245,11 @@ int nft_compatible_revision(const char *name, uint8_t rev, int opt) 39 err: 40 mnl_socket_close(nl); 41 42+ /* pretend revision 0 is valid if not permitted to check - 43+ * this is required for printing extension help texts as user */ 44+ if (ret < 0 && errno == EPERM && rev == 0) 45+ return 1; 46+ 47 return ret < 0 ? 0 : 1; 48 } 49 50diff --git a/iptables/tests/shell/testcases/iptables/0008-unprivileged_0 b/iptables/tests/shell/testcases/iptables/0008-unprivileged_0 51new file mode 100644 52index 0000000..0914c88 53--- /dev/null 54+++ b/iptables/tests/shell/testcases/iptables/0008-unprivileged_0 55@@ -0,0 +1,59 @@ 56+#!/bin/bash 57+# iptables may print match/target specific help texts 58+# help output should work for unprivileged users 59+ 60+run() { 61+ echo "running: $*" >&2 62+ runuser -u nobody -- "$@" 63+} 64+ 65+grep_or_rc() { 66+ declare -g rc 67+ grep -q "$*" && return 0 68+ echo "missing in output: $*" >&2 69+ return 1 70+} 71+ 72+out=$(run $XT_MULTI iptables --help) 73+let "rc+=$?" 74+grep_or_rc "iptables -h (print this help information)" <<< "$out" 75+let "rc+=$?" 76+ 77+out=$(run $XT_MULTI iptables -m limit --help) 78+let "rc+=$?" 79+grep_or_rc "limit match options:" <<< "$out" 80+let "rc+=$?" 81+ 82+out=$(run $XT_MULTI iptables -p tcp --help) 83+let "rc+=$?" 84+grep_or_rc "tcp match options:" <<< "$out" 85+let "rc+=$?" 86+ 87+out=$(run $XT_MULTI iptables -j DNAT --help) 88+let "rc+=$?" 89+grep_or_rc "DNAT target options:" <<< "$out" 90+let "rc+=$?" 91+ 92+out=$(run $XT_MULTI iptables -p tcp -j DNAT --help) 93+let "rc+=$?" 94+grep_or_rc "tcp match options:" <<< "$out" 95+let "rc+=$?" 96+out=$(run $XT_MULTI iptables -p tcp -j DNAT --help) 97+let "rc+=$?" 98+grep_or_rc "DNAT target options:" <<< "$out" 99+let "rc+=$?" 100+ 101+ 102+run $XT_MULTI iptables -L 2>&1 | \ 103+ grep_or_rc "Permission denied" 104+let "rc+=$?" 105+ 106+run $XT_MULTI iptables -A FORWARD -p tcp --dport 123 2>&1 | \ 107+ grep_or_rc "Permission denied" 108+let "rc+=$?" 109+ 110+run $XT_MULTI iptables -A FORWARD -j DNAT --to-destination 1.2.3.4 2>&1 | \ 111+ grep_or_rc "Permission denied" 112+let "rc+=$?" 113+ 114+exit $rc 115diff --git a/iptables/xtables.c b/iptables/xtables.c 116index 9779bd8..a16bba7 100644 117--- a/iptables/xtables.c 118+++ b/iptables/xtables.c 119@@ -645,7 +645,7 @@ void do_parse(struct nft_handle *h, int argc, char *argv[], 120 121 printhelp(cs->matches); 122 p->command = CMD_NONE; 123- return; 124+ exit(0); 125 126 /* 127 * Option selection 128-- 1292.23.0 130 131