* [PATCH nf v2 0/1] netfilter: ip6t_rt: fix zero-address non-strict match out-of-bounds read
@ 2026-09-06 13:29 Ren Wei
2026-09-06 13:29 ` [PATCH nf v2 1/1] " Ren Wei
0 siblings, 1 reply; 2+ messages in thread
From: Ren Wei @ 2026-09-06 13:29 UTC (permalink / raw)
To: netfilter-devel, fw; +Cc: pablo, phil, vega, rakukuip, weir
From: Luxiao Xu <rakukuip@gmail.com>
Hi Florian, netfilter maintainers,
This patch fixes an out-of-bounds read in net/ipv6/netfilter/ip6t_rt.c
reachable by unprivileged users with CAP_NET_ADMIN in user/net namespaces
when configuring non-strict routing match rules with addrnr == 0.
v1 -> v2:
- Move the loop termination check (i < rtinfo->addrnr) into the for-loop
header condition in rt_mt6() and remove the backwards break check at
the bottom of the loop body (suggested by Florian Westphal).
- v1 Link: https://lore.kernel.org/all/cover.1788337633.git.rakukuip@gmail.com/
Thanks,
Ren Wei
Luxiao Xu
Luxiao Xu (1):
netfilter: ip6t_rt: fix zero-address non-strict match out-of-bounds
read
net/ipv6/netfilter/ip6t_rt.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 2+ messages in thread
* [PATCH nf v2 1/1] netfilter: ip6t_rt: fix zero-address non-strict match out-of-bounds read
2026-09-06 13:29 [PATCH nf v2 0/1] netfilter: ip6t_rt: fix zero-address non-strict match out-of-bounds read Ren Wei
@ 2026-09-06 13:29 ` Ren Wei
0 siblings, 0 replies; 2+ messages in thread
From: Ren Wei @ 2026-09-06 13:29 UTC (permalink / raw)
To: netfilter-devel, fw; +Cc: pablo, phil, vega, rakukuip, weir
From: Luxiao Xu <rakukuip@gmail.com>
rt_mt6_check() permits rules to be configured with rtinfo->addrnr == 0
even when address matching (IP6T_RT_FST_MASK) is requested.
In the IP6T_RT_FST_NSTRICT path, rt_mt6() evaluates packet routing
addresses against rtinfo->addrs[i] and terminates backwards at the bottom
of the loop:
if (ipv6_addr_equal(ap, &rtinfo->addrs[i])) {
i++;
}
if (i == rtinfo->addrnr)
break;
When addrnr is 0, if the first packet address matches rtinfo->addrs[0],
i is incremented to 1. Because i is now strictly greater than addrnr (0),
the loop termination condition (i == rtinfo->addrnr) is bypassed and will
never be satisfied.
If a crafted IPv6 packet contains matching routing addresses, i will
advance past IP6T_RT_HOPS (16). The subsequent call to ipv6_addr_equal()
reads beyond struct ip6t_rt, triggering UBSAN/KASAN out-of-bounds warnings
or kernel panics.
Fix this by:
1. Rejecting rules in rt_mt6_check() where IP6T_RT_FST_MASK is set but
rtinfo->addrnr is zero.
2. In rt_mt6(), moving the termination condition (i < rtinfo->addrnr)
into the for-loop header condition and removing the backwards break
at the end of the loop body.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Suggested-by: Florian Westphal <fw@strlen.de>
Assisted-by: LLM
Signed-off-by: Luxiao Xu <rakukuip@gmail.com>
Signed-off-by: Ren Wei <weir@nebusec.ai>
---
v1 -> v2:
- In rt_mt6(), check i < rtinfo->addrnr in the for-loop header and
drop the backwards loop termination break at the end of the loop
body (Florian Westphal).
- v1 Link: https://lore.kernel.org/all/cover.1788337633.git.rakukuip@gmail.com/
---
net/ipv6/netfilter/ip6t_rt.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c
index 8051425213dd..9880faf3cc7d 100644
--- a/net/ipv6/netfilter/ip6t_rt.c
+++ b/net/ipv6/netfilter/ip6t_rt.c
@@ -96,7 +96,8 @@ static bool rt_mt6(const struct sk_buff *skb, struct xt_action_param *par)
unsigned int i = 0;
for (temp = 0;
- temp < (unsigned int)((hdrlen - 8) / 16);
+ temp < (unsigned int)((hdrlen - 8) / 16) &&
+ i < rtinfo->addrnr;
temp++) {
ap = skb_header_pointer(skb,
ptr
@@ -112,8 +113,6 @@ static bool rt_mt6(const struct sk_buff *skb, struct xt_action_param *par)
if (ipv6_addr_equal(ap, &rtinfo->addrs[i]))
i++;
- if (i == rtinfo->addrnr)
- break;
}
if (i == rtinfo->addrnr)
return ret;
@@ -162,6 +161,12 @@ static int rt_mt6_check(const struct xt_mtchk_param *par)
pr_info_ratelimited("too many addresses specified\n");
return -EINVAL;
}
+
+ if ((rtinfo->flags & IP6T_RT_FST_MASK) && !rtinfo->addrnr) {
+ pr_info_ratelimited("address list match requested but addrnr is 0\n");
+ return -EINVAL;
+ }
+
if ((rtinfo->flags & (IP6T_RT_RES | IP6T_RT_FST_MASK)) &&
(!(rtinfo->flags & IP6T_RT_TYP) ||
(rtinfo->rt_type != 0) ||
--
2.43.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-09-06 13:30 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-06 13:29 [PATCH nf v2 0/1] netfilter: ip6t_rt: fix zero-address non-strict match out-of-bounds read Ren Wei
2026-09-06 13:29 ` [PATCH nf v2 1/1] " Ren Wei
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.