From: Greg Kroah-Hartman Date: Mon, 12 Jan 2026 11:15:20 +0000 (+0100) Subject: 6.1-stable patches X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dccb890c228dd24302b39c770ec3f860573ee9d4;p=thirdparty%2Fkernel%2Fstable-queue.git 6.1-stable patches added patches: ext4-fix-out-of-bound-read-in-ext4_xattr_inode_dec_ref_all.patch ext4-introduce-itail-helper.patch net-add-locking-to-protect-skb-dev-access-in-ip_output.patch tls-use-__sk_dst_get-and-dst_dev_rcu-in-get_netdev_for_sock.patch --- diff --git a/queue-6.1/ext4-fix-out-of-bound-read-in-ext4_xattr_inode_dec_ref_all.patch b/queue-6.1/ext4-fix-out-of-bound-read-in-ext4_xattr_inode_dec_ref_all.patch new file mode 100644 index 0000000000..3f8dc7cd8d --- /dev/null +++ b/queue-6.1/ext4-fix-out-of-bound-read-in-ext4_xattr_inode_dec_ref_all.patch @@ -0,0 +1,194 @@ +From stable+bounces-207877-greg=kroah.com@vger.kernel.org Fri Jan 9 16:24:10 2026 +From: "David Nyström" +Date: Fri, 09 Jan 2026 16:23:14 +0100 +Subject: ext4: fix out-of-bound read in ext4_xattr_inode_dec_ref_all() +To: stable@vger.kernel.org +Cc: "Theodore Ts'o" , "Ye Bin" , "Sasha Levin" , "David Nyström" , "Jan Kara" +Message-ID: <20260109-ext4_splat-v3-2-bb8dfefb8f38@est.tech> + +From: Ye Bin + +[ Upstream commit 5701875f9609b000d91351eaa6bfd97fe2f157f4 ] + +There's issue as follows: +BUG: KASAN: use-after-free in ext4_xattr_inode_dec_ref_all+0x6ff/0x790 +Read of size 4 at addr ffff88807b003000 by task syz-executor.0/15172 + +CPU: 3 PID: 15172 Comm: syz-executor.0 +Call Trace: + __dump_stack lib/dump_stack.c:82 [inline] + dump_stack+0xbe/0xfd lib/dump_stack.c:123 + print_address_description.constprop.0+0x1e/0x280 mm/kasan/report.c:400 + __kasan_report.cold+0x6c/0x84 mm/kasan/report.c:560 + kasan_report+0x3a/0x50 mm/kasan/report.c:585 + ext4_xattr_inode_dec_ref_all+0x6ff/0x790 fs/ext4/xattr.c:1137 + ext4_xattr_delete_inode+0x4c7/0xda0 fs/ext4/xattr.c:2896 + ext4_evict_inode+0xb3b/0x1670 fs/ext4/inode.c:323 + evict+0x39f/0x880 fs/inode.c:622 + iput_final fs/inode.c:1746 [inline] + iput fs/inode.c:1772 [inline] + iput+0x525/0x6c0 fs/inode.c:1758 + ext4_orphan_cleanup fs/ext4/super.c:3298 [inline] + ext4_fill_super+0x8c57/0xba40 fs/ext4/super.c:5300 + mount_bdev+0x355/0x410 fs/super.c:1446 + legacy_get_tree+0xfe/0x220 fs/fs_context.c:611 + vfs_get_tree+0x8d/0x2f0 fs/super.c:1576 + do_new_mount fs/namespace.c:2983 [inline] + path_mount+0x119a/0x1ad0 fs/namespace.c:3316 + do_mount+0xfc/0x110 fs/namespace.c:3329 + __do_sys_mount fs/namespace.c:3540 [inline] + __se_sys_mount+0x219/0x2e0 fs/namespace.c:3514 + do_syscall_64+0x33/0x40 arch/x86/entry/common.c:46 + entry_SYSCALL_64_after_hwframe+0x67/0xd1 + +Memory state around the buggy address: + ffff88807b002f00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + ffff88807b002f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +>ffff88807b003000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ^ + ffff88807b003080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ffff88807b003100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + +Above issue happens as ext4_xattr_delete_inode() isn't check xattr +is valid if xattr is in inode. +To solve above issue call xattr_check_inode() check if xattr if valid +in inode. In fact, we can directly verify in ext4_iget_extra_inode(), +so that there is no divergent verification. + +Fixes: e50e5129f384 ("ext4: xattr-in-inode support") +Signed-off-by: Ye Bin +Reviewed-by: Jan Kara +Link: https://patch.msgid.link/20250208063141.1539283-3-yebin@huaweicloud.com +Signed-off-by: Theodore Ts'o +Signed-off-by: David Nyström +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/inode.c | 5 +++++ + fs/ext4/xattr.c | 26 +------------------------- + fs/ext4/xattr.h | 7 +++++++ + 3 files changed, 13 insertions(+), 25 deletions(-) + +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -4752,6 +4752,11 @@ static inline int ext4_iget_extra_inode( + *magic == cpu_to_le32(EXT4_XATTR_MAGIC)) { + int err; + ++ err = xattr_check_inode(inode, IHDR(inode, raw_inode), ++ ITAIL(inode, raw_inode)); ++ if (err) ++ return err; ++ + ext4_set_inode_state(inode, EXT4_STATE_XATTR); + err = ext4_find_inline_data_nolock(inode); + if (!err && ext4_has_inline_data(inode)) +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -263,7 +263,7 @@ errout: + __ext4_xattr_check_block((inode), (bh), __func__, __LINE__) + + +-static int ++int + __xattr_check_inode(struct inode *inode, struct ext4_xattr_ibody_header *header, + void *end, const char *function, unsigned int line) + { +@@ -280,9 +280,6 @@ errout: + return error; + } + +-#define xattr_check_inode(inode, header, end) \ +- __xattr_check_inode((inode), (header), (end), __func__, __LINE__) +- + static int + xattr_find_entry(struct inode *inode, struct ext4_xattr_entry **pentry, + void *end, int name_index, const char *name, int sorted) +@@ -600,9 +597,6 @@ ext4_xattr_ibody_get(struct inode *inode + raw_inode = ext4_raw_inode(&iloc); + header = IHDR(inode, raw_inode); + end = ITAIL(inode, raw_inode); +- error = xattr_check_inode(inode, header, end); +- if (error) +- goto cleanup; + entry = IFIRST(header); + error = xattr_find_entry(inode, &entry, end, name_index, name, 0); + if (error) +@@ -734,7 +728,6 @@ ext4_xattr_ibody_list(struct dentry *den + struct ext4_xattr_ibody_header *header; + struct ext4_inode *raw_inode; + struct ext4_iloc iloc; +- void *end; + int error; + + if (!ext4_test_inode_state(inode, EXT4_STATE_XATTR)) +@@ -744,14 +737,9 @@ ext4_xattr_ibody_list(struct dentry *den + return error; + raw_inode = ext4_raw_inode(&iloc); + header = IHDR(inode, raw_inode); +- end = ITAIL(inode, raw_inode); +- error = xattr_check_inode(inode, header, end); +- if (error) +- goto cleanup; + error = ext4_xattr_list_entries(dentry, IFIRST(header), + buffer, buffer_size); + +-cleanup: + brelse(iloc.bh); + return error; + } +@@ -819,7 +807,6 @@ int ext4_get_inode_usage(struct inode *i + struct ext4_xattr_ibody_header *header; + struct ext4_xattr_entry *entry; + qsize_t ea_inode_refs = 0; +- void *end; + int ret; + + lockdep_assert_held_read(&EXT4_I(inode)->xattr_sem); +@@ -830,10 +817,6 @@ int ext4_get_inode_usage(struct inode *i + goto out; + raw_inode = ext4_raw_inode(&iloc); + header = IHDR(inode, raw_inode); +- end = ITAIL(inode, raw_inode); +- ret = xattr_check_inode(inode, header, end); +- if (ret) +- goto out; + + for (entry = IFIRST(header); !IS_LAST_ENTRY(entry); + entry = EXT4_XATTR_NEXT(entry)) +@@ -2197,9 +2180,6 @@ int ext4_xattr_ibody_find(struct inode * + is->s.here = is->s.first; + is->s.end = ITAIL(inode, raw_inode); + if (ext4_test_inode_state(inode, EXT4_STATE_XATTR)) { +- error = xattr_check_inode(inode, header, is->s.end); +- if (error) +- return error; + /* Find the named attribute. */ + error = xattr_find_entry(inode, &is->s.here, is->s.end, + i->name_index, i->name, 0); +@@ -2750,10 +2730,6 @@ retry: + min_offs = end - base; + total_ino = sizeof(struct ext4_xattr_ibody_header) + sizeof(u32); + +- error = xattr_check_inode(inode, header, end); +- if (error) +- goto cleanup; +- + ifree = ext4_xattr_free_space(base, &min_offs, base, &total_ino); + if (ifree >= isize_diff) + goto shift; +--- a/fs/ext4/xattr.h ++++ b/fs/ext4/xattr.h +@@ -210,6 +210,13 @@ extern int ext4_xattr_ibody_set(handle_t + extern struct mb_cache *ext4_xattr_create_cache(void); + extern void ext4_xattr_destroy_cache(struct mb_cache *); + ++extern int ++__xattr_check_inode(struct inode *inode, struct ext4_xattr_ibody_header *header, ++ void *end, const char *function, unsigned int line); ++ ++#define xattr_check_inode(inode, header, end) \ ++ __xattr_check_inode((inode), (header), (end), __func__, __LINE__) ++ + #ifdef CONFIG_EXT4_FS_SECURITY + extern int ext4_init_security(handle_t *handle, struct inode *inode, + struct inode *dir, const struct qstr *qstr); diff --git a/queue-6.1/ext4-introduce-itail-helper.patch b/queue-6.1/ext4-introduce-itail-helper.patch new file mode 100644 index 0000000000..8717469418 --- /dev/null +++ b/queue-6.1/ext4-introduce-itail-helper.patch @@ -0,0 +1,84 @@ +From stable+bounces-207876-greg=kroah.com@vger.kernel.org Fri Jan 9 16:24:07 2026 +From: "David Nyström" +Date: Fri, 09 Jan 2026 16:23:13 +0100 +Subject: ext4: introduce ITAIL helper +To: stable@vger.kernel.org +Cc: "Theodore Ts'o" , "Ye Bin" , "Sasha Levin" , "David Nyström" , "Jan Kara" +Message-ID: <20260109-ext4_splat-v3-1-bb8dfefb8f38@est.tech> + +From: Ye Bin + +[ Upstream commit 69f3a3039b0d0003de008659cafd5a1eaaa0a7a4 ] + +Introduce ITAIL helper to get the bound of xattr in inode. + +Signed-off-by: Ye Bin +Reviewed-by: Jan Kara +Link: https://patch.msgid.link/20250208063141.1539283-2-yebin@huaweicloud.com +Signed-off-by: Theodore Ts'o +Signed-off-by: David Nyström +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/xattr.c | 10 +++++----- + fs/ext4/xattr.h | 3 +++ + 2 files changed, 8 insertions(+), 5 deletions(-) + +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -599,7 +599,7 @@ ext4_xattr_ibody_get(struct inode *inode + return error; + raw_inode = ext4_raw_inode(&iloc); + header = IHDR(inode, raw_inode); +- end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size; ++ end = ITAIL(inode, raw_inode); + error = xattr_check_inode(inode, header, end); + if (error) + goto cleanup; +@@ -744,7 +744,7 @@ ext4_xattr_ibody_list(struct dentry *den + return error; + raw_inode = ext4_raw_inode(&iloc); + header = IHDR(inode, raw_inode); +- end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size; ++ end = ITAIL(inode, raw_inode); + error = xattr_check_inode(inode, header, end); + if (error) + goto cleanup; +@@ -830,7 +830,7 @@ int ext4_get_inode_usage(struct inode *i + goto out; + raw_inode = ext4_raw_inode(&iloc); + header = IHDR(inode, raw_inode); +- end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size; ++ end = ITAIL(inode, raw_inode); + ret = xattr_check_inode(inode, header, end); + if (ret) + goto out; +@@ -2195,7 +2195,7 @@ int ext4_xattr_ibody_find(struct inode * + header = IHDR(inode, raw_inode); + is->s.base = is->s.first = IFIRST(header); + is->s.here = is->s.first; +- is->s.end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size; ++ is->s.end = ITAIL(inode, raw_inode); + if (ext4_test_inode_state(inode, EXT4_STATE_XATTR)) { + error = xattr_check_inode(inode, header, is->s.end); + if (error) +@@ -2746,7 +2746,7 @@ retry: + */ + + base = IFIRST(header); +- end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size; ++ end = ITAIL(inode, raw_inode); + min_offs = end - base; + total_ino = sizeof(struct ext4_xattr_ibody_header) + sizeof(u32); + +--- a/fs/ext4/xattr.h ++++ b/fs/ext4/xattr.h +@@ -68,6 +68,9 @@ struct ext4_xattr_entry { + ((void *)raw_inode + \ + EXT4_GOOD_OLD_INODE_SIZE + \ + EXT4_I(inode)->i_extra_isize)) ++#define ITAIL(inode, raw_inode) \ ++ ((void *)(raw_inode) + \ ++ EXT4_SB((inode)->i_sb)->s_inode_size) + #define IFIRST(hdr) ((struct ext4_xattr_entry *)((hdr)+1)) + + /* diff --git a/queue-6.1/net-add-locking-to-protect-skb-dev-access-in-ip_output.patch b/queue-6.1/net-add-locking-to-protect-skb-dev-access-in-ip_output.patch new file mode 100644 index 0000000000..617f672052 --- /dev/null +++ b/queue-6.1/net-add-locking-to-protect-skb-dev-access-in-ip_output.patch @@ -0,0 +1,119 @@ +From stable+bounces-208042-greg=kroah.com@vger.kernel.org Mon Jan 12 07:39:03 2026 +From: Keerthana K +Date: Mon, 12 Jan 2026 06:35:45 +0000 +Subject: net: Add locking to protect skb->dev access in ip_output +To: stable@vger.kernel.org, gregkh@linuxfoundation.org +Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, yoshfuji@linux-ipv6.org, dsahern@kernel.org, borisp@nvidia.com, john.fastabend@gmail.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, ajay.kaher@broadcom.com, alexey.makhalov@broadcom.com, vamsi-krishna.brahmajosyula@broadcom.com, yin.ding@broadcom.com, tapas.kundu@broadcom.com, Sharath Chandra Vurukala , Keerthana K +Message-ID: <20260112063546.2969089-2-keerthana.kalyanasundaram@broadcom.com> + +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 +@@ -555,6 +555,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); + diff --git a/queue-6.1/series b/queue-6.1/series index 2be510d6b8..c9f81378bc 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -12,3 +12,7 @@ libceph-replace-overzealous-bug_on-in-osdmap_apply_incremental.patch libceph-make-free_choose_arg_map-resilient-to-partial-allocation.patch libceph-return-the-handler-error-from-mon_handle_auth_done.patch libceph-make-calc_target-set-t-paused-not-just-clear-it.patch +ext4-introduce-itail-helper.patch +ext4-fix-out-of-bound-read-in-ext4_xattr_inode_dec_ref_all.patch +net-add-locking-to-protect-skb-dev-access-in-ip_output.patch +tls-use-__sk_dst_get-and-dst_dev_rcu-in-get_netdev_for_sock.patch diff --git a/queue-6.1/tls-use-__sk_dst_get-and-dst_dev_rcu-in-get_netdev_for_sock.patch b/queue-6.1/tls-use-__sk_dst_get-and-dst_dev_rcu-in-get_netdev_for_sock.patch new file mode 100644 index 0000000000..38e88ee2d2 --- /dev/null +++ b/queue-6.1/tls-use-__sk_dst_get-and-dst_dev_rcu-in-get_netdev_for_sock.patch @@ -0,0 +1,66 @@ +From stable+bounces-208043-greg=kroah.com@vger.kernel.org Mon Jan 12 07:39:25 2026 +From: Keerthana K +Date: Mon, 12 Jan 2026 06:35:46 +0000 +Subject: tls: Use __sk_dst_get() and dst_dev_rcu() in get_netdev_for_sock(). +To: stable@vger.kernel.org, gregkh@linuxfoundation.org +Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, yoshfuji@linux-ipv6.org, dsahern@kernel.org, borisp@nvidia.com, john.fastabend@gmail.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, ajay.kaher@broadcom.com, alexey.makhalov@broadcom.com, vamsi-krishna.brahmajosyula@broadcom.com, yin.ding@broadcom.com, tapas.kundu@broadcom.com, Kuniyuki Iwashima , Sabrina Dubroca , Sasha Levin , Keerthana K +Message-ID: <20260112063546.2969089-3-keerthana.kalyanasundaram@broadcom.com> + +From: Kuniyuki Iwashima + +[ Upstream commit c65f27b9c3be2269918e1cbad6d8884741f835c5 ] + +get_netdev_for_sock() is called during setsockopt(), +so not under RCU. + +Using sk_dst_get(sk)->dev could trigger UAF. + +Let's use __sk_dst_get() and dst_dev_rcu(). + +Note that the only ->ndo_sk_get_lower_dev() user is +bond_sk_get_lower_dev(), which uses RCU. + +Fixes: e8f69799810c ("net/tls: Add generic NIC offload infrastructure") +Signed-off-by: Kuniyuki Iwashima +Reviewed-by: Eric Dumazet +Reviewed-by: Sabrina Dubroca +Link: https://patch.msgid.link/20250916214758.650211-6-kuniyu@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +[ Keerthana: Backport to v5.15-v6.1 ] +Signed-off-by: Keerthana K +Signed-off-by: Greg Kroah-Hartman +--- + net/tls/tls_device.c | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +--- a/net/tls/tls_device.c ++++ b/net/tls/tls_device.c +@@ -125,17 +125,19 @@ static void tls_device_queue_ctx_destruc + /* We assume that the socket is already connected */ + static struct net_device *get_netdev_for_sock(struct sock *sk) + { +- struct dst_entry *dst = sk_dst_get(sk); +- struct net_device *netdev = NULL; ++ struct net_device *dev, *lowest_dev = NULL; ++ struct dst_entry *dst; + +- if (likely(dst)) { +- netdev = netdev_sk_get_lowest_dev(dst->dev, sk); +- dev_hold(netdev); ++ rcu_read_lock(); ++ dst = __sk_dst_get(sk); ++ dev = dst ? dst_dev_rcu(dst) : NULL; ++ if (likely(dev)) { ++ lowest_dev = netdev_sk_get_lowest_dev(dev, sk); ++ dev_hold(lowest_dev); + } ++ rcu_read_unlock(); + +- dst_release(dst); +- +- return netdev; ++ return lowest_dev; + } + + static void destroy_record(struct tls_record_info *record)