From owner-freebsd-emulation@FreeBSD.ORG Fri Sep 30 22:03:11 2011 Return-Path: Delivered-To: freebsd-emulation@FreeBSD.org Received: from [127.0.0.1] (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by hub.freebsd.org (Postfix) with ESMTP id 4B474106566B; Fri, 30 Sep 2011 22:03:10 +0000 (UTC) (envelope-from jkim@FreeBSD.org) From: Jung-uk Kim To: freebsd-emulation@FreeBSD.org, security-officer@freebsd.org Date: Fri, 30 Sep 2011 18:02:56 -0400 User-Agent: KMail/1.6.2 References: <4E857719.7060306@freebsd.org> In-Reply-To: <4E857719.7060306@freebsd.org> MIME-Version: 1.0 Content-Disposition: inline Content-Type: Multipart/Mixed; boundary="Boundary-00=_UyjhOe0Sia/n4Wb" Message-Id: <201109301803.01010.jkim@FreeBSD.org> Cc: Subject: Re: HEADS UP: breakage with linux emulation + SA-11:05.unix X-BeenThere: freebsd-emulation@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Development of Emulators of other operating systems List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 30 Sep 2011 22:03:11 -0000 --Boundary-00=_UyjhOe0Sia/n4Wb Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline [Removed freebsd-security@] On Friday 30 September 2011 04:00 am, FreeBSD Security Officer wrote: > Hi all, > > It appears that the security fix in SA-11:05.unix exposed a bug in > the linux emulation code: Linux has a different size of sockaddr_un > than FreeBSD, and the linux emulation code was passing socket > addresses through without doing any translation first. > > This appears to break all X-using Linux code -- both applications > and plugins such as the widely-used flash plugin -- and probably > other Linux applications too. > > I am working on a fix for this and will send an updated advisory > out as soon as it's ready. For the impatient, I have written *unofficial* patch for this Linuxulator regression. Please note that I am posting this patch to this ML only because I wanted to point out Linuxulator is actually missing very important feature, i.e., anonymous Unix domain socket. Jung-uk Kim --Boundary-00=_UyjhOe0Sia/n4Wb Content-Type: text/plain; charset="iso-8859-1"; name="linux_socket.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="linux_socket.diff" 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, pathlen; if (*osalen < 2 || *osalen > UCHAR_MAX || !osa) return (EINVAL); @@ -133,6 +132,15 @@ do_sa_get(struct sockaddr **sap, const struct osoc goto out; } + if (bdom == AF_LOCAL) { + pathlen = sizeof(struct sockaddr_un) - + offsetof(struct sockaddr_un, sun_path); + alloclen = strnlen(kosa->sa_data, pathlen); + if (alloclen >= pathlen) + log(LOG_DEBUG, "long sockaddr_un truncated\n"); + alloclen += sizeof(struct sockaddr_un) - pathlen; + } + #ifdef INET6 /* * Older Linux IPv6 code uses obsolete RFC2133 struct sockaddr_in6, @@ -696,6 +704,7 @@ static int linux_bind(struct thread *td, struct linux_bind_args *args) { struct sockaddr *sa; + size_t pathlen; int error; error = linux_getsockaddr(&sa, PTRIN(args->name), @@ -703,6 +712,17 @@ linux_bind(struct thread *td, struct linux_bind_ar 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); + return (0); + } + } + error = kern_bind(td, args->s, sa); free(sa, M_SONAME); if (error == EADDRNOTAVAIL && args->namelen != sizeof(struct sockaddr_in)) @@ -722,6 +742,7 @@ linux_connect(struct thread *td, struct linux_conn { struct socket *so; struct sockaddr *sa; + size_t pathlen; u_int fflag; int error; @@ -730,6 +751,17 @@ linux_connect(struct thread *td, struct linux_conn 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); + return (ENOENT); + } + } + 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 *); --Boundary-00=_UyjhOe0Sia/n4Wb--