From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 344A92E92B3; Sat, 30 May 2026 16:58:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780160337; cv=none; b=OeppPO77iOXiCGMx7KagkD80n1p9eaSeSuJVbrbHov+LzebLFlgTF50aYipyH1GRE1HwdiVVzOanI11hpQDSHeP+JGStIvkVKyGwXBMyf9H7vqDPJSOuD6i8yLXx5GJqp7rpCpMO9F3NwsIaook8iRuSIBkxhqbG0meiLULECWA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780160337; c=relaxed/simple; bh=rfA9Ij/6WYEzD6QvY6d+USnA03MNoPD6XiKCoBlT7vY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=AnMF5QxryUhovY3PVqic5xrLcelcOnotuhVPrnSyQKLbc1PurLe72idi2LTh66UK3imkX+vp8sCsSXzfHuSoquf/aQdbvj724fbQDHQGGg1pk2shPgGb9r7Xmgs42wOxM+xq8IWLHBybNJxNtjgGbG3ma0iTqOBoR9Kh3CKEsUs= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=a5bYanym; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="a5bYanym" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7813D1F00893; Sat, 30 May 2026 16:58:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1780160336; bh=xQNapEYZBOI5zXFfMfnzRgJUXNCLN3pfYc4Y7iz2JOo=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=a5bYanymClobdCXmSQYAl96F2DoCAj6vzEau/fNqsa9KLwdG07vTqAU8l1cJ8FYCA 3IO0JBmSy5VuasqPJ1f4L1MdK0UWnQVk9R3QuLZErWAGvLOWcwhAIC0c9DDYa477c+ +Xj5MjtTtGGdabigJvai8D21wbF3YgLc775f6BMA= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Andrea Mayer , Simon Horman , Justin Iurman , Paolo Abeni Subject: [PATCH 6.1 277/969] net: ipv6: fix NOREF dst use in seg6 and rpl lwtunnels Date: Sat, 30 May 2026 17:56:41 +0200 Message-ID: <20260530160308.124537860@linuxfoundation.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260530160300.485627683@linuxfoundation.org> References: <20260530160300.485627683@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.1-stable review patch. If anyone has any objections, please let me know. ------------------ From: Andrea Mayer commit f9c52a6ba9780bd27e0bf4c044fd91c13c778b6e upstream. seg6_input_core() and rpl_input() call ip6_route_input() which sets a NOREF dst on the skb, then pass it to dst_cache_set_ip6() invoking dst_hold() unconditionally. On PREEMPT_RT, ksoftirqd is preemptible and a higher-priority task can release the underlying pcpu_rt between the lookup and the caching through a concurrent FIB lookup on a shared nexthop. Simplified race sequence: ksoftirqd/X higher-prio task (same CPU X) ----------- -------------------------------- seg6_input_core(,skb)/rpl_input(skb) dst_cache_get() -> miss ip6_route_input(skb) -> ip6_pol_route(,skb,flags) [RT6_LOOKUP_F_DST_NOREF in flags] -> FIB lookup resolves fib6_nh [nhid=N route] -> rt6_make_pcpu_route() [creates pcpu_rt, refcount=1] pcpu_rt->sernum = fib6_sernum [fib6_sernum=W] -> cmpxchg(fib6_nh.rt6i_pcpu, NULL, pcpu_rt) [slot was empty, store succeeds] -> skb_dst_set_noref(skb, dst) [dst is pcpu_rt, refcount still 1] rt_genid_bump_ipv6() -> bumps fib6_sernum [fib6_sernum from W to Z] ip6_route_output() -> ip6_pol_route() -> FIB lookup resolves fib6_nh [nhid=N] -> rt6_get_pcpu_route() pcpu_rt->sernum != fib6_sernum [W <> Z, stale] -> prev = xchg(rt6i_pcpu, NULL) -> dst_release(prev) [prev is pcpu_rt, refcount 1->0, dead] dst = skb_dst(skb) [dst is the dead pcpu_rt] dst_cache_set_ip6(dst) -> dst_hold() on dead dst -> WARN / use-after-free For the race to occur, ksoftirqd must be preemptible (PREEMPT_RT without PREEMPT_RT_NEEDS_BH_LOCK) and a concurrent task must be able to release the pcpu_rt. Shared nexthop objects provide such a path, as two routes pointing to the same nhid share the same fib6_nh and its rt6i_pcpu entry. Fix seg6_input_core() and rpl_input() by calling skb_dst_force() after ip6_route_input() to force the NOREF dst into a refcounted one before caching. The output path is not affected as ip6_route_output() already returns a refcounted dst. Fixes: af4a2209b134 ("ipv6: sr: use dst_cache in seg6_input") Fixes: a7a29f9c361f ("net: ipv6: add rpl sr tunnel") Cc: stable@vger.kernel.org Signed-off-by: Andrea Mayer Reviewed-by: Simon Horman Reviewed-by: Justin Iurman Link: https://patch.msgid.link/20260421094735.20997-1-andrea.mayer@uniroma2.it Signed-off-by: Paolo Abeni Signed-off-by: Greg Kroah-Hartman --- net/ipv6/rpl_iptunnel.c | 9 +++++++++ net/ipv6/seg6_iptunnel.c | 9 +++++++++ 2 files changed, 18 insertions(+) --- a/net/ipv6/rpl_iptunnel.c +++ b/net/ipv6/rpl_iptunnel.c @@ -284,7 +284,16 @@ static int rpl_input(struct sk_buff *skb if (!dst) { ip6_route_input(skb); + + /* ip6_route_input() sets a NOREF dst; force a refcount on it + * before caching or further use. + */ + skb_dst_force(skb); dst = skb_dst(skb); + if (unlikely(!dst)) { + err = -ENETUNREACH; + goto drop; + } /* cache only if we don't create a dst reference loop */ if (!dst->error && lwtst != dst->lwtstate) { --- a/net/ipv6/seg6_iptunnel.c +++ b/net/ipv6/seg6_iptunnel.c @@ -498,7 +498,16 @@ static int seg6_input_core(struct net *n if (!dst) { ip6_route_input(skb); + + /* ip6_route_input() sets a NOREF dst; force a refcount on it + * before caching or further use. + */ + skb_dst_force(skb); dst = skb_dst(skb); + if (unlikely(!dst)) { + err = -ENETUNREACH; + goto drop; + } /* cache only if we don't create a dst reference loop */ if (!dst->error && lwtst != dst->lwtstate) {