* [PATCH net v4] kcm: reject attaching sockets with a ULP, and TLS on KCM sockets
@ 2026-10-29 20:34 Rishikesh Jethwani
2026-10-30 22:17 ` [syzbot ci] " syzbot ci
0 siblings, 1 reply; 2+ messages in thread
From: Rishikesh Jethwani @ 2026-10-29 20:34 UTC (permalink / raw)
To: netdev
Cc: Rishikesh Jethwani, stable, Jiayuan Chen, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman,
Hannes Reinecke, Sagi Grimberg, linux-kernel
KCM and kTLS RX do not work together, in either order.
KCM's psock_data_ready() is the lower socket's data_ready callback. It
can run in softirq context under read_lock_bh(&sk->sk_callback_lock),
and calls strp_data_ready(), which invokes sock->ops->read_sock()
inline. With kTLS RX, that is tls_sw_read_sock(), which can sleep: it
allocates with sk->sk_allocation, waits for async crypto, flushes the
socket backlog, and may wait in tls_rx_reader_acquire().
Found by code review. On an unmodified kernel with
CONFIG_DEBUG_ATOMIC_SLEEP, sending TLS records over loopback to a socket
with software kTLS RX attached to a KCM mux reports:
BUG: sleeping function called from invalid context at include/linux/sched/mm.h:321
in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 189, name: ksoftirqd/34
Call Trace:
__might_resched
kmem_cache_alloc_node_noprof
__alloc_skb
alloc_skb_with_frags
tls_rx_one_record
tls_sw_read_sock
strp_read_sock
strp_data_ready
psock_data_ready [kcm]
Before commit 662fbcec32f4 ("net/tls: implement ->read_sock()"), TLS
inherited tcp_read_sock(), so KCM parsed the ciphertext in the TCP
receive queue as messages. HW TLS RX uses the same proto_ops as SW
RX, so it is affected the same way.
The two also stack socket callbacks and neither restores the other's:
with TLS RX configured after the attach, kcm_unattach() overwrites
tls_data_ready(), and releasing TLS RX later reinstalls
psock_data_ready() on a socket no longer attached to KCM. On TX,
kcm_unattach() restores its saved sk_write_space, dropping
tls_write_space().
There is no known user of this combination, so reject it, as was done
for sockmap in commit 460e6486617c ("tls: reject the combination of TLS
and sockmap"). KCM takes over read_sock() and the socket callbacks like
a ULP does, so treat it as one:
- kcm_attach() refuses sockets that already have any ULP, not only
TLS, as sk_psock_init() does for sockmap, with -EOPNOTSUPP like its
other refusals;
- kcm_attach() then sets icsk_ulp_ops to a dummy, unregistered ULP, so
tcp_set_ulp() refuses TLS on an attached socket with -EEXIST and
nothing is needed on the TLS side. kcm_unattach() clears it.
The dummy is not registered, so TCP_ULP cannot select it by name. Both
sides run under the lower socket's lock (tcp_set_ulp() asserts this), so
the check is made at ULP install rather than at key configuration.
Holding a ULP also has visible side effects: getsockopt(TCP_ULP) and
inet_diag report "kcm" on an attached socket, sk_has_decrypt_user() is
true so PSP RX association is refused after the attach, and adding an
attached socket to a sockmap fails with -EINVAL rather than -EBUSY.
This is a user-visible change that will also reach stable kernels:
attaching a socket with a ULP now fails with -EOPNOTSUPP, and installing
a ULP on an attached socket fails with -EEXIST (espintcp previously
failed with -EBUSY). Every refused TLS setup was already broken as
described above, except one where only kTLS TX is configured. Such a
socket still passes data, because read_sock() stays tcp_read_sock()
until kTLS RX is configured, and KCM transmits with sock_sendmsg(), so
records reach TLS's sendmsg(). It is still wrong: if TLS was armed
before the attach, psock_write_space() shadows tls_write_space() and
does not chain to it, so a record deferred on a full send buffer waits
for the next send; if TLS was armed after the attach, the chain works
until kcm_unattach() drops tls_write_space(), as above. The direction is
not known at ULP install, so refusing it keeps one rule for both orders
and matches sk_psock_init().
Tested with CONFIG_DEBUG_ATOMIC_SLEEP: both orders are now rejected,
plain KCM still delivers messages, and the TLS ULP can be installed
after SIOCKCMUNATTACH.
Fixes: 662fbcec32f4 ("net/tls: implement ->read_sock()")
Cc: stable@vger.kernel.org
Suggested-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Link: https://lore.kernel.org/netdev/3108e934-ec00-458b-8720-450554b35b55@linux.dev/
Signed-off-by: Rishikesh Jethwani <rjethwani@purestorage.com>
---
net/kcm/kcmsock.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c
index a7f94d42036f..e0d6536306f4 100644
--- a/net/kcm/kcmsock.c
+++ b/net/kcm/kcmsock.c
@@ -30,11 +30,19 @@
#include <net/kcm.h>
#include <net/netns/generic.h>
#include <net/sock.h>
+#include <net/tcp.h>
#include <uapi/linux/kcm.h>
#include <trace/events/sock.h>
unsigned int kcm_net_id;
+/* Not registered, so TCP_ULP can't select it. It only holds
+ * icsk_ulp_ops so tcp_set_ulp() refuses other ULPs like kTLS.
+ */
+static const struct tcp_ulp_ops kcm_ulp_ops = {
+ .name = "kcm",
+};
+
static struct kmem_cache *kcm_psockp __read_mostly;
static struct kmem_cache *kcm_muxp __read_mostly;
static struct workqueue_struct *kcm_wq;
@@ -1272,6 +1280,14 @@ static int kcm_attach(struct socket *sock, struct socket *csock,
goto out;
}
+ /* KCM takes over read_sock() and the socket callbacks like a ULP
+ * does, the two can't stack.
+ */
+ if (inet_csk_has_ulp(csk)) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
psock = kmem_cache_zalloc(kcm_psockp, GFP_KERNEL);
if (!psock) {
err = -ENOMEM;
@@ -1305,6 +1321,7 @@ static int kcm_attach(struct socket *sock, struct socket *csock,
psock->save_write_space = csk->sk_write_space;
psock->save_state_change = csk->sk_state_change;
csk->sk_user_data = psock;
+ inet_csk(csk)->icsk_ulp_ops = &kcm_ulp_ops;
WRITE_ONCE(csk->sk_data_ready, psock_data_ready);
WRITE_ONCE(csk->sk_write_space, psock_write_space);
csk->sk_state_change = psock_state_change;
@@ -1382,6 +1399,7 @@ static void kcm_unattach(struct kcm_psock *psock)
*/
write_lock_bh(&csk->sk_callback_lock);
csk->sk_user_data = NULL;
+ inet_csk(csk)->icsk_ulp_ops = NULL;
WRITE_ONCE(csk->sk_data_ready, psock->save_data_ready);
WRITE_ONCE(csk->sk_write_space, psock->save_write_space);
csk->sk_state_change = psock->save_state_change;
--
2.50.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [syzbot ci] Re: kcm: reject attaching sockets with a ULP, and TLS on KCM sockets
2026-10-29 20:34 [PATCH net v4] kcm: reject attaching sockets with a ULP, and TLS on KCM sockets Rishikesh Jethwani
@ 2026-10-30 22:17 ` syzbot ci
0 siblings, 0 replies; 2+ messages in thread
From: syzbot ci @ 2026-10-30 22:17 UTC (permalink / raw)
To: davem, edumazet, hare, horms, jiayuan.chen, kuba, linux-kernel,
netdev, pabeni, rjethwani, sagi, stable
Cc: syzbot, syzkaller-bugs
syzbot ci has tested the following series
[v4] kcm: reject attaching sockets with a ULP, and TLS on KCM sockets
https://lore.kernel.org/all/20261029203428.3057054-1-rjethwani@purestorage.com
* [PATCH net v4] kcm: reject attaching sockets with a ULP, and TLS on KCM sockets
and found the following issue:
KASAN: slab-out-of-bounds Write in kcm_ioctl
Full report is available here:
https://ci.syzbot.org/series/8bb553bd-8792-4a67-b142-8c396f2f2594
***
KASAN: slab-out-of-bounds Write in kcm_ioctl
tree: net
URL: https://kernel.googlesource.com/pub/scm/linux/kernel/git/netdev/net.git
base: 5838f10563d58afca6711edb5e4eda968ca181d9
arch: amd64
compiler: Debian clang version 22.1.8 (1~deb13u4), Debian LLD 22.1.8
config: https://ci.syzbot.org/builds/371e9558-3281-4ec8-8935-9d7fa1e94ef9/config
syz repro: https://ci.syzbot.org/findings/b6f85fa5-eb30-4533-93b3-5c754fac4e45/syz_repro
==================================================================
BUG: KASAN: slab-out-of-bounds in kcm_attach net/kcm/kcmsock.c:1324 [inline]
BUG: KASAN: slab-out-of-bounds in kcm_attach_ioctl net/kcm/kcmsock.c:1376 [inline]
BUG: KASAN: slab-out-of-bounds in kcm_ioctl+0xced/0x1140 net/kcm/kcmsock.c:1583
Write of size 8 at addr ffff888113f70810 by task syz.1.18/5902
CPU: 0 UID: 0 PID: 5902 Comm: syz.1.18 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
Call Trace:
<TASK>
dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120
print_address_description+0x55/0x1e0 mm/kasan/report.c:378
print_report+0x58/0x70 mm/kasan/report.c:482
kasan_report+0x117/0x150 mm/kasan/report.c:595
kcm_attach net/kcm/kcmsock.c:1324 [inline]
kcm_attach_ioctl net/kcm/kcmsock.c:1376 [inline]
kcm_ioctl+0xced/0x1140 net/kcm/kcmsock.c:1583
sock_do_ioctl+0x101/0x320 net/socket.c:1328
sock_ioctl+0x57a/0x7e0 net/socket.c:1449
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:597 [inline]
__se_sys_ioctl+0xfc/0x170 fs/ioctl.c:583
do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
do_syscall_64+0x166/0x520 arch/x86/entry/syscall_64.c:84
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f96df39f559
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f96e01fe028 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 00007f96df625fa0 RCX: 00007f96df39f559
RDX: 0000200000003880 RSI: 00000000000089e0 RDI: 0000000000000004
RBP: 00007f96df436b20 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007f96df626038 R14: 00007f96df625fa0 R15: 00007ffc97de2138
</TASK>
Allocated by task 5902:
kasan_save_stack mm/kasan/common.c:57 [inline]
kasan_save_track+0x3e/0x80 mm/kasan/common.c:78
unpoison_slab_object mm/kasan/common.c:351 [inline]
__kasan_slab_alloc+0x6c/0x80 mm/kasan/common.c:377
kasan_slab_alloc include/linux/kasan.h:253 [inline]
slab_post_alloc_hook mm/slub.c:4720 [inline]
slab_alloc_node mm/slub.c:5033 [inline]
kmem_cache_alloc_noprof+0x2b4/0x600 mm/slub.c:5047
sk_prot_alloc+0x57/0x210 net/core/sock.c:2275
sk_alloc+0x3a/0x390 net/core/sock.c:2337
inet6_create+0x81a/0x1270 net/ipv6/af_inet6.c:178
__sock_create+0x4b5/0xac0 net/socket.c:1679
sock_create net/socket.c:1737 [inline]
__sys_socket_create net/socket.c:1774 [inline]
__sys_socket+0xd6/0x1b0 net/socket.c:1821
__do_sys_socket net/socket.c:1835 [inline]
__se_sys_socket net/socket.c:1833 [inline]
__x64_sys_socket+0x7a/0x90 net/socket.c:1833
do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
do_syscall_64+0x166/0x520 arch/x86/entry/syscall_64.c:84
entry_SYSCALL_64_after_hwframe+0x77/0x7f
The buggy address belongs to the object at ffff888113f70000
which belongs to the cache RAWv6 of size 1984
The buggy address is located 80 bytes to the right of
allocated 1984-byte region [ffff888113f70000, ffff888113f707c0)
The buggy address belongs to the physical page:
page: refcount:0 mapcount:0 mapping:0000000000000000 index:0xffff888113f73300 pfn:0x113f70
head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
memcg:ffff888113f77f81
flags: 0x17ff00000000240(workingset|head|node=0|zone=2|lastcpupid=0x7ff)
page_type: f5(slab)
raw: 017ff00000000240 ffff888167e03500 ffffea000442be10 ffff888104ae4948
raw: ffff888113f73300 00000002000f0006 00000000f5000000 ffff888113f77f81
head: 017ff00000000240 ffff888167e03500 ffffea000442be10 ffff888104ae4948
head: ffff888113f73300 00000002000f0006 00000000f5000000 ffff888113f77f81
head: 017ff00000000003 fffffffffffffe01 00000000ffffffff 00000000ffffffff
head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000008
page dumped because: kasan: bad access detected
page_owner tracks the page as allocated
page last allocated via order 3, migratetype Unmovable, gfp_mask 0xd20c0(__GFP_IO|__GFP_FS|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC), pid 5785, tgid 5785 (syz-executor), ts 69263183053
set_page_owner include/linux/page_owner.h:33 [inline]
post_alloc_hook+0x1f9/0x250 mm/page_alloc.c:1856
prep_new_page mm/page_alloc.c:1864 [inline]
get_page_from_freelist+0x220f/0x2280 mm/page_alloc.c:3935
__alloc_frozen_pages_noprof+0x1fe/0x410 mm/page_alloc.c:5444
alloc_slab_page mm/slub.c:3384 [inline]
allocate_slab+0x7d/0x5e0 mm/slub.c:3499
new_slab mm/slub.c:3550 [inline]
refill_objects+0x2d5/0x350 mm/slub.c:7539
refill_sheaf mm/slub.c:2917 [inline]
__pcs_replace_empty_main+0x2c8/0x6c0 mm/slub.c:4811
alloc_from_pcs mm/slub.c:4887 [inline]
slab_alloc_node mm/slub.c:5021 [inline]
kmem_cache_alloc_noprof+0x394/0x600 mm/slub.c:5047
sk_prot_alloc+0x57/0x210 net/core/sock.c:2275
sk_alloc+0x3a/0x390 net/core/sock.c:2337
inet6_create+0x81a/0x1270 net/ipv6/af_inet6.c:178
__sock_create+0x4b5/0xac0 net/socket.c:1679
inet_ctl_sock_create+0xa2/0x220 net/ipv4/af_inet.c:1640
tcpv6_net_init+0x34/0xb0 net/ipv6/tcp_ipv6.c:2348
ops_init+0x35d/0x5d0 net/core/net_namespace.c:137
setup_net+0x118/0x350 net/core/net_namespace.c:443
copy_net_ns+0x536/0x770 net/core/net_namespace.c:582
page last free pid 5803 tgid 5803 ts 69160417533 stack trace:
reset_page_owner include/linux/page_owner.h:26 [inline]
__free_pages_prepare mm/page_alloc.c:1403 [inline]
__free_frozen_pages+0xc97/0xd90 mm/page_alloc.c:2954
__slab_free+0x269/0x2c0 mm/slub.c:5926
qlink_free mm/kasan/quarantine.c:163 [inline]
qlist_free_all+0x99/0x100 mm/kasan/quarantine.c:179
kasan_quarantine_reduce+0x148/0x160 mm/kasan/quarantine.c:286
__kasan_slab_alloc+0x22/0x80 mm/kasan/common.c:361
kasan_slab_alloc include/linux/kasan.h:253 [inline]
slab_post_alloc_hook mm/slub.c:4720 [inline]
slab_alloc_node mm/slub.c:5033 [inline]
kmem_cache_alloc_noprof+0x2b4/0x600 mm/slub.c:5047
ptlock_alloc mm/memory.c:7769 [inline]
ptlock_init include/linux/mm.h:4039 [inline]
pmd_ptlock_init include/linux/mm.h:4151 [inline]
pagetable_pmd_ctor include/linux/mm.h:4179 [inline]
pmd_alloc_one_noprof include/asm-generic/pgalloc.h:146 [inline]
__pmd_alloc+0xc1/0x5c0 mm/memory.c:7029
pmd_alloc include/linux/mm.h:3865 [inline]
__handle_mm_fault mm/memory.c:6725 [inline]
handle_mm_fault+0xe9d/0x3750 mm/memory.c:6943
do_user_addr_fault+0x7f6/0x1480 arch/x86/mm/fault.c:1394
handle_page_fault arch/x86/mm/fault.c:1483 [inline]
exc_page_fault+0x6a/0xc0 arch/x86/mm/fault.c:1536
asm_exc_page_fault+0x26/0x30 arch/x86/include/asm/idtentry.h:595
Memory state around the buggy address:
ffff888113f70700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
ffff888113f70780: 00 00 00 00 00 00 00 00 fc fc fc fc fc fc fc fc
>ffff888113f70800: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
^
ffff888113f70880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
ffff888113f70900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
==================================================================
***
If these findings have caused you to resend the series or submit a
separate fix, please add the following tag to your commit message:
Tested-by: syzbot@syzkaller.appspotmail.com
---
This report is generated by a bot. It may contain errors.
syzbot ci engineers can be reached at syzkaller@googlegroups.com.
To test a fix for this bug, please reply with `#syz test`
(on a separate line) and attach the patch to the email.
Notes:
- The patch will be applied on top of the tested series (as an
incremental fix).
- To test a new version of the whole series, please send it directly
to syzbot@lists.linux.dev.
- Arguments like custom git repos and branches are not supported.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-10-30 22:17 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-29 20:34 [PATCH net v4] kcm: reject attaching sockets with a ULP, and TLS on KCM sockets Rishikesh Jethwani
2026-10-30 22:17 ` [syzbot ci] " syzbot ci
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox