From nobody Mon Aug 10 17:40:34 2026 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 4hJhqR03Nxz6X2sh for ; Mon, 10 Aug 2026 17:40:35 +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 "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hJhqQ4FZ6z48ys for ; Mon, 10 Aug 2026 17:40:34 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1786383634; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=02wpAnwu5HzUOlUphnrvPxawzSCbFlgGQHuYLnWtF08=; b=CIN2skzEi/h4jIh34HDvG+BFak8UeeD251p/wR2F6UOpbnAEjZAXvQ5kn1ZXH6vZWl3EwK Rz0h1r207IC1X5oSJC/yMfa2An9Tvd5SP/1a086TXNZtPIjJFPCgw8pLbU5RZUNj0kZPpq 4feKbMSuHzdfwZeDiN+bTFB6X3BMxI13aEi0bhtXQQp5+0/jZNROFILA6bADh5Rid20I3/ tvD5aq1MT4fOABFpZlOw80CJ38KH8f+mHSp+BmCHuV+4TTGIT9k9GBbERLMW+3tugq7SQW 7I3S5zGruOI7YySbftHpkDxeuKPqyjNjVvawVun0m7xbsTMmE4IeKgklA9B1Ng== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1786383634; a=rsa-sha256; cv=none; b=DesWp59jhhaTcQJ1SAC6Q0yVuXYvIX4I9Jc3UOhWrixg+fNU+ITRJUdHPDLMyOrixAZ+lO DARIPqOKbTzpBhHfbBY96PP9oWSPfVR9iafBiY7SV+JAq/rvWJbkaMFDfqkuZyCJRmMeWJ 3r7N20NFg9CsdLze72R9FfET0TENAsQ9ddckel9dYKmymOMBKbIUYI7xM4YuP5dJKeH2jb fNTNbz4jBf1dbJXxKAFLoLTp0x1sJcmE+Kh7H4GxeCao3RwIIcHuT4v+9WQHoiCfVGIT3G 3pu7gMhYDL0mtBHVuiNBazCw3JgRNXC/40lVjxuUyiFuNGeF/rz5IqpyNRtXTQ== 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=1786383634; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=02wpAnwu5HzUOlUphnrvPxawzSCbFlgGQHuYLnWtF08=; b=WjE/ZtcBUHzEVS8pn7UiN0pb52M2PbqWDuRlNXUCxlYv82tk9DwFedu9vW4xg/xG2sIn3v OpPJ88CqyqSw3I8figJAtKLmxdaVDxiai3BCKVQV+fXJQDKueFxxo5r0xQshsP0Fp1kISo guk5vtyGz3yxayw8JC7nTQjOcIyPEOdPcfcJhhRN1bz0ePCKXGIyvoTwq4Wj7TV6nPh2AA fLC1Tv7h+cP+K7lf8+NxYYNud8wW9FEWQOP8wjZbG6JIZNMwTeNDdyo9qghcg7B3Ok3six rwhpWWTKtJoG3g+EhcOUrK1s/PZWaZoAhTDLpIH3TBAb/S/CpJd/SKgWhytPeQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hJhqQ38XQz373 for ; Mon, 10 Aug 2026 17:40:34 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 40b32 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Mon, 10 Aug 2026 17:40:34 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Cc: John Ericson From: Mark Johnston Subject: git: 2c01d10f67b3 - main - unix: factor unp_vnode_peer() out of unp_connectat() 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 List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list 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: 2c01d10f67b343254fd4e747f822a8cdcc326f9d Auto-Submitted: auto-generated Date: Mon, 10 Aug 2026 17:40:34 +0000 Message-Id: <6a7a0d12.40b32.14ac1239@gitrepo.freebsd.org> The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=2c01d10f67b343254fd4e747f822a8cdcc326f9d commit 2c01d10f67b343254fd4e747f822a8cdcc326f9d Author: John Ericson AuthorDate: 2026-08-10 15:04:25 +0000 Commit: Mark Johnston CommitDate: 2026-08-10 17:31:21 +0000 unix: factor unp_vnode_peer() out of unp_connectat() Move the "resolve a locked vnode to the referenced peer socket it names" block into a helper. Pure code motion: the caller now calls `unp_vnode_peer()` and keeps the `vput()`/connect/`sorele()` sequence. No functional change intended. Note: This refactor isn't really necessary as `unp_vnode_peer()` will only be called once throughout this entire patch series. I am just including it out of my personal preferences for decomposing tasks into smaller functions --- we can skip this patch if the reviewers don't like this. Signed-off-by: John Ericson Assisted-by: Claude Code (Claude Opus 4.8 and Fable 5) Reviewed by: markj MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D58461 --- sys/kern/uipc_usrreq.c | 85 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 51 insertions(+), 34 deletions(-) diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index ac8de59b57b2..418c43a8ac85 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -296,6 +296,8 @@ static int unp_connectat(int, struct socket *, struct sockaddr *, struct thread *, struct socket **); static int unp_connect_peer(struct socket *, struct unpcb *, struct sockaddr **, struct thread *, bool); +static int unp_vnode_peer(struct vnode *, struct thread *, + struct socket **); static void unp_connect2(struct socket *, struct socket *, bool); static void unp_disconnect(struct unpcb *unp, struct unpcb *unp2); static void unp_dispose(struct socket *so); @@ -2930,10 +2932,8 @@ static int unp_connectat(int fd, struct socket *so, struct sockaddr *nam, struct thread *td, struct socket **referenced_peerp) { - struct mtx *vplock; struct socket *so2; - struct vnode *vp; - struct unpcb *unp, *unp2; + struct unpcb *unp; struct nameidata nd; char buf[SOCK_MAXADDRLEN]; struct sockaddr *sa; @@ -3001,40 +3001,15 @@ unp_connectat(int fd, struct socket *so, struct sockaddr *nam, if (error) goto out; NDFREE_PNBUF(&nd); - vp = nd.ni_vp; - ASSERT_VOP_LOCKED(vp, "unp_connect"); /* - * Resolve the vnode to a referenced peer socket, then drop the vnode - * before connecting. Holding a reference on the peer keeps it stable - * in place of the per-vnode unp_vp_mtxpool lock, so no vnode lock is - * held across unp_connect_peer() -- which is what the return_locked - * datagram fast path needs, since vput() must not sleep while the peer - * is locked. + * Resolve the vnode to a referenced peer socket and drop the vnode + * before connecting: the reference keeps the peer stable, so no vnode + * lock is held across unp_connect_peer() (which matters for the + * return_locked datagram fast path). */ - if (vp->v_type != VSOCK) { - error = ENOTSOCK; - goto drop_vp; - } -#ifdef MAC - error = mac_vnode_check_open(td->td_ucred, vp, VWRITE | VREAD); - if (error) - goto drop_vp; -#endif - error = VOP_ACCESS(vp, VWRITE, td->td_ucred, td); - if (error) - goto drop_vp; - - vplock = mtx_pool_find(unp_vp_mtxpool, vp); - mtx_lock(vplock); - VOP_UNP_CONNECT(vp, &unp2); - if (unp2 == NULL) - error = ECONNREFUSED; - else - soref(so2 = unp2->unp_socket); - mtx_unlock(vplock); -drop_vp: - vput(vp); + error = unp_vnode_peer(nd.ni_vp, td, &so2); + vput(nd.ni_vp); if (error != 0) goto out; error = unp_connect_peer(so, sotounpcb(so2), &sa, td, @@ -3056,6 +3031,48 @@ out: return (error); } +/* + * Resolve locked vnode 'vp' to the unix-domain socket it names and return a + * referenced peer socket in '*so2p'. As the connect(2)-time resolution, this + * enforces the caller's authorization to reach the socket -- filesystem + * permission (VOP_ACCESS) and MAC (mac_vnode_check_open) -- which bare readers + * of the vnode->pcb binding, such as vfs_unp_reclaim(), deliberately skip. + * + * The returned reference keeps the peer stable for unp_connect_peer() once vp's + * per-vnode binding lock is dropped, so the caller must release it with + * sorele(). Does not consume 'vp'. + */ +static int +unp_vnode_peer(struct vnode *vp, struct thread *td, struct socket **so2p) +{ + struct mtx *vplock; + struct unpcb *unp2; + int error; + + ASSERT_VOP_LOCKED(vp, __func__); + + if (vp->v_type != VSOCK) + return (ENOTSOCK); +#ifdef MAC + error = mac_vnode_check_open(td->td_ucred, vp, VWRITE | VREAD); + if (error != 0) + return (error); +#endif + error = VOP_ACCESS(vp, VWRITE, td->td_ucred, td); + if (error != 0) + return (error); + + vplock = mtx_pool_find(unp_vp_mtxpool, vp); + mtx_lock(vplock); + VOP_UNP_CONNECT(vp, &unp2); + if (unp2 == NULL) + error = ECONNREFUSED; + else + soref(*so2p = unp2->unp_socket); + mtx_unlock(vplock); + return (error); +} + /* * Second half of connecting a unix socket: 'so' is our connecting socket, * with UNP_CONNECTING set, and 'unp2' is the PCB of the peer named by the