Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F173547140
D58461.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D58461.diff
View Options
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -296,6 +296,8 @@
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 @@
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 @@
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 @@
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
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Sep 27, 6:36 PM (5 h, 26 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
36516283
Default Alt Text
D58461.diff (3 KB)
Attached To
Mode
D58461: unix: factor `unp_vnode_peer()` out of `unp_connectat()`
Attached
Detach File
Event Timeline
Log In to Comment