chiark / gitweb /
sd-rtnl: recv_message - drop message when peeking fails
[elogind.git] / src / libsystemd / sd-rtnl / rtnl-message.c
index 9099440ad461bf0475eb0a66822c1a1b97be3b5b..640c0ea93eadf34f451ef9ce3a492923ccef122f 100644 (file)
@@ -1348,8 +1348,10 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool
                 /* no data */
                 if (errno == ENOBUFS)
                         log_debug("rtnl: kernel receive buffer overrun");
+                else if (errno == EAGAIN)
+                        log_debug("rtnl: no data in socket");
 
-                return (errno == EAGAIN) ? 0 : -errno;
+                return (errno == EAGAIN || errno == EINTR) ? 0 : -errno;
         } else if (r == 0)
                 /* connection was closed by the kernel */
                 return -ECONNRESET;
@@ -1363,6 +1365,8 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool
                         /* from the kernel */
                         if (ucred->uid == 0 && ucred->pid == 0)
                                 auth = true;
+                        else
+                                log_debug("rtnl: ignoring message from uid %u pid %u", ucred->uid, ucred->pid);
                 } else if (cmsg->cmsg_level == SOL_NETLINK &&
                            cmsg->cmsg_type == NETLINK_PKTINFO &&
                            cmsg->cmsg_len == CMSG_LEN(sizeof(struct nl_pktinfo))) {
@@ -1373,9 +1377,17 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool
                 }
         }
 
-        if (!auth)
+        if (!auth) {
                 /* not from the kernel, ignore */
+                if (peek) {
+                        /* drop the message */
+                        r = recvmsg(fd, &msg, 0);
+                        if (r < 0)
+                                return (errno == EAGAIN || errno == EINTR) ? 0 : -errno;
+                }
+
                 return 0;
+        }
 
         if (group)
                 *_group = group;