Fix alignment issues in FD passing code
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 struct alignment architectures like OpenBSD/sparc64. The canonical solution is to use a union to force proper alignment. Signed-off-by: Mark Kettenis <kettenis@openbsd.org> Reviewed-by: Matthieu Herrb <matthieu@herrb.eu> Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
parent
e8663a9358
commit
c7c5b710f2
|
@ -216,13 +216,16 @@ static int write_vec(xcb_connection_t *c, struct iovec **vector, int *count)
|
||||||
|
|
||||||
#if HAVE_SENDMSG
|
#if HAVE_SENDMSG
|
||||||
if (c->out.out_fd.nfd) {
|
if (c->out.out_fd.nfd) {
|
||||||
char cmsgbuf[CMSG_SPACE(sizeof(int) * XCB_MAX_PASS_FD)];
|
union {
|
||||||
|
struct cmsghdr cmsghdr;
|
||||||
|
char buf[CMSG_SPACE(XCB_MAX_PASS_FD * sizeof(int))];
|
||||||
|
} cmsgbuf;
|
||||||
struct msghdr msg = {
|
struct msghdr msg = {
|
||||||
.msg_name = NULL,
|
.msg_name = NULL,
|
||||||
.msg_namelen = 0,
|
.msg_namelen = 0,
|
||||||
.msg_iov = *vector,
|
.msg_iov = *vector,
|
||||||
.msg_iovlen = n,
|
.msg_iovlen = n,
|
||||||
.msg_control = cmsgbuf,
|
.msg_control = cmsgbuf.buf,
|
||||||
.msg_controllen = CMSG_LEN(c->out.out_fd.nfd * sizeof (int)),
|
.msg_controllen = CMSG_LEN(c->out.out_fd.nfd * sizeof (int)),
|
||||||
};
|
};
|
||||||
int i;
|
int i;
|
||||||
|
|
|
@ -888,13 +888,16 @@ int _xcb_in_read(xcb_connection_t *c)
|
||||||
.iov_base = c->in.queue + c->in.queue_len,
|
.iov_base = c->in.queue + c->in.queue_len,
|
||||||
.iov_len = sizeof(c->in.queue) - c->in.queue_len,
|
.iov_len = sizeof(c->in.queue) - c->in.queue_len,
|
||||||
};
|
};
|
||||||
char cmsgbuf[CMSG_SPACE(sizeof(int) * XCB_MAX_PASS_FD)];
|
union {
|
||||||
|
struct cmsghdr cmsghdr;
|
||||||
|
char buf[CMSG_SPACE(XCB_MAX_PASS_FD * sizeof(int))];
|
||||||
|
} cmsgbuf;
|
||||||
struct msghdr msg = {
|
struct msghdr msg = {
|
||||||
.msg_name = NULL,
|
.msg_name = NULL,
|
||||||
.msg_namelen = 0,
|
.msg_namelen = 0,
|
||||||
.msg_iov = &iov,
|
.msg_iov = &iov,
|
||||||
.msg_iovlen = 1,
|
.msg_iovlen = 1,
|
||||||
.msg_control = cmsgbuf,
|
.msg_control = cmsgbuf.buf,
|
||||||
.msg_controllen = CMSG_SPACE(sizeof(int) * (XCB_MAX_PASS_FD - c->in.in_fd.nfd)),
|
.msg_controllen = CMSG_SPACE(sizeof(int) * (XCB_MAX_PASS_FD - c->in.in_fd.nfd)),
|
||||||
};
|
};
|
||||||
n = recvmsg(c->fd, &msg, 0);
|
n = recvmsg(c->fd, &msg, 0);
|
||||||
|
|
Loading…
Reference in New Issue