diff options
author | Petr Štetiar <ynezz@true.cz> | 2019-12-27 14:48:32 +0100 |
---|---|---|
committer | Petr Štetiar <ynezz@true.cz> | 2019-12-27 15:11:41 +0100 |
commit | 041c9d1c052bb4936fd03240f7d0dd64aedda972 (patch) | |
tree | 2ead372ff8f53fcfb23b0797efb653187d645b31 /ubusd.c | |
parent | 8f2292478c5776dd7533a68f0a963b64d5dd92e3 (diff) | |
download | ubus-041c9d1c052bb4936fd03240f7d0dd64aedda972.tar.gz |
ubusd/libubus-io: fix socket descriptor passing
In commit 5d7ca8309d0a ("ubusd/libubus-io: fix variable sized struct
position warning") the position of cmsghdr struct has been changed in
order to fix clang-9 compiler warning, but it has introduced regression
in at least `logread` which hanged indefinitely.
So this patch reworks the socket descriptor passing in a way recommended
in the `cmsg(3)` manual page.
Ref: http://lists.infradead.org/pipermail/openwrt-devel/2019-December/020840.html
Fixes: 5d7ca8309d0a ("ubusd/libubus-io: fix variable sized struct position warning")
Reported-by: Hannu Nyman <hannu.nyman@welho.com>
Signed-off-by: Petr Štetiar <ynezz@true.cz>
Diffstat (limited to 'ubusd.c')
-rw-r--r-- | ubusd.c | 35 |
1 files changed, 18 insertions, 17 deletions
@@ -82,27 +82,28 @@ void ubus_msg_free(struct ubus_msg_buf *ub) ssize_t ubus_msg_writev(int fd, struct ubus_msg_buf *ub, size_t offset) { + uint8_t fd_buf[CMSG_SPACE(sizeof(int))] = { 0 }; static struct iovec iov[2]; - static struct { - int fd; - struct cmsghdr h; - } fd_buf = { - .h = { - .cmsg_len = sizeof(fd_buf), - .cmsg_level = SOL_SOCKET, - .cmsg_type = SCM_RIGHTS, - }, - }; - struct msghdr msghdr = { - .msg_iov = iov, - .msg_iovlen = ARRAY_SIZE(iov), - .msg_control = &fd_buf, - .msg_controllen = sizeof(fd_buf), - }; + struct msghdr msghdr = { 0 }; struct ubus_msghdr hdr; + struct cmsghdr *cmsg; ssize_t ret; + int *pfd; - fd_buf.fd = ub->fd; + msghdr.msg_iov = iov; + msghdr.msg_iovlen = ARRAY_SIZE(iov); + msghdr.msg_control = fd_buf; + msghdr.msg_controllen = sizeof(fd_buf); + + cmsg = CMSG_FIRSTHDR(&msghdr); + cmsg->cmsg_type = SCM_RIGHTS; + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); + + pfd = (int *) CMSG_DATA(cmsg); + msghdr.msg_controllen = cmsg->cmsg_len; + + *pfd = ub->fd; if (ub->fd < 0 || offset) { msghdr.msg_control = NULL; msghdr.msg_controllen = 0; |