]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
tree-wide: ignore messages with too long control data
authorLennart Poettering <lennart@poettering.net>
Tue, 19 Jan 2021 20:34:20 +0000 (21:34 +0100)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 20 Jan 2021 05:05:45 +0000 (14:05 +0900)
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

src/core/manager.c
src/nspawn/nspawn.c
src/shared/ask-password-api.c

index 4b215a617665663f8a9eadc298b401c459341fd6..a1d6f7cc10bd0fc9b087f365665e226ff13d2177 100644 (file)
@@ -2387,6 +2387,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
index 75cefe84142aac537ae0d03da78b817f998933e2..a564b95d85147b66283cf5acf4d8a867f3bd5fca 100644 (file)
@@ -3995,6 +3995,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");
 
index c8ce17ad5b0c032f28de234baac04058b2eefd2c..bd33bdd2c5245d96bf0432603fbc7c6762784d7d 100644 (file)
@@ -943,6 +943,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;