git: 44e99b672835 - main - unix: factor unp_sun_path() out of bind and connect
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 10 Aug 2026 17:40:32 UTC
The branch main has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=44e99b67283517207d4e482feee63bc15f4f710e
commit 44e99b67283517207d4e482feee63bc15f4f710e
Author: John Ericson <John.Ericson@Obsidian.Systems>
AuthorDate: 2026-08-10 15:04:20 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
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 <John.Ericson@Obsidian.Systems>
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;