From f96df55cd895b1cb26b9f8d12529e4387503fade Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 19 Jan 2021 21:34:20 +0100 Subject: [PATCH] tree-wide: ignore messages with too long control data Apparently SELinux inserts control data into AF_UNIX datagrams where we don't expect it, thus miscalculating the control data. This looks like something to fix in SELinux, but we still should handle this gracefully and just drop the offending datagram and continue. recvmsg_safe() actually already drops the datagram, it's just a matter of actually ignoring EXFULL (which it generates if control data is too large) in the right places. This does this wherever an AF_UNIX/SOCK_DGRAM socket is used with recvmsg_safe() that is not just internal communication. Fixes: #17795 Follow-up for: 3691bcf3c5eebdcca5b4f1c51c745441c57a6cd1 (cherry picked from commit 741bfd7f4e60fdc07ecaadbd93f1196dbee657ca) (cherry picked from commit b7e0ac754eba3c91b76dc7b92802716144b569b8) --- src/core/manager.c | 4 ++++ src/nspawn/nspawn.c | 4 ++++ src/shared/ask-password-api.c | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/src/core/manager.c b/src/core/manager.c index 19f95b3b5b..a822a0d39d 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -2389,6 +2389,10 @@ static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t n = recvmsg_safe(m->notify_fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC|MSG_TRUNC); if (IN_SET(n, -EAGAIN, -EINTR)) return 0; /* Spurious wakeup, try again */ + if (n == -EXFULL) { + log_warning("Got message with truncated control data (too many fds sent?), ignoring."); + return 0; + } if (n < 0) /* If this is any other, real error, then let's stop processing this socket. This of course * means we won't take notification messages anymore, but that's still better than busy diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 83e6581e14..98125886be 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -3772,6 +3772,10 @@ static int nspawn_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t r n = recvmsg_safe(fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC); if (IN_SET(n, -EAGAIN, -EINTR)) return 0; + if (n == -EXFULL) { + log_warning("Got message with truncated control data (too many fds sent?), ignoring."); + return 0; + } if (n < 0) return log_warning_errno(n, "Couldn't read notification socket: %m"); diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c index a727b98e7c..7bf64e1cf8 100644 --- a/src/shared/ask-password-api.c +++ b/src/shared/ask-password-api.c @@ -946,6 +946,10 @@ int ask_password_agent( n = recvmsg_safe(socket_fd, &msghdr, 0); if (IN_SET(n, -EAGAIN, -EINTR)) continue; + if (n == -EXFULL) { + log_debug("Got message with truncated control data, ignoring."); + continue; + } if (n < 0) { r = (int) n; goto finish;