From: bestswngs@gmail.com
To: pablo@netfilter.org, fw@strlen.de
Cc: phil@nwl.cc, davem@davemloft.net, edumazet@google.com,
kuba@kernel.org, pabeni@redhat.com, horms@kernel.org,
xmei5@asu.edu, Weiming Shi <bestswngs@gmail.com>,
stable@vger.kernel.org
Subject: [PATCH nf] netfilter: xt_devgroup: reject unsupported families in checkentry
Date: Sun, 22 Mar 2026 12:18:46 +0800 [thread overview]
Message-ID: <20260322041844.983129-3-bestswngs@gmail.com> (raw)
From: Weiming Shi <bestswngs@gmail.com>
devgroup_mt_checkentry() validates hook_mask using NF_INET_* constants,
but the match is registered with NFPROTO_UNSPEC, which allows it to be
used from any protocol family through nft_compat.
On an ARP nftables output chain, nft_compat passes
hook_mask = 1 << NF_ARP_OUT. Because NF_ARP_OUT == 1 == NF_INET_LOCAL_IN,
the source-group hook validation incorrectly accepts the rule. At runtime
arp_xmit() invokes the chain with state->in == NULL, and devgroup_mt()
dereferences xt_in(par)->group, crashing the kernel:
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000044: 0000 [#1] SMP KASAN NOPTI
KASAN: null-ptr-deref in range [0x0000000000000220-0x0000000000000227]
RIP: 0010:devgroup_mt+0xff/0x350
Call Trace:
<TASK>
nft_match_eval (net/netfilter/nft_compat.c:407)
nft_do_chain (net/netfilter/nf_tables_core.c:285)
nft_do_chain_arp (net/netfilter/nft_chain_filter.c:61)
nf_hook_slow (net/netfilter/core.c:623)
arp_xmit (net/ipv4/arp.c:666)
arp_solicit (net/ipv4/arp.c:393)
neigh_probe (net/core/neighbour.c:1098)
__neigh_event_send (net/core/neighbour.c:1277)
neigh_resolve_output (net/core/neighbour.c:1604)
ip_finish_output2 (net/ipv4/ip_output.c:237)
</TASK>
Kernel panic - not syncing: Fatal exception in interrupt
Reject families whose hook numbering differs from the NF_INET_* scheme
early in checkentry. NFPROTO_INET and NFPROTO_BRIDGE share the same
five-hook layout (PRE_ROUTING ... POST_ROUTING) and the same
state->in/state->out semantics as IPv4/IPv6, so they are safe.
ARP only has three hooks (IN=0, OUT=1, FORWARD=2) with different
semantics, causing the numbering collision that triggers this bug.
The match is intentionally registered as NFPROTO_UNSPEC (it carries
MODULE_ALIAS entries for both ipt_devgroup and ip6t_devgroup), but
accepting it on ARP chains was never intended and is unsafe.
Trigger conditions:
- Required CONFIG: CONFIG_NF_TABLES=y, CONFIG_NFT_COMPAT=y,
CONFIG_NF_TABLES_ARP=y, CONFIG_NETFILTER_XT_MATCH_DEVGROUP=y
(all enabled by default on Ubuntu 24.04)
- Required privilege: CAP_NET_ADMIN (namespace-reachable via user+net
namespace on systems with unprivileged user namespaces)
- Attack vector: local, via nftables ARP output chain + xt-compat match
Fixes: 9291747f118d ("netfilter: xtables: add device group match")
Cc: stable@vger.kernel.org
Reported-by: Xiang Mei <xmei5@asu.edu>
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
---
net/netfilter/xt_devgroup.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/net/netfilter/xt_devgroup.c b/net/netfilter/xt_devgroup.c
index 9520dd00070b2..86eb07d63274e 100644
--- a/net/netfilter/xt_devgroup.c
+++ b/net/netfilter/xt_devgroup.c
@@ -37,6 +37,12 @@ static int devgroup_mt_checkentry(const struct xt_mtchk_param *par)
{
const struct xt_devgroup_info *info = par->matchinfo;
+ if (par->family != NFPROTO_IPV4 &&
+ par->family != NFPROTO_IPV6 &&
+ par->family != NFPROTO_INET &&
+ par->family != NFPROTO_BRIDGE)
+ return -EINVAL;
+
if (info->flags & ~(XT_DEVGROUP_MATCH_SRC | XT_DEVGROUP_INVERT_SRC |
XT_DEVGROUP_MATCH_DST | XT_DEVGROUP_INVERT_DST))
return -EINVAL;
--
2.43.0
next reply other threads:[~2026-03-22 4:30 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-22 4:18 bestswngs [this message]
2026-03-22 8:39 ` [PATCH nf] netfilter: xt_devgroup: reject unsupported families in checkentry Florian Westphal
2026-03-22 9:03 ` Weiming Shi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260322041844.983129-3-bestswngs@gmail.com \
--to=bestswngs@gmail.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=fw@strlen.de \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=pabeni@redhat.com \
--cc=pablo@netfilter.org \
--cc=phil@nwl.cc \
--cc=stable@vger.kernel.org \
--cc=xmei5@asu.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.