X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fsystemd.git;a=blobdiff_plain;f=src%2Flibsystemd%2Fsd-bus%2Fbus-socket.c;h=441b4a816f3af989459fc4024378fd0b413c2736;hp=d2101028418faf45dead4628587eef5a9f247557;hb=6d586a13717ae057aa1b4127400c3de61cd5b9e7;hpb=392cf1d05dbfa1395f6d99102e5ea41debb58fec diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c index d2101028418..441b4a816f3 100644 --- a/src/libsystemd/sd-bus/bus-socket.c +++ b/src/libsystemd/sd-bus/bus-socket.c @@ -1,22 +1,4 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ -/*** - This file is part of systemd. - - Copyright 2013 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see . -***/ #include #include @@ -39,6 +21,7 @@ #include "missing.h" #include "path-util.h" #include "process-util.h" +#include "rlimit-util.h" #include "selinux-util.h" #include "signal-util.h" #include "stdio-util.h" @@ -62,8 +45,7 @@ static void iovec_advance(struct iovec iov[], unsigned *idx, size_t size) { size -= i->iov_len; - i->iov_base = NULL; - i->iov_len = 0; + *i = IOVEC_MAKE(NULL, 0); (*idx)++; } @@ -74,9 +56,7 @@ static int append_iovec(sd_bus_message *m, const void *p, size_t sz) { assert(p); assert(sz > 0); - m->iovec[m->n_iovec].iov_base = (void*) p; - m->iovec[m->n_iovec].iov_len = sz; - m->n_iovec++; + m->iovec[m->n_iovec++] = IOVEC_MAKE((void*) p, sz); return 0; } @@ -261,16 +241,10 @@ static bool line_equals(const char *s, size_t m, const char *line) { } static bool line_begins(const char *s, size_t m, const char *word) { - size_t l; - - l = strlen(word); - if (m < l) - return false; - - if (memcmp(s, word, l) != 0) - return false; + const char *p; - return m == l || (m > l && s[l] == ' '); + p = memory_startswith(s, m, word); + return p && (p == (s + m) || *p == ' '); } static int verify_anonymous_token(sd_bus *b, const char *p, size_t l) { @@ -540,8 +514,7 @@ static int bus_socket_read_auth(sd_bus *b) { b->rbuffer = p; - iov.iov_base = (uint8_t*) b->rbuffer + b->rbuffer_size; - iov.iov_len = n - b->rbuffer_size; + iov = IOVEC_MAKE((uint8_t *)b->rbuffer + b->rbuffer_size, n - b->rbuffer_size); if (b->prefer_readv) k = readv(b->input_fd, &iov, 1); @@ -552,7 +525,7 @@ static int bus_socket_read_auth(sd_bus *b) { mh.msg_control = &control; mh.msg_controllen = sizeof(control); - k = recvmsg(b->input_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC); + k = recvmsg(b->input_fd, &mh, MSG_DONTWAIT|MSG_CMSG_CLOEXEC); if (k < 0 && errno == ENOTSOCK) { b->prefer_readv = true; k = readv(b->input_fd, &iov, 1); @@ -658,12 +631,9 @@ static int bus_socket_start_auth_client(sd_bus *b) { else auth_suffix = "\r\nBEGIN\r\n"; - b->auth_iovec[0].iov_base = (void*) auth_prefix; - b->auth_iovec[0].iov_len = 1 + strlen(auth_prefix + 1); - b->auth_iovec[1].iov_base = (void*) b->auth_buffer; - b->auth_iovec[1].iov_len = l * 2; - b->auth_iovec[2].iov_base = (void*) auth_suffix; - b->auth_iovec[2].iov_len = strlen(auth_suffix); + b->auth_iovec[0] = IOVEC_MAKE((void*) auth_prefix, 1 + strlen(auth_prefix + 1)); + b->auth_iovec[1] = IOVEC_MAKE(b->auth_buffer, l * 2); + b->auth_iovec[2] = IOVEC_MAKE_STRING(auth_suffix); return bus_socket_write_auth(b); } @@ -713,6 +683,8 @@ static int bus_socket_inotify_setup(sd_bus *b) { b->inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC); if (b->inotify_fd < 0) return -errno; + + b->inotify_fd = fd_move_above_stdio(b->inotify_fd); } /* Make sure the path is NUL terminated */ @@ -788,7 +760,7 @@ static int bus_socket_inotify_setup(sd_bus *b) { if (IN_SET(errno, ENOENT, ELOOP)) break; /* This component doesn't exist yet, or the path contains a cyclic symlink right now */ - r = log_debug_errno(errno, "Failed to add inotify watch on %s: %m", isempty(prefix) ? "/" : prefix); + r = log_debug_errno(errno, "Failed to add inotify watch on %s: %m", empty_to_root(prefix)); goto fail; } else new_watches[n++] = wd; @@ -879,6 +851,8 @@ int bus_socket_connect(sd_bus *b) { if (b->input_fd < 0) return -errno; + b->input_fd = fd_move_above_stdio(b->input_fd); + b->output_fd = b->input_fd; bus_socket_setup(b); @@ -956,16 +930,10 @@ int bus_socket_exec(sd_bus *b) { if (r == 0) { /* Child */ - assert_se(dup3(s[1], STDIN_FILENO, 0) == STDIN_FILENO); - assert_se(dup3(s[1], STDOUT_FILENO, 0) == STDOUT_FILENO); - - if (!IN_SET(s[1], STDIN_FILENO, STDOUT_FILENO)) - safe_close(s[1]); + if (rearrange_stdio(s[1], s[1], STDERR_FILENO) < 0) + _exit(EXIT_FAILURE); - (void) fd_cloexec(STDIN_FILENO, false); - (void) fd_cloexec(STDOUT_FILENO, false); - (void) fd_nonblock(STDIN_FILENO, false); - (void) fd_nonblock(STDOUT_FILENO, false); + (void) rlimit_nofile_safe(); if (b->exec_argv) execvp(b->exec_path, b->exec_argv); @@ -978,7 +946,7 @@ int bus_socket_exec(sd_bus *b) { } safe_close(s[1]); - b->output_fd = b->input_fd = s[0]; + b->output_fd = b->input_fd = fd_move_above_stdio(s[0]); bus_socket_setup(b); @@ -1013,7 +981,7 @@ int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) { return r; n = m->n_iovec * sizeof(struct iovec); - iov = alloca(n); + iov = newa(struct iovec, n); memcpy_safe(iov, m->iovec, n); j = 0; @@ -1104,7 +1072,7 @@ static int bus_socket_read_message_need(sd_bus *bus, size_t *need) { } static int bus_socket_make_message(sd_bus *bus, size_t size) { - sd_bus_message *t; + sd_bus_message *t = NULL; void *b; int r; @@ -1129,7 +1097,9 @@ static int bus_socket_make_message(sd_bus *bus, size_t size) { bus->fds, bus->n_fds, NULL, &t); - if (r < 0) { + if (r == -EBADMSG) + log_debug_errno(r, "Received invalid message from connection %s, dropping.", strna(bus->description)); + else if (r < 0) { free(b); return r; } @@ -1140,7 +1110,8 @@ static int bus_socket_make_message(sd_bus *bus, size_t size) { bus->fds = NULL; bus->n_fds = 0; - bus->rqueue[bus->rqueue_size++] = t; + if (t) + bus->rqueue[bus->rqueue_size++] = t; return 1; } @@ -1174,8 +1145,7 @@ int bus_socket_read_message(sd_bus *bus) { bus->rbuffer = b; - iov.iov_base = (uint8_t*) bus->rbuffer + bus->rbuffer_size; - iov.iov_len = need - bus->rbuffer_size; + iov = IOVEC_MAKE((uint8_t *)bus->rbuffer + bus->rbuffer_size, need - bus->rbuffer_size); if (bus->prefer_readv) k = readv(bus->input_fd, &iov, 1); @@ -1186,7 +1156,7 @@ int bus_socket_read_message(sd_bus *bus) { mh.msg_control = &control; mh.msg_controllen = sizeof(control); - k = recvmsg(bus->input_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC); + k = recvmsg(bus->input_fd, &mh, MSG_DONTWAIT|MSG_CMSG_CLOEXEC); if (k < 0 && errno == ENOTSOCK) { bus->prefer_readv = true; k = readv(bus->input_fd, &iov, 1); @@ -1206,7 +1176,7 @@ int bus_socket_read_message(sd_bus *bus) { CMSG_FOREACH(cmsg, &mh) if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) { - int n, *f; + int n, *f, i; n = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int); @@ -1219,15 +1189,15 @@ int bus_socket_read_message(sd_bus *bus) { return -EIO; } - f = realloc(bus->fds, sizeof(int) * (bus->n_fds + n)); + f = reallocarray(bus->fds, bus->n_fds + n, sizeof(int)); if (!f) { close_many((int*) CMSG_DATA(cmsg), n); return -ENOMEM; } - memcpy_safe(f + bus->n_fds, CMSG_DATA(cmsg), n * sizeof(int)); + for (i = 0; i < n; i++) + f[bus->n_fds++] = fd_move_above_stdio(((int*) CMSG_DATA(cmsg))[i]); bus->fds = f; - bus->n_fds += n; } else log_debug("Got unexpected auxiliary data with level=%d and type=%d", cmsg->cmsg_level, cmsg->cmsg_type);