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