From: Yu Watanabe Date: Tue, 8 Oct 2024 06:25:13 +0000 (+0900) Subject: sd-bus: introduce bus_process_cmsg() X-Git-Tag: v257-rc1~295^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5f9f38b8dfcf24e321ad65a56518e4b1b036d041;p=thirdparty%2Fsystemd.git sd-bus: introduce bus_process_cmsg() - Close all fds on failure. - Close pidfd on success. --- diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c index 07179e07052..ecaf5b33b4a 100644 --- a/src/libsystemd/sd-bus/bus-socket.c +++ b/src/libsystemd/sd-bus/bus-socket.c @@ -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);