[PATCH nf 1/1] netfilter: ip6t_rt: fix zero-address non-strict match out-of-bounds read

Ren Wei <[email protected]>
Newsgroups gmane.comp.security.firewalls.netfilter.devel
Message-ID <902c0940944fc2401aafed55dbb356056ec8ecbb.1788337633.git.rakukuip@gmail.com>
From: Luxiao Xu <[email protected]>

rt_mt6_check() allows rules to be configured with rtinfo->addrnr == 0.
In the IP6T_RT_FST_NSTRICT path, rt_mt6() enters the routing-address loop
and compares each packet address with rtinfo->addrs[i] before checking
whether i has already reached addrnr.

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 can
never be met.

A crafted IPv6 packet with consecutive matching routing header addresses
can advance i up to and beyond IP6T_RT_HOPS (16). The subsequent call to
ipv6_addr_equal() accesses rtinfo->addrs[i], resulting in an out-of-bounds
read past struct ip6t_rt into adjacent xtables memory, triggering UBSAN /
KASAN warnings and kernel panics.

Additionally, this logic error causes packets to fail rule matching when
the first address matches, allowing traffic to evade firewall rules.

Fix this by properly validating rtinfo->addrnr in rt_mt6_check() /
handling zero addrnr in rt_mt6().

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: [email protected]
Reported-by: Vega <[email protected]>
Assisted-by: LLM
Signed-off-by: Luxiao Xu <[email protected]>
Signed-off-by: Ren Wei <[email protected]>
---
 net/ipv6/netfilter/ip6t_rt.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c
index 8051425213dd..cab169b5563a 100644
--- a/net/ipv6/netfilter/ip6t_rt.c
+++ b/net/ipv6/netfilter/ip6t_rt.c
@@ -162,6 +162,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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.