From d4ae89c676373bec9e922eb3ade04128624615e0 Mon Sep 17 00:00:00 2001 From: Kyle Zeng Date: Thu, 7 Sep 2023 18:19:00 -0700 Subject: [PATCH] fix null-deref in ipv4_link_failure Currently, we assume the skb is associated with a device before calling __ip_options_compile, which is not always the case if it is re-routed by ipvs. When skb->dev is NULL, dev_net(skb->dev) will become null-dereference. This patch adds a check for the edge case and switch to use the net_device from the rtable when skb->dev is NULL. Suggested-by: Paolo Abeni Suggested-by: David Ahern Signed-off-by: Kyle Zeng Cc: Stephen Suryaputra --- net/ipv4/route.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index d8c99bdc617..1be34e5eea1 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1214,6 +1214,7 @@ EXPORT_INDIRECT_CALLABLE(ipv4_dst_check); static void ipv4_send_dest_unreach(struct sk_buff *skb) { struct ip_options opt; + struct net_device *dev; int res; /* Recompile ip options since IPCB may not be valid anymore. @@ -1230,7 +1231,8 @@ static void ipv4_send_dest_unreach(struct sk_buff *skb) opt.optlen = ip_hdr(skb)->ihl * 4 - sizeof(struct iphdr); rcu_read_lock(); - res = __ip_options_compile(dev_net(skb->dev), &opt, skb, NULL); + dev = skb->dev ? skb->dev : skb_rtable(skb)->dst.dev; + res = __ip_options_compile(dev_net(dev), &opt, skb, NULL); rcu_read_unlock(); if (res) -- 2.34.1