]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
netfilter: x_tables: disable 32bit compat interface in user namespaces
authorFlorian Westphal <fw@strlen.de>
Sat, 25 Apr 2026 13:00:50 +0000 (15:00 +0200)
committerFlorian Westphal <fw@strlen.de>
Sun, 24 May 2026 20:55:37 +0000 (22:55 +0200)
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>
include/linux/netfilter/x_tables.h
net/bridge/netfilter/ebtables.c
net/ipv4/netfilter/arp_tables.c
net/ipv4/netfilter/ip_tables.c
net/ipv6/netfilter/ip6_tables.c

index 5a1c5c336fa4fec3d8facc4edd7031ba55419904..20d70dddbe509870a203d0fd48e887a40f0001c9 100644 (file)
@@ -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 */
index b9f4daac09af36ddddee24900e3f162190a7685b..8d8f1a7c9ad5fe41c757b08db364b47e50d5ebaf 100644 (file)
@@ -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:
index ad2259678c7854359a7c909aa82aa93763a932fc..341ae049e5a21c62c9c113a5c0d6807c2c194ebc 100644 (file)
@@ -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:
index 5cbdb0815857f402df4bb57bb9dddc327ff01841..f917a9004a01adaadf596972f1353f4d7039d55c 100644 (file)
@@ -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:
index 9d9c3763f2f5e90a3d6ed50efbaed5e5865911ae..ecf79d05a51bc082f3dbb403be8c9c318d9bb911 100644 (file)
@@ -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: