Module Name: src
Committed By: christos
Date: Tue Oct 8 17:21:24 UTC 2013
Modified Files:
src/sys/kern: uipc_usrreq.c
Log Message:
Centralize the sockaddr_un allocation code. Set sun_len appropriately so
that the address length returned is correct, not always 106. Note that
we do things slightly differently than linux and explain why. Unit-tests
to come.
To generate a diff of this commit:
cvs rdiff -u -r1.145 -r1.146 src/sys/kern/uipc_usrreq.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/kern/uipc_usrreq.c
diff -u src/sys/kern/uipc_usrreq.c:1.145 src/sys/kern/uipc_usrreq.c:1.146
--- src/sys/kern/uipc_usrreq.c:1.145 Tue Oct 8 11:09:51 2013
+++ src/sys/kern/uipc_usrreq.c Tue Oct 8 13:21:24 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: uipc_usrreq.c,v 1.145 2013/10/08 15:09:51 christos Exp $ */
+/* $NetBSD: uipc_usrreq.c,v 1.146 2013/10/08 17:21:24 christos Exp $ */
/*-
* Copyright (c) 1998, 2000, 2004, 2008, 2009 The NetBSD Foundation, Inc.
@@ -96,7 +96,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_usrreq.c,v 1.145 2013/10/08 15:09:51 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_usrreq.c,v 1.146 2013/10/08 17:21:24 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -882,6 +882,29 @@ unp_detach(struct unpcb *unp)
unp_free(unp);
}
+/*
+ * Allocate the new sockaddr. We have to allocate one
+ * extra byte so that we can ensure that the pathname
+ * is nul-terminated. Note that unlike linux, we don't
+ * include in the address length the NUL in the path
+ * component, because doing so, would exceed sizeof(sockaddr_un)
+ * for fully occupied pathnames. Linux is also inconsistent,
+ * because it does not include the NUL in the length of
+ * what it calls "abstract" unix sockets.
+ */
+static struct sockaddr_un *
+makeun(struct mbuf *nam, size_t *addrlen) {
+ struct sockaddr_un *sun;
+
+ *addrlen = nam->m_len + 1;
+ sun = malloc(*addrlen, M_SONAME, M_WAITOK);
+ m_copydata(nam, 0, nam->m_len, (void *)sun);
+ *(((char *)sun) + nam->m_len) = '\0';
+ sun->sun_len = strlen(sun->sun_path) +
+ offsetof(struct sockaddr_un, sun_path);
+ return sun;
+}
+
int
unp_bind(struct socket *so, struct mbuf *nam, struct lwp *l)
{
@@ -908,16 +931,8 @@ unp_bind(struct socket *so, struct mbuf
unp->unp_flags |= UNP_BUSY;
sounlock(so);
- /*
- * Allocate the new sockaddr. We have to allocate one
- * extra byte so that we can ensure that the pathname
- * is nul-terminated.
- */
p = l->l_proc;
- addrlen = nam->m_len + 1;
- sun = malloc(addrlen, M_SONAME, M_WAITOK);
- m_copydata(nam, 0, nam->m_len, (void *)sun);
- *(((char *)sun) + nam->m_len) = '\0';
+ sun = makeun(nam, &addrlen);
pb = pathbuf_create(sun->sun_path);
if (pb == NULL) {
@@ -996,17 +1011,7 @@ unp_connect(struct socket *so, struct mb
unp->unp_flags |= UNP_BUSY;
sounlock(so);
- /*
- * Allocate a temporary sockaddr. We have to allocate one extra
- * byte so that we can ensure that the pathname is nul-terminated.
- * When we establish the connection, we copy the other PCB's
- * sockaddr to our own.
- */
- addrlen = nam->m_len + 1;
- sun = malloc(addrlen, M_SONAME, M_WAITOK);
- m_copydata(nam, 0, nam->m_len, (void *)sun);
- *(((char *)sun) + nam->m_len) = '\0';
-
+ sun = makeun(nam, &addrlen);
pb = pathbuf_create(sun->sun_path);
if (pb == NULL) {
error = ENOMEM;