svn commit: r226231 - stable/9/sys/compat/linux

Jung-uk Kim jkim at FreeBSD.org
Mon Oct 10 19:54:51 UTC 2011


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 <compat/linux/linux_socket.h>
 #include <compat/linux/linux_util.h>
 
-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;
 				}


More information about the svn-src-stable-9 mailing list