X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Fcommon%2Funix.c;h=9918db2e683e18f9e880e1025779057bb1289456;hb=3afa94aeca5a0daae40fd7b6cc96b7e4c150c7d8;hp=50200242529992ce4b8244d4c4d897a28d35583d;hpb=fe489250ce102edf511e99669025934ec9587c63;p=lttng-tools.git diff --git a/src/common/unix.c b/src/common/unix.c index 502002425..9918db2e6 100644 --- a/src/common/unix.c +++ b/src/common/unix.c @@ -7,7 +7,6 @@ */ #define _LGPL_SOURCE -#include #include #include #include @@ -15,9 +14,9 @@ #include #include #include -#include #include +#include #include #include @@ -26,7 +25,6 @@ /* * Connect to unix socket using the path name. */ -LTTNG_HIDDEN int lttcomm_connect_unix_sock(const char *pathname) { struct sockaddr_un s_un; @@ -76,7 +74,6 @@ error: * Do an accept(2) on the sock and return the new file descriptor. The socket * MUST be bind(2) before. */ -LTTNG_HIDDEN int lttcomm_accept_unix_sock(int sock) { int new_fd; @@ -92,7 +89,6 @@ int lttcomm_accept_unix_sock(int sock) return new_fd; } -LTTNG_HIDDEN int lttcomm_create_anon_unix_socketpair(int *fds) { if (socketpair(PF_UNIX, SOCK_STREAM, 0, fds) < 0) { @@ -106,7 +102,6 @@ int lttcomm_create_anon_unix_socketpair(int *fds) * Creates a AF_UNIX local socket using pathname bind the socket upon creation * and return the fd. */ -LTTNG_HIDDEN int lttcomm_create_unix_sock(const char *pathname) { struct sockaddr_un s_un; @@ -154,7 +149,6 @@ error: /* * Make the socket listen using LTTNG_SESSIOND_COMM_MAX_LISTEN. */ -LTTNG_HIDDEN int lttcomm_listen_unix_sock(int sock) { int ret; @@ -173,7 +167,6 @@ int lttcomm_listen_unix_sock(int sock) * * Return the size of received data. */ -LTTNG_HIDDEN ssize_t lttcomm_recv_unix_sock(int sock, void *buf, size_t len) { struct msghdr msg; @@ -181,6 +174,10 @@ ssize_t lttcomm_recv_unix_sock(int sock, void *buf, size_t len) ssize_t ret = -1; size_t len_last; + LTTNG_ASSERT(sock); + LTTNG_ASSERT(buf); + LTTNG_ASSERT(len > 0); + memset(&msg, 0, sizeof(msg)); iov[0].iov_base = buf; @@ -194,7 +191,7 @@ ssize_t lttcomm_recv_unix_sock(int sock, void *buf, size_t len) if (ret > 0) { iov[0].iov_base += ret; iov[0].iov_len -= ret; - assert(ret <= len_last); + LTTNG_ASSERT(ret <= len_last); } } while ((ret > 0 && ret < len_last) || (ret < 0 && errno == EINTR)); if (ret < 0) { @@ -216,13 +213,16 @@ ssize_t lttcomm_recv_unix_sock(int sock, void *buf, size_t len) * * Return the size of received data. */ -LTTNG_HIDDEN ssize_t lttcomm_recv_unix_sock_non_block(int sock, void *buf, size_t len) { struct msghdr msg; struct iovec iov[1]; ssize_t ret; + LTTNG_ASSERT(sock); + LTTNG_ASSERT(buf); + LTTNG_ASSERT(len > 0); + memset(&msg, 0, sizeof(msg)); iov[0].iov_base = buf; @@ -264,13 +264,16 @@ end: * * Return the size of sent data. */ -LTTNG_HIDDEN ssize_t lttcomm_send_unix_sock(int sock, const void *buf, size_t len) { struct msghdr msg; struct iovec iov[1]; ssize_t ret; + LTTNG_ASSERT(sock); + LTTNG_ASSERT(buf); + LTTNG_ASSERT(len > 0); + memset(&msg, 0, sizeof(msg)); iov[0].iov_base = (void *) buf; @@ -314,13 +317,16 @@ end: * * Return the size of sent data. */ -LTTNG_HIDDEN ssize_t lttcomm_send_unix_sock_non_block(int sock, const void *buf, size_t len) { struct msghdr msg; struct iovec iov[1]; ssize_t ret; + LTTNG_ASSERT(sock); + LTTNG_ASSERT(buf); + LTTNG_ASSERT(len > 0); + memset(&msg, 0, sizeof(msg)); iov[0].iov_base = (void *) buf; @@ -360,7 +366,6 @@ end: /* * Shutdown cleanly a unix socket. */ -LTTNG_HIDDEN int lttcomm_close_unix_sock(int sock) { int ret, closeret; @@ -384,7 +389,6 @@ int lttcomm_close_unix_sock(int sock) * * Returns the size of data sent, or negative error value. */ -LTTNG_HIDDEN ssize_t lttcomm_send_fds_unix_sock(int sock, const int *fds, size_t nb_fd) { struct msghdr msg; @@ -395,6 +399,10 @@ ssize_t lttcomm_send_fds_unix_sock(int sock, const int *fds, size_t nb_fd) char tmp[CMSG_SPACE(sizeof_fds)]; char dummy = 0; + LTTNG_ASSERT(sock); + LTTNG_ASSERT(fds); + LTTNG_ASSERT(nb_fd > 0); + memset(&msg, 0, sizeof(msg)); memset(tmp, 0, sizeof(tmp)); @@ -453,6 +461,11 @@ ssize_t _lttcomm_send_payload_view_fds_unix_sock(int sock, lttng_dynamic_array_init(&raw_fds, sizeof(int), NULL); + if (fd_count < 0) { + ret = -LTTNG_ERR_INVALID; + goto end; + } + /* * Prepare a contiguous array of file descriptors to send them. * @@ -489,14 +502,12 @@ end: return ret; } -LTTNG_HIDDEN ssize_t lttcomm_send_payload_view_fds_unix_sock(int sock, struct lttng_payload_view *view) { return _lttcomm_send_payload_view_fds_unix_sock(sock, view, true); } -LTTNG_HIDDEN ssize_t lttcomm_send_payload_view_fds_unix_sock_non_block(int sock, struct lttng_payload_view *view) { @@ -509,7 +520,6 @@ ssize_t lttcomm_send_payload_view_fds_unix_sock_non_block(int sock, * * Returns the size of data sent, or negative error value. */ -LTTNG_HIDDEN ssize_t lttcomm_send_fds_unix_sock_non_block(int sock, const int *fds, size_t nb_fd) { struct msghdr msg; @@ -520,6 +530,10 @@ ssize_t lttcomm_send_fds_unix_sock_non_block(int sock, const int *fds, size_t nb char tmp[CMSG_SPACE(sizeof_fds)]; char dummy = 0; + LTTNG_ASSERT(sock); + LTTNG_ASSERT(fds); + LTTNG_ASSERT(nb_fd > 0); + memset(&msg, 0, sizeof(msg)); memset(tmp, 0, sizeof(tmp)); @@ -590,7 +604,6 @@ end: * Expect at most "nb_fd" file descriptors. Returns the number of fd * actually received in nb_fd. */ -LTTNG_HIDDEN ssize_t lttcomm_recv_fds_unix_sock(int sock, int *fds, size_t nb_fd) { struct iovec iov[1]; @@ -609,6 +622,10 @@ ssize_t lttcomm_recv_fds_unix_sock(int sock, int *fds, size_t nb_fd) struct msghdr msg; char dummy; + LTTNG_ASSERT(sock); + LTTNG_ASSERT(fds); + LTTNG_ASSERT(nb_fd > 0); + memset(&msg, 0, sizeof(msg)); /* Prepare to receive the structures */ @@ -725,6 +742,8 @@ enum lttng_error_code add_fds_to_payload(struct lttng_dynamic_array *raw_fds, int *raw_fd = (int *) lttng_dynamic_array_get_element( raw_fds, i); + LTTNG_ASSERT(*raw_fd != -1); + handle = fd_handle_create(*raw_fd); if (!handle) { ret_code = LTTNG_ERR_NOMEM; @@ -750,15 +769,23 @@ static ssize_t _lttcomm_recv_payload_fds_unix_sock(int sock, size_t nb_fd, struct lttng_payload *payload, bool blocking) { + int i = 0; enum lttng_error_code add_ret; ssize_t ret; + int default_value = -1; struct lttng_dynamic_array raw_fds; + LTTNG_ASSERT(sock); + LTTNG_ASSERT(payload); + LTTNG_ASSERT(nb_fd > 0); + lttng_dynamic_array_init(&raw_fds, sizeof(int), close_raw_fd); - ret = lttng_dynamic_array_set_count(&raw_fds, nb_fd); - if (ret) { - ret = -LTTNG_ERR_NOMEM; - goto end; + + for (i = 0; i < nb_fd; i++) { + if (lttng_dynamic_array_add_element(&raw_fds, &default_value)) { + ret = -LTTNG_ERR_NOMEM; + goto end; + } } if (blocking) { @@ -769,7 +796,7 @@ ssize_t _lttcomm_recv_payload_fds_unix_sock(int sock, size_t nb_fd, sock, (int *) raw_fds.buffer.data, nb_fd); } - if (ret < 0) { + if (ret <= 0) { goto end; } @@ -784,14 +811,12 @@ end: return ret; } -LTTNG_HIDDEN ssize_t lttcomm_recv_payload_fds_unix_sock(int sock, size_t nb_fd, struct lttng_payload *payload) { return _lttcomm_recv_payload_fds_unix_sock(sock, nb_fd, payload, true); } -LTTNG_HIDDEN ssize_t lttcomm_recv_payload_fds_unix_sock_non_block(int sock, size_t nb_fd, struct lttng_payload *payload) { @@ -810,7 +835,6 @@ ssize_t lttcomm_recv_payload_fds_unix_sock_non_block(int sock, size_t nb_fd, * possible since the FDs are actually in the control message. It is all or * nothing, still the sender side can send the wrong number of fds. */ -LTTNG_HIDDEN ssize_t lttcomm_recv_fds_unix_sock_non_block(int sock, int *fds, size_t nb_fd) { struct iovec iov[1]; @@ -818,6 +842,10 @@ ssize_t lttcomm_recv_fds_unix_sock_non_block(int sock, int *fds, size_t nb_fd) struct cmsghdr *cmsg; size_t sizeof_fds = nb_fd * sizeof(int); + LTTNG_ASSERT(sock); + LTTNG_ASSERT(fds); + LTTNG_ASSERT(nb_fd > 0); + #ifdef __linux__ /* Account for the struct ucred cmsg in the buffer size */ #define LTTNG_SOCK_RECV_FDS_BUF_SIZE CMSG_SPACE(sizeof_fds) + CMSG_SPACE(sizeof(struct ucred)) @@ -939,29 +967,32 @@ end: * * Returns the size of data sent, or negative error value. */ -LTTNG_HIDDEN ssize_t lttcomm_send_creds_unix_sock(int sock, const void *buf, size_t len) { struct msghdr msg; struct iovec iov[1]; ssize_t ret = -1; -#ifdef __linux__ +#if defined(__linux__) || defined(__CYGWIN__) struct cmsghdr *cmptr; size_t sizeof_cred = sizeof(lttng_sock_cred); char anc_buf[CMSG_SPACE(sizeof_cred)]; lttng_sock_cred *creds; memset(anc_buf, 0, CMSG_SPACE(sizeof_cred) * sizeof(char)); -#endif /* __linux__ */ +#endif /* __linux__, __CYGWIN__ */ memset(&msg, 0, sizeof(msg)); + LTTNG_ASSERT(sock); + LTTNG_ASSERT(buf); + LTTNG_ASSERT(len > 0); + iov[0].iov_base = (void *) buf; iov[0].iov_len = len; msg.msg_iov = iov; msg.msg_iovlen = 1; -#ifdef __linux__ +#if defined(__linux__) || defined(__CYGWIN__) msg.msg_control = (caddr_t) anc_buf; msg.msg_controllen = CMSG_LEN(sizeof_cred); @@ -978,7 +1009,7 @@ ssize_t lttcomm_send_creds_unix_sock(int sock, const void *buf, size_t len) LTTNG_SOCK_SET_UID_CRED(creds, geteuid()); LTTNG_SOCK_SET_GID_CRED(creds, getegid()); LTTNG_SOCK_SET_PID_CRED(creds, getpid()); -#endif /* __linux__ */ +#endif /* __linux__, __CYGWIN__ */ do { ret = sendmsg(sock, &msg, 0); @@ -1000,7 +1031,6 @@ ssize_t lttcomm_send_creds_unix_sock(int sock, const void *buf, size_t len) * * Returns the size of received data, or negative error value. */ -LTTNG_HIDDEN ssize_t lttcomm_recv_creds_unix_sock(int sock, void *buf, size_t len, lttng_sock_cred *creds) { @@ -1008,19 +1038,18 @@ ssize_t lttcomm_recv_creds_unix_sock(int sock, void *buf, size_t len, struct iovec iov[1]; ssize_t ret; size_t len_last; -#ifdef __linux__ +#if defined(__linux__) || defined(__CYGWIN__) struct cmsghdr *cmptr; size_t sizeof_cred = sizeof(lttng_sock_cred); char anc_buf[CMSG_SPACE(sizeof_cred)]; -#endif /* __linux__ */ +#endif /* __linux__, __CYGWIN__ */ - memset(&msg, 0, sizeof(msg)); + LTTNG_ASSERT(sock); + LTTNG_ASSERT(buf); + LTTNG_ASSERT(len > 0); + LTTNG_ASSERT(creds); - /* Not allowed */ - if (creds == NULL) { - ret = -1; - goto end; - } + memset(&msg, 0, sizeof(msg)); /* Prepare to receive the structures */ iov[0].iov_base = buf; @@ -1028,10 +1057,10 @@ ssize_t lttcomm_recv_creds_unix_sock(int sock, void *buf, size_t len, msg.msg_iov = iov; msg.msg_iovlen = 1; -#ifdef __linux__ +#if defined(__linux__) || defined(__CYGWIN__) msg.msg_control = anc_buf; msg.msg_controllen = sizeof(anc_buf); -#endif /* __linux__ */ +#endif /* __linux__, __CYGWIN__ */ do { len_last = iov[0].iov_len; @@ -1039,7 +1068,7 @@ ssize_t lttcomm_recv_creds_unix_sock(int sock, void *buf, size_t len, if (ret > 0) { iov[0].iov_base += ret; iov[0].iov_len -= ret; - assert(ret <= len_last); + LTTNG_ASSERT(ret <= len_last); } } while ((ret > 0 && ret < len_last) || (ret < 0 && errno == EINTR)); if (ret < 0) { @@ -1050,7 +1079,7 @@ ssize_t lttcomm_recv_creds_unix_sock(int sock, void *buf, size_t len, } /* Else ret = 0 meaning an orderly shutdown. */ -#ifdef __linux__ +#if defined(__linux__) || defined(__CYGWIN__) if (msg.msg_flags & MSG_CTRUNC) { fprintf(stderr, "Error: Control message truncated.\n"); ret = -1; @@ -1079,18 +1108,15 @@ ssize_t lttcomm_recv_creds_unix_sock(int sock, void *buf, size_t len, } memcpy(creds, CMSG_DATA(cmptr), sizeof_cred); -#elif (defined(__FreeBSD__) || defined(__CYGWIN__) || defined(__sun__) || defined(__APPLE__)) - { - int peer_ret; - - peer_ret = getpeereid(sock, &creds->uid, &creds->gid); - if (peer_ret != 0) { - return peer_ret; - } +#elif (defined(__FreeBSD__) || defined(__sun__) || defined(__APPLE__)) + if (lttng_get_unix_socket_peer_creds(sock, creds)) { + fprintf(stderr, "ARG\n"); + ret = -1; + goto end; } #else #error "Please implement credential support for your OS." -#endif /* __linux__ */ +#endif /* __linux__, __CYGWIN__ */ end: return ret; @@ -1099,8 +1125,7 @@ end: /* * Set socket option to use credentials passing. */ -#ifdef __linux__ -LTTNG_HIDDEN +#if defined(__linux__) || defined(__CYGWIN__) int lttcomm_setsockopt_creds_unix_sock(int sock) { int ret, on = 1; @@ -1112,8 +1137,7 @@ int lttcomm_setsockopt_creds_unix_sock(int sock) } return ret; } -#elif (defined(__FreeBSD__) || defined(__CYGWIN__) || defined(__sun__) || defined(__APPLE__)) -LTTNG_HIDDEN +#elif (defined(__FreeBSD__) || defined(__sun__) || defined(__APPLE__)) int lttcomm_setsockopt_creds_unix_sock(int sock) { return 0;