]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-bus: introduce bus_process_cmsg()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 8 Oct 2024 06:25:13 +0000 (15:25 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 8 Oct 2024 10:56:00 +0000 (19:56 +0900)
- Close all fds on failure.
- Close pidfd on success.

src/libsystemd/sd-bus/bus-socket.c

index 07179e070523493a507ce676e276fe38fb78cb42..ecaf5b33b4ab98e3204cb788a66d1fb1af5861aa 100644 (file)
@@ -553,6 +553,52 @@ static int bus_socket_write_auth(sd_bus *b) {
         return bus_socket_auth_verify(b);
 }
 
+static int bus_process_cmsg(sd_bus *bus, struct msghdr *mh, bool allow_fds) {
+        _cleanup_close_ int pidfd = -EBADF;
+        const int *fds = NULL;
+        size_t n_fds = 0;
+
+        assert(bus);
+        assert(mh);
+
+        CLEANUP_ARRAY(fds, n_fds, close_many);
+
+        struct cmsghdr *cmsg;
+        CMSG_FOREACH(cmsg, mh)
+                if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
+                        assert(!fds);
+                        fds = CMSG_TYPED_DATA(cmsg, int);
+                        n_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
+
+                } else if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_PIDFD) {
+                        log_debug("Got unexpected auxiliary pidfd, ignoring.");
+                        assert(pidfd < 0);
+                        pidfd = *CMSG_TYPED_DATA(cmsg, int);
+
+                } else
+                        log_debug("Got unexpected auxiliary data with level=%d and type=%d, ignoring.",
+                                  cmsg->cmsg_level, cmsg->cmsg_type);
+
+        if (!allow_fds) {
+                if (fds)
+                        /* Whut? We received fds during the auth protocol or so? Somebody is playing games
+                         * with us. Close them all, and fail */
+                        return -EIO;
+
+                return 0;
+        }
+
+        if (!GREEDY_REALLOC(bus->fds, bus->n_fds + n_fds))
+                return -ENOMEM;
+
+        FOREACH_ARRAY(i, fds, n_fds)
+                bus->fds[bus->n_fds++] = fd_move_above_stdio(*i);
+
+        TAKE_PTR(fds);
+        n_fds = 0;
+        return 0;
+}
+
 static int bus_socket_read_auth(sd_bus *b) {
         struct msghdr mh;
         struct iovec iov = {};
@@ -620,22 +666,9 @@ static int bus_socket_read_auth(sd_bus *b) {
         b->rbuffer_size += k;
 
         if (handle_cmsg) {
-                struct cmsghdr *cmsg;
-
-                CMSG_FOREACH(cmsg, &mh)
-                        if (cmsg->cmsg_level == SOL_SOCKET &&
-                            cmsg->cmsg_type == SCM_RIGHTS) {
-                                int j;
-
-                                /* Whut? We received fds during the auth
-                                 * protocol? Somebody is playing games with
-                                 * us. Close them all, and fail */
-                                j = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
-                                close_many(CMSG_TYPED_DATA(cmsg, int), j);
-                                return -EIO;
-                        } else
-                                log_debug("Got unexpected auxiliary data with level=%d and type=%d",
-                                          cmsg->cmsg_level, cmsg->cmsg_type);
+                r = bus_process_cmsg(b, &mh, /* allow_fds = */ false);
+                if (r < 0)
+                        return r;
         }
 
         r = bus_socket_auth_verify(b);
@@ -1405,36 +1438,9 @@ int bus_socket_read_message(sd_bus *bus) {
         bus->rbuffer_size += k;
 
         if (handle_cmsg) {
-                struct cmsghdr *cmsg;
-
-                CMSG_FOREACH(cmsg, &mh)
-                        if (cmsg->cmsg_level == SOL_SOCKET &&
-                            cmsg->cmsg_type == SCM_RIGHTS) {
-                                int n, *f, i;
-
-                                n = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
-
-                                if (!bus->can_fds) {
-                                        /* Whut? We received fds but this
-                                         * isn't actually enabled? Close them,
-                                         * and fail */
-
-                                        close_many(CMSG_TYPED_DATA(cmsg, int), n);
-                                        return -EIO;
-                                }
-
-                                f = reallocarray(bus->fds, bus->n_fds + n, sizeof(int));
-                                if (!f) {
-                                        close_many(CMSG_TYPED_DATA(cmsg, int), n);
-                                        return -ENOMEM;
-                                }
-
-                                for (i = 0; i < n; i++)
-                                        f[bus->n_fds++] = fd_move_above_stdio(CMSG_TYPED_DATA(cmsg, int)[i]);
-                                bus->fds = f;
-                        } else
-                                log_debug("Got unexpected auxiliary data with level=%d and type=%d",
-                                          cmsg->cmsg_level, cmsg->cmsg_type);
+                r = bus_process_cmsg(bus, &mh, bus->can_fds);
+                if (r < 0)
+                        return r;
         }
 
         r = bus_socket_read_message_need(bus, &need);