summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/kern/uipc_usrreq.c42
1 files changed, 25 insertions, 17 deletions
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index 8e6fe6447b7..728ff34305b 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_usrreq.c,v 1.65 2012/04/23 15:36:07 matthew Exp $ */
+/* $OpenBSD: uipc_usrreq.c,v 1.66 2012/04/26 17:18:17 matthew Exp $ */
/* $NetBSD: uipc_usrreq.c,v 1.18 1996/02/09 19:00:50 christos Exp $ */
/*
@@ -401,30 +401,35 @@ unp_bind(struct unpcb *unp, struct mbuf *nam, struct proc *p)
struct mbuf *nam2;
struct vnode *vp;
struct vattr vattr;
- int error, namelen;
+ int error;
struct nameidata nd;
+ size_t pathlen;
if (unp->unp_vnode != NULL)
return (EINVAL);
- namelen = soun->sun_len - offsetof(struct sockaddr_un, sun_path);
- if (namelen <= 0 || namelen > sizeof(soun->sun_path))
- return EINVAL;
- if (namelen == sizeof(soun->sun_path) &&
- memchr(soun->sun_path, '\0', namelen) == NULL)
- return EINVAL;
- /*
- * if namelen < sizeof(sun_path) then the strncpy below
- * will NUL terminate it
- */
- nam2 = m_getclr(M_WAITOK, MT_SONAME);
- nam2->m_len = soun->sun_len;
- memcpy(mtod(nam2, caddr_t), soun,
+ if (soun->sun_len > sizeof(struct sockaddr_un) ||
+ soun->sun_len < offsetof(struct sockaddr_un, sun_path))
+ return (EINVAL);
+ if (soun->sun_family != AF_UNIX)
+ return (EAFNOSUPPORT);
+
+ pathlen = strnlen(soun->sun_path, soun->sun_len -
offsetof(struct sockaddr_un, sun_path));
- strncpy(mtod(nam2, caddr_t) +
- offsetof(struct sockaddr_un, sun_path), soun->sun_path, namelen);
+ if (pathlen == sizeof(soun->sun_path))
+ return (EINVAL);
+
+ nam2 = m_getclr(M_WAITOK, MT_SONAME);
+ nam2->m_len = sizeof(struct sockaddr_un);
+ memcpy(mtod(nam2, struct sockaddr_un *), soun,
+ offsetof(struct sockaddr_un, sun_path) + pathlen);
+ /* No need to NUL terminate: m_getclr() returns bzero'd mbufs. */
soun = mtod(nam2, struct sockaddr_un *);
+
+ /* Fixup sun_len to keep it in sync with m_len. */
+ soun->sun_len = nam2->m_len;
+
NDINIT(&nd, CREATE, NOFOLLOW | LOCKPARENT, UIO_SYSSPACE,
soun->sun_path, p);
/* SHOULD BE ABLE TO ADOPT EXISTING AND wakeup() ALA FIFO's */
@@ -473,6 +478,9 @@ unp_connect(struct socket *so, struct mbuf *nam, struct proc *p)
int error;
struct nameidata nd;
+ if (soun->sun_family != AF_UNIX)
+ return (EAFNOSUPPORT);
+
if (nam->m_len < sizeof(struct sockaddr_un))
*(mtod(nam, caddr_t) + nam->m_len) = 0;
else if (nam->m_len > sizeof(struct sockaddr_un))