Skip to content

[LTS 9.2] net RCU: CVE-2025-40170, CVE-2025-40158, CVE-2025-40135, CVE-2025-21765, CVE-2025-21766, CVE-2024-44985, CVE-2024-44986 - #1534

Open
pvts-mat wants to merge 24 commits into
ctrliq:ciqlts9_2from
pvts-mat:CVE-batch-43_ciqlts9_2
Open

[LTS 9.2] net RCU: CVE-2025-40170, CVE-2025-40158, CVE-2025-40135, CVE-2025-21765, CVE-2025-21766, CVE-2024-44985, CVE-2024-44986#1534
pvts-mat wants to merge 24 commits into
ctrliq:ciqlts9_2from
pvts-mat:CVE-batch-43_ciqlts9_2

Conversation

@pvts-mat

Copy link
Copy Markdown
Contributor

[LTS 9.2]

CVE-2025-40170 VULN-160265
CVE-2025-40158 VULN-160216
CVE-2025-40135 VULN-160160
CVE-2025-21765 VULN-53991
CVE-2025-21766 VULN-54043
CVE-2024-44985 VULN-8328
CVE-2024-44986 VULN-8330

About

This PR is similar to its LTS 9.6 version, which was based, in turn, on the CentOS 9.8 MR. The differences and similarities between the versions can be summarized in the following table:

Issue LTS 9.2 PR (this one) LTS 9.6 PR CentOS 9 MR
Commits ordering Reflecting the upstream Reflecting the CentOS 9 MR Unspecified
Backported 1395121 (CVE-2025-21766 fix) Backported as prerequisite, tagged with its own CVE for bookkeeping Backported as prerequisite, tagged with its own CVE for bookkeeping No
Backported 4693085 Yes. Needed as prerequisite Yes. Needed as prerequisite No. Already in place as aa0e0ee
Backported 3c8ffcd (CVE-2025-21765 fix) Yes. Not a prerequisite nor a bugfix. Pulled into the solution because it picks cleanly and is part of an upstream branch already being backported. No. Already in place as 9601d84 No. Already in place as bad0070
Backported 2d5ff7e (CVE-2024-44985 fix) Yes. Backported to minimize conflicts for 9085e56 fixing CVE-2025-40135 No. Already in place as 30b315f No. Already in place as 30b315f
Backported da273b3 (CVE-2024-44986 fix) Yes. Needed as prerequisite for 1170957 fixing CVE-2025-40158 No. Already in place as ddb848f No. Already in place as ddb848f
Backported 448a5ce Yes. Minor prerequisite for 99a2ace fixing CVE-2025-40170. Also a fix itself, although without CVE. No. Already in place as 251dcf6 No. Already in place as 251dcf6
Backported 09eed11 Yes. Needed as prerequisite for 09eed11 No. Already in place as c2c5210 No. Already in place as c2c5210
Backported 427faee Yes. Needed as prerequisite for 99a2ace solving CVE-2025-40170 No. (It's a bug, actually) No. (It's a bug, actually)

Commits

net: use dst_dev_rcu() in sk_setup_caps()

jira VULN-160265
cve CVE-2025-40170
commit-author Eric Dumazet <edumazet@google.com>
commit 99a2ace61b211b0be861b07fbaa062fca4b58879
upstream-diff Used CentOS 9 backport
  acc5b1b3f6e937c219da6eff70f79f29c0c794e0 as the base. It dealt already
  with the missing commits:
  - a74fc62eec155ca5a6da8ff3856f3dc87fe24558 ("ipv4: adopt dst_dev,
    skb_dst_dev and skb_dst_dev_net[_rcu]")
  - 1caf27297215a5241f9bfc9c07336349d9034ee3 ("ipv6: adopt dst_dev()
    helper")
  Additionally, in net/core/sock.c:
  - Omitted changes to the `sk_trim_gso_size()' function
    (`sk_dst_gso_max_size()' in the upstream), because `dst->dev' is not
    used there (introduced in 5a01b46698289af301f7ec7ed4f35129ffb9d188
    ("net: add support for ipv4 big tcp")).
  - In `sk_setup_caps()', instead of changing the last argument of the
    nonexistent `sk_dst_gso_max_size()' call from `dst' to `dev' a
    `dst_dev(dst)' to `dev' substitution was made similarly to how it was
    done 4 lines later.
ipv6: use RCU in ip6_output()

jira VULN-160216
cve CVE-2025-40158
commit-author Eric Dumazet <edumazet@google.com>
commit 11709573cc4e48dc34c80fc7ab9ce5b159e29695
upstream-diff Used CentOS 9 backport
  9b21011cae661b5f80f0ea5220b288f423d6df69 as the base. It deals with
  the similarly non-backported commits
  1caf27297215a5241f9bfc9c07336349d9034ee3 and
  93d1cff35adc522a5d21e722eee1071f3f7dc716. Resolved some context
  conflicts in `ip6_finish_output2()'.
ipv6: use RCU in ip6_xmit()

jira VULN-160160
cve CVE-2025-40135
commit-author Eric Dumazet <edumazet@google.com>
commit 9085e56501d93af9f2d7bd16f7fcfacdde47b99c
upstream-diff Used CentOS 9 backport
  f37f7b3231da22922882bd67b4918788919216b8 for a clean pick. It deals
  already with the similarly non-backported commit
  1caf27297215a5241f9bfc9c07336349d9034ee3 ("ipv6: adopt dst_dev()
  helper").
net: dst: introduce dst->dev_rcu

jira VULN-160265
cve-pre CVE-2025-40170
commit-author Eric Dumazet <edumazet@google.com>
commit caedcc5b6df1b2e2b5f39079e3369c1d4d5c5f50
upstream-diff Used CentOS 9 backport
  ca6810ffc83408a1dd36676447c35d0348ef0571 as a clean cherry-pick base.
  - Used RH_KABI_REPLACE in `struct dst_entry' to silence the kABI
    checker. Originally the `struct net_device *dev' field was changed
    into a union of `struct net_device *dev' and `struct net_device __rcu
    *dev_rcu'. The latter has the same size and alignment as the former
    (this is actually checked statically by the RH_KABI_REPLACE macro),
    with the `__rcu' annotation serving only at compile time and being
    invisible to the binary output. The `dev_rcu' is therefore just an
    alias for the `dev' field.
  - Omitted changes to the `ipv4_default_advmss()' function because no
    `dst->dev' is being referenced there in LTS 9.2 (and CentOS 9). The
    `ip_rt_min_advmss' parameter was made dev-specific in commit
    2e9589ff809e9232f689acd51da73390e135146a ("ipv4: Namespaceify
    min_adv_mss sysctl knob").
  - Resolved context conflicts in `dst_dev_put()' due to missing
    d62607c3fe45911b2331fac073355a8c914bbde2 ("net: rename
    reference+tracking helpers")
net: Add locking to protect skb->dev access in ip_output

jira VULN-160160
cve-pre CVE-2025-40135
commit-author Sharath Chandra Vurukala <quic_sharathv@quicinc.com>
commit 1dbf1d590d10a6d1978e8184f8dfe20af22d680a
upstream-diff Resolved context conflicts in `ip_output()' due to
  missing a74fc62eec155ca5a6da8ff3856f3dc87fe24558 ("ipv4: adopt
  dst_dev, skb_dst_dev and skb_dst_dev_net[_rcu]")
net: dst: add four helpers to annotate data-races around dst->dev

jira VULN-160265
cve-pre CVE-2025-40170
commit-author Eric Dumazet <edumazet@google.com>
commit 88fe14253e181878c2ddb51a298ae8c468a63010
upstream-diff |
  net/core/dst.c
        Resolved context conflicts in `dst_dev_put' function. (Missing
        commits: f1c5fd34891a1c242885f48c2e4dc52df180f311,
        2dce8c52a98995c4719def6f88629ab1581c0b82,
        d62607c3fe45911b2331fac073355a8c914bbde2)
  net/core/sock.c
        - Changes to `sk_dst_gso_max_size()' omitted, because `dst'
          paramater not present in the function (introduced in the
          non-backported b1a78b9b98862cda167b643690e43662ea060625 ("net:
          add support for ipv4 big tcp")).
        - In function `sk_setup_caps()', the `dst->dev' to `dst_dev(dst)'
          conversion applied also in the `sk->sk_gso_max_size'
          assignment. (Ine the upstream this is delegated to the
          aforementioned `sk_dst_gso_max_size()' function.)
ipv6: use RCU protection in ip6_default_advmss()

jira VULN-53991
cve CVE-2025-21765
commit-author Eric Dumazet <edumazet@google.com>
commit 3c8ffcd248da34fc41e52a46e51505900115fc2a

Part of one of the upstream branches backported as prerequisite (the net: first round to use dev_net_rcu() branch, identified as ip group in the LTS 9.6 PR). Pulled into the solution because it picks cleanly and is part of a branch already being backported as prerequisite.

ipv4: use RCU protection in __ip_rt_update_pmtu()

jira VULN-54043
cve CVE-2025-21766
commit-author Eric Dumazet <edumazet@google.com>
commit 139512191bd06f1b496117c76372b2ce372c9a41
upstream-diff Used CentOS 9 backport
  fd7e9d21f4fa35270f40feb436ad53deebbcc0ee for the clean pick. The
  modified function `__ip_rt_update_pmtu' is identicial in LTS 9.2 and
  CentOS 9.
ipv4: use RCU protection in ip_dst_mtu_maybe_forward()

jira VULN-160265
cve-pre CVE-2025-40170
commit-author Eric Dumazet <edumazet@google.com>
commit 071d8012869b6af352acca346ade13e7be90a49f
upstream-diff Used CentOS 9 backport
  4ea98f09499595e3b4b380e5ef60c2c9563b06be which dealt with the context
  conflicts.
ipv4: add RCU protection to ip4_dst_hoplimit()

jira VULN-160265
cve-pre CVE-2025-40170
commit-author Eric Dumazet <edumazet@google.com>
commit 469308552ca4560176cfc100e7ca84add1bebd7c

Prerequisite for net: use dst_dev_rcu() in sk_setup_caps().

bpf: Fix mismatched RCU unlock flavour in bpf_out_neigh_v6

jira VULN-160216
cve-pre CVE-2025-40158
commit-author Jiawei Ye <jiawei.ye@foxmail.com>
commit fb86c42a2a5d44e849ddfbc98b8d2f4f40d36ee3

Bugfix for neighbour: switch to standard rcu, instead of rcu_bh.

ipv6: prevent possible UAF in ip6_xmit()

jira VULN-8328
cve CVE-2024-44985
commit-author Eric Dumazet <edumazet@google.com>
commit 2d5ff7e339d04622d8282661df36151906d0e1c7

Prerequisite for ipv6: use RCU in ip6_xmit().

ipv6: fix possible UAF in ip6_finish_output2()

jira VULN-8330
cve CVE-2024-44986
commit-author Eric Dumazet <edumazet@google.com>
commit da273b377ae0d9bd255281ed3c2adb228321687b

Prerequisite for ipv6: use RCU in ip6_output().

vrf: Fix lockdep splat in output path

jira VULN-160216
cve-pre CVE-2025-40158
commit-author Ido Schimmel <idosch@nvidia.com>
commit 2033ab90380d46e0e9f0520fd6776a73d107fd95

Bugfix for neighbour: switch to standard rcu, instead of rcu_bh.

udp6: Fix race condition in udp6_sendmsg & connect

jira VULN-160265
cve-pre CVE-2025-40170
commit-author Vladislav Efanov <VEfanov@ispras.ru>
commit 448a5ce1120c5bdbce1f1ccdabcd31c7d029f328

Prerequisite for net: use dst_dev_rcu() in sk_setup_caps().

ipv6: remove nexthop_fib6_nh_bh()

jira VULN-160216
cve-pre CVE-2025-40158
commit-author Eric Dumazet <edumazet@google.com>
commit ef1148d4487438a3408d6face2a8360d91b4af70

Bugfix for neighbour: switch to standard rcu, instead of rcu_bh.

net: remove rcu_dereference_bh_rtnl()

jira VULN-160216
cve-pre CVE-2025-40158
commit-author Eric Dumazet <edumazet@google.com>
commit fe602c87df1b6927562f4ee61edd851bb9578a49
neighbour: switch to standard rcu, instead of rcu_bh

jira VULN-160216
cve-pre CVE-2025-40158
commit-author Eric Dumazet <edumazet@google.com>
commit 09eed1192cec1755967f2af8394207acdde579a1
upstream-diff Used CentOS 9 backport
  8b5b9707c3f82d029fbcad0997be1905bdd6945e which dealt with most of the
  context conflicts.
ipv6: flowlabel: do not disable BH where not needed

jira VULN-160216
cve-pre CVE-2025-40158
commit-author Eric Dumazet <edumazet@google.com>
commit 4c5c496a942fa3d2197f5be22762695170c95863
ipv6: remove one read_lock()/read_unlock() pair in rt6_check_neigh()

jira VULN-160216
cve-pre CVE-2025-40158
commit-author Eric Dumazet <edumazet@google.com>
commit c486640aa710ddd06c13a7f7162126e1552e8842
ipv6: refactor ip6_finish_output2()

jira VULN-160216
cve-pre CVE-2025-40158
commit-author Pavel Begunkov <asml.silence@gmail.com>
commit 58f71be58b8713e41f8568938a0199190f723d1d

Prerequisite for neighbour: switch to standard rcu, instead of rcu_bh.

neigh: introduce neigh_confirm() helper function

jira VULN-160216
cve-pre CVE-2025-40158
commit-author Yajun Deng <yajun.deng@linux.dev>
commit 1e84dc6b7bbfc4d1dd846decece4611b7e035772
net: ipv4: Consolidate ipv4_mtu and ip_dst_mtu_maybe_forward

jira VULN-160265
cve-pre CVE-2025-40170
commit-author Vadim Fedorenko <vfedorenko@novek.ru>
commit ac6627a28dbfb5d96736544a00c3938fa7ea6dfb
net: ipv6: introduce ip6_dst_mtu_maybe_forward

jira VULN-160265
cve-pre CVE-2025-40170
commit-author Vadim Fedorenko <vfedorenko@novek.ru>
commit 427faee167bce4ccb0b22f6815a9ac509e31d4c3

Prerequisite for net: use dst_dev_rcu() in sk_setup_caps(). Needed so that the change to ip6_dst_mtu_maybe_forward done by that commit doesn't have to be duplicated in ip6_mtu.

kABI check: passed

[0/1] kabi_check_kernel	Check ABI of kernel [ciqlts9_2-CVE-batch-43]	_kabi_check_kernel__x86_64--test--ciqlts9_2-CVE-batch-43
ninja explain: output state/kernels/ciqlts9_2-CVE-batch-43/x86_64/kabi_checked doesn't exist
ninja explain: state/kernels/ciqlts9_2-CVE-batch-43/x86_64/kabi_checked is dirty
+ dist_git_version=el-9.2
+ local_version=ciqlts9_2-CVE-batch-43
+ arch=x86_64
+ user=pvts
+ buildmachine=x86_64--build--ciqlts9_2
+ virsh_timeout=600
+ ssh_daemon_wait=20
+ src_dir=/mnt/code/kernel-dist-git-el-9.2
+ build_dir=/mnt/build_files/kernel-src-tree-ciqlts9_2-CVE-batch-43
+ sudo chmod +x /data/src/ctrliq-github-haskell/kernel-dist-git-el-9.2/SOURCES/check-kabi
+ ninja-back/virssh.xsh --max 8 --shutdown-on-success --shutdown-on-failure --timeout 600 --ssh-daemon-wait 20 pvts x86_64--build--ciqlts9_2 ''\''/mnt/code/kernel-dist-git-el-9.2/SOURCES/check-kabi'\'' -k '\''/mnt/code/kernel-dist-git-el-9.2/SOURCES/Module.kabi_x86_64'\'' -s '\''/mnt/build_files/kernel-src-tree-ciqlts9_2-CVE-batch-43/Module.symvers'\'''
kABI check passed
+ touch state/kernels/ciqlts9_2-CVE-batch-43/x86_64/kabi_checked

Boot test: passed

boot-test.log

Kselftests: passed relative

Reference

kselftests–ciqlts9_2–run1.log
kselftests–ciqlts9_2–run2.log
kselftests–ciqlts9_2–run3.log

Patch

kselftests–ciqlts9_2-CVE-batch-43–run1.log
kselftests–ciqlts9_2-CVE-batch-43–run2.log
kselftests–ciqlts9_2-CVE-batch-43–run3.log

Comparison

The tests results for the reference and the patch are the same.

$ ktests.xsh diff  kselftests*.log

Column    File
--------  --------------------------------------------
Status0   kselftests--ciqlts9_2--run1.log
Status1   kselftests--ciqlts9_2--run2.log
Status2   kselftests--ciqlts9_2--run3.log
Status3   kselftests--ciqlts9_2-CVE-batch-43--run1.log
Status4   kselftests--ciqlts9_2-CVE-batch-43--run2.log
Status5   kselftests--ciqlts9_2-CVE-batch-43--run3.log

full-test-results-comparison.log

jira VULN-160265
cve-pre CVE-2025-40170
commit-author Vadim Fedorenko <vfedorenko@novek.ru>
commit 427faee

Replace ip6_dst_mtu_forward with ip6_dst_mtu_maybe_forward and
reuse this code in ip6_mtu. Actually these two functions were
almost duplicates, this change will simplify the maintaince of
mtu calculation code.

	Signed-off-by: Vadim Fedorenko <vfedorenko@novek.ru>
	Reviewed-by: David Ahern <dsahern@kernel.org>
	Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 427faee)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160265
cve-pre CVE-2025-40170
commit-author Vadim Fedorenko <vfedorenko@novek.ru>
commit ac6627a

Consolidate IPv4 MTU code the same way it is done in IPv6 to have code
aligned in both address families

	Signed-off-by: Vadim Fedorenko <vfedorenko@novek.ru>
	Reviewed-by: David Ahern <dsahern@kernel.org>
	Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit ac6627a)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160216
cve-pre CVE-2025-40158
commit-author Yajun Deng <yajun.deng@linux.dev>
commit 1e84dc6

Add neigh_confirm() for the confirmed member in struct neighbour,
it can be called as an independent unit by other functions.

	Signed-off-by: Yajun Deng <yajun.deng@linux.dev>
	Reviewed-by: Eric Dumazet <edumazet@google.com>
	Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 1e84dc6)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160216
cve-pre CVE-2025-40158
commit-author Pavel Begunkov <asml.silence@gmail.com>
commit 58f71be

Throw neigh checks in ip6_finish_output2() under a single slow path if,
so we don't have the overhead in the hot path.

	Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
	Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 58f71be)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160216
cve-pre CVE-2025-40158
commit-author Eric Dumazet <edumazet@google.com>
commit c486640

rt6_check_neigh() uses read_lock() to protect n->nud_state reading.

This seems overkill and causes false sharing.

	Signed-off-by: Eric Dumazet <edumazet@google.com>
	Reviewed-by: David Ahern <dsahern@kernel.org>
	Reviewed-by: Martin KaFai Lau <martin.lau@kernel.org>
	Signed-off-by: Jakub Kicinski <kuba@kernel.org>
(cherry picked from commit c486640)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160216
cve-pre CVE-2025-40158
commit-author Eric Dumazet <edumazet@google.com>
commit 4c5c496

struct ip6_flowlabel are rcu managed, and call_rcu() is used
to delay fl_free_rcu() after RCU grace period.

There is no point disabling BH for pure RCU lookups.

	Signed-off-by: Eric Dumazet <edumazet@google.com>
	Signed-off-by: Jakub Kicinski <kuba@kernel.org>
(cherry picked from commit 4c5c496)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160216
cve-pre CVE-2025-40158
commit-author Eric Dumazet <edumazet@google.com>
commit 09eed11
upstream-diff Used CentOS 9 backport
  8b5b970 which dealt with most of the
  context conflicts.

rcu_bh is no longer a win, especially for objects freed
with standard call_rcu().

Switch neighbour code to no longer disable BH when not necessary.

	Signed-off-by: Eric Dumazet <edumazet@google.com>
	Signed-off-by: Jakub Kicinski <kuba@kernel.org>
(cherry picked from commit 8b5b970)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160216
cve-pre CVE-2025-40158
commit-author Eric Dumazet <edumazet@google.com>
commit fe602c8

This helper is no longer used in the tree.

	Signed-off-by: Eric Dumazet <edumazet@google.com>
	Signed-off-by: Jakub Kicinski <kuba@kernel.org>
(cherry picked from commit fe602c8)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160216
cve-pre CVE-2025-40158
commit-author Eric Dumazet <edumazet@google.com>
commit ef1148d

After blamed commit, nexthop_fib6_nh_bh() and nexthop_fib6_nh()
are the same.

Delete nexthop_fib6_nh_bh(), and convert /proc/net/ipv6_route
to standard rcu to avoid this splat:

[ 5723.180080] WARNING: suspicious RCU usage
[ 5723.180083] -----------------------------
[ 5723.180084] include/net/nexthop.h:516 suspicious rcu_dereference_check() usage!
[ 5723.180086]
other info that might help us debug this:

[ 5723.180087]
rcu_scheduler_active = 2, debug_locks = 1
[ 5723.180089] 2 locks held by cat/55856:
[ 5723.180091] #0: ffff9440a582afa8 (&p->lock){+.+.}-{3:3}, at: seq_read_iter (fs/seq_file.c:188)
[ 5723.180100] ctrliq#1: ffffffffaac07040 (rcu_read_lock_bh){....}-{1:2}, at: rcu_lock_acquire (include/linux/rcupdate.h:326)
[ 5723.180109]
stack backtrace:
[ 5723.180111] CPU: 14 PID: 55856 Comm: cat Tainted: G S        I        6.3.0-dbx-DEV ctrliq#528
[ 5723.180115] Call Trace:
[ 5723.180117]  <TASK>
[ 5723.180119] dump_stack_lvl (lib/dump_stack.c:107)
[ 5723.180124] dump_stack (lib/dump_stack.c:114)
[ 5723.180126] lockdep_rcu_suspicious (include/linux/context_tracking.h:122)
[ 5723.180132] ipv6_route_seq_show (include/net/nexthop.h:?)
[ 5723.180135] ? ipv6_route_seq_next (net/ipv6/ip6_fib.c:2605)
[ 5723.180140] seq_read_iter (fs/seq_file.c:272)
[ 5723.180145] seq_read (fs/seq_file.c:163)
[ 5723.180151] proc_reg_read (fs/proc/inode.c:316 fs/proc/inode.c:328)
[ 5723.180155] vfs_read (fs/read_write.c:468)
[ 5723.180160] ? up_read (kernel/locking/rwsem.c:1617)
[ 5723.180164] ksys_read (fs/read_write.c:613)
[ 5723.180168] __x64_sys_read (fs/read_write.c:621)
[ 5723.180170] do_syscall_64 (arch/x86/entry/common.c:?)
[ 5723.180174] entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:120)
[ 5723.180177] RIP: 0033:0x7fa455677d2a

Fixes: 09eed11 ("neighbour: switch to standard rcu, instead of rcu_bh")
	Reported-by: syzbot <syzkaller@googlegroups.com>
	Signed-off-by: Eric Dumazet <edumazet@google.com>
	Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://lore.kernel.org/r/20230510154646.370659-1-edumazet@google.com
	Signed-off-by: Jakub Kicinski <kuba@kernel.org>
(cherry picked from commit ef1148d)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160265
cve-pre CVE-2025-40170
commit-author Vladislav Efanov <VEfanov@ispras.ru>
commit 448a5ce

Syzkaller got the following report:
BUG: KASAN: use-after-free in sk_setup_caps+0x621/0x690 net/core/sock.c:2018
Read of size 8 at addr ffff888027f82780 by task syz-executor276/3255

The function sk_setup_caps (called by ip6_sk_dst_store_flow->
ip6_dst_store) referenced already freed memory as this memory was
freed by parallel task in udpv6_sendmsg->ip6_sk_dst_lookup_flow->
sk_dst_check.

          task1 (connect)              task2 (udp6_sendmsg)
        sk_setup_caps->sk_dst_set |
                                  |  sk_dst_check->
                                  |      sk_dst_set
                                  |      dst_release
        sk_setup_caps references  |
        to already freed dst_entry|

The reason for this race condition is: sk_setup_caps() keeps using
the dst after transferring the ownership to the dst cache.

Found by Linux Verification Center (linuxtesting.org) with syzkaller.

Fixes: 1da177e ("Linux-2.6.12-rc2")
	Signed-off-by: Vladislav Efanov <VEfanov@ispras.ru>
	Signed-off-by: Paolo Abeni <pabeni@redhat.com>
	Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 448a5ce)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160216
cve-pre CVE-2025-40158
commit-author Ido Schimmel <idosch@nvidia.com>
commit 2033ab9

Cited commit converted the neighbour code to use the standard RCU
variant instead of the RCU-bh variant, but the VRF code still uses
rcu_read_lock_bh() / rcu_read_unlock_bh() around the neighbour lookup
code in its IPv4 and IPv6 output paths, resulting in lockdep splats
[1][2]. Can be reproduced using [3].

Fix by switching to rcu_read_lock() / rcu_read_unlock().

[1]
=============================
WARNING: suspicious RCU usage
6.5.0-rc1-custom-g9c099e6dbf98 ctrliq#403 Not tainted
-----------------------------
include/net/neighbour.h:302 suspicious rcu_dereference_check() usage!

other info that might help us debug this:

rcu_scheduler_active = 2, debug_locks = 1
2 locks held by ping/183:
 #0: ffff888105ea1d80 (sk_lock-AF_INET){+.+.}-{0:0}, at: raw_sendmsg+0xc6c/0x33c0
 ctrliq#1: ffffffff85b46820 (rcu_read_lock_bh){....}-{1:2}, at: vrf_output+0x2e3/0x2030

stack backtrace:
CPU: 0 PID: 183 Comm: ping Not tainted 6.5.0-rc1-custom-g9c099e6dbf98 ctrliq#403
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-1.fc37 04/01/2014
Call Trace:
 <TASK>
 dump_stack_lvl+0xc1/0xf0
 lockdep_rcu_suspicious+0x211/0x3b0
 vrf_output+0x1380/0x2030
 ip_push_pending_frames+0x125/0x2a0
 raw_sendmsg+0x200d/0x33c0
 inet_sendmsg+0xa2/0xe0
 __sys_sendto+0x2aa/0x420
 __x64_sys_sendto+0xe5/0x1c0
 do_syscall_64+0x38/0x80
 entry_SYSCALL_64_after_hwframe+0x63/0xcd

[2]
=============================
WARNING: suspicious RCU usage
6.5.0-rc1-custom-g9c099e6dbf98 ctrliq#403 Not tainted
-----------------------------
include/net/neighbour.h:302 suspicious rcu_dereference_check() usage!

other info that might help us debug this:

rcu_scheduler_active = 2, debug_locks = 1
2 locks held by ping6/182:
 #0: ffff888114b63000 (sk_lock-AF_INET6){+.+.}-{0:0}, at: rawv6_sendmsg+0x1602/0x3e50
 ctrliq#1: ffffffff85b46820 (rcu_read_lock_bh){....}-{1:2}, at: vrf_output6+0xe9/0x1310

stack backtrace:
CPU: 0 PID: 182 Comm: ping6 Not tainted 6.5.0-rc1-custom-g9c099e6dbf98 ctrliq#403
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-1.fc37 04/01/2014
Call Trace:
 <TASK>
 dump_stack_lvl+0xc1/0xf0
 lockdep_rcu_suspicious+0x211/0x3b0
 vrf_output6+0xd32/0x1310
 ip6_local_out+0xb4/0x1a0
 ip6_send_skb+0xbc/0x340
 ip6_push_pending_frames+0xe5/0x110
 rawv6_sendmsg+0x2e6e/0x3e50
 inet_sendmsg+0xa2/0xe0
 __sys_sendto+0x2aa/0x420
 __x64_sys_sendto+0xe5/0x1c0
 do_syscall_64+0x38/0x80
 entry_SYSCALL_64_after_hwframe+0x63/0xcd

[3]
#!/bin/bash

ip link add name vrf-red up numtxqueues 2 type vrf table 10
ip link add name swp1 up master vrf-red type dummy
ip address add 192.0.2.1/24 dev swp1
ip address add 2001:db8:1::1/64 dev swp1
ip neigh add 192.0.2.2 lladdr 00:11:22:33:44:55 nud perm dev swp1
ip neigh add 2001:db8:1::2 lladdr 00:11:22:33:44:55 nud perm dev swp1
ip vrf exec vrf-red ping 192.0.2.2 -c 1 &> /dev/null
ip vrf exec vrf-red ping6 2001:db8:1::2 -c 1 &> /dev/null

Fixes: 09eed11 ("neighbour: switch to standard rcu, instead of rcu_bh")
	Reported-by: Naresh Kamboju <naresh.kamboju@linaro.org>
Link: https://lore.kernel.org/netdev/CA+G9fYtEr-=GbcXNDYo3XOkwR+uYgehVoDjsP0pFLUpZ_AZcyg@mail.gmail.com/
	Signed-off-by: Ido Schimmel <idosch@nvidia.com>
	Reviewed-by: David Ahern <dsahern@kernel.org>
	Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://lore.kernel.org/r/20230715153605.4068066-1-idosch@nvidia.com
	Signed-off-by: Paolo Abeni <pabeni@redhat.com>
(cherry picked from commit 2033ab9)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-8330
cve CVE-2024-44986
commit-author Eric Dumazet <edumazet@google.com>
commit da273b3

If skb_expand_head() returns NULL, skb has been freed
and associated dst/idev could also have been freed.

We need to hold rcu_read_lock() to make sure the dst and
associated idev are alive.

Fixes: 5796015 ("ipv6: allocate enough headroom in ip6_finish_output2()")
	Signed-off-by: Eric Dumazet <edumazet@google.com>
	Cc: Vasily Averin <vasily.averin@linux.dev>
	Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://patch.msgid.link/20240820160859.3786976-3-edumazet@google.com
	Signed-off-by: Jakub Kicinski <kuba@kernel.org>
(cherry picked from commit da273b3)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-8328
cve CVE-2024-44985
commit-author Eric Dumazet <edumazet@google.com>
commit 2d5ff7e

If skb_expand_head() returns NULL, skb has been freed
and the associated dst/idev could also have been freed.

We must use rcu_read_lock() to prevent a possible UAF.

Fixes: 0c9f227 ("ipv6: use skb_expand_head in ip6_xmit")
	Signed-off-by: Eric Dumazet <edumazet@google.com>
	Cc: Vasily Averin <vasily.averin@linux.dev>
	Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://patch.msgid.link/20240820160859.3786976-4-edumazet@google.com
	Signed-off-by: Jakub Kicinski <kuba@kernel.org>
(cherry picked from commit 2d5ff7e)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160216
cve-pre CVE-2025-40158
commit-author Jiawei Ye <jiawei.ye@foxmail.com>
commit fb86c42

In the bpf_out_neigh_v6 function, rcu_read_lock() is used to begin an RCU
read-side critical section. However, when unlocking, one branch
incorrectly uses a different RCU unlock flavour rcu_read_unlock_bh()
instead of rcu_read_unlock(). This mismatch in RCU locking flavours can
lead to unexpected behavior and potential concurrency issues.

This possible bug was identified using a static analysis tool developed
by myself, specifically designed to detect RCU-related issues.

This patch corrects the mismatched unlock flavour by replacing the
incorrect rcu_read_unlock_bh() with the appropriate rcu_read_unlock(),
ensuring that the RCU critical section is properly exited. This change
prevents potential synchronization issues and aligns with proper RCU
usage patterns.

Fixes: 09eed11 ("neighbour: switch to standard rcu, instead of rcu_bh")
	Signed-off-by: Jiawei Ye <jiawei.ye@foxmail.com>
	Acked-by: Yonghong Song <yonghong.song@linux.dev>
Link: https://lore.kernel.org/r/tencent_CFD3D1C3D68B45EA9F52D8EC76D2C4134306@qq.com
	Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
(cherry picked from commit fb86c42)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160265
cve-pre CVE-2025-40170
commit-author Eric Dumazet <edumazet@google.com>
commit 4693085

ip4_dst_hoplimit() must use RCU protection to make
sure the net structure it reads does not disappear.

Fixes: fa50d97 ("ipv4: Namespaceify ip_default_ttl sysctl knob")
	Signed-off-by: Eric Dumazet <edumazet@google.com>
	Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Link: https://patch.msgid.link/20250205155120.1676781-3-edumazet@google.com
	Signed-off-by: Jakub Kicinski <kuba@kernel.org>
(cherry picked from commit 4693085)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160265
cve-pre CVE-2025-40170
commit-author Eric Dumazet <edumazet@google.com>
commit 071d801
upstream-diff Used CentOS 9 backport
  4ea98f0 which dealt with the context
  conflicts.

ip_dst_mtu_maybe_forward() must use RCU protection to make
sure the net structure it reads does not disappear.

Fixes: f87c10a ("ipv4: introduce ip_dst_mtu_maybe_forward and protect forwarding path against pmtu spoofing")
	Signed-off-by: Eric Dumazet <edumazet@google.com>
	Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Link: https://patch.msgid.link/20250205155120.1676781-4-edumazet@google.com
	Signed-off-by: Jakub Kicinski <kuba@kernel.org>
(cherry picked from commit 4ea98f0)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-54043
cve CVE-2025-21766
commit-author Eric Dumazet <edumazet@google.com>
commit 1395121
upstream-diff Used CentOS 9 backport
  fd7e9d2 for the clean pick. The
  modified function `__ip_rt_update_pmtu' is identicial in LTS 9.2 and
  CentOS 9.

__ip_rt_update_pmtu() must use RCU protection to make
sure the net structure it reads does not disappear.

Fixes: 2fbc6e8 ("ipv4: Update exception handling for multipath routes via same device")
Fixes: 1de6b15 ("Namespaceify min_pmtu sysctl")
	Signed-off-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20250205155120.1676781-8-edumazet@google.com
	Signed-off-by: Jakub Kicinski <kuba@kernel.org>
(cherry picked from commit fd7e9d2)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-53991
cve CVE-2025-21765
commit-author Eric Dumazet <edumazet@google.com>
commit 3c8ffcd

ip6_default_advmss() needs rcu protection to make
sure the net structure it reads does not disappear.

Fixes: 5578689 ("[NETNS][IPV6] route6 - make route6 per namespace")
	Signed-off-by: Eric Dumazet <edumazet@google.com>
	Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Link: https://patch.msgid.link/20250205155120.1676781-11-edumazet@google.com
	Signed-off-by: Jakub Kicinski <kuba@kernel.org>
(cherry picked from commit 3c8ffcd)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160265
cve-pre CVE-2025-40170
commit-author Eric Dumazet <edumazet@google.com>
commit 88fe142
upstream-diff |
  net/core/dst.c
        Resolved context conflicts in `dst_dev_put' function. (Missing
        commits: f1c5fd3,
        2dce8c5,
        d62607c)
  net/core/sock.c
        - Changes to `sk_dst_gso_max_size()' omitted, because `dst'
          paramater not present in the function (introduced in the
          non-backported b1a78b9 ("net:
          add support for ipv4 big tcp")).
        - In function `sk_setup_caps()', the `dst->dev' to `dst_dev(dst)'
          conversion applied also in the `sk->sk_gso_max_size'
          assignment. (Ine the upstream this is delegated to the
          aforementioned `sk_dst_gso_max_size()' function.)

dst->dev is read locklessly in many contexts,
and written in dst_dev_put().

Fixing all the races is going to need many changes.

We probably will have to add full RCU protection.

Add three helpers to ease this painful process.

static inline struct net_device *dst_dev(const struct dst_entry *dst)
{
       return READ_ONCE(dst->dev);
}

static inline struct net_device *skb_dst_dev(const struct sk_buff *skb)
{
       return dst_dev(skb_dst(skb));
}

static inline struct net *skb_dst_dev_net(const struct sk_buff *skb)
{
       return dev_net(skb_dst_dev(skb));
}

static inline struct net *skb_dst_dev_net_rcu(const struct sk_buff *skb)
{
       return dev_net_rcu(skb_dst_dev(skb));
}

Fixes: 4a6ce2b ("net: introduce a new function dst_dev_put()")
	Signed-off-by: Eric Dumazet <edumazet@google.com>
	Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20250630121934.3399505-7-edumazet@google.com
	Signed-off-by: Jakub Kicinski <kuba@kernel.org>
(cherry picked from commit 88fe142)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160160
cve-pre CVE-2025-40135
commit-author Sharath Chandra Vurukala <quic_sharathv@quicinc.com>
commit 1dbf1d5
upstream-diff Resolved context conflicts in `ip_output()' due to
  missing a74fc62 ("ipv4: adopt
  dst_dev, skb_dst_dev and skb_dst_dev_net[_rcu]")

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 <quic_sharathv@quicinc.com>
	Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20250730105118.GA26100@hu-sharathv-hyd.qualcomm.com
	Signed-off-by: Jakub Kicinski <kuba@kernel.org>
(cherry picked from commit 1dbf1d5)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160265
cve-pre CVE-2025-40170
commit-author Eric Dumazet <edumazet@google.com>
commit caedcc5
upstream-diff Used CentOS 9 backport
  ca6810f as a clean cherry-pick base.
  - Used RH_KABI_REPLACE in `struct dst_entry' to silence the kABI
    checker. Originally the `struct net_device *dev' field was changed
    into a union of `struct net_device *dev' and `struct net_device __rcu
    *dev_rcu'. The latter has the same size and alignment as the former
    (this is actually checked statically by the RH_KABI_REPLACE macro),
    with the `__rcu' annotation serving only at compile time and being
    invisible to the binary output. The `dev_rcu' is therefore just an
    alias for the `dev' field.
  - Omitted changes to the `ipv4_default_advmss()' function because no
    `dst->dev' is being referenced there in LTS 9.2 (and CentOS 9). The
    `ip_rt_min_advmss' parameter was made dev-specific in commit
    2e9589f ("ipv4: Namespaceify
    min_adv_mss sysctl knob").
  - Resolved context conflicts in `dst_dev_put()' due to missing
    d62607c ("net: rename
    reference+tracking helpers")

Followup of commit 88fe142 ("net: dst: add four helpers
to annotate data-races around dst->dev").

We want to gradually add explicit RCU protection to dst->dev,
including lockdep support.

Add an union to alias dst->dev_rcu and dst->dev.

Add dst_dev_net_rcu() helper.

Fixes: 4a6ce2b ("net: introduce a new function dst_dev_put()")
	Signed-off-by: Eric Dumazet <edumazet@google.com>
	Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://patch.msgid.link/20250828195823.3958522-2-edumazet@google.com
	Signed-off-by: Jakub Kicinski <kuba@kernel.org>
(cherry picked from commit ca6810f)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160160
cve CVE-2025-40135
commit-author Eric Dumazet <edumazet@google.com>
commit 9085e56
upstream-diff Used CentOS 9 backport
  f37f7b3 for a clean pick. It deals
  already with the similarly non-backported commit
  1caf272 ("ipv6: adopt dst_dev()
  helper").

Use RCU in ip6_xmit() in order to use dst_dev_rcu() to prevent
possible UAF.

Fixes: 4a6ce2b ("net: introduce a new function dst_dev_put()")
	Signed-off-by: Eric Dumazet <edumazet@google.com>
	Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://patch.msgid.link/20250828195823.3958522-4-edumazet@google.com
	Signed-off-by: Jakub Kicinski <kuba@kernel.org>
(cherry picked from commit f37f7b3)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160216
cve CVE-2025-40158
commit-author Eric Dumazet <edumazet@google.com>
commit 1170957
upstream-diff Used CentOS 9 backport
  9b21011 as the base. It deals with
  the similarly non-backported commits
  1caf272 and
  93d1cff. Resolved some context
  conflicts in `ip6_finish_output2()'.

Use RCU in ip6_output() in order to use dst_dev_rcu() to prevent
possible UAF.

We can remove rcu_read_lock()/rcu_read_unlock() pairs
from ip6_finish_output2().

Fixes: 4a6ce2b ("net: introduce a new function dst_dev_put()")
	Signed-off-by: Eric Dumazet <edumazet@google.com>
	Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://patch.msgid.link/20250828195823.3958522-5-edumazet@google.com
	Signed-off-by: Jakub Kicinski <kuba@kernel.org>
(cherry picked from commit 9b21011)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-160265
cve CVE-2025-40170
commit-author Eric Dumazet <edumazet@google.com>
commit 99a2ace
upstream-diff Used CentOS 9 backport
  acc5b1b as the base. It dealt already
  with the missing commits:
  - a74fc62 ("ipv4: adopt dst_dev,
    skb_dst_dev and skb_dst_dev_net[_rcu]")
  - 1caf272 ("ipv6: adopt dst_dev()
    helper")
  Additionally, in net/core/sock.c:
  - Omitted changes to the `sk_trim_gso_size()' function
    (`sk_dst_gso_max_size()' in the upstream), because `dst->dev' is not
    used there (introduced in 5a01b46
    ("net: add support for ipv4 big tcp")).
  - In `sk_setup_caps()', instead of changing the last argument of the
    nonexistent `sk_dst_gso_max_size()' call from `dst' to `dev' a
    `dst_dev(dst)' to `dev' substitution was made similarly to how it was
    done 4 lines later.

Use RCU to protect accesses to dst->dev from sk_setup_caps()
and sk_dst_gso_max_size().

Also use dst_dev_rcu() in ip6_dst_mtu_maybe_forward(),
and ip_dst_mtu_maybe_forward().

ip4_dst_hoplimit() can use dst_dev_net_rcu().

Fixes: 4a6ce2b ("net: introduce a new function dst_dev_put()")
	Signed-off-by: Eric Dumazet <edumazet@google.com>
	Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://patch.msgid.link/20250828195823.3958522-6-edumazet@google.com
	Signed-off-by: Jakub Kicinski <kuba@kernel.org>
(cherry picked from commit acc5b1b)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
@pvts-mat
pvts-mat force-pushed the CVE-batch-43_ciqlts9_2 branch from 139de76 to 4bcf01b Compare August 18, 2026 19:05
@github-actions

Copy link
Copy Markdown

🤖 Validation Checks In Progress Workflow run: https://github.com/ctrliq/kernel-src-tree/actions/runs/32178826591

@github-actions

Copy link
Copy Markdown

🔍 Interdiff Analysis

  • ⚠️ PR commit 73cd9154b9d (net: ipv4: Consolidate ipv4_mtu and ip_dst_mtu_maybe_forward) → upstream ac6627a28dbf
    Differences found:
================================================================================
*    CONTEXT DIFFERENCES - surrounding code differences between the patches    *
================================================================================

--- b/include/net/ip.h
+++ b/include/net/ip.h
@@ -436,7 +436,7 @@
 	struct net *net = dev_net(dst->dev);
 	unsigned int mtu;
 
-	if (READ_ONCE(net->ipv4.sysctl_ip_fwd_use_pmtu) ||
+	if (net->ipv4.sysctl_ip_fwd_use_pmtu ||
 	    ip_mtu_locked(dst) ||
 	    !forwarding)
 		return dst_mtu(dst);
  • ⚠️ PR commit 8daef1f4d0a (neighbour: switch to standard rcu, instead of rcu_bh) → upstream 09eed1192cec
    Differences found:
================================================================================
*    DELTA DIFFERENCES - code changes that differ between the patches          *
================================================================================

--- b/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1017,7 +1017,7 @@
 	unsigned int hash = inet6_addr_hash(dev_net(dev), &ifa->addr);
 	int err = 0;
 
-	spin_lock_bh(&addrconf_hash_lock);
+	spin_lock(&addrconf_hash_lock);
 
 	/* Ignore adding duplicate addresses on an interface */
 	if (ipv6_chk_same_addr(dev_net(dev), &ifa->addr, dev, hash)) {
@@ -1027,7 +1027,7 @@
 		hlist_add_head_rcu(&ifa->addr_lst, &inet6_addr_lst[hash]);
 	}
 
-	spin_unlock_bh(&addrconf_hash_lock);
+	spin_unlock(&addrconf_hash_lock);
 
 	return err;
 }

################################################################################
!    REJECTED PATCH2 HUNKS - could not be compared; manual review needed       !
################################################################################

--- b/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1034,7 +1034,7 @@
 	unsigned int hash = inet6_addr_hash(net, &ifa->addr);
 	int err = 0;
 
-	spin_lock(&net->ipv6.addrconf_hash_lock);
+	spin_lock_bh(&net->ipv6.addrconf_hash_lock);
 
 	/* Ignore adding duplicate addresses on an interface */
 	if (ipv6_chk_same_addr(net, &ifa->addr, dev, hash)) {
@@ -1044,7 +1044,7 @@
 		hlist_add_head_rcu(&ifa->addr_lst, &net->ipv6.inet6_addr_lst[hash]);
 	}
 
-	spin_unlock(&net->ipv6.addrconf_hash_lock);
+	spin_unlock_bh(&net->ipv6.addrconf_hash_lock);
 
 	return err;
 }
--- b/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1154,7 +1154,7 @@
 	n = __ipv6_neigh_lookup_noref(rt->dst.dev,
 				      rt6_nexthop(rt, &fl6->daddr));
 	err = n && !(READ_ONCE(n->nud_state) & NUD_VALID) ? -EINVAL : 0;
-	rcu_read_unlock_bh();
+	rcu_read_unlock();
 
 	if (err) {
 		struct inet6_ifaddr *ifp;

================================================================================
*    CONTEXT DIFFERENCES - surrounding code differences between the patches    *
================================================================================

--- b/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -3055,4 +3198,4 @@
-			if (n->nud_state & ~NUD_NOARP)
+			if (READ_ONCE(n->nud_state) & ~NUD_NOARP)
 				break;
 next:
 			n = rcu_dereference_bh(n->next);
@@ -3097,4 +3240,4 @@
-			if (n->nud_state & ~NUD_NOARP)
+			if (READ_ONCE(n->nud_state) & ~NUD_NOARP)
 				break;
 next:
 			n = rcu_dereference_bh(n->next);
--- b/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -2222,5 +2202,5 @@
 		if (n)
-			state = n->nud_state;
+			state = READ_ONCE(n->nud_state);
 
 		rcu_read_unlock_bh();
 	}
--- b/net/ipv4/nexthop.c
+++ b/net/ipv4/nexthop.c
@@ -1128,7 +1128,7 @@
 
 	n = __ipv6_neigh_lookup_noref_stub(nh->fib_nh_dev, &nh->fib_nh_gw6);
 	if (n)
-		state = n->nud_state;
+		state = READ_ONCE(n->nud_state);
 
 	rcu_read_unlock_bh();
 
@@ -1145,7 +1145,7 @@
 	n = __ipv4_neigh_lookup_noref(nh->fib_nh_dev,
 				      (__force u32)nh->fib_nh_gw4);
 	if (n)
-		state = n->nud_state;
+		state = READ_ONCE(n->nud_state);
 
 	rcu_read_unlock_bh();
 
--- b/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1014,5 +1015,5 @@
 	int err = 0;
 
-	spin_lock(&addrconf_hash_lock);
+	spin_lock(&net->ipv6.addrconf_hash_lock);
 
 	/* Ignore adding duplicate addresses on an interface */
@@ -1020,7 +1020,8 @@
-		hlist_add_head_rcu(&ifa->addr_lst, &inet6_addr_lst[hash]);
+	if (ipv6_chk_same_addr(net, &ifa->addr, dev, hash)) {
+		hlist_add_head_rcu(&ifa->addr_lst, &net->ipv6.inet6_addr_lst[hash]);
 	}
 
-	spin_unlock(&addrconf_hash_lock);
+	spin_unlock(&net->ipv6.addrconf_hash_lock);
 
 	return err;
 }
--- b/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1150,7 +1150,7 @@
 	rcu_read_lock_bh();
 	n = __ipv6_neigh_lookup_noref(rt->dst.dev,
 				      rt6_nexthop(rt, &fl6->daddr));
-	err = n && !(n->nud_state & NUD_VALID) ? -EINVAL : 0;
+	err = n && !(READ_ONCE(n->nud_state) & NUD_VALID) ? -EINVAL : 0;
 	rcu_read_unlock_bh();
 
 	if (err) {
--- b/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -635,4 +634,5 @@
+	neigh = __ipv6_neigh_lookup_noref(dev, nh_gw);
-		if (neigh->nud_state & NUD_VALID)
+		if (READ_ONCE(neigh->nud_state) & NUD_VALID)
 			goto out;
 
 		write_lock(&neigh->lock);
  • ⚠️ PR commit 0c9e392128c (ipv4: use RCU protection in ip_dst_mtu_maybe_forward()) → upstream 071d8012869b
    Differences found:
################################################################################
!    REJECTED PATCH2 HUNKS - could not be compared; manual review needed       !
################################################################################

--- b/include/net/ip.h
+++ b/include/net/ip.h
@@ -471,8 +471,10 @@
 						    bool forwarding)
 {
 	const struct rtable *rt = dst_rtable(dst);
-	struct net *net = dev_net(dst->dev);
-	unsigned int mtu;
+	unsigned int mtu, res;
+	struct net *net;
+
+	rcu_read_lock();
 
 	if (READ_ONCE(net->ipv4.sysctl_ip_fwd_use_pmtu) ||
 	    ip_mtu_locked(dst) ||

================================================================================
*    CONTEXT DIFFERENCES - surrounding code differences between the patches    *
================================================================================

--- b/include/net/ip.h
+++ b/include/net/ip.h
@@ -438,6 +438,6 @@
 						    bool forwarding)
 {
-	const struct rtable *rt = container_of(dst, struct rtable, dst);
+	const struct rtable *rt = dst_rtable(dst);
 	struct net *net = dev_net(dst->dev);
 	unsigned int mtu;
  • ⚠️ PR commit d2cf3cc09f5 (ipv4: use RCU protection in __ip_rt_update_pmtu()) → upstream 139512191bd0
    Differences found:
################################################################################
!    REJECTED PATCH2 HUNKS - could not be compared; manual review needed       !
################################################################################

--- b/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1020,6 +1020,8 @@
 	if (old_mtu < mtu)
 		return;
 
+	rcu_read_lock();
+	net = dev_net_rcu(dst->dev);
 	if (mtu < net->ipv4.ip_rt_min_pmtu) {
 		lock = true;
 		mtu = min(old_mtu, net->ipv4.ip_rt_min_pmtu);
@@ -1027,7 +1029,7 @@
 
 	if (rt->rt_pmtu == mtu && !lock &&
 	    time_before(jiffies, dst->expires - net->ipv4.ip_rt_mtu_expires / 2))
-		return;
+		goto out;
 
 	rcu_read_lock();
 	if (fib_lookup(net, fl4, &res, 0) == 0) {
@@ -1042,8 +1043,7 @@
 				update_or_create_fnhe(nhc, fl4->daddr, 0, mtu, lock,
 						      jiffies + net->ipv4.ip_rt_mtu_expires);
 			}
-			rcu_read_unlock();
-			return;
+			goto out;
 		}
 #endif /* CONFIG_IP_ROUTE_MULTIPATH */
 		nhc = FIB_RES_NHC(res);

================================================================================
*    CONTEXT DIFFERENCES - surrounding code differences between the patches    *
================================================================================

--- b/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1034,6 +1020,6 @@
 	if (old_mtu < mtu)
 		return;
 
-	if (mtu < ip_rt_min_pmtu) {
+	if (mtu < net->ipv4.ip_rt_min_pmtu) {
 		lock = true;
-		mtu = min(old_mtu, ip_rt_min_pmtu);
+		mtu = min(old_mtu, net->ipv4.ip_rt_min_pmtu);
@@ -1040,6 +1026,6 @@
 
 	if (rt->rt_pmtu == mtu && !lock &&
-	    time_before(jiffies, dst->expires - ip_rt_mtu_expires / 2))
+	    time_before(jiffies, dst->expires - net->ipv4.ip_rt_mtu_expires / 2))
 		return;
 
 	rcu_read_lock();
@@ -1049,5 +1043,5 @@
 		update_or_create_fnhe(nhc, fl4->daddr, 0, mtu, lock,
-				      jiffies + ip_rt_mtu_expires);
+				      jiffies + net->ipv4.ip_rt_mtu_expires);
 	}
 	rcu_read_unlock();
 }
  • ⚠️ PR commit dfd72b87bb1 (net: dst: add four helpers to annotate data-races around dst->dev) → upstream 88fe14253e18
    Differences found:
================================================================================
*    DELTA DIFFERENCES - code changes that differ between the patches          *
================================================================================

--- b/net/core/sock.c
+++ b/net/core/sock.c
@@ -2298,7 +2298,7 @@
 		} else {
 			sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM;
 			/* pairs with the WRITE_ONCE() in netif_set_gso_max_size() */
-			sk->sk_gso_max_size = READ_ONCE(dst_dev(dst)->gso_max_size);
+			sk->sk_gso_max_size = READ_ONCE(dst->dev->gso_max_size);
 			sk_trim_gso_size(sk);
 			sk->sk_gso_max_size -= (MAX_TCP_HEADER + 1);
 			/* pairs with the WRITE_ONCE() in netif_set_gso_max_segs() */

################################################################################
!    REJECTED PATCH2 HUNKS - could not be compared; manual review needed       !
################################################################################

--- b/net/core/dst.c
+++ b/net/core/dst.c
@@ -150,7 +150,7 @@
 		dst->ops->ifdown(dst, dev);
 	WRITE_ONCE(dst->input, dst_discard);
 	WRITE_ONCE(dst->output, dst_discard_out);
-	dst->dev = blackhole_netdev;
+	WRITE_ONCE(dst->dev, blackhole_netdev);
 	netdev_ref_replace(dev, blackhole_netdev, &dst->dev_tracker,
 			   GFP_ATOMIC);
 }
--- b/net/core/sock.c
+++ b/net/core/sock.c
@@ -2588,8 +2588,8 @@
 		   !ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr));
 #endif
 	/* pairs with the WRITE_ONCE() in netif_set_gso(_ipv4)_max_size() */
-	max_size = is_ipv6 ? READ_ONCE(dst->dev->gso_max_size) :
-			READ_ONCE(dst->dev->gso_ipv4_max_size);
+	max_size = is_ipv6 ? READ_ONCE(dst_dev(dst)->gso_max_size) :
+			READ_ONCE(dst_dev(dst)->gso_ipv4_max_size);
 	if (max_size > GSO_LEGACY_MAX_SIZE && !sk_is_tcp(sk))
 		max_size = GSO_LEGACY_MAX_SIZE;
 
@@ -2600,7 +2600,7 @@
 {
 	u32 max_segs = 1;
 
-	sk->sk_route_caps = dst->dev->features;
+	sk->sk_route_caps = dst_dev(dst)->features;
 	if (sk_is_tcp(sk)) {
 		struct inet_connection_sock *icsk = inet_csk(sk);
 

================================================================================
*    CONTEXT DIFFERENCES - surrounding code differences between the patches    *
================================================================================

--- b/net/core/dst.c
+++ b/net/core/dst.c
@@ -147,7 +147,7 @@
-		dst->ops->ifdown(dst, dev, true);
-	dst->input = dst_discard;
-	dst->output = dst_discard_out;
+		dst->ops->ifdown(dst, dev);
+	WRITE_ONCE(dst->input, dst_discard);
+	WRITE_ONCE(dst->output, dst_discard_out);
 	dst->dev = blackhole_netdev;
-	dev_replace_track(dev, blackhole_netdev, &dst->dev_tracker,
-			  GFP_ATOMIC);
+	netdev_ref_replace(dev, blackhole_netdev, &dst->dev_tracker,
+			   GFP_ATOMIC);
 }
--- b/net/core/sock.c
+++ b/net/core/sock.c
@@ -2282,7 +2290,7 @@
 {
 	u32 max_segs = 1;
 
 	sk->sk_route_caps = dst->dev->features;
-	if (sk_is_tcp(sk))
-		sk->sk_route_caps |= NETIF_F_GSO;
-	if (sk->sk_route_caps & NETIF_F_GSO)
+	if (sk_is_tcp(sk)) {
+		struct inet_connection_sock *icsk = inet_csk(sk);
+
@@ -2290,8 +2297,5 @@
 			sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM;
-			/* pairs with the WRITE_ONCE() in netif_set_gso_max_size() */
-			sk->sk_gso_max_size = READ_ONCE(dst->dev->gso_max_size);
-			sk_trim_gso_size(sk);
-			sk->sk_gso_max_size -= (MAX_TCP_HEADER + 1);
+			sk->sk_gso_max_size = sk_dst_gso_max_size(sk, dst);
 			/* pairs with the WRITE_ONCE() in netif_set_gso_max_segs() */
 			max_segs = max_t(u32, READ_ONCE(dst->dev->gso_max_segs), 1);
 		}
  • ⚠️ PR commit 5ee590c4dc6 (net: Add locking to protect skb->dev access in ip_output) → upstream 1dbf1d590d10
    Differences found:
================================================================================
*    DELTA DIFFERENCES - code changes that differ between the patches          *
================================================================================

--- b/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -420,8 +420,7 @@
 
 int ip_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 {
-	struct net_device *dev, *indev = skb->dev;
-	int ret_val;
+	struct net_device *dev = skb_dst(skb)->dev, *indev = skb->dev;
 
 	IP_UPD_PO_STATS(net, IPSTATS_MIB_OUT, skb->len);
 

################################################################################
!    REJECTED PATCH2 HUNKS - could not be compared; manual review needed       !
################################################################################

--- b/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -425,7 +425,8 @@
 
 int ip_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 {
-	struct net_device *dev = skb_dst_dev(skb), *indev = skb->dev;
+	struct net_device *dev, *indev = skb->dev;
+	int ret_val;
 
 	skb->dev = dev;
 	skb->protocol = htons(ETH_P_IP);

================================================================================
*    CONTEXT DIFFERENCES - surrounding code differences between the patches    *
================================================================================

--- b/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -417,9 +417,7 @@
 
 int ip_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 {
-	struct net_device *dev = skb_dst(skb)->dev, *indev = skb->dev;
-
-	IP_UPD_PO_STATS(net, IPSTATS_MIB_OUT, skb->len);
+	struct net_device *dev = skb_dst_dev(skb), *indev = skb->dev;
 
 	skb->dev = dev;
 	skb->protocol = htons(ETH_P_IP);
  • ⚠️ PR commit 811de06e9b5 (net: dst: introduce dst->dev_rcu) → upstream caedcc5b6df1
    Differences found:
================================================================================
*    DELTA DIFFERENCES - code changes that differ between the patches          *
================================================================================

--- b/include/net/dst.h
+++ b/include/net/dst.h
@@ -23,12 +23,10 @@
 struct sk_buff;
 
 struct dst_entry {
-	RH_KABI_REPLACE(
-		struct net_device       *dev,
-		union {
-			struct net_device       *dev;
-			struct net_device __rcu *dev_rcu;
-		})
+	union {
+		struct net_device       *dev;
+		struct net_device __rcu *dev_rcu;
+	};
 	struct  dst_ops	        *ops;
 	unsigned long		_metrics;
 	unsigned long           expires;
--- b/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1035,7 +1035,7 @@
 		return;
 
 	rcu_read_lock();
-	net = dst_dev_net_rcu(dst);
+	net = dev_net_rcu(dst->dev);
 	if (mtu < ip_rt_min_pmtu) {
 		lock = true;
 		mtu = min(old_mtu, ip_rt_min_pmtu);

################################################################################
!    REJECTED PATCH2 HUNKS - could not be compared; manual review needed       !
################################################################################

--- b/net/core/dst.c
+++ b/net/core/dst.c
@@ -150,7 +150,7 @@
 		dst->ops->ifdown(dst, dev);
 	WRITE_ONCE(dst->input, dst_discard);
 	WRITE_ONCE(dst->output, dst_discard_out);
-	WRITE_ONCE(dst->dev, blackhole_netdev);
+	rcu_assign_pointer(dst->dev_rcu, blackhole_netdev);
 	netdev_ref_replace(dev, blackhole_netdev, &dst->dev_tracker,
 			   GFP_ATOMIC);
 }
--- b/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1027,7 +1027,7 @@
 		return;
 
 	rcu_read_lock();
-	net = dev_net_rcu(dst_dev(dst));
+	net = dst_dev_net_rcu(dst);
 	if (mtu < net->ipv4.ip_rt_min_pmtu) {
 		lock = true;
 		mtu = min(old_mtu, net->ipv4.ip_rt_min_pmtu);
@@ -1327,7 +1327,7 @@
 	struct net *net;
 
 	rcu_read_lock();
-	net = dev_net_rcu(dst_dev(dst));
+	net = dst_dev_net_rcu(dst);
 	advmss = max_t(unsigned int, ipv4_mtu(dst) - header_size,
 				   net->ipv4.ip_rt_min_advmss);
 	rcu_read_unlock();

================================================================================
*    CONTEXT DIFFERENCES - surrounding code differences between the patches    *
================================================================================

--- b/net/core/dst.c
+++ b/net/core/dst.c
@@ -147,7 +147,7 @@
-		dst->ops->ifdown(dst, dev, true);
-	dst->input = dst_discard;
-	dst->output = dst_discard_out;
+		dst->ops->ifdown(dst, dev);
+	WRITE_ONCE(dst->input, dst_discard);
+	WRITE_ONCE(dst->output, dst_discard_out);
 	WRITE_ONCE(dst->dev, blackhole_netdev);
-	dev_replace_track(dev, blackhole_netdev, &dst->dev_tracker,
-			  GFP_ATOMIC);
+	netdev_ref_replace(dev, blackhole_netdev, &dst->dev_tracker,
+			   GFP_ATOMIC);
 }
--- b/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1032,6 +1040,6 @@
 
 	rcu_read_lock();
-	net = dev_net_rcu(dst->dev);
-	if (mtu < ip_rt_min_pmtu) {
-		lock = true;
-		mtu = min(old_mtu, ip_rt_min_pmtu);
+	net = dev_net_rcu(dst_dev(dst));
+	advmss = max_t(unsigned int, ipv4_mtu(dst) - header_size,
+				   net->ipv4.ip_rt_min_advmss);
+	rcu_read_unlock();
  • ⚠️ PR commit 541ee876d36 (ipv6: use RCU in ip6_xmit()) → upstream 9085e56501d9
    Differences found:
================================================================================
*    DELTA DIFFERENCES - code changes that differ between the patches          *
================================================================================

--- b/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -256,6 +256,7 @@
 	const struct ipv6_pinfo *np = inet6_sk(sk);
 	struct in6_addr *first_hop = &fl6->daddr;
 	struct dst_entry *dst = skb_dst(skb);
+	struct net_device *dev = dst->dev;
 	struct inet6_dev *idev = ip6_dst_idev(dst);
 	struct hop_jumbo_hdr *hop_jumbo;
 	int hoplen = sizeof(*hop_jumbo);

################################################################################
!    REJECTED PATCH2 HUNKS - could not be compared; manual review needed       !
################################################################################

--- b/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -271,7 +270,6 @@
 	const struct ipv6_pinfo *np = inet6_sk(sk);
 	struct in6_addr *first_hop = &fl6->daddr;
 	struct dst_entry *dst = skb_dst(skb);
-	struct net_device *dev = dst_dev(dst);
 	struct inet6_dev *idev = ip6_dst_idev(dst);
 	struct hop_jumbo_hdr *hop_jumbo;
 	int hoplen = sizeof(*hop_jumbo);

================================================================================
*    CONTEXT DIFFERENCES - surrounding code differences between the patches    *
================================================================================

--- b/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -257,7 +272,7 @@
 	const struct ipv6_pinfo *np = inet6_sk(sk);
 	struct in6_addr *first_hop = &fl6->daddr;
 	struct dst_entry *dst = skb_dst(skb);
-	struct net_device *dev = dst->dev;
+	struct net_device *dev = dst_dev(dst);
 	struct inet6_dev *idev = ip6_dst_idev(dst);
 	struct hop_jumbo_hdr *hop_jumbo;
 	int hoplen = sizeof(*hop_jumbo);
  • ⚠️ PR commit 53772374ea4 (ipv6: use RCU in ip6_output()) → upstream 11709573cc4e
    Differences found:
================================================================================
*    DELTA DIFFERENCES - code changes that differ between the patches          *
================================================================================

--- b/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -59,7 +59,7 @@
 static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *skb)
 {
 	struct dst_entry *dst = skb_dst(skb);
-	struct net_device *dev = dst_dev_rcu(dst);
+	struct net_device *dev = dst->dev;
 	struct inet6_dev *idev = ip6_dst_idev(dst);
 	unsigned int hh_len = LL_RESERVED_SPACE(dev);
 	const struct in6_addr *daddr, *nexthop;
@@ -211,10 +212,8 @@
 
 int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 {
-	struct dst_entry *dst = skb_dst(skb);
-	struct net_device *dev, *indev = skb->dev;
-	struct inet6_dev *idev;
-	int ret;
+	struct net_device *dev = skb_dst(skb)->dev, *indev = skb->dev;
+	struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
 
 	skb->protocol = htons(ETH_P_IPV6);
 	rcu_read_lock();

################################################################################
!    REJECTED PATCH2 HUNKS - could not be compared; manual review needed       !
################################################################################

--- b/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -60,7 +60,7 @@
 static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *skb)
 {
 	struct dst_entry *dst = skb_dst(skb);
-	struct net_device *dev = dst_dev(dst);
+	struct net_device *dev = dst_dev_rcu(dst);
 	struct inet6_dev *idev = ip6_dst_idev(dst);
 	unsigned int hh_len = LL_RESERVED_SPACE(dev);
 	const struct in6_addr *daddr, *nexthop;
@@ -120,7 +117,6 @@
 
 	IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
 
-	rcu_read_lock();
 	nexthop = rt6_nexthop(dst_rt6_info(dst), daddr);
 	neigh = __ipv6_neigh_lookup_noref(dev, nexthop);
 
@@ -228,8 +222,9 @@
 int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 {
 	struct dst_entry *dst = skb_dst(skb);
-	struct net_device *dev = dst_dev(dst), *indev = skb->dev;
-	struct inet6_dev *idev = ip6_dst_idev(dst);
+	struct net_device *dev, *indev = skb->dev;
+	struct inet6_dev *idev;
+	int ret;
 
 	skb->protocol = htons(ETH_P_IPV6);
 	skb->dev = dev;

================================================================================
*    CONTEXT DIFFERENCES - surrounding code differences between the patches    *
================================================================================

--- b/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -56,7 +56,7 @@
 static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *skb)
 {
 	struct dst_entry *dst = skb_dst(skb);
-	struct net_device *dev = dst->dev;
+	struct net_device *dev = dst_dev(dst);
 	struct inet6_dev *idev = ip6_dst_idev(dst);
 	unsigned int hh_len = LL_RESERVED_SPACE(dev);
 	const struct in6_addr *daddr, *nexthop;
@@ -117,7 +115,7 @@
-			return res;
-	}
+
+	IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
 
 	rcu_read_lock();
-	nexthop = rt6_nexthop((struct rt6_info *)dst, daddr);
+	nexthop = rt6_nexthop(dst_rt6_info(dst), daddr);
 	neigh = __ipv6_neigh_lookup_noref(dev, nexthop);
 
@@ -214,12 +215,13 @@
 int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 {
-	struct net_device *dev = skb_dst(skb)->dev, *indev = skb->dev;
-	struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
+	struct dst_entry *dst = skb_dst(skb);
+	struct net_device *dev = dst_dev(dst), *indev = skb->dev;
+	struct inet6_dev *idev = ip6_dst_idev(dst);
 
 	skb->protocol = htons(ETH_P_IPV6);
 	skb->dev = dev;
 
-	if (unlikely(idev->cnf.disable_ipv6)) {
+	if (unlikely(!idev || READ_ONCE(idev->cnf.disable_ipv6))) {
 		IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
 		kfree_skb_reason(skb, SKB_DROP_REASON_IPV6DISABLED);
 		return 0;
  • ⚠️ PR commit 4bcf01b2a53 (net: use dst_dev_rcu() in sk_setup_caps()) → upstream 99a2ace61b21
    Differences found:
================================================================================
*    DELTA DIFFERENCES - code changes that differ between the patches          *
================================================================================

--- b/include/net/ip.h
+++ b/include/net/ip.h
@@ -441,14 +441,12 @@
 						    bool forwarding)
 {
 	const struct rtable *rt = container_of(dst, struct rtable, dst);
-	const struct net_device *dev;
 	unsigned int mtu, res;
 	struct net *net;
 
 	rcu_read_lock();
 
-	dev = dst_dev_rcu(dst);
-	net = dev_net_rcu(dev);
+	net = dev_net_rcu(dst->dev);
 	if (READ_ONCE(net->ipv4.sysctl_ip_fwd_use_pmtu) ||
 	    ip_mtu_locked(dst) ||
 	    !forwarding) {
@@ -462,7 +460,7 @@
 	if (mtu)
 		goto out;
 
-	mtu = READ_ONCE(dev->mtu);
+	mtu = READ_ONCE(dst->dev->mtu);
 
 	if (unlikely(ip_mtu_locked(dst))) {
 		if (rt->rt_uses_gateway && mtu > 576)
--- b/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -330,7 +330,7 @@
 
 	mtu = IPV6_MIN_MTU;
 	rcu_read_lock();
-	idev = __in6_dev_get(dst_dev_rcu(dst));
+	idev = __in6_dev_get(dst->dev);
 	if (idev)
 		mtu = idev->cnf.mtu6;
 	rcu_read_unlock();
--- b/include/net/route.h
+++ b/include/net/route.h
@@ -363,7 +363,7 @@
 		const struct net *net;
 
 		rcu_read_lock();
-		net = dst_dev_net_rcu(dst);
+		net = dev_net_rcu(dst->dev);
 		hoplimit = READ_ONCE(net->ipv4.sysctl_ip_default_ttl);
 		rcu_read_unlock();
 	}
--- b/net/core/sock.c
+++ b/net/core/sock.c
@@ -2301,7 +2299,7 @@
 		} else {
 			sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM;
 			/* pairs with the WRITE_ONCE() in netif_set_gso_max_size() */
-			sk->sk_gso_max_size = READ_ONCE(dev->gso_max_size);
+			sk->sk_gso_max_size = READ_ONCE(dst_dev(dst)->gso_max_size);
 			sk_trim_gso_size(sk);
 			sk->sk_gso_max_size -= (MAX_TCP_HEADER + 1);
 			/* pairs with the WRITE_ONCE() in netif_set_gso_max_segs() */

################################################################################
!    REJECTED PATCH2 HUNKS - could not be compared; manual review needed       !
################################################################################

--- b/include/net/ip.h
+++ b/include/net/ip.h
@@ -467,6 +467,7 @@
 						    bool forwarding)
 {
 	const struct rtable *rt = dst_rtable(dst);
+	const struct net_device *dev;
 	unsigned int mtu, res;
 	struct net *net;
 
@@ -470,7 +471,8 @@
 
 	rcu_read_lock();
 
-	net = dev_net_rcu(dst_dev(dst));
+	dev = dst_dev_rcu(dst);
+	net = dev_net_rcu(dev);
 	if (READ_ONCE(net->ipv4.sysctl_ip_fwd_use_pmtu) ||
 	    ip_mtu_locked(dst) ||
 	    !forwarding) {
@@ -486,7 +488,7 @@
 	if (mtu)
 		goto out;
 
-	mtu = READ_ONCE(dst_dev(dst)->mtu);
+	mtu = READ_ONCE(dev->mtu);
 
 	if (unlikely(ip_mtu_locked(dst))) {
 		if (rt->rt_uses_gateway && mtu > 576)
--- b/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -337,7 +337,7 @@
 
 	mtu = IPV6_MIN_MTU;
 	rcu_read_lock();
-	idev = __in6_dev_get(dst_dev(dst));
+	idev = __in6_dev_get(dst_dev_rcu(dst));
 	if (idev)
 		mtu = READ_ONCE(idev->cnf.mtu6);
 	rcu_read_unlock();
--- b/include/net/route.h
+++ b/include/net/route.h
@@ -390,7 +390,7 @@
 		const struct net *net;
 
 		rcu_read_lock();
-		net = dev_net_rcu(dst_dev(dst));
+		net = dst_dev_net_rcu(dst);
 		hoplimit = READ_ONCE(net->ipv4.sysctl_ip_default_ttl);
 		rcu_read_unlock();
 	}
--- b/net/core/sock.c
+++ b/net/core/sock.c
@@ -2587,7 +2587,7 @@
 }
 EXPORT_SYMBOL_GPL(sk_clone_lock);
 
-static u32 sk_dst_gso_max_size(struct sock *sk, struct dst_entry *dst)
+static u32 sk_dst_gso_max_size(struct sock *sk, const struct net_device *dev)
 {
 	bool is_ipv6 = false;
 	u32 max_size;
@@ -2597,8 +2597,8 @@
 		   !ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr));
 #endif
 	/* pairs with the WRITE_ONCE() in netif_set_gso(_ipv4)_max_size() */
-	max_size = is_ipv6 ? READ_ONCE(dst_dev(dst)->gso_max_size) :
-			READ_ONCE(dst_dev(dst)->gso_ipv4_max_size);
+	max_size = is_ipv6 ? READ_ONCE(dev->gso_max_size) :
+			READ_ONCE(dev->gso_ipv4_max_size);
 	if (max_size > GSO_LEGACY_MAX_SIZE && !sk_is_tcp(sk))
 		max_size = GSO_LEGACY_MAX_SIZE;
 
@@ -2610,7 +2611,9 @@
 {
 	u32 max_segs = 1;
 
-	sk->sk_route_caps = dst_dev(dst)->features;
+	rcu_read_lock();
+	dev = dst_dev_rcu(dst);
+	sk->sk_route_caps = dev->features;
 	if (sk_is_tcp(sk)) {
 		struct inet_connection_sock *icsk = inet_csk(sk);
 
@@ -2626,7 +2629,7 @@
 			sk->sk_route_caps &= ~NETIF_F_GSO_MASK;
 		} else {
 			sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM;
-			sk->sk_gso_max_size = sk_dst_gso_max_size(sk, dst);
+			sk->sk_gso_max_size = sk_dst_gso_max_size(sk, dev);
 			/* pairs with the WRITE_ONCE() in netif_set_gso_max_segs() */
 			max_segs = max_t(u32, READ_ONCE(dst_dev(dst)->gso_max_segs), 1);
 		}

================================================================================
*    CONTEXT DIFFERENCES - surrounding code differences between the patches    *
================================================================================

--- b/include/net/ip.h
+++ b/include/net/ip.h
@@ -438,12 +438,12 @@
 						    bool forwarding)
 {
-	const struct rtable *rt = container_of(dst, struct rtable, dst);
+	const struct rtable *rt = dst_rtable(dst);
 	unsigned int mtu, res;
 	struct net *net;
 
 	rcu_read_lock();
 
-	net = dev_net_rcu(dst->dev);
+	net = dev_net_rcu(dst_dev(dst));
 	if (READ_ONCE(net->ipv4.sysctl_ip_fwd_use_pmtu) ||
 	    ip_mtu_locked(dst) ||
 	    !forwarding) {
@@ -460,7 +486,7 @@
 	if (mtu)
 		goto out;
 
-	mtu = READ_ONCE(dst->dev->mtu);
+	mtu = READ_ONCE(dst_dev(dst)->mtu);
 
 	if (unlikely(ip_mtu_locked(dst))) {
 		if (rt->rt_uses_gateway && mtu > 576)
--- b/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -329,5 +329,5 @@
 	rcu_read_lock();
-	idev = __in6_dev_get(dst->dev);
+	idev = __in6_dev_get(dst_dev(dst));
 	if (idev)
-		mtu = idev->cnf.mtu6;
+		mtu = READ_ONCE(idev->cnf.mtu6);
 	rcu_read_unlock();
--- b/include/net/route.h
+++ b/include/net/route.h
@@ -360,7 +360,7 @@
 		const struct net *net;
 
 		rcu_read_lock();
-		net = dev_net_rcu(dst->dev);
+		net = dev_net_rcu(dst_dev(dst));
 		hoplimit = READ_ONCE(net->ipv4.sysctl_ip_default_ttl);
 		rcu_read_unlock();
 	}
--- b/net/core/sock.c
+++ b/net/core/sock.c
@@ -2280,9 +2295,9 @@
 
 void sk_setup_caps(struct sock *sk, struct dst_entry *dst)
 {
 	u32 max_segs = 1;
 
 	sk->sk_route_caps = dst_dev(dst)->features;
-	if (sk_is_tcp(sk))
-		sk->sk_route_caps |= NETIF_F_GSO;
-	if (sk->sk_route_caps & NETIF_F_GSO)
+	if (sk_is_tcp(sk)) {
+		struct inet_connection_sock *icsk = inet_csk(sk);
+
@@ -2289,9 +2305,6 @@
 		} else {
 			sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM;
-			/* pairs with the WRITE_ONCE() in netif_set_gso_max_size() */
-			sk->sk_gso_max_size = READ_ONCE(dst_dev(dst)->gso_max_size);
-			sk_trim_gso_size(sk);
-			sk->sk_gso_max_size -= (MAX_TCP_HEADER + 1);
+			sk->sk_gso_max_size = sk_dst_gso_max_size(sk, dst);
 			/* pairs with the WRITE_ONCE() in netif_set_gso_max_segs() */
 			max_segs = max_t(u32, READ_ONCE(dst_dev(dst)->gso_max_segs), 1);
 		}

This is an automated interdiff check for backported commits.

@github-actions

Copy link
Copy Markdown

JIRA PR Check Results

24 commit(s) with issues found:

Commit 4bcf01b2a530

Summary: net: use dst_dev_rcu() in sk_setup_caps()

❌ Errors:

  • VULN-160265: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-160265: No time logged - please log time manually

Commit 53772374ea44

Summary: ipv6: use RCU in ip6_output()

❌ Errors:

  • VULN-160216: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-160216: No time logged - please log time manually

Commit 541ee876d36e

Summary: ipv6: use RCU in ip6_xmit()

❌ Errors:

  • VULN-160160: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-160160: No time logged - please log time manually

Commit 811de06e9b5c

Summary: net: dst: introduce dst->dev_rcu

❌ Errors:

  • VULN-160265: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-160265: No time logged - please log time manually

Commit 5ee590c4dc6f

Summary: net: Add locking to protect skb->dev access in ip_output

❌ Errors:

  • VULN-160160: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-160160: No time logged - please log time manually

Commit dfd72b87bb1b

Summary: net: dst: add four helpers to annotate data-races around dst->dev

❌ Errors:

  • VULN-160265: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-160265: No time logged - please log time manually

Commit 386ec44ca8ce

Summary: ipv6: use RCU protection in ip6_default_advmss()

⚠️ Warnings:

  • VULN-53991: No time logged - please log time manually

Commit d2cf3cc09f56

Summary: ipv4: use RCU protection in __ip_rt_update_pmtu()

❌ Errors:

  • VULN-54043: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-54043: No time logged - please log time manually

Commit 0c9e392128c6

Summary: ipv4: use RCU protection in ip_dst_mtu_maybe_forward()

❌ Errors:

  • VULN-160265: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-160265: No time logged - please log time manually

Commit e8f6e299a198

Summary: ipv4: add RCU protection to ip4_dst_hoplimit()

❌ Errors:

  • VULN-160265: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-160265: No time logged - please log time manually

Commit a929c54a9620

Summary: bpf: Fix mismatched RCU unlock flavour in bpf_out_neigh_v6

❌ Errors:

  • VULN-160216: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-160216: No time logged - please log time manually

Commit 6df41e0063ff

Summary: ipv6: prevent possible UAF in ip6_xmit()

⚠️ Warnings:

  • VULN-8328: No time logged - please log time manually

Commit 35e211eeac1f

Summary: ipv6: fix possible UAF in ip6_finish_output2()

⚠️ Warnings:

  • VULN-8330: No time logged - please log time manually

Commit 134eb77056d7

Summary: vrf: Fix lockdep splat in output path

❌ Errors:

  • VULN-160216: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-160216: No time logged - please log time manually

Commit 0635c6763570

Summary: udp6: Fix race condition in udp6_sendmsg & connect

❌ Errors:

  • VULN-160265: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-160265: No time logged - please log time manually

Commit 89ba4d648ec6

Summary: ipv6: remove nexthop_fib6_nh_bh()

❌ Errors:

  • VULN-160216: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-160216: No time logged - please log time manually

Commit dcb336d78555

Summary: net: remove rcu_dereference_bh_rtnl()

❌ Errors:

  • VULN-160216: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-160216: No time logged - please log time manually

Commit 8daef1f4d0a8

Summary: neighbour: switch to standard rcu, instead of rcu_bh

❌ Errors:

  • VULN-160216: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-160216: No time logged - please log time manually

Commit a008d80b7a67

Summary: ipv6: flowlabel: do not disable BH where not needed

❌ Errors:

  • VULN-160216: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-160216: No time logged - please log time manually

Commit 5d22bf790bbc

Summary: ipv6: remove one read_lock()/read_unlock() pair in rt6_check_neigh()

❌ Errors:

  • VULN-160216: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-160216: No time logged - please log time manually

Commit 2f09acffe4ef

Summary: ipv6: refactor ip6_finish_output2()

❌ Errors:

  • VULN-160216: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-160216: No time logged - please log time manually

Commit 9499f8cc3ee2

Summary: neigh: introduce neigh_confirm() helper function

❌ Errors:

  • VULN-160216: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-160216: No time logged - please log time manually

Commit 73cd9154b9db

Summary: net: ipv4: Consolidate ipv4_mtu and ip_dst_mtu_maybe_forward

❌ Errors:

  • VULN-160265: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-160265: No time logged - please log time manually

Commit 040383ccdbeb

Summary: net: ipv6: introduce ip6_dst_mtu_maybe_forward

❌ Errors:

  • VULN-160265: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-160265: No time logged - please log time manually

Summary: Checked 24 commit(s) total.

@github-actions

Copy link
Copy Markdown

Validation checks completed with issues View full results: https://github.com/ctrliq/kernel-src-tree/actions/runs/32178826591

@bmastbergen bmastbergen left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a commit that removes rcu_dereference_bh_rtnl as unused, but there are still two callers in net/sched/cls_tcindex.c CONFIG_NET_CLS_TCINDEX is not set in our configs, so not a big deal but maybe we should remove them for correctness' sake?

Comment thread net/core/neighbour.c

NEIGH_CACHE_STAT_INC(tbl, lookups);

rcu_read_lock_bh();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be switched to rcu_read_lock() as well?

Comment thread net/core/neighbour.c
}
}

rcu_read_unlock_bh();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be switched to rcu_read_unlock() as well?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants