summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2011-07-05 23:06:44 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2011-07-05 23:06:44 +0000
commitf1303edfde79aacbe075553a2fa8999de7266cbb (patch)
tree2c09eb5543a48578d1c7cc0f08af31fc32c6ccbf /sys/kern
parente38ae7fb683c329831aba5bb5c866da618bcc03a (diff)
Enforce that the path to the unix socket fits into struct sockaddr_un
and that it is nul terminated. This means the longest path is now 103 char longs. With and OK guenther@
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/uipc_usrreq.c30
1 files changed, 20 insertions, 10 deletions
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index 52861e3d610..53acf003c10 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_usrreq.c,v 1.52 2011/06/28 10:15:38 thib Exp $ */
+/* $OpenBSD: uipc_usrreq.c,v 1.53 2011/07/05 23:06:43 claudio Exp $ */
/* $NetBSD: uipc_usrreq.c,v 1.18 1996/02/09 19:00:50 christos Exp $ */
/*
@@ -389,16 +389,26 @@ unp_bind(struct unpcb *unp, struct mbuf *nam, struct proc *p)
struct vattr vattr;
int error, namelen;
struct nameidata nd;
- char buf[MLEN];
if (unp->unp_vnode != NULL)
return (EINVAL);
namelen = soun->sun_len - offsetof(struct sockaddr_un, sun_path);
- if (namelen <= 0 || namelen >= MLEN)
+ if (namelen <= 0 || namelen > sizeof(soun->sun_path))
return EINVAL;
- strncpy(buf, soun->sun_path, namelen);
- buf[namelen] = 0; /* null-terminate the string */
- NDINIT(&nd, CREATE, NOFOLLOW | LOCKPARENT, UIO_SYSSPACE, buf, p);
+ if (namelen == sizeof(soun->sun_path) &&
+ soun->sun_path[namelen - 1] != '\0')
+ return EINVAL;
+
+ unp->unp_addr = m_getclr(M_WAITOK, MT_SONAME);
+ unp->unp_addr->m_len = soun->sun_len;
+ memcpy(mtod(unp->unp_addr, caddr_t *), soun,
+ offsetof(struct sockaddr_un, sun_path));
+ strncpy(mtod(unp->unp_addr, caddr_t) +
+ offsetof(struct sockaddr_un, sun_path), soun->sun_path, namelen);
+
+ soun = mtod(unp->unp_addr, struct sockaddr_un *);
+ NDINIT(&nd, CREATE, NOFOLLOW | LOCKPARENT, UIO_SYSSPACE,
+ soun->sun_path, p);
/* SHOULD BE ABLE TO ADOPT EXISTING AND wakeup() ALA FIFO's */
if ((error = namei(&nd)) != 0)
return (error);
@@ -421,7 +431,6 @@ unp_bind(struct unpcb *unp, struct mbuf *nam, struct proc *p)
vp = nd.ni_vp;
vp->v_socket = unp->unp_socket;
unp->unp_vnode = vp;
- unp->unp_addr = m_copy(nam, 0, (int)M_COPYALL);
unp->unp_connid.uid = p->p_ucred->cr_uid;
unp->unp_connid.gid = p->p_ucred->cr_gid;
unp->unp_connid.pid = p->p_p->ps_mainproc->p_pid;
@@ -440,12 +449,13 @@ unp_connect(struct socket *so, struct mbuf *nam, struct proc *p)
int error;
struct nameidata nd;
- NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, soun->sun_path, p);
- if (nam->m_data + nam->m_len == &nam->m_dat[MLEN]) { /* XXX */
- if (*(mtod(nam, caddr_t) + nam->m_len - 1) != 0)
+ if (nam->m_len >= sizeof(struct sockaddr_un)) {
+ if (nam->m_len > sizeof(struct sockaddr_un) ||
+ *(mtod(nam, caddr_t) + nam->m_len - 1) != 0)
return (EMSGSIZE);
} else
*(mtod(nam, caddr_t) + nam->m_len) = 0;
+ NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, soun->sun_path, p);
if ((error = namei(&nd)) != 0)
return (error);
vp = nd.ni_vp;