From 33923454fd225ebec4341c76e1bf2e08ab267a25 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 16 Oct 2024 16:13:12 +0100 Subject: [PATCH 1/2] utils: Don't assume cmsg data is aligned suitably for struct ucred As documented in cmsg(3), the alignment of control messages is not guaranteed, so for portability to architectures with strong alignment requirements we should memcpy to and from a suitably aligned instance of the desired data structure on the stack. Helps: https://github.com/containers/bubblewrap/issues/637 Signed-off-by: Simon McVittie --- utils.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/utils.c b/utils.c index 985173e7..1c978664 100644 --- a/utils.c +++ b/utils.c @@ -761,7 +761,7 @@ send_pid_on_socket (int sockfd) const ssize_t control_len_snd = CMSG_SPACE(sizeof(struct ucred)); char control_buf_snd[control_len_snd]; struct cmsghdr *cmsg; - struct ucred *cred; + struct ucred cred; msg.msg_iov = &iov; msg.msg_iovlen = 1; @@ -772,11 +772,11 @@ send_pid_on_socket (int sockfd) cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_CREDENTIALS; cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred)); - cred = (struct ucred *)CMSG_DATA(cmsg); - cred->pid = getpid (); - cred->uid = geteuid (); - cred->gid = getegid (); + cred.pid = getpid (); + cred.uid = geteuid (); + cred.gid = getegid (); + memcpy (CMSG_DATA (cmsg), &cred, sizeof (cred)); if (TEMP_FAILURE_RETRY (sendmsg (sockfd, &msg, 0)) < 0) die_with_error ("Can't send pid"); @@ -822,8 +822,10 @@ read_pid_from_socket (int sockfd) cmsg->cmsg_type == SCM_CREDENTIALS && payload_len == sizeof(struct ucred)) { - struct ucred *cred = (struct ucred *)CMSG_DATA(cmsg); - return cred->pid; + struct ucred cred; + + memcpy (&cred, CMSG_DATA (cmsg), sizeof (cred)); + return cred.pid; } } die ("No pid returned on socket"); From 1fd7c383efc72e3e43de6aefc20c6897bef62b0a Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 16 Oct 2024 16:22:30 +0100 Subject: [PATCH 2/2] utils: Ensure that the buffer for struct cmsghdr is suitably-aligned A char array on the stack is not guaranteed to have any particular alignment. Resolves: https://github.com/containers/bubblewrap/issues/637 Signed-off-by: Simon McVittie --- utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utils.c b/utils.c index 1c978664..51875aea 100644 --- a/utils.c +++ b/utils.c @@ -759,7 +759,7 @@ send_pid_on_socket (int sockfd) struct msghdr msg = {}; struct iovec iov = { buf, sizeof (buf) }; const ssize_t control_len_snd = CMSG_SPACE(sizeof(struct ucred)); - char control_buf_snd[control_len_snd]; + _Alignas(struct cmsghdr) char control_buf_snd[control_len_snd]; struct cmsghdr *cmsg; struct ucred cred; @@ -801,7 +801,7 @@ read_pid_from_socket (int sockfd) struct msghdr msg = {}; struct iovec iov = { recv_buf, sizeof (recv_buf) }; const ssize_t control_len_rcv = CMSG_SPACE(sizeof(struct ucred)); - char control_buf_rcv[control_len_rcv]; + _Alignas(struct cmsghdr) char control_buf_rcv[control_len_rcv]; struct cmsghdr* cmsg; msg.msg_iov = &iov;