Avoid member access within misaligned address for ancillary data buffer.
authorAndre Noll <maan@tuebingen.mpg.de>
Wed, 16 Mar 2016 22:05:56 +0000 (23:05 +0100)
committerAndre Noll <maan@tuebingen.mpg.de>
Mon, 28 Mar 2016 17:16:16 +0000 (17:16 +0000)
For glibc-2.23, the CMSG_FIRSTHDR macro is defined as

#define CMSG_FIRSTHDR(mhdr) \
  ((size_t) (mhdr)->msg_controllen >= sizeof (struct cmsghdr)                 \
   ? (struct cmsghdr *) (mhdr)->msg_control : (struct cmsghdr *) 0)

In recv_cred_buffer(), pass_afd() and dispose_fds() the on-stack
ancillary data buffer is not necessarily aligned. The pointer is
cast to struct cmsghdr *, then dereferenced, resulting in undefined
behaviour due to the lack of alignment.

This patch asks the compiler to align the ancillary data buffers.

afs.c
net.c
vss.c

diff --git a/afs.c b/afs.c
index c87fdf7..1a5e602 100644 (file)
--- a/afs.c
+++ b/afs.c
@@ -419,7 +419,7 @@ static int pass_afd(int fd, char *buf, size_t size)
 {
        struct msghdr msg = {.msg_iov = NULL};
        struct cmsghdr *cmsg;
-       char control[255];
+       char control[255] __a_aligned(8);
        int ret;
        struct iovec iov;
 
diff --git a/net.c b/net.c
index 2ec3f03..708e83f 100644 (file)
--- a/net.c
+++ b/net.c
@@ -980,7 +980,7 @@ static void dispose_fds(int *fds, unsigned num)
  */
 int recv_cred_buffer(int fd, char *buf, size_t size)
 {
-       char control[255];
+       char control[255] __a_aligned(8);
        struct msghdr msg;
        struct cmsghdr *cmsg;
        struct iovec iov;
diff --git a/vss.c b/vss.c
index 06707d6..4c9f362 100644 (file)
--- a/vss.c
+++ b/vss.c
@@ -938,7 +938,7 @@ static void vss_pre_select(struct sched *s, struct task *t)
 
 static int recv_afs_msg(int afs_socket, int *fd, uint32_t *code, uint32_t *data)
 {
-       char control[255], buf[8];
+       char control[255] __a_aligned(8), buf[8];
        struct msghdr msg = {.msg_iov = NULL};
        struct cmsghdr *cmsg;
        struct iovec iov;