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;

Reply via email to