• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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