git: 44e99b672835 - main - unix: factor unp_sun_path() out of bind and connect

Mark Johnston <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src
Message-ID <6a7a0d10.40b2e.2c7a70e0__10146.8244612747$1786383740$gmane$org@gitrepo.freebsd.org>
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=44e99b67283517207d4e482feee63bc15f4f710e

commit 44e99b67283517207d4e482feee63bc15f4f710e
Author:     John Ericson <[email protected]>
AuthorDate: 2026-08-10 15:04:20 +0000
Commit:     Mark Johnston <[email protected]>
CommitDate: 2026-08-10 17:31:21 +0000

    unix: factor unp_sun_path() out of bind and connect
    
    Extract the AF_UNIX validation plus sun_path/length lookup shared by
    `uipc_bindat()`, `unp_connect()`, and `unp_connectat()` into a helper that
    hands back the path pointer and its length.  Each caller keeps its own
    empty-path policy and, where needed, its own copy of the path.
    
    Signed-off-by: John Ericson <[email protected]>
    Assisted-by: Claude Code (Claude Opus 4.8 and Fable 5)
    
    Reviewed by:    markj
    MFC after:      2 weeks
    Differential Revision:  https://reviews.freebsd.org/D58459
---
 sys/kern/uipc_usrreq.c | 58 +++++++++++++++++++++++++++++++++-----------------
 1 file changed, 39 insertions(+), 19 deletions(-)

diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index c1d00e66f614..d198f8732a93 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -563,10 +563,35 @@ common:
 	return (0);
 }
 
+/*
+ * Validate a bind/connect address as AF_UNIX and hand back its sun_path
+ * and the path length.
+ *
+ * Rejects a wrong family (EAFNOSUPPORT) or a malformed sa_len (EINVAL).
+ */
+static int
+unp_sun_path(const struct sockaddr *nam, const char **pathp, int *lenp)
+{
+	const struct sockaddr_un *soun;
+	int len;
+
+	if (nam->sa_family != AF_UNIX)
+		return (EAFNOSUPPORT);
+	if (nam->sa_len > sizeof(struct sockaddr_un))
+		return (EINVAL);
+	len = nam->sa_len - offsetof(struct sockaddr_un, sun_path);
+	if (len < 0)
+		return (EINVAL);
+	soun = (const struct sockaddr_un *)nam;
+	*pathp = soun->sun_path;
+	*lenp = len;
+	return (0);
+}
+
 static int
 uipc_bindat(int fd, struct socket *so, struct sockaddr *nam, struct thread *td)
 {
-	struct sockaddr_un *soun = (struct sockaddr_un *)nam;
+	struct sockaddr_un *soun;
 	struct vattr vattr;
 	int error, namelen;
 	struct nameidata nd;
@@ -574,21 +599,19 @@ uipc_bindat(int fd, struct socket *so, struct sockaddr *nam, struct thread *td)
 	struct vnode *vp;
 	struct mount *mp;
 	cap_rights_t rights;
+	const char *path;
 	char *buf;
 	mode_t mode;
 
-	if (nam->sa_family != AF_UNIX)
-		return (EAFNOSUPPORT);
+	error = unp_sun_path(nam, &path, &namelen);
+	if (error != 0)
+		return (error);
+	if (namelen == 0)
+		return (EINVAL);
 
 	unp = sotounpcb(so);
 	KASSERT(unp != NULL, ("uipc_bind: unp == NULL"));
 
-	if (soun->sun_len > sizeof(struct sockaddr_un))
-		return (EINVAL);
-	namelen = soun->sun_len - offsetof(struct sockaddr_un, sun_path);
-	if (namelen <= 0)
-		return (EINVAL);
-
 	/*
 	 * We don't allow simultaneous bind() calls on a single UNIX domain
 	 * socket, so flag in-progress operations, and return an error if an
@@ -612,7 +635,7 @@ uipc_bindat(int fd, struct socket *so, struct sockaddr *nam, struct thread *td)
 	UNP_PCB_UNLOCK(unp);
 
 	buf = malloc(namelen + 1, M_TEMP, M_WAITOK);
-	bcopy(soun->sun_path, buf, namelen);
+	bcopy(path, buf, namelen);
 	buf[namelen] = 0;
 
 restart:
@@ -2889,27 +2912,24 @@ unp_connectat(int fd, struct socket *so, struct sockaddr *nam,
     struct thread *td, bool return_locked)
 {
 	struct mtx *vplock;
-	struct sockaddr_un *soun;
 	struct vnode *vp;
 	struct unpcb *unp, *unp2;
 	struct nameidata nd;
 	char buf[SOCK_MAXADDRLEN];
 	struct sockaddr *sa;
 	cap_rights_t rights;
+	const char *path;
 	int error, len;
 	bool connreq;
 
 	CURVNET_ASSERT_SET();
 
-	if (nam->sa_family != AF_UNIX)
-		return (EAFNOSUPPORT);
-	if (nam->sa_len > sizeof(struct sockaddr_un))
-		return (EINVAL);
-	len = nam->sa_len - offsetof(struct sockaddr_un, sun_path);
-	if (len <= 0)
+	error = unp_sun_path(nam, &path, &len);
+	if (error != 0)
+		return (error);
+	if (len == 0)
 		return (EINVAL);
-	soun = (struct sockaddr_un *)nam;
-	bcopy(soun->sun_path, buf, len);
+	bcopy(path, buf, len);
 	buf[len] = 0;
 
 	error = 0;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.