Index: sys/compat/linux/linux_socket.c =================================================================== --- sys/compat/linux/linux_socket.c (revision 225884) +++ sys/compat/linux/linux_socket.c (working copy) @@ -96,14 +96,13 @@ static int do_sa_get(struct sockaddr **sap, const struct osockaddr *osa, int *osalen, struct malloc_type *mtype) { - int error=0, bdom; struct sockaddr *sa; struct osockaddr *kosa; - int alloclen; #ifdef INET6 + struct sockaddr_in6 *sin6; int oldv6size; - struct sockaddr_in6 *sin6; #endif + int alloclen, bdom, error, hdrlen, pathlen; if (*osalen < 2 || *osalen > UCHAR_MAX || !osa) return (EINVAL); @@ -133,6 +132,17 @@ do_sa_get(struct sockaddr **sap, const struct osoc goto out; } + if (bdom == AF_LOCAL) { + hdrlen = offsetof(struct sockaddr_un, sun_path); + if (alloclen > hdrlen) { + pathlen = sizeof(struct sockaddr_un) - hdrlen; + alloclen = strnlen(kosa->sa_data, pathlen); + if (alloclen == pathlen) + log(LOG_DEBUG, "long sockaddr_un truncated\n"); + alloclen += hdrlen; + } + } + #ifdef INET6 /* * Older Linux IPv6 code uses obsolete RFC2133 struct sockaddr_in6, @@ -696,13 +706,26 @@ static int linux_bind(struct thread *td, struct linux_bind_args *args) { struct sockaddr *sa; - int error; + int error, pathlen; error = linux_getsockaddr(&sa, PTRIN(args->name), args->namelen); if (error) return (error); + /* + * XXX Anonymous Unix domain socket not supported. + */ + if (sa->sa_family == AF_LOCAL) { + pathlen = sa->sa_len - offsetof(struct sockaddr_un, sun_path); + if (pathlen <= 0) { + free(sa, M_SONAME); + if (pathlen == 0) + return (0); + return (EINVAL); + } + } + error = kern_bind(td, args->s, sa); free(sa, M_SONAME); if (error == EADDRNOTAVAIL && args->namelen != sizeof(struct sockaddr_in)) @@ -723,13 +746,26 @@ linux_connect(struct thread *td, struct linux_conn struct socket *so; struct sockaddr *sa; u_int fflag; - int error; + int error, pathlen; error = linux_getsockaddr(&sa, (struct osockaddr *)PTRIN(args->name), args->namelen); if (error) return (error); + /* + * XXX Anonymous Unix domain socket not supported. + */ + if (sa->sa_family == AF_LOCAL) { + pathlen = sa->sa_len - offsetof(struct sockaddr_un, sun_path); + if (pathlen <= 0) { + free(sa, M_SONAME); + if (pathlen == 0) + return (ENOENT); + return (EINVAL); + } + } + error = kern_connect(td, args->s, sa); free(sa, M_SONAME); if (error != EISCONN) Index: sys/conf/files =================================================================== --- sys/conf/files (revision 225884) +++ sys/conf/files (working copy) @@ -2548,6 +2548,7 @@ libkern/strlcpy.c standard libkern/strlen.c standard libkern/strncmp.c standard libkern/strncpy.c standard +libkern/strnlen.c standard libkern/strsep.c standard libkern/strspn.c standard libkern/strstr.c standard Index: sys/libkern/strnlen.c =================================================================== --- sys/libkern/strnlen.c (revision 225884) +++ sys/libkern/strnlen.c (working copy) @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2009 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include + +size_t +strnlen(const char *s, size_t maxlen) +{ + size_t len; + + for (len = 0; len < maxlen; len++, s++) { + if (!*s) + break; + } + return (len); +} Index: sys/sys/libkern.h =================================================================== --- sys/sys/libkern.h (revision 225884) +++ sys/sys/libkern.h (working copy) @@ -116,6 +116,7 @@ size_t strlen(const char *); int strncasecmp(const char *, const char *, size_t); int strncmp(const char *, const char *, size_t); char *strncpy(char * __restrict, const char * __restrict, size_t); +size_t strnlen(const char *, size_t); char *strsep(char **, const char *delim); size_t strspn(const char *, const char *); char *strstr(const char *, const char *);