From nobody Sun Mar 23 11:59:56 2025 X-Original-To: dev-commits-src-main@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 4ZLF9S3kzjz5rC1G; Sun, 23 Mar 2025 11:59:56 +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 4ZLF9S1bRxz3R3s; Sun, 23 Mar 2025 11:59:56 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1742731196; 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=lgKmsxqQhZA9q1r3qZIWUTJm4VWRUkny44e3hYYEl0k=; b=fKL0f1/AbaQeU5UvGfWB3DM1WYXaHSR4tqHWF1dNhJZY/aEO6/ZgSAHzUmiBYn+xstndsl iAarimOuJAfL5bCjuo21eEin20KECVo7cyjMk4Yb3rkY9+HVDt1gN0DcA5PC+2/8Fege2x mUajnIGMrEpzcjlqd8FQZEJF33ibeKmmGYfn/B+fnLBBHBZy3jxfeUwjMxGWCDAXKSNDbW /GZl3obljuSbgEGT+vs5Ia/iieFBXq6gJcjjBpMLjFIG9wp4azq84cIQGdbEelN58DOV6K frOFTPYi8plvBQtokI0eDfV/DNehzmXlVRQ1HvZPh/ZCk1brO8lU5Sj4PQBenA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1742731196; a=rsa-sha256; cv=none; b=uY/6xJYyLVRsdPwNj0+1J+UFOWUrI61exR3bIP6OSFrn/ThEXO+6mKOG8XWlbTQVfIRcdU bU1nnj7VfMTOej4VhKTeTZrMSNvTVPAVF+vAX8GFASqZlSFYOqjdnVl5hRXa45U0bO26qJ P4tYk2q9clnxHJqBp7/jmUPdThLTX7ffm7YXH817F5s9HFZKBI6iFI9wWxBxoU1B7E5aWi BtW75fsVzxjFVFrzYnLH0iqza5Ki7yz/yBLeSmCXmOhZW0o+72DDkowZ/RBQ8XKg+SdGET zCg/a4P6cuA+d7kA2rWOAMb72lTI+QXnC+go94RRgo/3UFTBgwMA0z3Qr96RBQ== 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=1742731196; 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=lgKmsxqQhZA9q1r3qZIWUTJm4VWRUkny44e3hYYEl0k=; b=pTfcCrik1sJrxUzgWCRhC1ntZZp7LYJDcN+YP9lPMOXXDMh4+4YCqalq5kaKLu9T9sLmII yCsJhp2jgUS7Nh+ww06doPd0foI+7yRSgFcYmztFLbmt3TGZAgZjmEXpPh22WLknH1JEy/ Oc+r5E2uV8GNu1789T+TEAmdbF43XsYpCKdQ/okdxa7rtZow5jEnsxnKFwUuGEaQKyLHKr tNgz2h12mWsyulkw3HETTcgZs6JUchmQaBRl+c8vOBogKXLtyA4hz7ikmYisz19AMU3ILT L6HOAGugy+n6zpSNwy1Sn82nt4l/cfaZlvEULdHrKGCEl2REI5NN6PBEBgowzg== 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 4ZLF9S0tCMz16Ct; Sun, 23 Mar 2025 11:59:56 +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 52NBxusP044910; Sun, 23 Mar 2025 11:59:56 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 52NBxuOa044907; Sun, 23 Mar 2025 11:59:56 GMT (envelope-from git) Date: Sun, 23 Mar 2025 11:59:56 GMT Message-Id: <202503231159.52NBxuOa044907@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Mark Johnston Subject: git: 574816356834 - main - socket: Fix a race in the SO_SPLICE state machine List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@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/main X-Git-Reftype: branch X-Git-Commit: 574816356834cb99295b124be0ec34bd9e0b9c72 Auto-Submitted: auto-generated The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=574816356834cb99295b124be0ec34bd9e0b9c72 commit 574816356834cb99295b124be0ec34bd9e0b9c72 Author: Mark Johnston AuthorDate: 2025-03-23 11:55:56 +0000 Commit: Mark Johnston CommitDate: 2025-03-23 11:55:56 +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 --- 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 03bfea721dd2..c27b007cafc6 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) @@ -1638,7 +1633,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 735ff49062de..02d0ca139fa4 100644 --- a/sys/sys/socketvar.h +++ b/sys/sys/socketvar.h @@ -80,6 +80,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 */