From owner-svn-src-all@FreeBSD.ORG Mon Oct 10 19:54:50 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id CE502106564A; Mon, 10 Oct 2011 19:54:50 +0000 (UTC) (envelope-from jkim@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id BCC808FC16; Mon, 10 Oct 2011 19:54:50 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p9AJsoYF079513; Mon, 10 Oct 2011 19:54:50 GMT (envelope-from jkim@svn.freebsd.org) Received: (from jkim@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p9AJsoWw079511; Mon, 10 Oct 2011 19:54:50 GMT (envelope-from jkim@svn.freebsd.org) Message-Id: <201110101954.p9AJsoWw079511@svn.freebsd.org> From: Jung-uk Kim Date: Mon, 10 Oct 2011 19:54:50 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r226231 - stable/9/sys/compat/linux X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Oct 2011 19:54:51 -0000 Author: jkim Date: Mon Oct 10 19:54:50 2011 New Revision: 226231 URL: http://svn.freebsd.org/changeset/base/226231 Log: MFC: r226068, r226069, r226071, r226072, r226073, r226074, r226078, r226079 - Unroll inlined strnlen(9) and make it easier to read. - Inline do_sa_get() function and remove an unused return value. - Retern more appropriate errno when Linux path name is too long. - Restore the original socket address length if it was not really AF_INET6. - Make sure to ignore the leading NULL byte from Linux abstract namespace. - Use uint32_t instead of u_int32_t. Fix style(9) nits. - Remove a now-defunct variable. - Use the caculated length instead of maximum length. Approved by: re (kib) Modified: stable/9/sys/compat/linux/linux_socket.c Directory Properties: stable/9/sys/ (props changed) stable/9/sys/amd64/include/xen/ (props changed) stable/9/sys/boot/ (props changed) stable/9/sys/boot/i386/efi/ (props changed) stable/9/sys/boot/ia64/efi/ (props changed) stable/9/sys/boot/ia64/ski/ (props changed) stable/9/sys/boot/powerpc/boot1.chrp/ (props changed) stable/9/sys/boot/powerpc/ofw/ (props changed) stable/9/sys/cddl/contrib/opensolaris/ (props changed) stable/9/sys/conf/ (props changed) stable/9/sys/contrib/dev/acpica/ (props changed) stable/9/sys/contrib/octeon-sdk/ (props changed) stable/9/sys/contrib/pf/ (props changed) stable/9/sys/contrib/x86emu/ (props changed) Modified: stable/9/sys/compat/linux/linux_socket.c ============================================================================== --- stable/9/sys/compat/linux/linux_socket.c Mon Oct 10 19:41:00 2011 (r226230) +++ stable/9/sys/compat/linux/linux_socket.c Mon Oct 10 19:54:50 2011 (r226231) @@ -72,44 +72,29 @@ __FBSDID("$FreeBSD$"); #include #include -static int do_sa_get(struct sockaddr **, const struct osockaddr *, int *, - struct malloc_type *); static int linux_to_bsd_domain(int); /* * Reads a linux sockaddr and does any necessary translation. * Linux sockaddrs don't have a length field, only a family. - */ -static int -linux_getsockaddr(struct sockaddr **sap, const struct osockaddr *osa, int len) -{ - int osalen = len; - - return (do_sa_get(sap, osa, &osalen, M_SONAME)); -} - -/* * Copy the osockaddr structure pointed to by osa to kernel, adjust * family and convert to sockaddr. */ static int -do_sa_get(struct sockaddr **sap, const struct osockaddr *osa, int *osalen, - struct malloc_type *mtype) +linux_getsockaddr(struct sockaddr **sap, const struct osockaddr *osa, int salen) { - int error=0, bdom; struct sockaddr *sa; struct osockaddr *kosa; - int alloclen; #ifdef INET6 - int oldv6size; struct sockaddr_in6 *sin6; + int oldv6size; #endif - int namelen; + char *name; + int bdom, error, hdrlen, namelen; - if (*osalen < 2 || *osalen > UCHAR_MAX || !osa) + if (salen < 2 || salen > UCHAR_MAX || !osa) return (EINVAL); - alloclen = *osalen; #ifdef INET6 oldv6size = 0; /* @@ -117,15 +102,15 @@ do_sa_get(struct sockaddr **sap, const s * if it's a v4-mapped address, so reserve the proper space * for it. */ - if (alloclen == sizeof (struct sockaddr_in6) - sizeof (u_int32_t)) { - alloclen = sizeof (struct sockaddr_in6); + if (salen == sizeof(struct sockaddr_in6) - sizeof(uint32_t)) { + salen += sizeof(uint32_t); oldv6size = 1; } #endif - kosa = malloc(alloclen, mtype, M_WAITOK); + kosa = malloc(salen, M_SONAME, M_WAITOK); - if ((error = copyin(osa, kosa, *osalen))) + if ((error = copyin(osa, kosa, salen))) goto out; bdom = linux_to_bsd_domain(kosa->sa_family); @@ -142,55 +127,61 @@ do_sa_get(struct sockaddr **sap, const s * * Still accept addresses for which the scope id is not used. */ - if (oldv6size && bdom == AF_INET6) { - sin6 = (struct sockaddr_in6 *)kosa; - if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) || - (!IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) && - !IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) && - !IN6_IS_ADDR_V4COMPAT(&sin6->sin6_addr) && - !IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) && - !IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))) { - sin6->sin6_scope_id = 0; - } else { - log(LOG_DEBUG, - "obsolete pre-RFC2553 sockaddr_in6 rejected\n"); - error = EINVAL; - goto out; - } - } else + if (oldv6size) { + if (bdom == AF_INET6) { + sin6 = (struct sockaddr_in6 *)kosa; + if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) || + (!IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) && + !IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) && + !IN6_IS_ADDR_V4COMPAT(&sin6->sin6_addr) && + !IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) && + !IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))) { + sin6->sin6_scope_id = 0; + } else { + log(LOG_DEBUG, + "obsolete pre-RFC2553 sockaddr_in6 rejected\n"); + error = EINVAL; + goto out; + } + } else + salen -= sizeof(uint32_t); + } #endif if (bdom == AF_INET) { - alloclen = sizeof(struct sockaddr_in); - if (*osalen < alloclen) { + if (salen < sizeof(struct sockaddr_in)) { error = EINVAL; goto out; } + salen = sizeof(struct sockaddr_in); } - if ((bdom == AF_LOCAL) && (*osalen > sizeof(struct sockaddr_un))) { - for (namelen = 0; - namelen < *osalen - offsetof(struct sockaddr_un, sun_path); - namelen++) - if (!((struct sockaddr_un *)kosa)->sun_path[namelen]) - break; - if (namelen + offsetof(struct sockaddr_un, sun_path) > - sizeof(struct sockaddr_un)) { - error = EINVAL; + if (bdom == AF_LOCAL && salen > sizeof(struct sockaddr_un)) { + hdrlen = offsetof(struct sockaddr_un, sun_path); + name = ((struct sockaddr_un *)kosa)->sun_path; + if (*name == '\0') { + /* + * Linux abstract namespace starts with a NULL byte. + * XXX We do not support abstract namespace yet. + */ + namelen = strnlen(name + 1, salen - hdrlen - 1) + 1; + } else + namelen = strnlen(name, salen - hdrlen); + salen = hdrlen + namelen; + if (salen > sizeof(struct sockaddr_un)) { + error = ENAMETOOLONG; goto out; } - alloclen = sizeof(struct sockaddr_un); } - sa = (struct sockaddr *) kosa; + sa = (struct sockaddr *)kosa; sa->sa_family = bdom; - sa->sa_len = alloclen; + sa->sa_len = salen; *sap = sa; - *osalen = alloclen; return (0); out: - free(kosa, mtype); + free(kosa, M_SONAME); return (error); } @@ -1239,9 +1230,9 @@ linux_sendmsg(struct thread *td, struct cmsg->cmsg_len = CMSG_LEN(datalen); error = ENOBUFS; - if (!m_append(control, CMSG_HDRSZ, (c_caddr_t) cmsg)) + if (!m_append(control, CMSG_HDRSZ, (c_caddr_t)cmsg)) goto bad; - if (!m_append(control, datalen, (c_caddr_t) data)) + if (!m_append(control, datalen, (c_caddr_t)data)) goto bad; } while ((ptr_cmsg = LINUX_CMSG_NXTHDR(&linux_msg, ptr_cmsg))); @@ -1380,7 +1371,7 @@ linux_recvmsg(struct thread *td, struct * effect for Linux so no need to worry * about sockcred */ - if (datalen != sizeof (*cmcred)) { + if (datalen != sizeof(*cmcred)) { error = EMSGSIZE; goto bad; }