Skip to content

Commit 4727629

Browse files
edumazetgregkh
authored andcommitted
inet: RAW sockets using IPPROTO_RAW MUST drop incoming ICMP
[ Upstream commit c89477a ] Yizhou Zhao reported that simply having one RAW socket on protocol IPPROTO_RAW (255) was dangerous. socket(AF_INET, SOCK_RAW, 255); A malicious incoming ICMP packet can set the protocol field to 255 and match this socket, leading to FNHE cache changes. inner = IP(src="192.168.2.1", dst="8.8.8.8", proto=255)/Raw("TEST") pkt = IP(src="192.168.1.1", dst="192.168.2.1")/ICMP(type=3, code=4, nexthopmtu=576)/inner "man 7 raw" states: A protocol of IPPROTO_RAW implies enabled IP_HDRINCL and is able to send any IP protocol that is specified in the passed header. Receiving of all IP protocols via IPPROTO_RAW is not possible using raw sockets. Make sure we drop these malicious packets. Fixes: 1da177e ("Linux-2.6.12-rc2") Reported-by: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn> Link: https://lore.kernel.org/netdev/20251109134600.292125-1-zhaoyz24@mails.tsinghua.edu.cn/ Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: David Ahern <dsahern@kernel.org> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20260203192509.682208-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> [ in 6.1.y kernel icmpv6_notify returns void, not skb_drop_reason ] Signed-off-by: Juhandré Knoetze <juhandre.knoetze@windriver.com> Signed-off-by: Dmitriy Korovkin <dmitriy.korovkin@windriver.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 9b7d66e commit 4727629

2 files changed

Lines changed: 13 additions & 4 deletions

File tree

net/ipv4/icmp.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -868,16 +868,22 @@ static void icmp_socket_deliver(struct sk_buff *skb, u32 info)
868868
/* Checkin full IP header plus 8 bytes of protocol to
869869
* avoid additional coding at protocol handlers.
870870
*/
871-
if (!pskb_may_pull(skb, iph->ihl * 4 + 8)) {
872-
__ICMP_INC_STATS(dev_net_rcu(skb->dev), ICMP_MIB_INERRORS);
873-
return;
874-
}
871+
if (!pskb_may_pull(skb, iph->ihl * 4 + 8))
872+
goto out;
873+
874+
/* IPPROTO_RAW sockets are not supposed to receive anything. */
875+
if (protocol == IPPROTO_RAW)
876+
goto out;
875877

876878
raw_icmp_error(skb, protocol, info);
877879

878880
ipprot = rcu_dereference(inet_protos[protocol]);
879881
if (ipprot && ipprot->err_handler)
880882
ipprot->err_handler(skb, info);
883+
return;
884+
885+
out:
886+
__ICMP_INC_STATS(dev_net_rcu(skb->dev), ICMP_MIB_INERRORS);
881887
}
882888

883889
static bool icmp_tag_validation(int proto)

net/ipv6/icmp.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -861,6 +861,9 @@ void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info)
861861
if (!pskb_may_pull(skb, inner_offset+8))
862862
goto out;
863863

864+
if (nexthdr == IPPROTO_RAW)
865+
goto out;
866+
864867
/* BUGGG_FUTURE: we should try to parse exthdrs in this packet.
865868
Without this we will not able f.e. to make source routed
866869
pmtu discovery.

0 commit comments

Comments
 (0)