linux/net
John Fastabend 65ad600b9b bpf, sockmap: Fix skb refcnt race after locking changes
commit a454d84ee2 upstream.

There is a race where skb's from the sk_psock_backlog can be referenced
after userspace side has already skb_consumed() the sk_buff and its refcnt
dropped to zer0 causing use after free.

The flow is the following:

  while ((skb = skb_peek(&psock->ingress_skb))
    sk_psock_handle_Skb(psock, skb, ..., ingress)
    if (!ingress) ...
    sk_psock_skb_ingress
       sk_psock_skb_ingress_enqueue(skb)
          msg->skb = skb
          sk_psock_queue_msg(psock, msg)
    skb_dequeue(&psock->ingress_skb)

The sk_psock_queue_msg() puts the msg on the ingress_msg queue. This is
what the application reads when recvmsg() is called. An application can
read this anytime after the msg is placed on the queue. The recvmsg hook
will also read msg->skb and then after user space reads the msg will call
consume_skb(skb) on it effectively free'ing it.

But, the race is in above where backlog queue still has a reference to
the skb and calls skb_dequeue(). If the skb_dequeue happens after the
user reads and free's the skb we have a use after free.

The !ingress case does not suffer from this problem because it uses
sendmsg_*(sk, msg) which does not pass the sk_buff further down the
stack.

The following splat was observed with 'test_progs -t sockmap_listen':

  [ 1022.710250][ T2556] general protection fault, ...
  [...]
  [ 1022.712830][ T2556] Workqueue: events sk_psock_backlog
  [ 1022.713262][ T2556] RIP: 0010:skb_dequeue+0x4c/0x80
  [ 1022.713653][ T2556] Code: ...
  [...]
  [ 1022.720699][ T2556] Call Trace:
  [ 1022.720984][ T2556]  <TASK>
  [ 1022.721254][ T2556]  ? die_addr+0x32/0x80^M
  [ 1022.721589][ T2556]  ? exc_general_protection+0x25a/0x4b0
  [ 1022.722026][ T2556]  ? asm_exc_general_protection+0x22/0x30
  [ 1022.722489][ T2556]  ? skb_dequeue+0x4c/0x80
  [ 1022.722854][ T2556]  sk_psock_backlog+0x27a/0x300
  [ 1022.723243][ T2556]  process_one_work+0x2a7/0x5b0
  [ 1022.723633][ T2556]  worker_thread+0x4f/0x3a0
  [ 1022.723998][ T2556]  ? __pfx_worker_thread+0x10/0x10
  [ 1022.724386][ T2556]  kthread+0xfd/0x130
  [ 1022.724709][ T2556]  ? __pfx_kthread+0x10/0x10
  [ 1022.725066][ T2556]  ret_from_fork+0x2d/0x50
  [ 1022.725409][ T2556]  ? __pfx_kthread+0x10/0x10
  [ 1022.725799][ T2556]  ret_from_fork_asm+0x1b/0x30
  [ 1022.726201][ T2556]  </TASK>

To fix we add an skb_get() before passing the skb to be enqueued in the
engress queue. This bumps the skb->users refcnt so that consume_skb()
and kfree_skb will not immediately free the sk_buff. With this we can
be sure the skb is still around when we do the dequeue. Then we just
need to decrement the refcnt or free the skb in the backlog case which
we do by calling kfree_skb() on the ingress case as well as the sendmsg
case.

Before locking change from fixes tag we had the sock locked so we
couldn't race with user and there was no issue here.

Fixes: 799aa7f98d ("skmsg: Avoid lock_sock() in sk_psock_backlog()")
Reported-by: Jiri Olsa  <jolsa@kernel.org>
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Tested-by: Xu Kuohai <xukuohai@huawei.com>
Tested-by: Jiri Olsa <jolsa@kernel.org>
Link: https://lore.kernel.org/bpf/20230901202137.214666-1-john.fastabend@gmail.com
Signed-off-by: Pranav Tyagi <pranav.tyagi03@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
History 2025-07-17 18:30:48 +02:00
..
6lowpan 6lowpan: iphc: Fix an off-by-one check of array index 2021-07-22 16:19:03 +02:00
9p 9p/xen: fix release of IRQ 2024-12-14 19:51:21 +01:00
802 net: 802: LLC+SNAP OID:PID lookup on start of skb data 2025-01-23 17:15:49 +01:00
8021q net: vlan: don't propagate flags on open 2025-05-02 07:43:56 +02:00
appletalk appletalk: Fix Use-After-Free in atalk_ioctl 2023-12-20 15:17:37 +01:00
atm atm: clip: Fix NULL pointer dereference in vcc_sendmsg() 2025-07-17 18:30:47 +02:00
ax25 net: ax25: Fix deadlock caused by skb_recv_datagram in ax25_recvmsg 2022-06-22 14:22:01 +02:00
batman-adv batman-adv: Ignore own maximum aggregation size during RX 2025-04-10 14:31:55 +02:00
bluetooth Bluetooth: L2CAP: Fix L2CAP MTU negotiation 2025-07-10 15:57:39 +02:00
bpf bpf: Set run context for rawtp test_run callback 2024-07-05 09:14:06 +02:00
bpfilter bpfilter: Specify the log level for the kmsg message 2021-06-25 13:13:50 +02:00
bridge net: bridge: mcast: re-implement br_multicast_{enable, disable}_port functions 2025-06-27 11:05:32 +01:00
caif net: caif: Fix use-after-free in cfusbl_device_notify() 2023-03-17 08:48:54 +01:00
can can: bcm: add missing rcu read protection for procfs content 2025-06-04 14:38:06 +02:00
ceph libceph: fix race between delayed_work() and ceph_monc_stop() 2024-07-18 13:07:42 +02:00
core bpf, sockmap: Fix skb refcnt race after locking changes 2025-07-17 18:30:48 +02:00
dcb net: dcb: choose correct policy to parse DCB_ATTR_BCN 2023-08-11 15:13:53 +02:00
dccp net: fix data-races around sk->sk_forward_alloc 2025-01-23 17:16:04 +01:00
dns_resolver keys, dns: Fix size check of V1 server-list header 2024-01-25 14:52:46 -08:00
dsa net: dsa: tag_brcm: legacy: fix pskb_may_pull length 2025-06-27 11:05:17 +01:00
ethernet gro: remove rcu_read_lock/rcu_read_unlock from gro_complete handlers 2024-09-12 11:07:47 +02:00
ethtool net: ethtool: Don't call .cleanup_data when prepare_data fails 2025-05-02 07:43:52 +02:00
hsr net: hsr: fix fill_frame_info() regression vs VLAN packets 2025-03-13 12:50:13 +01:00
ieee802154 net: ieee802154: do not leave a dangling sk pointer in ieee802154_create() 2024-12-14 19:51:37 +01:00
ife net: sched: ife: fix potential use-after-free 2024-01-05 15:13:29 +01:00
ipv4 tcp: fix tcp_packet_delayed() for tcp_is_non_sack_preventing_reopen() behavior 2025-06-27 11:05:36 +01:00
ipv6 Revert "ipv6: save dontfrag in cork" 2025-07-10 15:57:42 +02:00
iucv s390/iucv: fix receive buffer virtual vs physical address confusion 2024-09-04 13:23:27 +02:00
kcm kcm: Serialise kcm_sendmsg() for the same socket. 2024-09-04 13:23:32 +02:00
key net: af_key: fix sadb_x_filter validation 2023-08-26 14:23:32 +02:00
l2tp genetlink: hold RCU in genlmsg_mcast() 2024-11-01 01:52:34 +01:00
l3mdev net: Add l3mdev index to flow struct and avoid oif reset for port devices 2024-10-17 15:11:57 +02:00
lapb net: lapb: Use list_for_each_entry() to simplify code in lapb_iface.c 2021-06-08 16:31:25 -07:00
llc llc: fix data loss when reading from a socket in llc_ui_recvmsg() 2025-06-04 14:38:06 +02:00
mac80211 wifi: mac80211: drop invalid source address OCB frames 2025-07-10 15:57:47 +02:00
mac802154 mac802154: check local interfaces before deleting sdata list 2025-01-23 17:16:00 +01:00
mctp net: mctp: Set SOCK_RCU_FREE 2025-05-02 07:44:10 +02:00
mpls mpls: Use rcu_dereference_rtnl() in mpls_route_input_rcu(). 2025-06-27 11:05:36 +01:00
mptcp net: make sock_inuse_add() available 2025-05-02 07:44:20 +02:00
ncsi net: ncsi: Fix GCPS 64-bit member variables 2025-06-27 11:05:12 +01:00
netfilter netfilter: nf_set_pipapo_avx2: fix initial map fill 2025-06-27 11:05:18 +01:00
netlabel calipso: unlock rcu before returning -EAFNOSUPPORT 2025-06-27 11:05:22 +01:00
netlink netlink: Fix wraparounds of sk->sk_rmem_alloc. 2025-07-17 18:30:46 +02:00
netrom netrom: check buffer length before accessing it 2025-01-09 13:28:46 +01:00
nfc NFC: nci: uart: Set tty->disc_data only in success path 2025-06-27 11:05:25 +01:00
nsh nsh: Restore skb->{protocol,data,mac_header} for outer header in nsh_gso_segment(). 2024-05-17 11:50:48 +02:00
openvswitch net: openvswitch: Fix the dead loop of MPLS parse 2025-06-27 11:05:14 +01:00
packet af_packet: fix vlan_get_protocol_dgram() vs MSG_PEEK 2025-01-09 13:28:47 +01:00
phonet phonet/pep: fix racy skb_queue_empty() use 2025-05-02 07:44:18 +02:00
psample psample: Require 'CAP_NET_ADMIN' when joining "packets" group 2023-12-13 18:36:37 +01:00
qrtr net: qrtr: Update packets cloning when broadcasting 2024-10-17 15:11:08 +02:00
rds net:rds: Fix possible deadlock in rds_message_put 2024-09-04 13:23:39 +02:00
rfkill net: rfkill: gpio: Add check for clk_enable() 2024-12-14 19:50:58 +01:00
rose rose: fix dangling neighbour pointers in rose_rt_device_down() 2025-07-10 15:57:46 +02:00
rxrpc rxrpc: Fix oops due to non-existence of prealloc backlog struct 2025-07-17 18:30:48 +02:00
sched net/sched: Abort __tc_modify_qdisc if parent class does not exist 2025-07-17 18:30:47 +02:00
sctp sctp: Do not wake readers in __sctp_write_space() 2025-06-27 11:05:31 +01:00
smc net/smc: fix data error when recvmsg with MSG_PEEK flag 2025-03-13 12:49:57 +01:00
strparser bpf: sockmap, strparser, and tls are reusing qdisc_skb_cb and colliding 2021-11-18 19:17:11 +01:00
sunrpc sunrpc: fix race in cache cleanup causing stale nextcheck time 2025-06-27 11:05:29 +01:00
switchdev net: make switchdev_bridge_port_{,unoffload} loosely coupled with the bridge 2021-08-04 12:35:07 +01:00
tipc tipc: Fix use-after-free in tipc_conn_close(). 2025-07-17 18:30:46 +02:00
tls ktls, sockmap: Fix missing uncharge operation 2025-06-27 11:05:13 +01:00
unix af_unix: Don't set -ECONNRESET for consumed OOB skb. 2025-07-10 15:57:38 +02:00
vmw_vsock vsock: Fix IOCTL_VM_SOCKETS_GET_LOCAL_CID to check also transport_local 2025-07-17 18:30:46 +02:00
wireless wifi: nl80211: reject cooked mode if it is set along with other flags 2025-03-13 12:51:03 +01:00
x25 net/x25: fix incorrect parameter validation in the x25_getsockopt() function 2024-03-26 18:21:23 -04:00
xdp xsk: fix OOB map writes when deleting elements 2024-12-14 19:51:33 +01:00
xfrm xfrm: Sanitize marks before insert 2025-06-04 14:38:05 +02:00
compat.c net: Return the correct errno code 2021-06-03 15:13:56 -07:00
devres.c net: devres: Correct a grammatical error 2021-06-11 12:55:28 -07:00
Kconfig Remove DECnet support from kernel 2023-06-21 15:59:15 +02:00
Makefile Remove DECnet support from kernel 2023-06-21 15:59:15 +02:00
socket.c net: explicitly clear the sk pointer, when pf->create fails 2024-10-17 15:12:00 +02:00
sysctl_net.c net: Ensure net namespace isolation of sysctls 2021-04-12 13:27:11 -07:00