diff options
author | Lennart Poettering <lennart@poettering.net> | 2020-04-23 09:40:03 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2020-04-23 09:41:47 +0200 |
commit | 3691bcf3c5eebdcca5b4f1c51c745441c57a6cd1 (patch) | |
tree | caff7067ab4c3b4c5871c1869ed4e806c65f512d /src/udev/udevd.c | |
parent | 47eae6ce0c28b1984f8f5ec4c2f7bc428cf3b6ad (diff) | |
download | systemd-3691bcf3c5eebdcca5b4f1c51c745441c57a6cd1.tar.gz |
tree-wide: use recvmsg_safe() at various places
Let's be extra careful whenever we return from recvmsg() and see
MSG_CTRUNC set. This generally means we ran into a programming error, as
we didn't size the control buffer large enough. It's an error condition
we should at least log about, or propagate up. Hence do that.
This is particularly important when receiving fds, since for those the
control data can be of any size. In particular on stream sockets that's
nasty, because if we miss an fd because of control data truncation we
cannot recover, we might not even realize that we are one off.
(Also, when failing early, if there's any chance the socket might be
AF_UNIX let's close all received fds, all the time. We got this right
most of the time, but there were a few cases missing. God, UNIX is hard
to use)
Diffstat (limited to 'src/udev/udevd.c')
-rw-r--r-- | src/udev/udevd.c | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/src/udev/udevd.c b/src/udev/udevd.c index 456bc8c479..4b15159c5b 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -921,16 +921,18 @@ static int on_worker(sd_event_source *s, int fd, uint32_t revents, void *userdat struct ucred *ucred = NULL; struct worker *worker; - size = recvmsg(fd, &msghdr, MSG_DONTWAIT); - if (size < 0) { - if (errno == EINTR) - continue; - else if (errno == EAGAIN) - /* nothing more to read */ - break; + size = recvmsg_safe(fd, &msghdr, MSG_DONTWAIT); + if (size == -EINTR) + continue; + if (size == -EAGAIN) + /* nothing more to read */ + break; + if (size < 0) + return log_error_errno(size, "Failed to receive message: %m"); + + cmsg_close_all(&msghdr); - return log_error_errno(errno, "Failed to receive message: %m"); - } else if (size != sizeof(struct worker_message)) { + if (size != sizeof(struct worker_message)) { log_warning("Ignoring worker message with invalid size %zi bytes", size); continue; } |