From 33923454fd225ebec4341c76e1bf2e08ab267a25 Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@collabora.com>
Date: Wed, 16 Oct 2024 16:13:12 +0100
Subject: [PATCH] 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 <smcv@collabora.com>
---
 utils.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/utils.c b/utils.c
index 985173e7b..1c978664d 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");
-- 
GitLab