diff options
| author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2016-05-04 19:47:21 +0000 |
|---|---|---|
| committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2016-05-04 19:47:21 +0000 |
| commit | 642f2603a073324180f95c0876410fb840b84236 (patch) | |
| tree | 570092278a3ea4c3acb3d058cdc8f94f2e9fa3a0 /usr/src/lib | |
| parent | 5a8ae43fd4929960d6d09a974597aca8f7542425 (diff) | |
| download | illumos-joyent-642f2603a073324180f95c0876410fb840b84236.tar.gz | |
OS-5357 datadog doesn't work correctly in LX zone
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
Diffstat (limited to 'usr/src/lib')
| -rw-r--r-- | usr/src/lib/brand/lx/lx_brand/common/lx_brand.c | 8 | ||||
| -rw-r--r-- | usr/src/lib/brand/lx/lx_brand/common/socket.c | 358 | ||||
| -rw-r--r-- | usr/src/lib/brand/lx/lx_brand/sys/lx_syscall.h | 4 |
3 files changed, 9 insertions, 361 deletions
diff --git a/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c b/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c index 7024a5d567..3f64d3e806 100644 --- a/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c +++ b/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c @@ -1006,7 +1006,7 @@ static lx_syscall_handler_t lx_handlers[] = { lx_sendfile64, /* 40: sendfile */ NULL, /* 41: socket */ NULL, /* 42: connect */ - lx_accept, /* 43: accept */ + NULL, /* 43: accept */ NULL, /* 44: sendto */ NULL, /* 45: recvfrom */ NULL, /* 46: sendmsg */ @@ -1014,8 +1014,8 @@ static lx_syscall_handler_t lx_handlers[] = { lx_shutdown, /* 48: shutdown */ NULL, /* 49: bind */ lx_listen, /* 50: listen */ - lx_getsockname, /* 51: getsockname */ - lx_getpeername, /* 52: getpeername */ + NULL, /* 51: getsockname */ + NULL, /* 52: getpeername */ lx_socketpair, /* 53: socketpair */ NULL, /* 54: setsockopt */ NULL, /* 55: getsockopt */ @@ -1251,7 +1251,7 @@ static lx_syscall_handler_t lx_handlers[] = { NULL, /* 285: fallocate */ lx_timerfd_settime, /* 286: timerfd_settime */ lx_timerfd_gettime, /* 287: timerfd_gettime */ - lx_accept4, /* 288: accept4 */ + NULL, /* 288: accept4 */ lx_signalfd4, /* 289: signalfd4 */ lx_eventfd2, /* 290: eventfd2 */ NULL, /* 291: epoll_create1 */ diff --git a/usr/src/lib/brand/lx/lx_brand/common/socket.c b/usr/src/lib/brand/lx/lx_brand/common/socket.c index 20e30b9a52..e8659cf9ba 100644 --- a/usr/src/lib/brand/lx/lx_brand/common/socket.c +++ b/usr/src/lib/brand/lx/lx_brand/common/socket.c @@ -22,7 +22,7 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. - * Copyright 2015 Joyent, Inc. All rights reserved. + * Copyright 2016 Joyent, Inc. */ #include <unistd.h> @@ -56,29 +56,11 @@ #include <sys/lx_misc.h> #include <netpacket/packet.h> -/* - * This string is used to prefix all abstract namespace Unix sockets, ie all - * abstract namespace sockets are converted to regular sockets in the /tmp - * directory with .ABSK_ prefixed to their names. - */ -#define ABST_PRFX "/tmp/.ABSK_" -#define ABST_PRFX_LEN 11 - -typedef enum { - lxa_none, - lxa_abstract, - lxa_devlog -} lx_addr_type_t; - #ifdef __i386 static int lx_listen32(ulong_t *); -static int lx_accept32(ulong_t *); -static int lx_getsockname32(ulong_t *); -static int lx_getpeername32(ulong_t *); static int lx_socketpair32(ulong_t *); static int lx_shutdown32(ulong_t *); -static int lx_accept4_32(ulong_t *); static int lx_recvmmsg32(ulong_t *); static int lx_sendmmsg32(ulong_t *); @@ -92,9 +74,9 @@ static struct { NULL, 3, NULL, 3, lx_listen32, 2, - lx_accept32, 3, - lx_getsockname32, 3, - lx_getpeername32, 3, + NULL, 3, + NULL, 3, + NULL, 3, lx_socketpair32, 4, NULL, 4, NULL, 4, @@ -105,7 +87,7 @@ static struct { NULL, 5, NULL, 3, NULL, 3, - lx_accept4_32, 4, + NULL, 4, lx_recvmmsg32, 5, lx_sendmmsg32, 4 }; @@ -199,62 +181,6 @@ convert_pkt_proto(int protocol) } static int -stol_sockaddr(struct sockaddr *addr, socklen_t *len, - struct sockaddr *inaddr, socklen_t inlen, socklen_t orig) -{ - int size = inlen; - - switch (inaddr->sa_family) { - case AF_INET: - if (inlen > sizeof (struct sockaddr)) - return (EINVAL); - break; - - case AF_INET6: - if (inlen != sizeof (struct sockaddr_in6)) - return (EINVAL); - /* - * The linux sockaddr_in6 is shorter than illumos. - * We just truncate the extra field on the way out - */ - size = (sizeof (lx_sockaddr_in6_t)); - inlen = (sizeof (lx_sockaddr_in6_t)); - break; - - case AF_UNIX: - if (inlen > sizeof (struct sockaddr_un)) - return (EINVAL); - break; - - case (sa_family_t)AF_NOTSUPPORTED: - return (EPROTONOSUPPORT); - - case (sa_family_t)AF_INVAL: - return (EAFNOSUPPORT); - - default: - break; - } - - inaddr->sa_family = STOL_FAMILY(inaddr->sa_family); - - /* - * If inlen is larger than orig, copy out the maximum amount of - * data possible and then update *len to indicate the actual - * size of all the data that it wanted to copy out. - */ - size = (orig > 0 && orig < size) ? orig : size; - - if (uucopy(inaddr, addr, size) < 0) - return (errno); - - if (uucopy(&inlen, len, sizeof (socklen_t)) < 0) - return (errno); - - return (0); -} - -static int convert_sock_args(int in_dom, int in_type, int in_protocol, int *out_dom, int *out_type, int *out_options, int *out_protocol) { @@ -315,193 +241,6 @@ lx_listen(int sockfd, int backlog) } long -lx_accept(int sockfd, void *name, int *nlp) -{ - socklen_t namelen = 0, origlen; - struct sockaddr *saddr; - int r, err; - int size; - - lx_debug("\taccept(%d, 0x%p, 0x%p", sockfd, (struct sockaddr *)name, - nlp); - - /* - * The Linux man page says that -1 is returned and errno is set to - * EFAULT if the "name" address is bad, but it is silent on what to - * set errno to if the "namelen" address is bad. Experimentation - * shows that Linux (at least the 2.4.21 kernel in CentOS) actually - * sets errno to EINVAL in both cases. - * - * Note that we must first check the name pointer, as the Linux - * docs state nothing is copied out if the "name" pointer is NULL. - * If it is NULL, we don't care about the namelen pointer's value - * or about dereferencing it. - * - * Happily, illumos' accept(3SOCKET) treats NULL name pointers and - * zero namelens the same way. - */ - if ((name != NULL) && - (uucopy((void *)nlp, &namelen, sizeof (socklen_t)) != 0)) - return ((errno == EFAULT) ? -EINVAL : -errno); - origlen = namelen; - - if (name != NULL) { - /* - * Use sizeof (struct sockaddr_in6) as the minimum temporary - * name allocation. This will allow families such as AF_INET6 - * to work properly when their namelen differs between LX and - * illumos. - */ - size = sizeof (struct sockaddr_in6); - if (namelen > size) - size = namelen; - - saddr = SAFE_ALLOCA(size); - if (saddr == NULL) - return (-EINVAL); - bzero(saddr, size); - } else { - saddr = NULL; - } - - lx_debug("\taccept namelen = %d", namelen); - - if ((r = accept(sockfd, saddr, &namelen)) < 0) - return ((errno == EFAULT) ? -EINVAL : -errno); - - lx_debug("\taccept namelen returned %d bytes", namelen); - - /* - * In Linux, accept()ed sockets do not inherit anything set by - * fcntl(), so filter those out. - */ - if (fcntl(r, F_SETFL, 0) < 0) - return (-errno); - - /* - * Once again, a bad "namelen" address sets errno to EINVAL, not - * EFAULT. If namelen was zero, there's no need to copy a zero back - * out. - * - * Logic might dictate that we should check if we can write to - * the namelen pointer earlier so we don't accept a pending connection - * only to fail the call because we can't write the namelen value back - * out. However, testing shows Linux does indeed fail the call after - * accepting the connection so we must behave in a compatible manner. - */ - if ((name != NULL) && (namelen != 0)) { - err = stol_sockaddr((struct sockaddr *)name, (socklen_t *)nlp, - saddr, namelen, origlen); - if (err != 0) { - close(r); - return ((err == EFAULT) ? -EINVAL : -err); - } - } - - return (r); -} - -long -lx_getsockname(int sockfd, void *np, int *nlp) -{ - struct sockaddr *name = NULL; - socklen_t namelen, namelen_orig; - struct stat sb; - int err; - - if (uucopy((void *)nlp, &namelen, sizeof (socklen_t)) != 0) - return (-errno); - namelen_orig = namelen; - - lx_debug("\tgetsockname(%d, 0x%p, 0x%p (=%d))", sockfd, - (struct sockaddr *)np, nlp, namelen); - - if (fstat(sockfd, &sb) == 0 && !S_ISSOCK(sb.st_mode)) - return (-ENOTSOCK); - - /* - * Use sizeof (struct sockaddr_in6) as the minimum temporary - * name allocation. This will allow families such as AF_INET6 - * to work properly when their namelen differs between LX and - * illumos. - */ - if (namelen <= 0) - return (-EBADF); - else if (namelen < sizeof (struct sockaddr_in6)) - namelen = sizeof (struct sockaddr_in6); - - if ((name = SAFE_ALLOCA(namelen)) == NULL) - return (-ENOMEM); - bzero(name, namelen); - - if (getsockname(sockfd, name, &namelen) < 0) - return (-errno); - - /* - * If the name that getsockname() wants to return is larger - * than namelen, getsockname() will copy out the maximum amount - * of data possible and then update namelen to indicate the - * actually size of all the data that it wanted to copy out. - */ - err = stol_sockaddr((struct sockaddr *)np, (socklen_t *)nlp, name, - namelen, namelen_orig); - return ((err != 0) ? -err : 0); -} - -long -lx_getpeername(int sockfd, void *np, int *nlp) -{ - struct sockaddr *name; - socklen_t namelen, namelen_orig; - int err; - - if (uucopy((void *)nlp, &namelen, sizeof (socklen_t)) != 0) - return (-errno); - namelen_orig = namelen; - - lx_debug("\tgetpeername(%d, 0x%p, 0x%p (=%d))", sockfd, - (struct sockaddr *)np, nlp, namelen); - - /* LTP can pass -1 but we'll limit the allocation to a page */ - if ((uint32_t)namelen > 4096) - return (-EINVAL); - - /* - * Linux returns EFAULT in this case, even if the namelen parameter - * is 0 (some test cases use -1, so we check for that too). This check - * will not catch other illegal addresses, but the benefit catching a - * non-null illegal address here is not worth the cost of another - * system call. - */ - if (np == NULL || np == (void *)-1) - return (-EFAULT); - - /* - * Use sizeof (struct sockaddr_in6) as the minimum temporary - * name allocation. This will allow families such as AF_INET6 - * to work properly when their namelen differs between LX and - * illumos. - */ - if (namelen < sizeof (struct sockaddr_in6)) - namelen = sizeof (struct sockaddr_in6); - - name = SAFE_ALLOCA(namelen); - if (name == NULL) - return (-EINVAL); - bzero(name, namelen); - - if ((getpeername(sockfd, name, &namelen)) < 0) - return (-errno); - - err = stol_sockaddr((struct sockaddr *)np, (socklen_t *)nlp, - name, namelen, namelen_orig); - if (err != 0) - return (-err); - - return (0); -} - -long lx_socketpair(int domain, int type, int protocol, int *sv) { int options; @@ -544,65 +283,6 @@ lx_shutdown(int sockfd, int how) return ((r < 0) ? -errno : r); } -/* - * Based on the lx_accept code with the addition of the flags handling. - * See internal comments in that function for more explanation. - */ -long -lx_accept4(int sockfd, void *np, int *nlp, int lx_flags) -{ - socklen_t namelen, namelen_orig; - struct sockaddr *name = NULL; - int flags = 0; - int r, err; - - lx_debug("\taccept4(%d, 0x%p, 0x%p 0x%x", sockfd, np, nlp, lx_flags); - - if ((np != NULL) && - (uucopy((void *)nlp, &namelen, sizeof (socklen_t)) != 0)) - return ((errno == EFAULT) ? -EINVAL : -errno); - - namelen_orig = namelen; - lx_debug("\taccept4 namelen = %d", namelen); - - if (np != NULL) { - /* - * Use sizeof (struct sockaddr_in6) as the minimum temporary - * name allocation. This will allow families such as AF_INET6 - * to work properly when their namelen differs between LX and - * illumos. - */ - if (namelen < sizeof (struct sockaddr_in6)) - namelen = sizeof (struct sockaddr_in6); - - name = SAFE_ALLOCA(namelen); - if (name == NULL) - return (-EINVAL); - bzero(name, namelen); - } - - if (lx_flags & LX_SOCK_NONBLOCK) - flags |= SOCK_NONBLOCK; - - if (lx_flags & LX_SOCK_CLOEXEC) - flags |= SOCK_CLOEXEC; - - if ((r = accept4(sockfd, name, &namelen, flags)) < 0) - return ((errno == EFAULT) ? -EINVAL : -errno); - - lx_debug("\taccept4 namelen returned %d bytes", namelen); - - if (np != NULL && namelen != 0) { - err = stol_sockaddr((struct sockaddr *)np, (socklen_t *)nlp, - name, namelen, namelen_orig); - if (err != 0) { - close(r); - return ((err == EFAULT) ? -EINVAL : -err); - } - } - return (r); -} - #ifdef __i386 static int @@ -612,27 +292,6 @@ lx_listen32(ulong_t *args) } static int -lx_accept32(ulong_t *args) -{ - return (lx_accept((int)args[0], (struct sockaddr *)args[1], - (int *)args[2])); -} - -static int -lx_getsockname32(ulong_t *args) -{ - return (lx_getsockname((int)args[0], (struct sockaddr *)args[1], - (int *)args[2])); -} - -static int -lx_getpeername32(ulong_t *args) -{ - return (lx_getpeername((int)args[0], (struct sockaddr *)args[1], - (int *)args[2])); -} - -static int lx_socketpair32(ulong_t *args) { return (lx_socketpair((int)args[0], (int)args[1], (int)args[2], @@ -646,13 +305,6 @@ lx_shutdown32(ulong_t *args) } static int -lx_accept4_32(ulong_t *args) -{ - return (lx_accept4((int)args[0], (struct sockaddr *)args[1], - (int *)args[2], (int)args[3])); -} - -static int lx_recvmmsg32(ulong_t *args) { lx_unsupported("Unsupported socketcall: recvmmsg\n."); diff --git a/usr/src/lib/brand/lx/lx_brand/sys/lx_syscall.h b/usr/src/lib/brand/lx/lx_brand/sys/lx_syscall.h index 4b2e23def8..20d027beaf 100644 --- a/usr/src/lib/brand/lx/lx_brand/sys/lx_syscall.h +++ b/usr/src/lib/brand/lx/lx_brand/sys/lx_syscall.h @@ -75,10 +75,6 @@ extern long lx_fadvise64(uintptr_t, off64_t, uintptr_t, uintptr_t); extern long lx_fadvise64_64(uintptr_t, off64_t, off64_t, uintptr_t); extern long lx_socketcall(uintptr_t, uintptr_t); -extern long lx_accept(int, void *, int *); -extern long lx_accept4(int, void *, int *, int); -extern long lx_getpeername(int, void *, int *); -extern long lx_getsockname(int, void *, int *); extern long lx_listen(int, int); extern long lx_shutdown(int, int); extern long lx_socketpair(int, int, int, int *); |
