linux-next/net/xfrm
Florian Westphal e952837f3d xfrm: state: fix out-of-bounds read during lookup
lookup and resize can run in parallel.

The xfrm_state_hash_generation seqlock ensures a retry, but the hash
functions can observe a hmask value that is too large for the new hlist
array.

rehash does:
  rcu_assign_pointer(net->xfrm.state_bydst, ndst) [..]
  net->xfrm.state_hmask = nhashmask;

While state lookup does:
  h = xfrm_dst_hash(net, daddr, saddr, tmpl->reqid, encap_family);
  hlist_for_each_entry_rcu(x, net->xfrm.state_bydst + h, bydst) {

This is only safe in case the update to state_bydst is larger than
net->xfrm.xfrm_state_hmask (or if the lookup function gets
serialized via state spinlock again).

Fix this by prefetching state_hmask and the associated pointers.
The xfrm_state_hash_generation seqlock retry will ensure that the pointer
and the hmask will be consistent.

The existing helpers, like xfrm_dst_hash(), are now unsafe for RCU side,
add lockdep assertions to document that they are only safe for insert
side.

xfrm_state_lookup_byaddr() uses the spinlock rather than RCU.
AFAICS this is an oversight from back when state lookup was converted to
RCU, this lock should be replaced with RCU in a future patch.

Reported-by: syzbot+5f9f31cb7d985f584d8e@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/netdev/CACT4Y+azwfrE3uz6A5ZErov5YN2LYBN5KrsymBerT36VU8qzBA@mail.gmail.com/
Diagnosed-by: Dmitry Vyukov <dvyukov@google.com>
Fixes: c2f672fc94 ("xfrm: state lookup can be lockless")
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
2024-12-05 09:43:02 +01:00
..
espintcp.c net: move netdev_max_backlog to net_hotdata 2024-03-07 21:12:42 -08:00
Kconfig ipsec: Select CRYPTO_AEAD 2023-10-01 16:28:14 +08:00
Makefile xfrm: support sending NAT keepalives in ESP in UDP states 2024-06-26 13:22:42 +02:00
xfrm_algo.c net: fill in MODULE_DESCRIPTION()s for xfrm 2024-02-09 14:12:01 -08:00
xfrm_compat.c xfrm: Add support for per cpu xfrm state handling. 2024-10-29 11:56:00 +01:00
xfrm_device.c xfrm: extract dst lookup parameters into a struct 2024-09-23 07:02:07 +02:00
xfrm_hash.c mm: remove include/linux/bootmem.h 2018-10-31 08:54:16 -07:00
xfrm_hash.h xfrm: add state hashtable keyed by seq 2021-05-14 13:52:01 +02:00
xfrm_inout.h xfrm: move xfrm4_extract_header to common helper 2020-05-06 09:40:08 +02:00
xfrm_input.c xfrm: Add an inbound percpu state cache. 2024-10-29 11:56:18 +01:00
xfrm_interface_bpf.c bpf: treewide: Annotate BPF kfuncs in BTF 2024-01-31 20:40:56 -08:00
xfrm_interface_core.c netdev_features: convert NETIF_F_LLTX to dev->lltx 2024-09-03 11:36:43 +02:00
xfrm_ipcomp.c net: introduce and use skb_frag_fill_page_desc() 2023-05-13 19:47:56 +01:00
xfrm_nat_keepalive.c xfrm: support sending NAT keepalives in ESP in UDP states 2024-06-26 13:22:42 +02:00
xfrm_output.c Revert "xfrm: add SA information to the offloaded packet" 2024-09-09 11:43:39 +02:00
xfrm_policy.c xfrm: Convert struct xfrm_dst_lookup_params -> tos to dscp_t. 2024-11-06 12:42:51 +01:00
xfrm_proc.c xfrm: Add dir validation to "in" data path lookup 2024-05-01 10:06:27 +02:00
xfrm_replay.c xfrm: replay: Fix the update of replay_esn->oseq_hi for GSO 2024-11-25 08:32:40 +01:00
xfrm_state_bpf.c bpf: treewide: Annotate BPF kfuncs in BTF 2024-01-31 20:40:56 -08:00
xfrm_state.c xfrm: state: fix out-of-bounds read during lookup 2024-12-05 09:43:02 +01:00
xfrm_sysctl.c net: Remove ctl_table sentinel elements from several networking subsystems 2024-05-03 13:29:42 +01:00
xfrm_user.c ipsec-next-2024-11-15 2024-11-18 11:52:49 +00:00