[PATCH libxxtrans 2/2] Fix alignment issues in FD passing code
Mark Kettenis
mark.kettenis at xs4all.nl
Mon Nov 11 14:22:56 PST 2013
From: Mark Kettenis <kettenis at openbsd.org>
A char array on the stack is not guaranteed to have more than byte
alignment. This means that casting it to a 'struct cmsghdr' and
accessing its members may result in unaligned access. This will
generate SIGBUS on strict alignment architectures like OpenBSD/sparc64.
The solution is to use a union to force proper alignment.
Signed-off-by: Mark Kettenis <kettenis at openbsd.org>
---
Xtranssock.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/Xtranssock.c b/Xtranssock.c
index 0370119..fdf1dd7 100644
--- a/Xtranssock.c
+++ b/Xtranssock.c
@@ -2197,9 +2197,9 @@ TRANS(SocketSendFdInvalid)(XtransConnInfo ciptr, int fd, int do_close)
#define MAX_FDS 128
-struct fd_pass {
+union fd_pass {
struct cmsghdr cmsghdr;
- int fd[MAX_FDS];
+ char buf[CMSG_SPACE(MAX_FDS * sizeof(int))];
};
#endif /* XTRANS_SEND_FDS */
@@ -2225,13 +2225,13 @@ TRANS(SocketRead) (XtransConnInfo ciptr, char *buf, int size)
.iov_base = buf,
.iov_len = size
};
- char cmsgbuf[CMSG_SPACE(sizeof(int) * MAX_FDS)];
+ union fd_pass cmsgbuf;
struct msghdr msg = {
.msg_name = NULL,
.msg_namelen = 0,
.msg_iov = &iov,
.msg_iovlen = 1,
- .msg_control = cmsgbuf,
+ .msg_control = cmsgbuf.buf,
.msg_controllen = CMSG_LEN(MAX_FDS * sizeof(int))
};
@@ -2266,13 +2266,13 @@ TRANS(SocketReadv) (XtransConnInfo ciptr, struct iovec *buf, int size)
#if XTRANS_SEND_FDS
{
- char cmsgbuf[CMSG_SPACE(sizeof(int) * MAX_FDS)];
+ union fd_pass cmsgbuf;
struct msghdr msg = {
.msg_name = NULL,
.msg_namelen = 0,
.msg_iov = buf,
.msg_iovlen = size,
- .msg_control = cmsgbuf,
+ .msg_control = cmsgbuf.buf,
.msg_controllen = CMSG_LEN(MAX_FDS * sizeof(int))
};
@@ -2308,7 +2308,7 @@ TRANS(SocketWritev) (XtransConnInfo ciptr, struct iovec *buf, int size)
#if XTRANS_SEND_FDS
if (ciptr->send_fds)
{
- char cmsgbuf[CMSG_SPACE(sizeof(int) * MAX_FDS)];
+ union fd_pass cmsgbuf;
int nfd = nFd(&ciptr->send_fds);
struct _XtransConnFd *cf = ciptr->send_fds;
struct msghdr msg = {
@@ -2316,7 +2316,7 @@ TRANS(SocketWritev) (XtransConnInfo ciptr, struct iovec *buf, int size)
.msg_namelen = 0,
.msg_iov = buf,
.msg_iovlen = size,
- .msg_control = cmsgbuf,
+ .msg_control = cmsgbuf.buf,
.msg_controllen = CMSG_LEN(nfd * sizeof(int))
};
struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg);
--
1.8.4.2
More information about the xorg-devel
mailing list