Skip to content

Commit 95be653

Browse files
ffmanceragregkh
authored andcommitted
netfilter: nfnetlink_osf: fix potential NULL dereference in ttl check
[ Upstream commit 711987b ] The nf_osf_ttl() function accessed skb->dev to perform a local interface address lookup without verifying that the device pointer was valid. Additionally, the implementation utilized an in_dev_for_each_ifa_rcu loop to match the packet source address against local interface addresses. It assumed that packets from the same subnet should not see a decrement on the initial TTL. A packet might appear it is from the same subnet but it actually isn't especially in modern environments with containers and virtual switching. Remove the device dereference and interface loop. Replace the logic with a switch statement that evaluates the TTL according to the ttl_check. Fixes: 11eeef4 ("netfilter: passive OS fingerprint xtables match") Reported-by: Kito Xu (veritas501) <hxzene@gmail.com> Closes: https://lore.kernel.org/netfilter-devel/20260414074556.2512750-1-hxzene@gmail.com/ Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 70a3f31 commit 95be653

1 file changed

Lines changed: 7 additions & 15 deletions

File tree

net/netfilter/nfnetlink_osf.c

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,26 +31,18 @@ EXPORT_SYMBOL_GPL(nf_osf_fingers);
3131
static inline int nf_osf_ttl(const struct sk_buff *skb,
3232
int ttl_check, unsigned char f_ttl)
3333
{
34-
struct in_device *in_dev = __in_dev_get_rcu(skb->dev);
3534
const struct iphdr *ip = ip_hdr(skb);
36-
const struct in_ifaddr *ifa;
37-
int ret = 0;
3835

39-
if (ttl_check == NF_OSF_TTL_TRUE)
36+
switch (ttl_check) {
37+
case NF_OSF_TTL_TRUE:
4038
return ip->ttl == f_ttl;
41-
if (ttl_check == NF_OSF_TTL_NOCHECK)
42-
return 1;
43-
else if (ip->ttl <= f_ttl)
39+
break;
40+
case NF_OSF_TTL_NOCHECK:
4441
return 1;
45-
46-
in_dev_for_each_ifa_rcu(ifa, in_dev) {
47-
if (inet_ifa_match(ip->saddr, ifa)) {
48-
ret = (ip->ttl == f_ttl);
49-
break;
50-
}
42+
case NF_OSF_TTL_LESS:
43+
default:
44+
return ip->ttl <= f_ttl;
5145
}
52-
53-
return ret;
5446
}
5547

5648
struct nf_osf_hdr_ctx {

0 commit comments

Comments
 (0)