From c43c1c24f3cdc0d2d3f59e5686573ac3129637aa Mon Sep 17 00:00:00 2001 From: Nandor Kracser Date: Wed, 21 Oct 2026 09:32:33 +0200 Subject: [PATCH] tls: avoid field-spanning write when copying crypto info do_tls_setsockopt_conf() copies the cipher-specific part of the crypto info to crypto_info + 1, where crypto_info points at the 4-byte info member of union tls_crypto_context. When optval is a kernel sockptr, copy_from_sockptr_offset() is a memcpy(), and FORTIFY_SOURCE bounds the destination by that member: [ 6.948348] memcpy: detected field-spanning write (size 52) of single field "dst" at include/linux/sockptr.h:49 (size 0) [ 6.948480] WARNING: include/linux/sockptr.h:49 at tls_setsockopt+0x9b2/0xa30, CPU#1: init/1 [ 7.001355] Call Trace: [ 7.003146] do_sock_setsockopt+0xb0/0x190 [ 7.003975] __sys_setsockopt+0x76/0xc0 [ 7.005368] do_syscall_64+0xda/0x4b0 tls_setsockopt() gets a kernel sockptr whenever a cgroup setsockopt BPF program is attached, even one that leaves the option alone, because __cgroup_bpf_run_filter_setsockopt() passes optval on in a kernel buffer. With a no-op program on the root cgroup, a plain TLS_TX setsockopt() with AES-GCM-256 triggers the warning above on an x86_64 build with CONFIG_FORTIFY_SOURCE. Copy into the union at offset sizeof(struct tls_crypto_info) instead. crypto_ctx already points at the right union for both the first set and the TLS 1.3 rekey (tmp) case, and the address is unchanged. Fixes: a7b75c5a8c41 ("net: pass a sockptr_t into ->setsockopt") Signed-off-by: Nandor Kracser Link: https://patch.msgid.link/20261021073233.16720-1-nandor@riptides.io Signed-off-by: Jakub Kicinski --- net/tls/tls_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c index 6b889f568dc1..b8d5a843f761 100644 --- a/net/tls/tls_main.c +++ b/net/tls/tls_main.c @@ -699,8 +699,8 @@ static int do_tls_setsockopt_conf(struct sock *sk, sockptr_t optval, goto err_crypto_info; } - rc = copy_from_sockptr_offset(crypto_info + 1, optval, - sizeof(*crypto_info), + rc = copy_from_sockptr_offset((u8 *)crypto_ctx + sizeof(*crypto_info), + optval, sizeof(*crypto_info), optlen - sizeof(*crypto_info)); if (rc) { rc = -EFAULT;