summaryrefslogtreecommitdiff
path: root/net/tls
AgeCommit message (Collapse)Author
5 daystls: device: fix out-of-bounds write in tls_append_frag()Jiayuan Chen
Found with syzkaller and a local syzbot instance running on top of a netdevsim TLS offload emulation; tls_device.c is otherwise only reachable on a machine with a NIC that implements the offload. tls_push_data() only checks whether the open record still has room for another frag at the bottom of its loop, and the MSG_MORE early break skips that check. The record survives to the next syscall with the frag count it already had, and tls_append_frag() does not check either, so with TLS_TX_ZEROCOPY_RO every splice(SPLICE_F_MORE) of a byte or two adds a non-coalescing pipe page and num_frags walks off the end of tls_record_info.frags[MAX_SKB_FRAGS]. Once the record is pushed, tls_push_record() runs the same index over sg_tx_data[MAX_SKB_FRAGS] and the sg_set_page() writes land on the destruct_work that follows it, which the workqueue then calls. The byte limit is fine because copy drops to 0 and the loop falls through to the same check; the frag count has no such feedback. Push the record rather than keep a full one open, which is what a plain TCP socket does - tcp_sendmsg_locked() uses tcp_mark_push() and new_segment in both the copy and the MSG_SPLICE_PAGES paths, and tls_sw already sets full_record when the sk_msg ring fills up, MSG_MORE or not. BUG: KASAN: slab-out-of-bounds in tls_append_frag ( net/tls/tls_device.c:269) Write of size 8 at addr ffff8881104d1530 by task tls_oob/450 CPU: 2 UID: 0 PID: 450 Comm: tls_oob Not tainted 7.2.0-rc7+ #329 PREEMPT Call Trace: <TASK> dump_stack_lvl (lib/dump_stack.c:94 lib/dump_stack.c:120) print_report (mm/kasan/report.c:378 mm/kasan/report.c:482) kasan_report (mm/kasan/report.c:595) tls_append_frag (net/tls/tls_device.c:269) tls_push_data (net/tls/tls_device.c:518) tls_device_sendmsg (net/tls/tls_device.c:583) inet_sendmsg (net/ipv4/af_inet.c:865) sock_sendmsg (net/socket.c:775 net/socket.c:790 net/socket.c:813) splice_to_socket (fs/splice.c:884) do_splice (fs/splice.c:936 fs/splice.c:1349) __do_splice (fs/splice.c:1431) __x64_sys_splice (fs/splice.c:1634 fs/splice.c:1616) do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94) entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121) </TASK> and, once the record is pushed: UBSAN: array-index-out-of-bounds in net/tls/tls_device.c:300:24 index 18 is out of range for type 'skb_frag_t [17]' UBSAN: array-index-out-of-bounds in net/tls/tls_device.c:301:41 index 18 is out of range for type 'scatterlist [17]' UBSAN: array-index-out-of-bounds in net/tls/tls_device.c:302:39 index 18 is out of range for type 'scatterlist [17]' UBSAN: array-index-out-of-bounds in net/tls/tls_device.c:307:38 index 26 is out of range for type 'scatterlist [17]' kernel tried to execute NX-protected page - exploit attempt? (uid: 0) BUG: unable to handle page fault for address: ffffea000411a680 #PF: supervisor instruction fetch in kernel mode #PF: error_code(0x0011) - permissions violation Oops: Oops: 0011 [#1] SMP KASAN PTI Workqueue: ktls_device_destruct 0xffffea000411a680 RIP: 0010:0xffffea000411a680 Call Trace: <TASK> worker_thread (kernel/workqueue.c:3405 kernel/workqueue.c:3486) kthread (kernel/kthread.c:436) ret_from_fork (arch/x86/kernel/process.c:158) ret_from_fork_asm (arch/x86/entry/entry_64.S:245) </TASK> Fixes: e8f69799810c ("net/tls: Add generic NIC offload infrastructure") Cc: stable@vger.kernel.org Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev> Link: https://patch.msgid.link/20260823084758.20936-1-jiayuan.chen@linux.dev Signed-off-by: Paolo Abeni <pabeni@redhat.com>
11 daysMerge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netJakub Kicinski
Merge in late fixes in preparation for the net-next PR. Conflicts: drivers/dpll/dpll_core.c drivers/dpll/dpll_netlink.c 33f016b23a219 ("dpll: fix NULL deref in dpll_device_ops() during teardown race") b1d0c412088e3 ("dpll: add STATE_CONNECTED_OVERRIDE pin capability") https://lore.kernel.org/aoR9YYY2P5--3x0N@sirena.org.uk https://lore.kernel.org/aoR9VmKllVGwmQn_@sirena.org.uk No adjacent changes. Signed-off-by: Jakub Kicinski <kuba@kernel.org>
12 daystls: fix RX desync on overlapping skbsMaximilian Immanuel Brandtner
The TCP receive queue can hold adjacent skbs whose sequence ranges overlap. The tls fast-path reads the record header with skb_copy_bits() by byte offset, which assumes skbs do not overlap, so a header split across the overlap is misread and the connection aborts (-EMSGSIZE/-EINVAL). tls_strp_check_queue_ok() detects such overlaps but only ran after the header was parsed, never covering the header itself. Observed with parallel kTLS connections on: - ConnectX-7 + IPsec crypto offload + GRO - VirtIO (8 queues) + GRO Fixes: 84c61fe1a75b ("tls: rx: do not use the standard strparser") Signed-off-by: Maximilian Immanuel Brandtner <maxbr@linux.ibm.com> Link: https://patch.msgid.link/20260813121337.3300688-1-maxbr@linux.ibm.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-13Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netJakub Kicinski
Cross-merge networking fixes after downstream PR (net-7.2-rc8). No conflicts. Adjacent changes: drivers/net/ethernet/wangxun/ngbe/ngbe_main.c 5f3a13e0bb5e ("net: ngbe: fix NULL pointer dereference in non-MSI-X interrupt enabling") d661abdc30c2 ("net: ngbe: correct misleading interrupt comment") drivers/net/ipvlan/ipvlan_main.c e16e960d55a4 ("ipvlan: inherit needed_headroom and needed_tailroom from phy_dev") 00a40d809207 ("ipvlan: Support per-netns netdev unregistration.") Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-11net/tls: Fail tls_sw_splice_read() after a failed async decryptChuck Lever
When an async decrypt fails, tls_decrypt_done() records the error in ctx->async_wait.err and calls tls_err_abort(), which stores it in sk_err. tls_sw_recvmsg() and tls_sw_read_sock() each read async_wait.err once they hold the reader lock and fail the call: a record that did not authenticate breaks the connection. tls_sw_splice_read() has no such check, and sk_err does not stand in for one. tls_rx_rec_wait() tests sk_err only inside the loop it skips whenever a record is already parsed, and the first reader to reach sock_error() clears it, while async_wait.err persists. A splice therefore keeps delivering records on a connection that recvmsg() and read_sock() refuse to read. Read async_wait.err in tls_sw_splice_read() as the other two readers do. Fixes: f314bfee81b1 ("tls: rx: return the already-copied data on crypto error") Reviewed-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Chuck Lever <cel@kernel.org> Reviewed-by: Sabrina Dubroca <sd@queasysnail.net> Link: https://patch.msgid.link/20260806-tls-splice-crypto-fix-v1-1-a2624005a286@kernel.org Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-08-06Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netJakub Kicinski
Cross-merge networking fixes after downstream PR (net-7.2-rc7). No conflicts, or adjacent changes. Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-06tls: don't abort the connection on signal-interrupted sendsMaximilian Immanuel Brandtner
When a signal interrupts a blocking send, tls_tx_records() treats the resulting -ERESTARTSYS as a transmission failure and marks the socket errored via tls_err_abort() with the raw error code. Later syscalls return the kernel-internal errno 512 (ERESTARTSYS) to userspace, as the signal it stems from is no longer pending during syscall exit and thus never translated. An interrupted send is not a connection error: the partially sent record stays queued and is resent later. Interrupt error codes are therefore excluded from the abort in the same way as -EAGAIN. Fixes: b341ca51d267 ("tls: Fix tls_sw_sendmsg error handling") Signed-off-by: Maximilian Immanuel Brandtner <maxbr@linux.ibm.com> Link: https://patch.msgid.link/20260805063109.1772314-1-maxbr@linux.ibm.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-06tls: rx: restore msg_iter before TLS 1.3 optimistic retryJérémy Jean
tls_decrypt_sg() advances msg->msg_iter when it maps user pages for the optimistic TLS 1.3 zero-copy path. If the decrypted record turns out not to be unpadded application data, tls_decrypt_sw() retries into a kernel skb, but leaves the iterator advanced. The subsequent copy from the skb then writes decrypted bytes again at a later point in the caller iovecs while recvmsg() reports only the post-retry length. A TLS peer can trigger this after the receiver enables TLS_RX_EXPECT_NO_PAD. Revert the iterator by the number of bytes consumed by the optimistic mapping before retrying without zero-copy. Add a selftest which sends a TLS 1.3 control record with TLS_RX_EXPECT_NO_PAD enabled and verifies that recvmsg() does not overwrite later iovecs beyond the returned length. Fixes: ce61327ce989 ("tls: rx: support optimistic decrypt to user buffer with TLS 1.3") Cc: stable@vger.kernel.org Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr> Link: https://patch.msgid.link/20260804125528.2139928-1-Jeremy.Jean@oss.cyber.gouv.fr Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-06tls: don't leave a full plaintext sk_msg ring unpushedchanyoung
When the copy path in tls_sw_sendmsg_locked() adds the fragment that fills the plaintext sk_msg ring, it does not set full_record, so the record is left full and unpushed. A later splice() then adds to an already full ring: sk_msg_page_add() has no fullness check of its own, so sg.end wraps onto sg.start and the ring appears empty. Fragments added after that overwrite live entries, and sg.size no longer matches what is reachable between sg.start and sg.end, so pushing the record runs the scatterwalk off the end of the scatterlist. An unprivileged user can trigger this on a loopback TCP socket with the "tls" ULP attached: BUG: kernel NULL pointer dereference, address: 0000000000000008 RIP: 0010:memcpy_from_scatterwalk+0x32/0xc0 Call Trace: skcipher_walk_next+0x1d1/0x2c0 gcm_encrypt_aesni_avx+0x1e9/0x220 bpf_exec_tx_verdict+0x3bb/0x860 tls_sw_sendmsg+0xa1a/0xca0 __sys_sendto+0x1da/0x1f0 Set full_record in the copy path when the ring becomes full, and push a record that is already full on entry to the sendmsg loop. Suggested-by: Sabrina Dubroca <sd@queasysnail.net> Fixes: fe1e81d4f73b ("tls/sw: Support MSG_SPLICE_PAGES") Cc: stable@vger.kernel.org Signed-off-by: chanyoung <ppoo1220@gmail.com> Link: https://patch.msgid.link/20260804052837.49015-2-ppoo1220@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-03tls: convert getsockopt to sockopt_tBreno Leitao
Continue converting the proto-layer getsockopt callbacks to the sockopt_t interface, converting do_tls_getsockopt() and its per-option helpers to take a sockopt_t. The thin tls_getsockopt() wrapper keeps its __user signature for now: it builds a user-backed sockopt_t with sockopt_init_user(), calls the helper, and writes the returned length back to optlen. The helpers use copy_to_iter() instead of copy_to_user(); the NULL optval check in the TLS_TX/TLS_RX path is preserved by testing the iterator user buffer. No functional change. Reviewed-by: Sabrina Dubroca <sd@queasysnail.net> Reviewed-by: Joe Damato <joe@dama.to> Acked-by: Stanislav Fomichev <sdf@fomichev.me> Signed-off-by: Breno Leitao <leitao@debian.org> Link: https://patch.msgid.link/20260729-getsockopt_phase4-v4-6-c44576757c17@debian.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-07-21tls: device: push pending open record on splice EOFRishikesh Jethwani
On kTLS device-offload sockets, sendfile() with count > EOF can reach ->splice_eof() with a fully assembled but still-open TLS record left pending. tls_device_splice_eof() only flushes partially sent records, so an abrupt close() can drop the final record and the peer receives a short file. Fix tls_device_splice_eof() to also push pending open records. This matches the software path, where splice EOF already flushes pending open records. Fixes: d4c1e80b0d1b ("tls/device: Use splice_eof() to flush") Link: https://lore.kernel.org/netdev/CAMPsyauZ+jzG9AysO0FWv6ZY0kvCUpjX_U7o=oOjCuOQ87BCgg@mail.gmail.com/ Reported-by: Nils Juenemann <nils.juenemann@gmail.com> Signed-off-by: Rishikesh Jethwani <rjethwani@purestorage.com> Tested-by: Nils Juenemann <nils.juenemann@gmail.com> Link: https://patch.msgid.link/20260709224436.1608993-2-rjethwani@purestorage.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-07-07net/tls: Consume empty data records in tls_sw_read_sock()Chuck Lever
A peer may send a zero-length TLS application_data record; TLS 1.3 explicitly permits these as a traffic-analysis countermeasure (RFC 8446, Section 5.1). After decryption such a record has full_len == 0. tls_sw_read_sock() hands it to the read_actor, which has no payload to consume and returns zero. The loop treats a zero return as backpressure (used <= 0), requeues the skb at the head of rx_list, and stops. rx_list is serviced head-first on the next call, so the empty record is dequeued, fails the same way, and is requeued again; every later record on the connection is blocked behind it. tls_sw_recvmsg() does not stall on this: a zero-length data record copies nothing and falls through to consume_skb(). Mirror that in the read_sock() path by recognizing an empty data record before the actor runs, consuming it, and continuing. Fixes: 662fbcec32f4 ("net/tls: implement ->read_sock()") Signed-off-by: Chuck Lever <cel@kernel.org> Reviewed-by: Sabrina Dubroca <sd@queasysnail.net> Link: https://patch.msgid.link/20260630191551.875664-1-cel@kernel.org Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-06-16tls: remove dead sockmap (psock) handling from the SW pathJakub Kicinski
TLS and sockmap are now mutually exclusive. Try to delete the code from sendmsg and recvmsg path which is now obviously dead. The main goal is to delete enough code for AI security scanners to no longer bother us with sockmap related bugs. At the same time retain the code in case someone has the cycles to fix all of this and make the integration work, again. If the integration does not get restored we can wipe the rest of the skmsg code from TLS in two or three releases. The changes on the Tx side are deeper since that's where most of the bugs are, Rx side simply takes the data from sockmap and gives it to the user. On Tx split record handling and rolling back the iterator were the two problem areas. Reviewed-by: Jakub Sitnicki <jakub@cloudflare.com> Reviewed-by: Sabrina Dubroca <sd@queasysnail.net> Link: https://patch.msgid.link/20260614014102.461064-3-kuba@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-06-16tls: reject the combination of TLS and sockmapJakub Kicinski
TLS and sockmap (BPF psock) integration hides a lot of latent bugs. Bugs which may be more or less relevant for real users but they are definitely exploitable. We could not find anyone actively using this integration so let's reject this config. Adding a TLS socket to a sockmap was already rejected by sk_psock_init() through the inet_csk_has_ulp() check. We need to reject the attempts to configure the TLS keys (rather than adding the ULP itself) because checking prior to the ULP installation is tricky without risking a race with sockmap getting added in parallel (sockmap does not hold the socket lock). This patch is a minimal rejection of the feature. Subsequent patch in the series will do a light dead code removal. Full cleanup would require a major rewrite of the Tx path, we don't need skmsg any more. Reviewed-by: Jakub Sitnicki <jakub@cloudflare.com> Reviewed-by: Sabrina Dubroca <sd@queasysnail.net> Link: https://patch.msgid.link/20260614014102.461064-2-kuba@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-06-12tls: remove tls_toe and the related driverSabrina Dubroca
The tls_toe feature and its single user (chelsio chtls) have been unmaintained for multiple years. It also hooks into the core of the TCP implementation, and bypasses most of the networking stack. Signed-off-by: Sabrina Dubroca <sd@queasysnail.net> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/1f30e73275c07bf879f547589872d0916025a52e.1781165969.git.sd@queasysnail.net Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-06-08tls: Flush backlog before waiting for a new recordChuck Lever
While lock_sock is held, incoming TCP segments land on sk->sk_backlog rather than sk->sk_receive_queue. tls_rx_rec_wait() inspects only sk_receive_queue, so backlog data remains invisible. For non-blocking callers (read_sock, and recvmsg or splice_read with MSG_DONTWAIT) this causes a spurious -EAGAIN. For blocking callers it forces an unnecessary sleep/wakeup cycle. Flush the backlog inside tls_rx_rec_wait() before checking sk_receive_queue so the strparser can parse newly-arrived segments immediately. On the next loop iteration tls_read_flush_backlog() may redundantly flush, but this path is cold and the cost is negligible. Backlog processing can run tcp_reset(), which calls tcp_done_with_error() to set sk->sk_err = ECONNRESET and then tcp_done() to set sk->sk_shutdown = SHUTDOWN_MASK. The pre-existing top-of-loop sk_err check already ran before the flush, so the freshly-set error would be masked by the next-line sk_shutdown test returning 0 (EOF). Re-check sk_err immediately before the sk_shutdown test so a connection abort surfaces as -ECONNRESET rather than a clean EOF. Commit f508262ae9f2 ("tls: Preserve sk_err across recvmsg() when data has been copied") gave the top-of-loop sk_err check a has_copied split. The recheck applies the same handling: when the caller has already copied bytes, sk_err is reported but preserved so the error surfaces on the next call; otherwise sock_error() consumes it so the error is reported exactly once. Suggested-by: Sabrina Dubroca <sd@queasysnail.net> Link: https://lore.kernel.org/netdev/ahgHgQ84RCc8uYrG@krikkit/ Reviewed-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Reviewed-by: Sabrina Dubroca <sd@queasysnail.net> Link: https://patch.msgid.link/20260604-tls-read-sock-v12-6-b114efa6e3e2@oracle.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-06-08tls: Suppress spurious saved_data_ready on all receive pathsChuck Lever
Each record release via tls_strp_msg_done() triggered tls_strp_check_rcv(), which called tls_rx_msg_ready() and fired saved_data_ready(). During a multi-record receive, the first N-1 wakeups are pure overhead: the caller is already running and will pick up subsequent records on the next loop iteration. The recvmsg and splice_read paths share this waste. Suppress per-record notifications and emit a single one on reader exit. tls_rx_rec_done() releases the current record and parses the next without announcing; tls_strp_check_rcv() gains a bool announce parameter so callers can request the quiet form. tls_rx_reader_release() fires the deferred announce on exit through tls_rx_msg_maybe_announce(), an idempotent helper that calls saved_data_ready() only when a record is parsed and has not yet been announced. To keep the final notification idempotent against records that the BH or the worker has already announced, tls_strparser gains a msg_announced bit. tls_rx_msg_maybe_announce() sets the bit when firing saved_data_ready(); the bit is cleared whenever the parsed record is wiped, by tls_strp_msg_consume() on consumption or by tls_strp_msg_load() when the lower socket loses bytes from under the parse. A second call for the same parsed record -- as when recvmsg() satisfies the request from ctx->rx_list without touching the strparser -- becomes a no-op. With no remaining callers, tls_strp_msg_done() is removed. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Reviewed-by: Hannes Reinecke <hare@kernel.org> Reviewed-by: Sabrina Dubroca <sd@queasysnail.net> Link: https://patch.msgid.link/20260604-tls-read-sock-v12-5-b114efa6e3e2@oracle.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-06-08tls: Factor tls_strp_msg_consume() from tls_strp_msg_done()Chuck Lever
tls_strp_msg_done() conflates releasing the current record with checking for the next one via tls_strp_check_rcv(). A subsequent patch needs to release a record without immediately triggering that check, so the release step is separated into tls_strp_msg_consume(). tls_strp_msg_done() is preserved as a wrapper for existing callers. Reviewed-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Reviewed-by: Sabrina Dubroca <sd@queasysnail.net> Link: https://patch.msgid.link/20260604-tls-read-sock-v12-4-b114efa6e3e2@oracle.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-06-08tls: Move decrypt-failure abort into tls_rx_one_record()Chuck Lever
Three receive paths -- recvmsg, read_sock, and splice_read -- each follow tls_rx_one_record() with the same tls_err_abort() call. Consolidate the abort into tls_rx_one_record() so the decrypt-and-abort sequence lives in one place. A tls_check_pending_rekey() failure after successful decryption no longer triggers tls_err_abort(). That path fires only when skb_copy_bits() fails on a valid skb, which is not a realistic scenario. Suggested-by: Sabrina Dubroca <sd@queasysnail.net> Reviewed-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Sabrina Dubroca <sd@queasysnail.net> Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Link: https://patch.msgid.link/20260604-tls-read-sock-v12-3-b114efa6e3e2@oracle.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-06-08tls: Re-present partially-consumed records in tls_sw_read_sock()Chuck Lever
The tls_sw_read_sock() loop releases the current skb whether read_actor() consumed the full record or only a prefix. When the actor takes only part of the record and leaves desc->count non-zero, the remainder is lost: skb is neither requeued nor freed, and the next iteration overwrites it during dequeue or tls_rx_rec_wait(). No mainline consumer reaches this path today. The only in-tree TLS read_sock user is nvme/tcp, whose actor nvme_tcp_recv_skb() loops until the input length is exhausted and returns either the full length or a negative error. The path becomes reachable with the upcoming NFSD svcsock receive built on read_sock_cmsg. Its data actor, svc_tcp_recv_actor(), parses an RPC fragment stream incrementally and returns at fragment boundaries. When a TLS record carries the tail of one RPC fragment plus the head of the next, the actor returns fewer bytes than offered while leaving desc->count non-zero, and without re-presentation the trailing fragment header vanishes. __tcp_read_sock() handles the equivalent case for plain TCP by leaving the unread bytes available for the next iteration to re-present, via sequence-number re-lookup. Adopt the same loop-level behavior: when read_actor() consumes only part of the record, update rxm->offset and rxm->full_len and requeue the skb to the head of rx_list so the next iteration re-presents the unread bytes. Switch the open-ended for-loop to "while (desc->count)" so the partial- and full-consume arms share a single exit check and read_actor() is not re-invoked once desc->count is exhausted. Cc: Sagi Grimberg <sagi@grimberg.me> Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Reviewed-by: Hannes Reinecke <hare@kernel.org> Reviewed-by: Sabrina Dubroca <sd@queasysnail.net> Link: https://patch.msgid.link/20260604-tls-read-sock-v12-2-b114efa6e3e2@oracle.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-06-08tls: Avoid evaluating freed skb in tls_sw_read_sock() loopChuck Lever
tls_sw_read_sock() ends its receive loop with while (skb), but the else branch in the body calls consume_skb(skb) before the predicate is re-evaluated. A pointer becomes indeterminate when the object it points to reaches end-of-lifetime (C2011 6.2.4p2), and using an indeterminate value is undefined behavior (Annex J.2). The pointer is not dereferenced today -- the predicate either exits the loop or skb is overwritten at the top of the next iteration -- but any future change that adds a dereference between consume_skb() and the predicate would silently introduce a use-after-free. Replace the do/while form with an explicit for(;;) loop so termination happens through a break statement rather than predicate evaluation of a freed pointer. Cc: Sagi Grimberg <sagi@grimberg.me> Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Reviewed-by: Hannes Reinecke <hare@kernel.org> Reviewed-by: Sabrina Dubroca <sd@queasysnail.net> Link: https://patch.msgid.link/20260604-tls-read-sock-v12-1-b114efa6e3e2@oracle.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-05-21Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netJakub Kicinski
Cross-merge networking fixes after downstream PR (net-7.1-rc5). No conflicts, adjacent changes: drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c cc199cd1b912 ("net/mlx5e: Reduce branches in napi poll") c326f9c68921 ("net/mlx5e: xsk: Fix unlocked writing to ICOSQ") drivers/net/ethernet/mellanox/mlx5/core/eswitch.c c6df9a65cbb0 ("net/mlx5: Skip disabled vports when setting max TX speed") 1fba57c91416 ("net/mlx5: Add VHCA_ID page management mode support") net/mac80211/mlme.c a6e6ccd5bd07 ("wifi: mac80211: consume only present negotiated TTLM maps") 49e62ec6eb06 ("wifi: mac80211: move frame RX handling to type files") Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-05-14tls: Preserve sk_err across recvmsg() when data has been copiedChuck Lever
The sk_err check in tls_rx_rec_wait() consumes the error via sock_error(), which clears sk_err atomically. When the caller (tls_sw_recvmsg, tls_sw_splice_read, or tls_sw_read_sock) already has bytes copied to userspace, it returns those bytes and discards the error from this call. sk_err is now zero on the socket, so the next read syscall observes only RCV_SHUTDOWN and reports a clean EOF instead of the actual error (typically -ECONNRESET). The race is reachable when tls_read_flush_backlog()'s periodic sk_flush_backlog() triggers tcp_reset() in the middle of a multi-record read. Pass a has_copied flag to tls_rx_rec_wait(). When has_copied is false, consume sk_err via sock_error() as before. When has_copied is true, report the error from READ_ONCE() but leave sk_err set: the caller returns the byte count and discards the err from this call, and the next read syscall surfaces the preserved sk_err. This mirrors the tcp_recvmsg() preserve-and-surface pattern. The decrypt-abort path is unaffected: tls_err_abort() raises sk_err to EBADMSG after tls_rx_rec_wait() returns, and nothing on the caller's return path consumes it, so the EBADMSG surfaces on the next read. tls_sw_splice_read() passes has_copied=false: it processes one record per call, so no bytes have been copied within the function when tls_rx_rec_wait() runs. A reset that arrives between iterations of splice_direct_to_actor() (the sendfile() path) is still consumed by sock_error() in the later call, and the outer loop returns the prior iterations' byte count and drops the error. tcp_splice_read() exhibits the same pattern at the iteration boundary; addressing it belongs at the splice_direct_to_actor() layer and is out of scope here. Fixes: c46b01839f7a ("tls: rx: periodically flush socket backlog") Suggested-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Link: https://patch.msgid.link/20260513125825.205189-1-cel@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-05-14Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netJakub Kicinski
Cross-merge networking fixes after downstream PR (net-7.1-rc4). No conflicts, or adjacent changes. Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-05-14net: tls: prevent chain-after-chain in plain text SGJakub Kicinski
Sashiko points out that if end = 0 (start != 0) the current code will create a chain link to content type right after the wrap link: This would create a chain where the wrap link points directly to another chain link. The scatterlist API sg_next iterator does not recursively resolve consecutive chain links. meaning this is illegal input to crypto. The wrapping link is unnecessary if end = 0. end is the entry after the last one used so end = 0 means there's nothing pushed after the wrap: end start i v v v [ ]...[ ][ d ][ d ][ d ][ d ][rsv for wrap] Skip the wrapping in this case. TLS 1.3 can use the "wrapping slot" for it's chaining if end = 0. This avoids the chain-after-chain. Move the wrap chaining before marking END and chaining off content type, that feels like more logical ordering to me, but should not matter from functional perspective. Reported-by: Sashiko <sashiko-bot@kernel.org> Fixes: 9aaaa56845a0 ("bpf: Sockmap/tls, skmsg can have wrapped skmsg that needs extra chaining") Signed-off-by: Jakub Kicinski <kuba@kernel.org> Link: https://patch.msgid.link/20260511174920.433155-3-kuba@kernel.org Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-05-14net: tls: fix off-by-one in sg_chain entry count for wrapped sk_msg ringJakub Kicinski
When an sk_msg scatterlist ring wraps (sg.end < sg.start), tls_push_record() chains the tail portion of the ring to the head using sg_chain(). An extra entry in the sg array is reserved for this: struct sk_msg_sg { [...] /* The extra two elements: * 1) used for chaining the front and sections when the list becomes * partitioned (e.g. end < start). The crypto APIs require the * chaining; * 2) to chain tailer SG entries after the message. */ struct scatterlist data[MAX_MSG_FRAGS + 2]; The current code uses MAX_SKB_FRAGS + 1 as the ring size: sg_chain(&msg_pl->sg.data[msg_pl->sg.start], MAX_SKB_FRAGS - msg_pl->sg.start + 1, msg_pl->sg.data); This places the chain pointer at sg_chain(data[start], (MAX_SKB_FRAGS - msg_start + 1) .. = &data[start] + (MAX_SKB_FRAGS - msg_start + 1) - 1 = data[start + (MAX_SKB_FRAGS - start + 1) - 1] = data[MAX_SKB_FRAGS] instead of the true last entry. This is likely due to a "race" of the commit under Fixes landing close to commit 031097d9e079 ("bpf: sk_msg, zap ingress queue on psock down") Convert to ARRAY_SIZE and drop the data[start] / - start (as suggested by Sabrina). Reported-by: 钱一铭 <yimingqian591@gmail.com> Fixes: 9aaaa56845a0 ("bpf: Sockmap/tls, skmsg can have wrapped skmsg that needs extra chaining") Signed-off-by: Jakub Kicinski <kuba@kernel.org> Reviewed-by: Sabrina Dubroca <sd@queasysnail.net> Link: https://patch.msgid.link/20260511174920.433155-2-kuba@kernel.org Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-05-07Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netJakub Kicinski
Cross-merge networking fixes after downstream PR (net-7.1-rc3). Conflicts: net/ipv4/igmp.c 726fa7da2d8c ("ipv4: igmp: get rid of IGMPV3_{QQIC,MRC} and simplify calculation") c6bebaa744f7 ("ipv4: igmp: annotate data-races in igmp_heard_query()") https://lore.kernel.org/a7365e4873340f7a5e30411207de3bf9@kernel.org Adjacent changes: net/psp/psp_main.c 30cb24f97d44 ("psp: strip variable-length PSP header in psp_dev_rcv()") c2b22277ad89 ("psp: validate IPv4 header fields in psp_dev_rcv()") net/sched/sch_fq_codel.c f83e07b29246 ("net/sched: sch_fq_codel: annotate data-races from fq_codel_dump_class_stats()") 3f3aa77ff1c8 ("net/sched: add qstats_cpu_drop_inc() helper") net/wireless/pmsr.c 0f3c0a197309 ("wifi: nl80211: fix NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST usage") 410aa47fd9d3 ("wifi: cfg80211: allow suppressing FTM result reporting for PD requests") Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-05-02net: tls: fix silent data drop under pipe back-pressureJakub Kicinski
tls_sw_splice_read() uses len when advancing rxm->offset / rxm->full_len after skb_splice_bits(), rather than copied (the actual number of bytes successfully spliced into the pipe). When the destination pipe cannot accept all the requested bytes, splice_to_pipe() returns fewer bytes than len, and 'len - copied' of data is effectively skipped over. Fixes: e062fe99cccd ("tls: splice_read: fix accessing pre-processed records") Link: https://patch.msgid.link/20260429222944.2139041-2-kuba@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-05-01net: tls: reshuffle the device ops checkJakub Kicinski
We try to validate during registration that the netdev has ops if it has features. This is currently somewhat sillily written because we have a dereference before a NULL check on the ops struct. Straighten this out. No functional change intended other than saving ourselves the very theoretical crash with a bad driver. Note that we check earlier in the function that either ops or TLS features are set for the device in question. Reviewed-by: Simon Horman <horms@kernel.org> Link: https://patch.msgid.link/20260429213001.1908235-1-kuba@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-04-30net: tls: fix strparser anchor skb leak on offload RX setup failureJakub Kicinski
When tls_set_device_offload_rx() fails at tls_dev_add(), the error path calls tls_sw_free_resources_rx() to clean up the SW context that was initialized by tls_set_sw_offload(). This function calls tls_sw_release_resources_rx() (which stops the strparser via tls_strp_stop()) and tls_sw_free_ctx_rx() (which kfrees the context), but never frees the anchor skb that was allocated by alloc_skb(0) in tls_strp_init(). Note that tls_sw_free_resources_rx() is exclusively used for this "failed to start offload" code path, there's no other caller. The leak did not exist before commit 84c61fe1a75b ("tls: rx: do not use the standard strparser"), because the standard strparser doesn't try to pre-allocate an skb. The normal close path in tls_sk_proto_close() handles cleanup by calling tls_sw_strparser_done() (which calls tls_strp_done()) after dropping the socket lock, because tls_strp_done() does cancel_work_sync() and the strparser work handler takes the socket lock. Fixes: 84c61fe1a75b ("tls: rx: do not use the standard strparser") Signed-off-by: Jakub Kicinski <kuba@kernel.org> Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev> Link: https://patch.msgid.link/20260428231559.1358502-1-kuba@kernel.org Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-04-09Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netJakub Kicinski
Cross-merge networking fixes after downstream PR (net-7.0-rc8). Conflicts: net/ipv6/seg6_iptunnel.c c3812651b522f ("seg6: separate dst_cache for input and output paths in seg6 lwtunnel") 78723a62b969a ("seg6: add per-route tunnel source address") https://lore.kernel.org/adZhwtOYfo-0ImSa@sirena.org.uk net/ipv4/icmp.c fde29fd934932 ("ipv4: icmp: fix null-ptr-deref in icmp_build_probe()") d98adfbdd5c01 ("ipv4: drop ipv6_stub usage and use direct function calls") https://lore.kernel.org/adO3dccqnr6j-BL9@sirena.org.uk Adjacent changes: drivers/net/ethernet/stmicro/stmmac/chain_mode.c 51f4e090b9f8 ("net: stmmac: fix integer underflow in chain mode") 6b4286e05508 ("net: stmmac: rename STMMAC_GET_ENTRY() -> STMMAC_NEXT_ENTRY()") Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-04-07net/tls: fix use-after-free in -EBUSY error path of tls_do_encryptionMuhammad Alifa Ramdhan
The -EBUSY handling in tls_do_encryption(), introduced by commit 859054147318 ("net: tls: handle backlogging of crypto requests"), has a use-after-free due to double cleanup of encrypt_pending and the scatterlist entry. When crypto_aead_encrypt() returns -EBUSY, the request is enqueued to the cryptd backlog and the async callback tls_encrypt_done() will be invoked upon completion. That callback unconditionally restores the scatterlist entry (sge->offset, sge->length) and decrements ctx->encrypt_pending. However, if tls_encrypt_async_wait() returns an error, the synchronous error path in tls_do_encryption() performs the same cleanup again, double-decrementing encrypt_pending and double-restoring the scatterlist. The double-decrement corrupts the encrypt_pending sentinel (initialized to 1), making tls_encrypt_async_wait() permanently skip the wait for pending async callbacks. A subsequent sendmsg can then free the tls_rec via bpf_exec_tx_verdict() while a cryptd callback is still pending, resulting in a use-after-free when the callback fires on the freed record. Fix this by skipping the synchronous cleanup when the -EBUSY async wait returns an error, since the callback has already handled encrypt_pending and sge restoration. Fixes: 859054147318 ("net: tls: handle backlogging of crypto requests") Cc: stable@vger.kernel.org Signed-off-by: Muhammad Alifa Ramdhan <ramdhan@starlabs.sg> Reviewed-by: Sabrina Dubroca <sd@queasysnail.net> Link: https://patch.msgid.link/20260403013617.2838875-1-ramdhan@starlabs.sg Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-03-26Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netJakub Kicinski
Cross-merge networking fixes after downstream PR (net-7.0-rc6). No conflicts, or adjacent changes. Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-03-26tls: Purge async_hold in tls_decrypt_async_wait()Chuck Lever
The async_hold queue pins encrypted input skbs while the AEAD engine references their scatterlist data. Once tls_decrypt_async_wait() returns, every AEAD operation has completed and the engine no longer references those skbs, so they can be freed unconditionally. A subsequent patch adds batch async decryption to tls_sw_read_sock(), introducing a new call site that must drain pending AEAD operations and release held skbs. Move __skb_queue_purge(&ctx->async_hold) into tls_decrypt_async_wait() so the purge is centralized and every caller -- recvmsg's drain path, the -EBUSY fallback in tls_do_decryption(), and the new read_sock batch path -- releases held skbs on synchronization without each site managing the purge independently. This fixes a leak when tls_strp_msg_hold() fails part-way through, after having added some cloned skbs to the async_hold queue. tls_decrypt_sg() will then call tls_decrypt_async_wait() to process all pending decrypts, and drop back to synchronous mode, but tls_sw_recvmsg() only flushes the async_hold queue when one record has been processed in "fully-async" mode, which may not be the case here. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Reported-by: Yiming Qian <yimingqian591@gmail.com> Fixes: b8a6ff84abbc ("tls: wait for pending async decryptions if tls_strp_msg_hold fails") Link: https://patch.msgid.link/20260324-tls-read-sock-v5-1-5408befe5774@oracle.com [pabeni@redhat.com: added leak comment] Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-03-02net: remove addr_len argument of recvmsg() handlersEric Dumazet
Use msg->msg_namelen as a place holder instead of a temporary variable, notably in inet[6]_recvmsg(). This removes stack canaries and allows tail-calls. $ scripts/bloat-o-meter -t vmlinux.old vmlinux add/remove: 0/0 grow/shrink: 2/19 up/down: 26/-532 (-506) Function old new delta rawv6_recvmsg 744 767 +23 vsock_dgram_recvmsg 55 58 +3 vsock_connectible_recvmsg 50 47 -3 unix_stream_recvmsg 161 158 -3 unix_seqpacket_recvmsg 62 59 -3 unix_dgram_recvmsg 42 39 -3 tcp_recvmsg 546 543 -3 mptcp_recvmsg 1568 1565 -3 ping_recvmsg 806 800 -6 tcp_bpf_recvmsg_parser 983 974 -9 ip_recv_error 588 576 -12 ipv6_recv_rxpmtu 442 428 -14 udp_recvmsg 1243 1224 -19 ipv6_recv_error 1046 1024 -22 udpv6_recvmsg 1487 1461 -26 raw_recvmsg 465 437 -28 udp_bpf_recvmsg 1027 984 -43 sock_common_recvmsg 103 27 -76 inet_recvmsg 257 175 -82 inet6_recvmsg 257 175 -82 tcp_bpf_recvmsg 663 568 -95 Total: Before=25143834, After=25143328, chg -0.00% Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Willem de Bruijn <willemb@google.com> Link: https://patch.msgid.link/20260227151120.1346573-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-02-27tls: don't select STREAM_PARSERSabrina Dubroca
ktls was converted to its own stream parser in commit 84c61fe1a75b ("tls: rx: do not use the standard strparser"), but the Kconfig dependency was left. The only part of the original strparser that's shared with ktls are a few structs (strp_msg, sk_skb_cb) and the strp_msg helper, those don't require building the net/strparser code. Signed-off-by: Sabrina Dubroca <sd@queasysnail.net> Link: https://patch.msgid.link/cb41e513a30eeaac0b419284cc87433f049b2ee0.1771871995.git.sd@queasysnail.net Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-02-26Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netJakub Kicinski
Cross-merge networking fixes after downstream PR (net-7.0-rc2). Conflicts: tools/testing/selftests/drivers/net/hw/rss_ctx.py 19c3a2a81d2b ("selftests: drv-net: rss: Generate unique ports for RSS context tests") ce5a0f4612db ("selftests: drv-net: rss_ctx: test RSS contexts persist after ifdown/up") include/net/inet_connection_sock.h 858d2a4f67ff6 ("tcp: fix potential race in tcp_v6_syn_recv_sock()") fcd3d039fab69 ("tcp: make tcp_v{4,6}_send_check() static") https://lore.kernel.org/aZ8PSFLzBrEU3I89@sirena.org.uk drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c drivers/net/ethernet/mellanox/mlx5/core/en/xsk/pool.c 69050f8d6d075 ("treewide: Replace kmalloc with kmalloc_obj for non-scalar types") bf4afc53b77ae ("Convert 'alloc_obj' family to use the new default GFP_KERNEL argument") 8a96b9144f18a ("net/mlx5e: Alloc xsk channel param out of mlx5e_open_xsk()") Adjacent changes: net/netfilter/ipvs/ip_vs_ctl.c c59bd9e62e06 ("ipvs: use more counters to avoid service lookups") bf4afc53b77a ("Convert 'alloc_obj' family to use the new default GFP_KERNEL argument") Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-02-26Merge tag 'net-7.0-rc2' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net Pull networking fixes from Paolo Abeni: "Including fixes from IPsec, Bluetooth and netfilter Current release - regressions: - wifi: fix dev_alloc_name() return value check - rds: fix recursive lock in rds_tcp_conn_slots_available Current release - new code bugs: - vsock: lock down child_ns_mode as write-once Previous releases - regressions: - core: - do not pass flow_id to set_rps_cpu() - consume xmit errors of GSO frames - netconsole: avoid OOB reads, msg is not nul-terminated - netfilter: h323: fix OOB read in decode_choice() - tcp: re-enable acceptance of FIN packets when RWIN is 0 - udplite: fix null-ptr-deref in __udp_enqueue_schedule_skb(). - wifi: brcmfmac: fix potential kernel oops when probe fails - phy: register phy led_triggers during probe to avoid AB-BA deadlock - eth: - bnxt_en: fix deleting of Ntuple filters - wan: farsync: fix use-after-free bugs caused by unfinished tasklets - xscale: check for PTP support properly Previous releases - always broken: - tcp: fix potential race in tcp_v6_syn_recv_sock() - kcm: fix zero-frag skb in frag_list on partial sendmsg error - xfrm: - fix race condition in espintcp_close() - always flush state and policy upon NETDEV_UNREGISTER event - bluetooth: - purge error queues in socket destructors - fix response to L2CAP_ECRED_CONN_REQ - eth: - mlx5: - fix circular locking dependency in dump - fix "scheduling while atomic" in IPsec MAC address query - gve: fix incorrect buffer cleanup for QPL - team: avoid NETDEV_CHANGEMTU event when unregistering slave - usb: validate USB endpoints" * tag 'net-7.0-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (72 commits) netfilter: nf_conntrack_h323: fix OOB read in decode_choice() dpaa2-switch: validate num_ifs to prevent out-of-bounds write net: consume xmit errors of GSO frames vsock: document write-once behavior of the child_ns_mode sysctl vsock: lock down child_ns_mode as write-once selftests/vsock: change tests to respect write-once child ns mode net/mlx5e: Fix "scheduling while atomic" in IPsec MAC address query net/mlx5: Fix missing devlink lock in SRIOV enable error path net/mlx5: E-switch, Clear legacy flag when moving to switchdev net/mlx5: LAG, disable MPESW in lag_disable_change() net/mlx5: DR, Fix circular locking dependency in dump selftests: team: Add a reference count leak test team: avoid NETDEV_CHANGEMTU event when unregistering slave net: mana: Fix double destroy_workqueue on service rescan PCI path MAINTAINERS: Update maintainer entry for QUALCOMM ETHQOS ETHERNET DRIVER dpll: zl3073x: Remove redundant cleanup in devm_dpll_init() selftests/net: packetdrill: Verify acceptance of FIN packets when RWIN is 0 tcp: re-enable acceptance of FIN packets when RWIN is 0 vsock: Use container_of() to get net namespace in sysctl handlers net: usb: kaweth: validate USB endpoints ...
2026-02-24tcp: make tcp_v{4,6}_send_check() staticEric Dumazet
tcp_v{4,6}_send_check() are only called from tcp_output.c and should be made static so that the compiler does not need to put an out of line copy of them. Remove (struct inet_connection_sock_af_ops) send_check field and use instead @net_header_len. Move @net_header_len close to @queue_xmit for data locality as both are used in TCP tx fast path. $ scripts/bloat-o-meter -t vmlinux.2 vmlinux.3 add/remove: 0/2 grow/shrink: 0/3 up/down: 0/-172 (-172) Function old new delta __tcp_transmit_skb 3426 3423 -3 tcp_v4_send_check 136 132 -4 mptcp_subflow_init 777 763 -14 __pfx_tcp_v6_send_check 16 - -16 tcp_v6_send_check 135 - -135 Total: Before=25143196, After=25143024, chg -0.00% Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20260223100729.3761597-4-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-02-23tls: Fix race condition in tls_sw_cancel_work_tx()Hyunwoo Kim
This issue was discovered during a code audit. After cancel_delayed_work_sync() is called from tls_sk_proto_close(), tx_work_handler() can still be scheduled from paths such as the Delayed ACK handler or ksoftirqd. As a result, the tx_work_handler() worker may dereference a freed TLS object. The following is a simple race scenario: cpu0 cpu1 tls_sk_proto_close() tls_sw_cancel_work_tx() tls_write_space() tls_sw_write_space() if (!test_and_set_bit(BIT_TX_SCHEDULED, &tx_ctx->tx_bitmask)) set_bit(BIT_TX_SCHEDULED, &ctx->tx_bitmask); cancel_delayed_work_sync(&ctx->tx_work.work); schedule_delayed_work(&tx_ctx->tx_work.work, 0); To prevent this race condition, cancel_delayed_work_sync() is replaced with disable_delayed_work_sync(). Fixes: f87e62d45e51 ("net/tls: remove close callback sock unlock/lock around TX work flush") Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com> Reviewed-by: Simon Horman <horms@kernel.org> Reviewed-by: Sabrina Dubroca <sd@queasysnail.net> Link: https://patch.msgid.link/aZgsFO6nfylfvLE7@v4bel Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-02-21Convert 'alloc_obj' family to use the new default GFP_KERNEL argumentLinus Torvalds
This was done entirely with mindless brute force, using git grep -l '\<k[vmz]*alloc_objs*(.*, GFP_KERNEL)' | xargs sed -i 's/\(alloc_objs*(.*\), GFP_KERNEL)/\1)/' to convert the new alloc_obj() users that had a simple GFP_KERNEL argument to just drop that argument. Note that due to the extreme simplicity of the scripting, any slightly more complex cases spread over multiple lines would not be triggered: they definitely exist, but this covers the vast bulk of the cases, and the resulting diff is also then easier to check automatically. For the same reason the 'flex' versions will be done as a separate conversion. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2026-02-21treewide: Replace kmalloc with kmalloc_obj for non-scalar typesKees Cook
This is the result of running the Coccinelle script from scripts/coccinelle/api/kmalloc_objs.cocci. The script is designed to avoid scalar types (which need careful case-by-case checking), and instead replace kmalloc-family calls that allocate struct or union object instances: Single allocations: kmalloc(sizeof(TYPE), ...) are replaced with: kmalloc_obj(TYPE, ...) Array allocations: kmalloc_array(COUNT, sizeof(TYPE), ...) are replaced with: kmalloc_objs(TYPE, COUNT, ...) Flex array allocations: kmalloc(struct_size(PTR, FAM, COUNT), ...) are replaced with: kmalloc_flex(*PTR, FAM, COUNT, ...) (where TYPE may also be *VAR) The resulting allocations no longer return "void *", instead returning "TYPE *". Signed-off-by: Kees Cook <kees@kernel.org>
2025-10-31Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netJakub Kicinski
Cross-merge networking fixes after downstream PR (net-6.18-rc4). No conflicts, adjacent changes: drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ded9813d17d3 ("net: stmmac: Consider Tx VLAN offload tag length for maxSDU") 26ab9830beab ("net: stmmac: replace has_xxxx with core_type") Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2025-10-29net: tls: Cancel RX async resync request on rcd_delta overflowShahar Shitrit
When a netdev issues a RX async resync request for a TLS connection, the TLS module handles it by logging record headers and attempting to match them to the tcp_sn provided by the device. If a match is found, the TLS module approves the tcp_sn for resynchronization. While waiting for a device response, the TLS module also increments rcd_delta each time a new TLS record is received, tracking the distance from the original resync request. However, if the device response is delayed or fails (e.g due to unstable connection and device getting out of tracking, hardware errors, resource exhaustion etc.), the TLS module keeps logging and incrementing, which can lead to a WARN() when rcd_delta exceeds the threshold. To address this, introduce tls_offload_rx_resync_async_request_cancel() to explicitly cancel resync requests when a device response failure is detected. Call this helper also as a final safeguard when rcd_delta crosses its threshold, as reaching this point implies that earlier cancellation did not occur. Signed-off-by: Shahar Shitrit <shshitrit@nvidia.com> Reviewed-by: Sabrina Dubroca <sd@queasysnail.net> Signed-off-by: Tariq Toukan <tariqt@nvidia.com> Link: https://patch.msgid.link/1761508983-937977-3-git-send-email-tariqt@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2025-10-27net/tls: support setting the maximum payload sizeWilfred Mallawa
During a handshake, an endpoint may specify a maximum record size limit. Currently, the kernel defaults to TLS_MAX_PAYLOAD_SIZE (16KB) for the maximum record size. Meaning that, the outgoing records from the kernel can exceed a lower size negotiated during the handshake. In such a case, the TLS endpoint must send a fatal "record_overflow" alert [1], and thus the record is discarded. Upcoming Western Digital NVMe-TCP hardware controllers implement TLS support. For these devices, supporting TLS record size negotiation is necessary because the maximum TLS record size supported by the controller is less than the default 16KB currently used by the kernel. Currently, there is no way to inform the kernel of such a limit. This patch adds support to a new setsockopt() option `TLS_TX_MAX_PAYLOAD_LEN` that allows for setting the maximum plaintext fragment size. Once set, outgoing records are no larger than the size specified. This option can be used to specify the record size limit. [1] https://www.rfc-editor.org/rfc/rfc8449 Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com> Reviewed-by: Sabrina Dubroca <sd@queasysnail.net> Link: https://patch.msgid.link/20251022001937.20155-1-wilfred.opensource@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2025-10-16net: Allow opt-out from global protocol memory accounting.Kuniyuki Iwashima
Some protocols (e.g., TCP, UDP) implement memory accounting for socket buffers and charge memory to per-protocol global counters pointed to by sk->sk_proto->memory_allocated. Sometimes, system processes do not want that limitation. For a similar purpose, there is SO_RESERVE_MEM for sockets under memcg. Also, by opting out of the per-protocol accounting, sockets under memcg can avoid paying costs for two orthogonal memory accounting mechanisms. A microbenchmark result is in the subsequent bpf patch. Let's allow opt-out from the per-protocol memory accounting if sk->sk_bypass_prot_mem is true. sk->sk_bypass_prot_mem and sk->sk_prot are placed in the same cache line, and sk_has_account() always fetches sk->sk_prot before accessing sk->sk_bypass_prot_mem, so there is no extra cache miss for this patch. The following patches will set sk->sk_bypass_prot_mem to true, and then, the per-protocol memory accounting will be skipped. Note that this does NOT disable memcg, but rather the per-protocol one. Another option not to use the hole in struct sock_common is create sk_prot variants like tcp_prot_bypass, but this would complicate SOCKMAP logic, tcp_bpf_prots etc. Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org> Reviewed-by: Shakeel Butt <shakeel.butt@linux.dev> Reviewed-by: Eric Dumazet <edumazet@google.com> Acked-by: Roman Gushchin <roman.gushchin@linux.dev> Link: https://patch.msgid.link/20251014235604.3057003-3-kuniyu@google.com
2025-10-15tls: don't rely on tx_work during send()Sabrina Dubroca
With async crypto, we rely on tx_work to actually transmit records once encryption completes. But while send() is running, both the tx_lock and socket lock are held, so tx_work_handler cannot process the queue of encrypted records, and simply reschedules itself. During a large send(), this could last a long time, and use a lot of memory. Transmit any pending encrypted records before restarting the main loop of tls_sw_sendmsg_locked. Fixes: a42055e8d2c3 ("net/tls: Add support for async encryption of records for performance") Reported-by: Jann Horn <jannh@google.com> Signed-off-by: Sabrina Dubroca <sd@queasysnail.net> Link: https://patch.msgid.link/8396631478f70454b44afb98352237d33f48d34d.1760432043.git.sd@queasysnail.net Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2025-10-15tls: wait for pending async decryptions if tls_strp_msg_hold failsSabrina Dubroca
Async decryption calls tls_strp_msg_hold to create a clone of the input skb to hold references to the memory it uses. If we fail to allocate that clone, proceeding with async decryption can lead to various issues (UAF on the skb, writing into userspace memory after the recv() call has returned). In this case, wait for all pending decryption requests. Fixes: 84c61fe1a75b ("tls: rx: do not use the standard strparser") Reported-by: Jann Horn <jannh@google.com> Signed-off-by: Sabrina Dubroca <sd@queasysnail.net> Link: https://patch.msgid.link/b9fe61dcc07dab15da9b35cf4c7d86382a98caf2.1760432043.git.sd@queasysnail.net Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2025-10-15tls: always set record_type in tls_process_cmsgSabrina Dubroca
When userspace wants to send a non-DATA record (via the TLS_SET_RECORD_TYPE cmsg), we need to send any pending data from a previous MSG_MORE send() as a separate DATA record. If that DATA record is encrypted asynchronously, tls_handle_open_record will return -EINPROGRESS. This is currently treated as an error by tls_process_cmsg, and it will skip setting record_type to the correct value, but the caller (tls_sw_sendmsg_locked) handles that return value correctly and proceeds with sending the new message with an incorrect record_type (DATA instead of whatever was requested in the cmsg). Always set record_type before handling the open record. If tls_handle_open_record returns an error, record_type will be ignored. If it succeeds, whether with synchronous crypto (returning 0) or asynchronous (returning -EINPROGRESS), the caller will proceed correctly. Fixes: a42055e8d2c3 ("net/tls: Add support for async encryption of records for performance") Reported-by: Jann Horn <jannh@google.com> Signed-off-by: Sabrina Dubroca <sd@queasysnail.net> Link: https://patch.msgid.link/0457252e578a10a94e40c72ba6288b3a64f31662.1760432043.git.sd@queasysnail.net Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2025-10-15tls: wait for async encrypt in case of error during latter iterations of sendmsgSabrina Dubroca
If we hit an error during the main loop of tls_sw_sendmsg_locked (eg failed allocation), we jump to send_end and immediately return. Previous iterations may have queued async encryption requests that are still pending. We should wait for those before returning, as we could otherwise be reading from memory that userspace believes we're not using anymore, which would be a sort of use-after-free. This is similar to what tls_sw_recvmsg already does: failures during the main loop jump to the "wait for async" code, not straight to the unlock/return. Fixes: a42055e8d2c3 ("net/tls: Add support for async encryption of records for performance") Reported-by: Jann Horn <jannh@google.com> Signed-off-by: Sabrina Dubroca <sd@queasysnail.net> Link: https://patch.msgid.link/c793efe9673b87f808d84fdefc0f732217030c52.1760432043.git.sd@queasysnail.net Signed-off-by: Jakub Kicinski <kuba@kernel.org>