From nobody Sun Apr 06 22:51:14 2025 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4ZW6yW2vDKz5s8Wf; Sun, 06 Apr 2025 22:51:15 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4ZW6yV2dh0z3KYK; Sun, 06 Apr 2025 22:51:14 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1743979874; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=K93fPBxKmfwVro0pBs15X1wuYCZfPRjCA3IHJEPwSew=; b=ZUKxZsjpsk+IwUbNUHBUUErik/ErS8DJiJJDG7tL8Xyfa/vrgGDjg25vovjPSfMdIKNLqn oy18bwtoAW0u/NlyO24KTEmCnvmf9N8jxDFFOudpxUjzSEFe0VCgaDLh4nMCwePsCw9YDR fEFBZDypqmaxGYaeBMQzSae1SzH5lpjlHnb2UC5guOfk/UArJYAA2NvSUvmvZeJTrHHA1q U6QqmjSevg8lcTcBObt8t5HuVaLrOegIpkqgiG83N7DW6WMriZZRCnjNWt4Jk/KNy1XStS zAsO9IQJDEzMcIfYXmbS0p6B/PS9Rp0t5mB3V5JLPM4lBwpmZbkXJD0WOZxTmw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1743979874; a=rsa-sha256; cv=none; b=BwqNy07ecqPyxntHdM5y7xwmB0+M2mYJ6z4vqmvmFC0OtSJXICNeZLLDBtsuj/LUp+h8i2 n8pVkRqRqfktUg+jq0bkOy3aJprOWjfTXk/RNd828AbWJl5OsCVw9foNljHukpeWkXE4W5 UoWjjo3luQOS5feohBL+1PDgp9MR8dQq66a1gJXONEgnKL7BQJ4G98qgB1eNrEmoRLM7j8 tGKw79G3zKLPsWqSWU5+f1XXVbHn65KwBKmAv/DoRXH08e4DgvZtLnkRDPtrOeE4+1Mua+ CSmdo2hUYF6RCj9zAWoCVNW0T3Tb0AbLhgYbpcMIgqGx37xQHCOcWUkvNALstQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1743979874; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=K93fPBxKmfwVro0pBs15X1wuYCZfPRjCA3IHJEPwSew=; b=Q1c8tJvTHcF/pMcPosBiSMuG86bMdIYhi1qsxGss5bKzZFuB24MKKiNPUVRtCLWqfAhnRD WBz4nBLQqr1oKgJtloO72OOlbVSBrBNKatGa3bVEvtF8APxZUWvwmGql3sWOyBmW4kHQSl 9/9A8/UAONJ9yM0d1urobA83jeA8TiSO8pDG2DcYCrUmtj34ucmzXlzFhgh5IibGoTCGDS UG7q+SxBmAY2/FC1IuPBi4PGWbOfU7ze5EZt44G/qhinQo+OseaOF3s375GENv7WE3srpl kOyvAe7f1jLbHBP+tl5100EBrrm52FDR573RyPXLGMeY42XQOMBCAMO/L0SW2w== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4ZW6yV1ys2z5kt; Sun, 06 Apr 2025 22:51:14 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 536MpEUa077192; Sun, 6 Apr 2025 22:51:14 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 536MpE7B077189; Sun, 6 Apr 2025 22:51:14 GMT (envelope-from git) Date: Sun, 6 Apr 2025 22:51:14 GMT Message-Id: <202504062251.536MpE7B077189@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Mark Johnston Subject: git: f2214e48d02c - stable/14 - socket: Fix a race in the SO_SPLICE state machine List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: markj X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: f2214e48d02c2a251f4aa9e95683d2f5e66337c7 Auto-Submitted: auto-generated The branch stable/14 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=f2214e48d02c2a251f4aa9e95683d2f5e66337c7 commit f2214e48d02c2a251f4aa9e95683d2f5e66337c7 Author: Mark Johnston AuthorDate: 2025-03-23 11:55:56 +0000 Commit: Mark Johnston CommitDate: 2025-04-06 13:54:20 +0000 socket: Fix a race in the SO_SPLICE state machine When so_splice() links two sockets together, it first attaches the splice control structure to the source socket; at that point, the splice is in the idle state. After that point, a socket wakeup will queue up work for a splice worker thread: in particular, so_splice_dispatch() only queues work if the splice is idle. Meanwhile, so_splice() continues initializing the splice, and finally calls so_splice_xfer() to transfer any already buffered data. This assumes that the splice is still idle, but that's not true if some async work was already dispatched. Solve the problem by introducing an initial "under construction" state for the splice control structure, such that wakeups won't queue any work until so_splice() has finished. While here, remove an outdated comment from the beginning of so_splice_xfer(). Reported by: syzkaller Reviewed by: gallatin Fixes: a1da7dc1cdad ("socket: Implement SO_SPLICE") MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D49437 (cherry picked from commit 574816356834cb99295b124be0ec34bd9e0b9c72) --- sys/kern/uipc_socket.c | 7 +------ sys/sys/socketvar.h | 1 + 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 58e374d7aed2..7a4e3b1f2507 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -592,11 +592,6 @@ so_splice_xfer_data(struct socket *so_src, struct socket *so_dst, off_t max, /* * Transfer data from the source to the sink. - * - * If "direct" is true, the transfer is done in the context of whichever thread - * is operating on one of the socket buffers. We do not know which locks are - * held, so we can only trylock the socket buffers; if this fails, we fall back - * to the worker thread, which invokes this routine with "direct" set to false. */ static void so_splice_xfer(struct so_splice *sp) @@ -1617,7 +1612,7 @@ so_splice_alloc(off_t max) sp->wq_index = atomic_fetchadd_32(&splice_index, 1) % (mp_maxid + 1); } while (CPU_ABSENT(sp->wq_index)); - sp->state = SPLICE_IDLE; + sp->state = SPLICE_INIT; TIMEOUT_TASK_INIT(taskqueue_thread, &sp->timeout, 0, so_splice_timeout, sp); return (sp); diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h index f7b23d239157..40fdd142525f 100644 --- a/sys/sys/socketvar.h +++ b/sys/sys/socketvar.h @@ -82,6 +82,7 @@ struct so_splice { struct mtx mtx; unsigned int wq_index; enum so_splice_state { + SPLICE_INIT, /* embryonic state, don't queue work yet */ SPLICE_IDLE, /* waiting for work to arrive */ SPLICE_QUEUED, /* a wakeup has queued some work */ SPLICE_RUNNING, /* currently transferring data */