summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2026-04-25 15:00:50 +0200
committerFlorian Westphal <fw@strlen.de>2026-05-24 22:55:37 +0200
commitec1806a730a1c0b3d68a7f9afe81514fb0dd7991 (patch)
treefeb60a3f214d1648ae4bcfded55651fc594a84b0
parentc0aa5f13826dcb035bec3d6b252e6b2020fa5f88 (diff)
downloadlinux-next-ec1806a730a1c0b3d68a7f9afe81514fb0dd7991.tar.gz
linux-next-ec1806a730a1c0b3d68a7f9afe81514fb0dd7991.zip
netfilter: x_tables: disable 32bit compat interface in user namespaces
This feature is required to use 32bit arp/ip/ip6/ebtables binaries on 64bit kernels. I don't think there are many users left. Support has been a compile-time option since 2021 and defaults to off since 2023. The XTABLES_COMPAT config option is already off in many distributions including Debian and Fedora. Give a few more months before complete removal but disable support in user namespaces already. Assisted-by: Claude:claude-sonnet-4-6 Signed-off-by: Florian Westphal <fw@strlen.de>
-rw-r--r--include/linux/netfilter/x_tables.h17
-rw-r--r--net/bridge/netfilter/ebtables.c4
-rw-r--r--net/ipv4/netfilter/arp_tables.c4
-rw-r--r--net/ipv4/netfilter/ip_tables.c4
-rw-r--r--net/ipv6/netfilter/ip6_tables.c4
5 files changed, 33 insertions, 0 deletions
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index 5a1c5c336fa4..20d70dddbe50 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -534,4 +534,21 @@ int xt_compat_check_entry_offsets(const void *base, const char *elems,
unsigned int next_offset);
#endif /* CONFIG_NETFILTER_XTABLES_COMPAT */
+
+static inline bool xt_compat_check(void)
+{
+#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
+ if (!in_compat_syscall())
+ return true;
+
+ pr_warn_once("%s %s\n",
+ "xtables 32bit compat interface no longer supported",
+ "in namespaces and will be removed soon.");
+
+ if (!capable(CAP_NET_ADMIN))
+ return false;
+#endif
+ return true;
+}
+
#endif /* _X_TABLES_H */
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index b9f4daac09af..8d8f1a7c9ad5 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -2455,6 +2455,8 @@ static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
return -EPERM;
+ if (!xt_compat_check())
+ return -EPERM;
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
/* try real handler in case userland supplied needed padding */
@@ -2520,6 +2522,8 @@ static int do_ebt_set_ctl(struct sock *sk, int cmd, sockptr_t arg,
if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
return -EPERM;
+ if (!xt_compat_check())
+ return -EPERM;
switch (cmd) {
case EBT_SO_SET_ENTRIES:
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index ad2259678c78..341ae049e5a2 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -1430,6 +1430,8 @@ static int do_arpt_set_ctl(struct sock *sk, int cmd, sockptr_t arg,
if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
return -EPERM;
+ if (!xt_compat_check())
+ return -EPERM;
switch (cmd) {
case ARPT_SO_SET_REPLACE:
@@ -1458,6 +1460,8 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len
if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
return -EPERM;
+ if (!xt_compat_check())
+ return -EPERM;
switch (cmd) {
case ARPT_SO_GET_INFO:
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 5cbdb0815857..f917a9004a01 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -1624,6 +1624,8 @@ do_ipt_set_ctl(struct sock *sk, int cmd, sockptr_t arg, unsigned int len)
if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
return -EPERM;
+ if (!xt_compat_check())
+ return -EPERM;
switch (cmd) {
case IPT_SO_SET_REPLACE:
@@ -1653,6 +1655,8 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
return -EPERM;
+ if (!xt_compat_check())
+ return -EPERM;
switch (cmd) {
case IPT_SO_GET_INFO:
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 9d9c3763f2f5..ecf79d05a51b 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -1633,6 +1633,8 @@ do_ip6t_set_ctl(struct sock *sk, int cmd, sockptr_t arg, unsigned int len)
if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
return -EPERM;
+ if (!xt_compat_check())
+ return -EPERM;
switch (cmd) {
case IP6T_SO_SET_REPLACE:
@@ -1662,6 +1664,8 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
return -EPERM;
+ if (!xt_compat_check())
+ return -EPERM;
switch (cmd) {
case IP6T_SO_GET_INFO: