ipv6: ioam: add NULL check for idev in ipv6_hop_ioam()

Reported by Sashiko:

The function ipv6_hop_ioam() accesses
__in6_dev_get(skb->dev)->cnf.ioam6_enabled without validating the returned
idev pointer. Because addrconf_ifdown() can concurrently clear dev->ip6_ptr
via RCU, __in6_dev_get() can return NULL during interface teardown, which
could cause a NULL pointer dereference when processing an IOAM Hop-by-Hop
option.

Let's add a check and use SKB_DROP_REASON_IPV6DISABLED accordingly.

Fixes: 9ee11f0fff ("ipv6: ioam: Data plane support for Pre-allocated Trace")
Cc: stable@vger.kernel.org
Signed-off-by: Justin Iurman <justin.iurman@gmail.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260517183059.29140-1-justin.iurman@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Justin Iurman 2026-05-17 20:30:59 +02:00 committed by Jakub Kicinski
parent d03e6124c7
commit d4ea0dfd75

View File

@ -910,16 +910,27 @@ static bool ipv6_hop_ra(struct sk_buff *skb, int optoff)
static bool ipv6_hop_ioam(struct sk_buff *skb, int optoff)
{
enum skb_drop_reason drop_reason;
struct ioam6_trace_hdr *trace;
struct ioam6_namespace *ns;
struct inet6_dev *idev;
struct ioam6_hdr *hdr;
drop_reason = SKB_DROP_REASON_IP_INHDR;
/* Bad alignment (must be 4n-aligned) */
if (optoff & 3)
goto drop;
/* Does the device still have IPv6 configuration? */
idev = __in6_dev_get(skb->dev);
if (!idev) {
drop_reason = SKB_DROP_REASON_IPV6DISABLED;
goto drop;
}
/* Ignore if IOAM is not enabled on ingress */
if (!READ_ONCE(__in6_dev_get(skb->dev)->cnf.ioam6_enabled))
if (!READ_ONCE(idev->cnf.ioam6_enabled))
goto ignore;
/* Truncated Option header */
@ -972,7 +983,7 @@ static bool ipv6_hop_ioam(struct sk_buff *skb, int optoff)
return true;
drop:
kfree_skb_reason(skb, SKB_DROP_REASON_IP_INHDR);
kfree_skb_reason(skb, drop_reason);
return false;
}