X-Git-Url: https://git.distorted.org.uk/~mdw/mLib/blobdiff_plain/18c831dcd0ae4d660c70ccac69d27ed2a97851be..dff095f3bac7c61f574346c553486798d7fec426:/sys/fdpass.c diff --git a/sys/fdpass.c b/sys/fdpass.c index e860ec3..15a4a2c 100644 --- a/sys/fdpass.c +++ b/sys/fdpass.c @@ -104,13 +104,19 @@ ssize_t fdpass_send(int sock, int fd, const void *p, size_t sz) * otherwise it will. At most one descriptor will be collected. */ +/* Qemu 2.8.1 clobbers 12 bytes beyond the end of the control-message + * buffer. This is fixed in 2.12, but I'll bodge it for the sake of Debian + * stable. + */ +#define QEMU_SCRATCHSZ 16 + ssize_t fdpass_recv(int sock, int *fd, void *p, size_t sz) { struct iovec iov; struct msghdr msg; ssize_t rc; #ifndef HAVE_MSG_ACCRIGHTS - char buf[CMSG_SPACE(sizeof(fd))]; + char buf[CMSG_SPACE(sizeof(fd)) + QEMU_SCRATCHSZ]; struct cmsghdr *cmsg; int fdtmp; #endif @@ -128,7 +134,7 @@ ssize_t fdpass_recv(int sock, int *fd, void *p, size_t sz) #else msg.msg_flags = 0; msg.msg_control = buf; - msg.msg_controllen = sizeof(buf); + msg.msg_controllen = sizeof(buf) - QEMU_SCRATCHSZ; #endif if ((rc = recvmsg(sock, &msg, 0)) < 0) return (rc); @@ -139,7 +145,7 @@ ssize_t fdpass_recv(int sock, int *fd, void *p, size_t sz) for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS && - cmsg->cmsg_len >= CMSG_LEN(sizeof(fd))) { + cmsg->cmsg_len >= CMSG_LEN(sizeof(*fd))) { memcpy(&fdtmp, CMSG_DATA(cmsg), sizeof(fdtmp)); if (*fd == -1) *fd = fdtmp; @@ -151,4 +157,6 @@ ssize_t fdpass_recv(int sock, int *fd, void *p, size_t sz) return (rc); } +#undef QEMU_SCRATCHSZ + /*----- That's all, folks -------------------------------------------------*/