From: Jérémie Galarneau Date: Thu, 12 Sep 2019 15:51:52 +0000 (-0400) Subject: inet: fix: possible unaligned access in packed structure (inet/inet6) X-Git-Tag: v2.9.13~4 X-Git-Url: https://git.liburcu.org/?p=lttng-tools.git;a=commitdiff_plain;h=e909777bf000d0fd8f0116569b3fb31676b228be inet: fix: possible unaligned access in packed structure (inet/inet6) Fix the warnings that unaligned pointers can be passed as parameters emitted when building inet.c and inet6.c. Signed-off-by: Jérémie Galarneau --- diff --git a/src/common/macros.h b/src/common/macros.h index 9637a3830..e2d0fcf3e 100644 --- a/src/common/macros.h +++ b/src/common/macros.h @@ -87,6 +87,13 @@ void *zmalloc(size_t len) #define member_sizeof(type, field) sizeof(((type *) 0)->field) +/* + * Get an aligned pointer to a value. This is meant + * as a helper to pass an aligned pointer to a member in a packed structure + * to a function. + */ +#define ALIGNED_CONST_PTR(value) (((const typeof(value) []) { value })) + /* * lttng_strncpy returns 0 on success, or nonzero on failure. * It checks that the @src string fits into @dst_len before performing diff --git a/src/common/sessiond-comm/inet.c b/src/common/sessiond-comm/inet.c index 6b7a894ad..22d9181ee 100644 --- a/src/common/sessiond-comm/inet.c +++ b/src/common/sessiond-comm/inet.c @@ -102,7 +102,8 @@ int lttcomm_bind_inet_sock(struct lttcomm_sock *sock) { int ret; - ret = bind(sock->fd, (const struct sockaddr *) &sock->sockaddr.addr.sin, + ret = bind(sock->fd, (const struct sockaddr *) ALIGNED_CONST_PTR( + sock->sockaddr.addr.sin), sizeof(sock->sockaddr.addr.sin)); if (ret < 0) { PERROR("bind inet"); @@ -114,7 +115,9 @@ int lttcomm_bind_inet_sock(struct lttcomm_sock *sock) static int connect_no_timeout(struct lttcomm_sock *sock) { - return connect(sock->fd, (struct sockaddr *) &sock->sockaddr.addr.sin, + return connect(sock->fd, + (const struct sockaddr *) ALIGNED_CONST_PTR( + sock->sockaddr.addr.sin), sizeof(sock->sockaddr.addr.sin)); } @@ -147,11 +150,11 @@ int connect_with_timeout(struct lttcomm_sock *sock) } connect_ret = connect(sock->fd, - (struct sockaddr *) &sock->sockaddr.addr.sin, - sizeof(sock->sockaddr.addr.sin)); - if (connect_ret == -1 && errno != EAGAIN - && errno != EWOULDBLOCK - && errno != EINPROGRESS) { + (const struct sockaddr *) ALIGNED_CONST_PTR( + sock->sockaddr.addr.sin), + sizeof(sock->sockaddr.addr.sin)); + if (connect_ret == -1 && errno != EAGAIN && errno != EWOULDBLOCK && + errno != EINPROGRESS) { goto error; } else if (!connect_ret) { /* Connect succeeded */ @@ -267,6 +270,7 @@ struct lttcomm_sock *lttcomm_accept_inet_sock(struct lttcomm_sock *sock) socklen_t len; struct lttcomm_sock *new_sock; unsigned long timeout; + struct sockaddr_in new_addr = {}; if (sock->proto == LTTCOMM_SOCK_UDP) { /* @@ -281,15 +285,15 @@ struct lttcomm_sock *lttcomm_accept_inet_sock(struct lttcomm_sock *sock) goto error; } - len = sizeof(new_sock->sockaddr.addr.sin); + len = sizeof(new_addr); /* Blocking call */ - new_fd = accept(sock->fd, (struct sockaddr *) &new_sock->sockaddr.addr.sin, - &len); + new_fd = accept(sock->fd, (struct sockaddr *) &new_addr, &len); if (new_fd < 0) { PERROR("accept inet"); goto error; } + new_sock->sockaddr.addr.sin = new_addr; timeout = lttcomm_get_network_timeout(); if (timeout) { int ret; @@ -362,6 +366,7 @@ ssize_t lttcomm_recvmsg_inet_sock(struct lttcomm_sock *sock, void *buf, struct iovec iov[1]; ssize_t ret = -1; size_t len_last; + struct sockaddr_in addr = sock->sockaddr.addr.sin; memset(&msg, 0, sizeof(msg)); @@ -370,7 +375,7 @@ ssize_t lttcomm_recvmsg_inet_sock(struct lttcomm_sock *sock, void *buf, msg.msg_iov = iov; msg.msg_iovlen = 1; - msg.msg_name = (struct sockaddr *) &sock->sockaddr.addr.sin; + msg.msg_name = (struct sockaddr *) &addr; msg.msg_namelen = sizeof(sock->sockaddr.addr.sin); do { @@ -414,9 +419,13 @@ ssize_t lttcomm_sendmsg_inet_sock(struct lttcomm_sock *sock, const void *buf, switch (sock->proto) { case LTTCOMM_SOCK_UDP: - msg.msg_name = (struct sockaddr *) &sock->sockaddr.addr.sin; + { + struct sockaddr_in addr = sock->sockaddr.addr.sin; + + msg.msg_name = (struct sockaddr *) &addr; msg.msg_namelen = sizeof(sock->sockaddr.addr.sin); break; + } default: break; } diff --git a/src/common/sessiond-comm/inet6.c b/src/common/sessiond-comm/inet6.c index 60fe44f1e..e8c761603 100644 --- a/src/common/sessiond-comm/inet6.c +++ b/src/common/sessiond-comm/inet6.c @@ -100,7 +100,8 @@ int lttcomm_bind_inet6_sock(struct lttcomm_sock *sock) { int ret; - ret = bind(sock->fd, (const struct sockaddr *) &sock->sockaddr.addr.sin6, + ret = bind(sock->fd, (const struct sockaddr *) ALIGNED_CONST_PTR( + sock->sockaddr.addr.sin6), sizeof(sock->sockaddr.addr.sin6)); if (ret < 0) { PERROR("bind inet6"); @@ -112,7 +113,9 @@ int lttcomm_bind_inet6_sock(struct lttcomm_sock *sock) static int connect_no_timeout(struct lttcomm_sock *sock) { - return connect(sock->fd, (struct sockaddr *) &sock->sockaddr.addr.sin6, + return connect(sock->fd, + (const struct sockaddr *) ALIGNED_CONST_PTR( + sock->sockaddr.addr.sin6), sizeof(sock->sockaddr.addr.sin6)); } @@ -145,11 +148,11 @@ int connect_with_timeout(struct lttcomm_sock *sock) } connect_ret = connect(sock->fd, - (struct sockaddr *) &sock->sockaddr.addr.sin6, - sizeof(sock->sockaddr.addr.sin6)); - if (connect_ret == -1 && errno != EAGAIN - && errno != EWOULDBLOCK - && errno != EINPROGRESS) { + (const struct sockaddr *) ALIGNED_CONST_PTR( + sock->sockaddr.addr.sin6), + sizeof(sock->sockaddr.addr.sin6)); + if (connect_ret == -1 && errno != EAGAIN && errno != EWOULDBLOCK && + errno != EINPROGRESS) { goto error; } else if (!connect_ret) { /* Connect succeeded */ @@ -265,6 +268,7 @@ struct lttcomm_sock *lttcomm_accept_inet6_sock(struct lttcomm_sock *sock) int new_fd; socklen_t len; struct lttcomm_sock *new_sock; + struct sockaddr_in6 new_addr = {}; if (sock->proto == LTTCOMM_SOCK_UDP) { /* @@ -279,16 +283,15 @@ struct lttcomm_sock *lttcomm_accept_inet6_sock(struct lttcomm_sock *sock) goto error; } - len = sizeof(new_sock->sockaddr.addr.sin6); + len = sizeof(new_addr); /* Blocking call */ - new_fd = accept(sock->fd, - (struct sockaddr *) &new_sock->sockaddr.addr.sin6, &len); + new_fd = accept(sock->fd, (struct sockaddr *) &new_addr, &len); if (new_fd < 0) { PERROR("accept inet6"); goto error; } - + new_sock->sockaddr.addr.sin6 = new_addr; new_sock->fd = new_fd; new_sock->ops = &inet6_ops; @@ -342,6 +345,7 @@ ssize_t lttcomm_recvmsg_inet6_sock(struct lttcomm_sock *sock, void *buf, struct iovec iov[1]; ssize_t ret = -1; size_t len_last; + struct sockaddr_in6 addr = sock->sockaddr.addr.sin6; memset(&msg, 0, sizeof(msg)); @@ -350,7 +354,7 @@ ssize_t lttcomm_recvmsg_inet6_sock(struct lttcomm_sock *sock, void *buf, msg.msg_iov = iov; msg.msg_iovlen = 1; - msg.msg_name = (struct sockaddr *) &sock->sockaddr.addr.sin6; + msg.msg_name = (struct sockaddr *) &addr; msg.msg_namelen = sizeof(sock->sockaddr.addr.sin6); do { @@ -394,9 +398,13 @@ ssize_t lttcomm_sendmsg_inet6_sock(struct lttcomm_sock *sock, const void *buf, switch (sock->proto) { case LTTCOMM_SOCK_UDP: - msg.msg_name = (struct sockaddr *) &sock->sockaddr.addr.sin6; + { + struct sockaddr_in6 addr = sock->sockaddr.addr.sin6; + + msg.msg_name = (struct sockaddr *) &addr; msg.msg_namelen = sizeof(sock->sockaddr.addr.sin6); break; + } default: break; }