From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 A1C9726CE04; Thu, 15 Jan 2026 17:37:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768498673; cv=none; b=Ik4nOW3EA40LcG9S2Dms9loiVH29dnjdnPSXDLkWLUodYmWOqPxlUlaXTqfnxXWYpWxQGOJoNSBpB9mi7ri+P6cJcFbWfvZHXbdKncQ+ba5f3nsU7xTzblhdziIi9s89GtDkioB9F562b+5vcJNAlQzd8pmE4MlCPf+JAoxns8s= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768498673; c=relaxed/simple; bh=nj//kZSVU27s2LkyvtU+zldWUvNsS+1OJfTITeuaAHA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pmOrMpcGJHTgGpoMzp11kVamf34lKsJeRESHOXkvHM+qz1sKdpSKRgKnjLuhfCDDm53p0It/PXZ7hymeCkCqjNJakLUs2AJHeHkzUoDeybCd4LToWGTCchKvsAiCJe8YiwveLmGBVxHu/5x9VMwYkQbB6Vox+AmfFaql+EvSFHQ= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=J5vlmjT+; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="J5vlmjT+" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2C24BC116D0; Thu, 15 Jan 2026 17:37:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1768498673; bh=nj//kZSVU27s2LkyvtU+zldWUvNsS+1OJfTITeuaAHA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=J5vlmjT+7aDcvLIINpLDSx8+dTs1sKVssMrKIaMjlztoBH8AtEdPF2pE95DBFUfJf usW8kDsVp4FXXtjz8YbD391cZD7ZHtqD0r/CBllziUmDLnLLUY92y+QKFgzxY9+17a dFNzlhM3hdt/W0YRkyk/AT/Ti/RwyrkLYZ0DPG7w= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Sharath Chandra Vurukala , Eric Dumazet , Jakub Kicinski , Keerthana K Subject: [PATCH 5.15 514/554] net: Add locking to protect skb->dev access in ip_output Date: Thu, 15 Jan 2026 17:49:40 +0100 Message-ID: <20260115164304.924756243@linuxfoundation.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260115164246.225995385@linuxfoundation.org> References: <20260115164246.225995385@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 5.15-stable review patch. If anyone has any objections, please let me know. ------------------ From: Sharath Chandra Vurukala [ Upstream commit 1dbf1d590d10a6d1978e8184f8dfe20af22d680a] In ip_output() skb->dev is updated from the skb_dst(skb)->dev this can become invalid when the interface is unregistered and freed, Introduced new skb_dst_dev_rcu() function to be used instead of skb_dst_dev() within rcu_locks in ip_output.This will ensure that all the skb's associated with the dev being deregistered will be transnmitted out first, before freeing the dev. Given that ip_output() is called within an rcu_read_lock() critical section or from a bottom-half context, it is safe to introduce an RCU read-side critical section within it. Multiple panic call stacks were observed when UL traffic was run in concurrency with device deregistration from different functions, pasting one sample for reference. [496733.627565][T13385] Call trace: [496733.627570][T13385] bpf_prog_ce7c9180c3b128ea_cgroupskb_egres+0x24c/0x7f0 [496733.627581][T13385] __cgroup_bpf_run_filter_skb+0x128/0x498 [496733.627595][T13385] ip_finish_output+0xa4/0xf4 [496733.627605][T13385] ip_output+0x100/0x1a0 [496733.627613][T13385] ip_send_skb+0x68/0x100 [496733.627618][T13385] udp_send_skb+0x1c4/0x384 [496733.627625][T13385] udp_sendmsg+0x7b0/0x898 [496733.627631][T13385] inet_sendmsg+0x5c/0x7c [496733.627639][T13385] __sys_sendto+0x174/0x1e4 [496733.627647][T13385] __arm64_sys_sendto+0x28/0x3c [496733.627653][T13385] invoke_syscall+0x58/0x11c [496733.627662][T13385] el0_svc_common+0x88/0xf4 [496733.627669][T13385] do_el0_svc+0x2c/0xb0 [496733.627676][T13385] el0_svc+0x2c/0xa4 [496733.627683][T13385] el0t_64_sync_handler+0x68/0xb4 [496733.627689][T13385] el0t_64_sync+0x1a4/0x1a8 Changes in v3: - Replaced WARN_ON() with WARN_ON_ONCE(), as suggested by Willem de Bruijn. - Dropped legacy lines mistakenly pulled in from an outdated branch. Changes in v2: - Addressed review comments from Eric Dumazet - Used READ_ONCE() to prevent potential load/store tearing - Added skb_dst_dev_rcu() and used along with rcu_read_lock() in ip_output Signed-off-by: Sharath Chandra Vurukala Reviewed-by: Eric Dumazet Link: https://patch.msgid.link/20250730105118.GA26100@hu-sharathv-hyd.qualcomm.com Signed-off-by: Jakub Kicinski [ Keerthana: Backported the patch to v5.15-v6.1 ] Signed-off-by: Keerthana K Signed-off-by: Greg Kroah-Hartman --- include/net/dst.h | 12 ++++++++++++ net/ipv4/ip_output.c | 16 +++++++++++----- 2 files changed, 23 insertions(+), 5 deletions(-) --- a/include/net/dst.h +++ b/include/net/dst.h @@ -554,6 +554,18 @@ static inline void skb_dst_update_pmtu_n dst->ops->update_pmtu(dst, NULL, skb, mtu, false); } +static inline struct net_device *dst_dev_rcu(const struct dst_entry *dst) +{ + /* In the future, use rcu_dereference(dst->dev) */ + WARN_ON_ONCE(!rcu_read_lock_held()); + return READ_ONCE(dst->dev); +} + +static inline struct net_device *skb_dst_dev_rcu(const struct sk_buff *skb) +{ + return dst_dev_rcu(skb_dst(skb)); +} + struct dst_entry *dst_blackhole_check(struct dst_entry *dst, u32 cookie); void dst_blackhole_update_pmtu(struct dst_entry *dst, struct sock *sk, struct sk_buff *skb, u32 mtu, bool confirm_neigh); --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -420,17 +420,23 @@ int ip_mc_output(struct net *net, struct int ip_output(struct net *net, struct sock *sk, struct sk_buff *skb) { - struct net_device *dev = skb_dst(skb)->dev, *indev = skb->dev; + struct net_device *dev, *indev = skb->dev; + int ret_val; + + rcu_read_lock(); + dev = skb_dst_dev_rcu(skb); IP_UPD_PO_STATS(net, IPSTATS_MIB_OUT, skb->len); skb->dev = dev; skb->protocol = htons(ETH_P_IP); - return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, - net, sk, skb, indev, dev, - ip_finish_output, - !(IPCB(skb)->flags & IPSKB_REROUTED)); + ret_val = NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, + net, sk, skb, indev, dev, + ip_finish_output, + !(IPCB(skb)->flags & IPSKB_REROUTED)); + rcu_read_unlock(); + return ret_val; } EXPORT_SYMBOL(ip_output);