tcp: fix use-after-free in do_tcp_getsockopt(TCP_CONGESTION)
Impact
In the Linux kernel, the following vulnerability has been resolved:
Source excerpt · LinuxAffected packages
Affected products
Vendor version evidence. Product records are separate from automatic dependency matching.
Linux · Linux
Other versions: unaffected
| Version / range | Source status |
|---|---|
| 0baf26b0fcd74bbfcef53c5d5e8bad2b99c8d0d2 to before c1804ef016392dd91267d2207ee43b1de34302ca | affected |
| 0baf26b0fcd74bbfcef53c5d5e8bad2b99c8d0d2 to before a8e45471afa230c1431c26c8e99ec24377e3b514 | affected |
| 0baf26b0fcd74bbfcef53c5d5e8bad2b99c8d0d2 to before 5271b79b7ad68dcb222e893773f92bdabf7750f3 | affected |
Linux · Linux
Other versions: affected
| Version / range | Source status |
|---|---|
| 5.6 | affected |
| 0 to before 5.6 | unaffected |
| 6.18.59 through 6.18.* (inclusive) | unaffected |
| 7.2.13 through 7.2.* (inclusive) | unaffected |
| 7.3 through * (inclusive) | unaffected |
Original source description
In the Linux kernel, the following vulnerability has been resolved:
tcp: fix use-after-free in do_tcp_getsockopt(TCP_CONGESTION)
do_tcp_getsockopt() reads icsk->icsk_ca_ops->name without holding rcu_read_lock(). Since commit 0baf26b0fcd7 ("bpf: tcp: Support tcp_congestion_ops in bpf"), icsk_ca_ops can point to dynamically allocated BPF struct_ops memory that may be freed concurrently via setsockopt(TCP_CONGESTION), leading to a use-after-free.
BUG: KASAN: slab-use-after-free in _copy_to_user+0x37/0x60 Read of size 16 at addr ffff888013505260 by task exploit/149 _copy_to_user+0x37/0x60 do_tcp_getsockopt+0x158a/0x2460 (net/ipv4/tcp.c:4585) tcp_getsockopt+0x91/0xf0 __sys_getsockopt+0xf7/0x170
Fix this by holding rcu_read_lock() around the ca_ops->name access, using READ_ONCE() to load icsk_ca_ops, and copying the name to a stack buffer before releasing the lock. Also annotate the relevant icsk_ca_ops stores with WRITE_ONCE() to fix the accompanying KCSAN data-race issue.