diff options
44 files changed, 390 insertions, 145 deletions
diff --git a/Makefile.am b/Makefile.am index 7603b2c0e1..5d30d7d51c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5176,9 +5176,6 @@ dist_dbuspolicy_DATA += \ polkitpolicy_files += \ src/machine/org.freedesktop.machine1.policy -polkitpolicy_in_files += \ - src/machine/org.freedesktop.machine1.policy.in - dist_zshcompletion_DATA += \ shell-completion/zsh/_machinectl \ shell-completion/zsh/_sd_machines @@ -5211,6 +5208,9 @@ lib_LTLIBRARIES += \ endif +polkitpolicy_in_files += \ + src/machine/org.freedesktop.machine1.policy.in + EXTRA_DIST += \ units/systemd-machined.service.in @@ -5359,9 +5359,6 @@ dist_dbuspolicy_DATA += \ polkitpolicy_files += \ src/import/org.freedesktop.import1.policy -polkitpolicy_in_files += \ - src/import/org.freedesktop.import1.policy.in - manual_tests += \ test-qcow2 @@ -5387,6 +5384,9 @@ endif endif +polkitpolicy_in_files += \ + src/import/org.freedesktop.import1.policy.in + EXTRA_DIST += \ units/systemd-importd.service.in \ src/resolve/resolved.conf.in diff --git a/configure.ac b/configure.ac index 2625e0d15b..5719075934 100644 --- a/configure.ac +++ b/configure.ac @@ -149,7 +149,6 @@ CC_CHECK_FLAGS_APPEND([with_cflags], [CFLAGS], [\ -pipe \ -Wall \ -Wextra \ - -Wno-inline \ -Wundef \ "-Wformat=2 -Wformat-security -Wformat-nonliteral" \ -Wlogical-op \ @@ -169,11 +168,8 @@ CC_CHECK_FLAGS_APPEND([with_cflags], [CFLAGS], [\ -Wendif-labels \ -Wstrict-aliasing=2 \ -Wwrite-strings \ - -Wno-long-long \ - -Wno-overlength-strings \ -Wno-unused-parameter \ -Wno-missing-field-initializers \ - -Wno-unused-result \ -Wno-format-signedness \ -Werror=overflow \ -Wdate-time \ diff --git a/rules/60-block.rules b/rules/60-block.rules index a69d648023..c74caca49f 100644 --- a/rules/60-block.rules +++ b/rules/60-block.rules @@ -8,4 +8,4 @@ ACTION=="add", SUBSYSTEM=="module", KERNEL=="block", ATTR{parameters/events_dfl_ ACTION=="change", SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_device", TEST=="block", ATTR{block/*/uevent}="change" # watch metadata changes, caused by tools closing the device node which was opened for writing -ACTION!="remove", SUBSYSTEM=="block", KERNEL=="loop*|nvme*|sd*|vd*", OPTIONS+="watch" +ACTION!="remove", SUBSYSTEM=="block", KERNEL=="loop*|nvme*|sd*|vd*|xvd*", OPTIONS+="watch" diff --git a/rules/60-persistent-storage.rules b/rules/60-persistent-storage.rules index 64c5f1cfdd..2daeb6db42 100644 --- a/rules/60-persistent-storage.rules +++ b/rules/60-persistent-storage.rules @@ -6,7 +6,7 @@ ACTION=="remove", GOTO="persistent_storage_end" SUBSYSTEM!="block", GOTO="persistent_storage_end" -KERNEL!="loop*|mmcblk*[0-9]|msblk*[0-9]|mspblk*[0-9]|nvme*|sd*|sr*|vd*|bcache*|xvd*", GOTO="persistent_storage_end" +KERNEL!="loop*|mmcblk*[0-9]|msblk*[0-9]|mspblk*[0-9]|nvme*|sd*|sr*|vd*|xvd*|bcache*", GOTO="persistent_storage_end" # ignore partitions that span the entire disk TEST=="whole_disk", GOTO="persistent_storage_end" diff --git a/src/activate/activate.c b/src/activate/activate.c index d345e28567..5318829442 100644 --- a/src/activate/activate.c +++ b/src/activate/activate.c @@ -33,6 +33,7 @@ #include "log.h" #include "strv.h" #include "macro.h" +#include "signal-util.h" static char** arg_listen = NULL; static bool arg_accept = false; @@ -192,6 +193,10 @@ static int launch1(const char* child, char** argv, char **env, int fd) { /* In the child */ if (child_pid == 0) { + + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); + r = dup2(fd, STDIN_FILENO); if (r < 0) { log_error_errno(errno, "Failed to dup connection to stdin: %m"); diff --git a/src/core/busname.c b/src/core/busname.c index 3f5abbcb24..2085721546 100644 --- a/src/core/busname.c +++ b/src/core/busname.c @@ -408,8 +408,8 @@ static int busname_make_starter(BusName *n, pid_t *_pid) { if (pid == 0) { int ret; - default_signals(SIGNALS_CRASH_HANDLER, SIGNALS_IGNORE, -1); - ignore_signals(SIGPIPE, -1); + (void) default_signals(SIGNALS_CRASH_HANDLER, SIGNALS_IGNORE, -1); + (void) ignore_signals(SIGPIPE, -1); log_forget_fds(); r = bus_kernel_make_starter(n->starter_fd, n->name, n->activating, n->accept_fd, n->policy, n->policy_world); diff --git a/src/core/execute.c b/src/core/execute.c index 4120493bda..f13c6936e0 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -823,6 +823,7 @@ static int setup_pam( /* Block SIGTERM, so that we know that it won't get lost in * the child */ + if (sigemptyset(&ss) < 0 || sigaddset(&ss, SIGTERM) < 0 || sigprocmask(SIG_BLOCK, &ss, &old_ss) < 0) @@ -857,6 +858,8 @@ static int setup_pam( if (setresuid(uid, uid, uid) < 0) log_error_errno(r, "Error: Failed to setresuid() in sd-pam: %m"); + (void) ignore_signals(SIGPIPE, -1); + /* Wait until our parent died. This will only work if * the above setresuid() succeeds, otherwise the kernel * will not allow unprivileged parents kill their privileged @@ -1324,11 +1327,11 @@ static int exec_child( * others we leave untouched because we set them to * SIG_DFL or a valid handler initially, both of which * will be demoted to SIG_DFL. */ - default_signals(SIGNALS_CRASH_HANDLER, - SIGNALS_IGNORE, -1); + (void) default_signals(SIGNALS_CRASH_HANDLER, + SIGNALS_IGNORE, -1); if (context->ignore_sigpipe) - ignore_signals(SIGPIPE, -1); + (void) ignore_signals(SIGPIPE, -1); r = reset_signal_mask(); if (r < 0) { diff --git a/src/core/killall.c b/src/core/killall.c index 6e85923581..2a9d72c901 100644 --- a/src/core/killall.c +++ b/src/core/killall.c @@ -158,6 +158,7 @@ static int killall(int sig, Set *pids, bool send_sighup) { while ((d = readdir(dir))) { pid_t pid; + int r; if (d->d_type != DT_DIR && d->d_type != DT_UNKNOWN) @@ -177,8 +178,11 @@ static int killall(int sig, Set *pids, bool send_sighup) { } if (kill(pid, sig) >= 0) { - if (pids) - set_put(pids, ULONG_TO_PTR(pid)); + if (pids) { + r = set_put(pids, ULONG_TO_PTR(pid)); + if (r < 0) + log_oom(); + } } else if (errno != ENOENT) log_warning_errno(errno, "Could not kill %d: %m", pid); diff --git a/src/core/main.c b/src/core/main.c index 29ccff7b63..332453a0ea 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1405,9 +1405,8 @@ int main(int argc, char *argv[]) { } /* Reset all signal handlers. */ - assert_se(reset_all_signal_handlers() == 0); - - ignore_signals(SIGNALS_IGNORE, -1); + (void) reset_all_signal_handlers(); + (void) ignore_signals(SIGNALS_IGNORE, -1); if (parse_config_file() < 0) { error_message = "Failed to parse config file"; @@ -1931,8 +1930,8 @@ finish: /* Reenable any blocked signals, especially important * if we switch from initial ramdisk to init=... */ - reset_all_signal_handlers(); - reset_signal_mask(); + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); if (switch_root_init) { args[0] = switch_root_init; diff --git a/src/core/socket.c b/src/core/socket.c index 0239962055..d3178e642b 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -1473,8 +1473,8 @@ static int socket_chown(Socket *s, pid_t *_pid) { gid_t gid = GID_INVALID; int ret; - default_signals(SIGNALS_CRASH_HANDLER, SIGNALS_IGNORE, -1); - ignore_signals(SIGPIPE, -1); + (void) default_signals(SIGNALS_CRASH_HANDLER, SIGNALS_IGNORE, -1); + (void) ignore_signals(SIGPIPE, -1); log_forget_fds(); if (!isempty(s->user)) { diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c index a5018f13ed..5c6c7c0ed8 100644 --- a/src/cryptsetup/cryptsetup.c +++ b/src/cryptsetup/cryptsetup.c @@ -238,6 +238,23 @@ static void log_glue(int level, const char *msg, void *usrptr) { log_debug("%s", msg); } +static int disk_major_minor(const char *path, char **ret) { + struct stat st; + + assert(path); + + if (stat(path, &st) < 0) + return -errno; + + if (!S_ISBLK(st.st_mode)) + return -EINVAL; + + if (asprintf(ret, "/dev/block/%d:%d", major(st.st_rdev), minor(st.st_rdev)) < 0) + return -errno; + + return 0; +} + static char* disk_description(const char *path) { static const char name_fields[] = @@ -295,20 +312,55 @@ static char *disk_mount_point(const char *label) { return NULL; } -static int get_password(const char *name, usec_t until, bool accept_cached, char ***passwords) { - int r; +static int get_password(const char *vol, const char *src, usec_t until, bool accept_cached, char ***passwords) { + int r = 0; char **p; _cleanup_free_ char *text = NULL; _cleanup_free_ char *escaped_name = NULL; char *id; + const char *name = NULL; + _cleanup_free_ char *description = NULL, *name_buffer = NULL, + *mount_point = NULL, *maj_min = NULL; - assert(name); + assert(vol); + assert(src); assert(passwords); + description = disk_description(src); + mount_point = disk_mount_point(vol); + + if (description && streq(vol, description)) { + /* If the description string is simply the + * volume name, then let's not show this + * twice */ + free(description); + description = NULL; + } + + if (mount_point && description) + r = asprintf(&name_buffer, "%s (%s) on %s", description, vol, mount_point); + else if (mount_point) + r = asprintf(&name_buffer, "%s on %s", vol, mount_point); + else if (description) + r = asprintf(&name_buffer, "%s (%s)", description, vol); + + if (r < 0) + return log_oom(); + + name = name_buffer ? name_buffer : vol; + if (asprintf(&text, "Please enter passphrase for disk %s!", name) < 0) return log_oom(); - escaped_name = cescape(name); + if (src) + (void) disk_major_minor(src, &maj_min); + + if (maj_min) { + escaped_name = maj_min; + maj_min = NULL; + } else + escaped_name = cescape(name); + if (!escaped_name) return log_oom(); @@ -552,8 +604,7 @@ int main(int argc, char *argv[]) { unsigned tries; usec_t until; crypt_status_info status; - const char *key_file = NULL, *name = NULL; - _cleanup_free_ char *description = NULL, *name_buffer = NULL, *mount_point = NULL; + const char *key_file = NULL; /* Arguments: systemd-cryptsetup attach VOLUME SOURCE-DEVICE [PASSWORD] [OPTIONS] */ @@ -581,31 +632,6 @@ int main(int argc, char *argv[]) { /* A delicious drop of snake oil */ mlockall(MCL_FUTURE); - description = disk_description(argv[3]); - mount_point = disk_mount_point(argv[2]); - - if (description && streq(argv[2], description)) { - /* If the description string is simply the - * volume name, then let's not show this - * twice */ - free(description); - description = NULL; - } - - k = 0; - if (mount_point && description) - k = asprintf(&name_buffer, "%s (%s) on %s", description, argv[2], mount_point); - else if (mount_point) - k = asprintf(&name_buffer, "%s on %s", argv[2], mount_point); - else if (description) - k = asprintf(&name_buffer, "%s (%s)", description, argv[2]); - - if (k < 0) { - log_oom(); - goto finish; - } - name = name_buffer ? name_buffer : argv[2]; - if (arg_header) { log_debug("LUKS header: %s", arg_header); k = crypt_init(&cd, arg_header); @@ -652,7 +678,7 @@ int main(int argc, char *argv[]) { _cleanup_strv_free_ char **passwords = NULL; if (!key_file) { - k = get_password(name, until, tries == 0 && !arg_verify, &passwords); + k = get_password(argv[2], argv[3], until, tries == 0 && !arg_verify, &passwords); if (k == -EAGAIN) continue; else if (k < 0) diff --git a/src/delta/delta.c b/src/delta/delta.c index c764bb4b46..b60aaef734 100644 --- a/src/delta/delta.c +++ b/src/delta/delta.c @@ -24,6 +24,7 @@ #include <string.h> #include <unistd.h> #include <getopt.h> +#include <sys/prctl.h> #include "hashmap.h" #include "util.h" @@ -34,6 +35,7 @@ #include "strv.h" #include "process-util.h" #include "terminal-util.h" +#include "signal-util.h" static const char prefixes[] = "/etc\0" @@ -189,9 +191,14 @@ static int found_override(const char *top, const char *bottom) { if (pid < 0) return log_error_errno(errno, "Failed to fork off diff: %m"); else if (pid == 0) { + + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); + assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); + execlp("diff", "diff", "-us", "--", bottom, top, NULL); log_error_errno(errno, "Failed to execute diff: %m"); - _exit(1); + _exit(EXIT_FAILURE); } wait_for_terminate_and_warn("diff", pid, false); diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c index f0e5c5f239..30254b6680 100644 --- a/src/fsck/fsck.c +++ b/src/fsck/fsck.c @@ -394,8 +394,8 @@ int main(int argc, char *argv[]) { /* Child */ - reset_all_signal_handlers(); - reset_signal_mask(); + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); /* Close the reading side of the progress pipe */ diff --git a/src/import/export.c b/src/import/export.c index d4bc88e010..e563bee96e 100644 --- a/src/import/export.c +++ b/src/import/export.c @@ -311,7 +311,7 @@ int main(int argc, char *argv[]) { if (r <= 0) goto finish; - ignore_signals(SIGPIPE, -1); + (void) ignore_signals(SIGPIPE, -1); r = export_main(argc, argv); diff --git a/src/import/import-common.c b/src/import/import-common.c index 9711614000..950c7b4acd 100644 --- a/src/import/import-common.c +++ b/src/import/import-common.c @@ -97,8 +97,8 @@ int import_fork_tar_x(const char *path, pid_t *ret) { /* Child */ - reset_all_signal_handlers(); - reset_signal_mask(); + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); pipefd[1] = safe_close(pipefd[1]); @@ -171,8 +171,8 @@ int import_fork_tar_c(const char *path, pid_t *ret) { /* Child */ - reset_all_signal_handlers(); - reset_signal_mask(); + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); pipefd[0] = safe_close(pipefd[0]); diff --git a/src/import/import.c b/src/import/import.c index fff5a104b1..3091ed1c45 100644 --- a/src/import/import.c +++ b/src/import/import.c @@ -328,7 +328,7 @@ int main(int argc, char *argv[]) { if (r <= 0) goto finish; - ignore_signals(SIGPIPE, -1); + (void) ignore_signals(SIGPIPE, -1); r = import_main(argc, argv); diff --git a/src/import/importd.c b/src/import/importd.c index 50566a6e5c..e2df44ad26 100644 --- a/src/import/importd.c +++ b/src/import/importd.c @@ -390,8 +390,8 @@ static int transfer_start(Transfer *t) { /* Child */ - reset_all_signal_handlers(); - reset_signal_mask(); + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); pipefd[0] = safe_close(pipefd[0]); diff --git a/src/import/pull-common.c b/src/import/pull-common.c index d2588d4fa0..652277e4be 100644 --- a/src/import/pull-common.c +++ b/src/import/pull-common.c @@ -339,8 +339,8 @@ int pull_verify( /* Child */ - reset_all_signal_handlers(); - reset_signal_mask(); + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); gpg_pipe[1] = safe_close(gpg_pipe[1]); diff --git a/src/import/pull.c b/src/import/pull.c index eec4583868..03fe3dcaf4 100644 --- a/src/import/pull.c +++ b/src/import/pull.c @@ -440,7 +440,7 @@ int main(int argc, char *argv[]) { if (r <= 0) goto finish; - ignore_signals(SIGPIPE, -1); + (void) ignore_signals(SIGPIPE, -1); r = pull_main(argc, argv); diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c index 911e2a178b..ae332d826f 100644 --- a/src/journal-remote/journal-remote.c +++ b/src/journal-remote/journal-remote.c @@ -96,6 +96,10 @@ static int spawn_child(const char* child, char** argv) { /* In the child */ if (child_pid == 0) { + + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); + r = dup2(fd[1], STDOUT_FILENO); if (r < 0) { log_error_errno(errno, "Failed to dup pipe to stdout: %m"); diff --git a/src/journal/coredumpctl.c b/src/journal/coredumpctl.c index 381bf72776..fc49b2e174 100644 --- a/src/journal/coredumpctl.c +++ b/src/journal/coredumpctl.c @@ -757,6 +757,9 @@ static int run_gdb(sd_journal *j) { goto finish; } if (pid == 0) { + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); + execlp("gdb", "gdb", exe, path, NULL); log_error_errno(errno, "Failed to invoke gdb: %m"); diff --git a/src/libsystemd/libsystemd.sym.m4 b/src/libsystemd/libsystemd.sym.m4 index 0b94a87dd6..3121e71282 100644 --- a/src/libsystemd/libsystemd.sym.m4 +++ b/src/libsystemd/libsystemd.sym.m4 @@ -320,6 +320,7 @@ global: sd_bus_get_name_creds; sd_bus_get_name_machine_id; sd_bus_call_method; + sd_bus_call_method_async; sd_bus_get_property; sd_bus_get_property_trivial; sd_bus_get_property_string; diff --git a/src/libsystemd/sd-bus/bus-convenience.c b/src/libsystemd/sd-bus/bus-convenience.c index 28bc8d2818..dfd82e746d 100644 --- a/src/libsystemd/sd-bus/bus-convenience.c +++ b/src/libsystemd/sd-bus/bus-convenience.c @@ -58,6 +58,43 @@ _public_ int sd_bus_emit_signal( return sd_bus_send(bus, m, NULL); } +_public_ int sd_bus_call_method_async( + sd_bus *bus, + sd_bus_slot **slot, + const char *destination, + const char *path, + const char *interface, + const char *member, + sd_bus_message_handler_t callback, + void *userdata, + const char *types, ...) { + + _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + int r; + + assert_return(bus, -EINVAL); + assert_return(!bus_pid_changed(bus), -ECHILD); + + if (!BUS_IS_OPEN(bus->state)) + return -ENOTCONN; + + r = sd_bus_message_new_method_call(bus, &m, destination, path, interface, member); + if (r < 0) + return r; + + if (!isempty(types)) { + va_list ap; + + va_start(ap, types); + r = bus_message_append_ap(m, types, ap); + va_end(ap); + if (r < 0) + return r; + } + + return sd_bus_call_async(bus, slot, m, callback, userdata, 0); +} + _public_ int sd_bus_call_method( sd_bus *bus, const char *destination, diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c index 4fffc6581d..93ebe80b07 100644 --- a/src/libsystemd/sd-bus/bus-socket.c +++ b/src/libsystemd/sd-bus/bus-socket.c @@ -738,7 +738,8 @@ int bus_socket_exec(sd_bus *b) { if (pid == 0) { /* Child */ - reset_all_signal_handlers(); + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); close_all_fds(s+1, 1); diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c index 2b8d1b87ed..00880c983b 100644 --- a/src/libsystemd/sd-event/sd-event.c +++ b/src/libsystemd/sd-event/sd-event.c @@ -2384,7 +2384,6 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) { } r = -errno; - goto finish; } diff --git a/src/login/inhibit.c b/src/login/inhibit.c index 57cfb5d0b5..0e5dce5925 100644 --- a/src/login/inhibit.c +++ b/src/login/inhibit.c @@ -33,6 +33,7 @@ #include "strv.h" #include "formats-util.h" #include "process-util.h" +#include "signal-util.h" static const char* arg_what = "idle:sleep:shutdown"; static const char* arg_who = NULL; @@ -274,6 +275,9 @@ int main(int argc, char *argv[]) { if (pid == 0) { /* Child */ + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); + close_all_fds(NULL, 0); execvp(argv[optind], argv + optind); diff --git a/src/login/logind-user.c b/src/login/logind-user.c index 373c9938e7..c0b473930d 100644 --- a/src/login/logind-user.c +++ b/src/login/logind-user.c @@ -738,8 +738,7 @@ int user_kill(User *u, int signo) { return manager_kill_unit(u->manager, u->slice, KILL_ALL, signo, NULL); } -static bool -elect_display_filter(Session *s) { +static bool elect_display_filter(Session *s) { /* Return true if the session is a candidate for the user’s ‘primary * session’ or ‘display’. */ assert(s); @@ -747,8 +746,7 @@ elect_display_filter(Session *s) { return (s->class == SESSION_USER && !s->stopping); } -static int -elect_display_compare(Session *s1, Session *s2) { +static int elect_display_compare(Session *s1, Session *s2) { /* Indexed by SessionType. Lower numbers mean more preferred. */ const int type_ranks[_SESSION_TYPE_MAX] = { [SESSION_UNSPECIFIED] = 0, diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index 20aee53d6e..71cc722bcc 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -561,7 +561,7 @@ int dhcp4_configure(Link *link) { assert(link); assert(link->network); - assert(IN_SET(link->network->dhcp, ADDRESS_FAMILY_YES, ADDRESS_FAMILY_IPV4)); + assert(link->network->dhcp & ADDRESS_FAMILY_IPV4); r = sd_dhcp_client_new(&link->dhcp_client); if (r < 0) diff --git a/src/network/networkd-ipv4ll.c b/src/network/networkd-ipv4ll.c index 74b3dea235..14b8770429 100644 --- a/src/network/networkd-ipv4ll.c +++ b/src/network/networkd-ipv4ll.c @@ -209,7 +209,7 @@ int ipv4ll_configure(Link *link) { assert(link); assert(link->network); - assert(IN_SET(link->network->link_local, ADDRESS_FAMILY_IPV4, ADDRESS_FAMILY_YES)); + assert(link->network->link_local & ADDRESS_FAMILY_IPV4); r = sd_ipv4ll_new(&link->ipv4ll); if (r < 0) diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index f039a2d687..127bc1249a 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -40,7 +40,7 @@ bool link_dhcp6_enabled(Link *link) { if (!link->network) return false; - return IN_SET(link->network->dhcp, ADDRESS_FAMILY_IPV6, ADDRESS_FAMILY_YES); + return link->network->dhcp & ADDRESS_FAMILY_IPV6; } bool link_dhcp4_enabled(Link *link) { @@ -50,7 +50,7 @@ bool link_dhcp4_enabled(Link *link) { if (!link->network) return false; - return IN_SET(link->network->dhcp, ADDRESS_FAMILY_IPV4, ADDRESS_FAMILY_YES); + return link->network->dhcp & ADDRESS_FAMILY_IPV4; } bool link_dhcp4_server_enabled(Link *link) { @@ -70,7 +70,7 @@ bool link_ipv4ll_enabled(Link *link) { if (!link->network) return false; - return IN_SET(link->network->link_local, ADDRESS_FAMILY_IPV4, ADDRESS_FAMILY_YES); + return link->network->link_local & ADDRESS_FAMILY_IPV4; } bool link_ipv6ll_enabled(Link *link) { @@ -80,7 +80,7 @@ bool link_ipv6ll_enabled(Link *link) { if (!link->network) return false; - return IN_SET(link->network->link_local, ADDRESS_FAMILY_IPV6, ADDRESS_FAMILY_YES); + return link->network->link_local & ADDRESS_FAMILY_IPV6; } bool link_lldp_enabled(Link *link) { @@ -103,7 +103,7 @@ static bool link_ipv4_forward_enabled(Link *link) { if (!link->network) return false; - return IN_SET(link->network->ip_forward, ADDRESS_FAMILY_IPV4, ADDRESS_FAMILY_YES); + return link->network->ip_forward & ADDRESS_FAMILY_IPV4; } static bool link_ipv6_forward_enabled(Link *link) { @@ -113,7 +113,7 @@ static bool link_ipv6_forward_enabled(Link *link) { if (!link->network) return false; - return IN_SET(link->network->ip_forward, ADDRESS_FAMILY_IPV6, ADDRESS_FAMILY_YES); + return link->network->ip_forward & ADDRESS_FAMILY_IPV6; } #define FLAG_STRING(string, flag, old, new) \ diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 4211a3d779..251af4a67c 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -3656,7 +3656,8 @@ static int spawn_getent(const char *database, const char *key, pid_t *rpid) { if (nullfd > 2) safe_close(nullfd); - reset_all_signal_handlers(); + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); close_all_fds(NULL, 0); execle("/usr/bin/getent", "getent", database, key, NULL, &empty_env); @@ -4739,8 +4740,8 @@ int main(int argc, char *argv[]) { rtnl_socket_pair[0] = safe_close(rtnl_socket_pair[0]); pid_socket_pair[0] = safe_close(pid_socket_pair[0]); - reset_all_signal_handlers(); - reset_signal_mask(); + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); r = outer_child(&barrier, arg_directory, diff --git a/src/quotacheck/quotacheck.c b/src/quotacheck/quotacheck.c index a729f592cf..cf6a239402 100644 --- a/src/quotacheck/quotacheck.c +++ b/src/quotacheck/quotacheck.c @@ -23,9 +23,11 @@ #include <stdbool.h> #include <errno.h> #include <unistd.h> +#include <sys/prctl.h> #include "util.h" #include "process-util.h" +#include "signal-util.h" static bool arg_skip = false; static bool arg_force = false; @@ -105,7 +107,13 @@ int main(int argc, char *argv[]) { log_error_errno(errno, "fork(): %m"); return EXIT_FAILURE; } else if (pid == 0) { + /* Child */ + + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); + assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); + execv(cmdline[0], (char**) cmdline); _exit(1); /* Operational error */ } diff --git a/src/remount-fs/remount-fs.c b/src/remount-fs/remount-fs.c index e701fc9fae..f904e48e75 100644 --- a/src/remount-fs/remount-fs.c +++ b/src/remount-fs/remount-fs.c @@ -95,6 +95,9 @@ int main(int argc, char *argv[]) { const char *arguments[5]; /* Child */ + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); + arguments[0] = MOUNT_PATH; arguments[1] = me->mnt_dir; arguments[2] = "-o"; diff --git a/src/shared/machine-pool.c b/src/shared/machine-pool.c index d27931cb4a..8c64908b1a 100644 --- a/src/shared/machine-pool.c +++ b/src/shared/machine-pool.c @@ -109,8 +109,8 @@ static int setup_machine_raw(uint64_t size, sd_bus_error *error) { /* Child */ - reset_all_signal_handlers(); - reset_signal_mask(); + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); fd = safe_close(fd); diff --git a/src/shared/pager.c b/src/shared/pager.c index 58b62fdccf..13f03e798b 100644 --- a/src/shared/pager.c +++ b/src/shared/pager.c @@ -30,6 +30,7 @@ #include "process-util.h" #include "macro.h" #include "terminal-util.h" +#include "signal-util.h" static pid_t pager_pid = 0; @@ -85,6 +86,9 @@ int pager_open(bool jump_to_end) { if (pager_pid == 0) { const char* less_opts; + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); + dup2(fd[0], STDIN_FILENO); safe_close_pair(fd); @@ -178,6 +182,10 @@ int show_man_page(const char *desc, bool null_stdio) { if (pid == 0) { /* Child */ + + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); + if (null_stdio) { r = make_null_stdio(); if (r < 0) { diff --git a/src/shared/path-util.c b/src/shared/path-util.c index be50a1865d..537705446a 100644 --- a/src/shared/path-util.c +++ b/src/shared/path-util.c @@ -640,7 +640,7 @@ fallback_fstat: /* flags can be AT_SYMLINK_FOLLOW or 0 */ int path_is_mount_point(const char *t, int flags) { _cleanup_close_ int fd = -1; - _cleanup_free_ char *parent = NULL; + _cleanup_free_ char *canonical = NULL, *parent = NULL; int r; assert(t); @@ -648,7 +648,17 @@ int path_is_mount_point(const char *t, int flags) { if (path_equal(t, "/")) return 1; - r = path_get_parent(t, &parent); + /* we need to resolve symlinks manually, we can't just rely on + * fd_is_mount_point() to do that for us; if we have a structure like + * /bin -> /usr/bin/ and /usr is a mount point, then the parent that we + * look at needs to be /usr, not /. */ + if (flags & AT_SYMLINK_FOLLOW) { + canonical = canonicalize_file_name(t); + if (!canonical) + return -errno; + } + + r = path_get_parent(canonical ?: t, &parent); if (r < 0) return r; @@ -656,7 +666,7 @@ int path_is_mount_point(const char *t, int flags) { if (fd < 0) return -errno; - return fd_is_mount_point(fd, basename(t), flags); + return fd_is_mount_point(fd, basename(canonical ?: t), flags); } int path_is_read_only_fs(const char *path) { diff --git a/src/shared/pty.c b/src/shared/pty.c index 119d66e9a2..a87b3ce6f0 100644 --- a/src/shared/pty.c +++ b/src/shared/pty.c @@ -239,7 +239,7 @@ int pty_setup_child(Pty *pty) { assert_return(pty_is_child(pty), -EINVAL); assert_return(pty_is_open(pty), -EALREADY); - r = sigprocmask_many(SIG_SETMASK, -1); + r = reset_signal_mask(); if (r < 0) return r; diff --git a/src/shared/signal-util.c b/src/shared/signal-util.c index 9a2973b6fd..84cf42b285 100644 --- a/src/shared/signal-util.c +++ b/src/shared/signal-util.c @@ -23,13 +23,13 @@ #include "signal-util.h" int reset_all_signal_handlers(void) { + static const struct sigaction sa = { + .sa_handler = SIG_DFL, + .sa_flags = SA_RESTART, + }; int sig, r = 0; for (sig = 1; sig < _NSIG; sig++) { - static const struct sigaction sa = { - .sa_handler = SIG_DFL, - .sa_flags = SA_RESTART, - }; /* These two cannot be caught... */ if (sig == SIGKILL || sig == SIGSTOP) @@ -38,7 +38,7 @@ int reset_all_signal_handlers(void) { /* On Linux the first two RT signals are reserved by * glibc, and sigaction() will return EINVAL for them. */ if ((sigaction(sig, &sa, NULL) < 0)) - if (errno != EINVAL && r == 0) + if (errno != EINVAL && r >= 0) r = -errno; } @@ -57,83 +57,123 @@ int reset_signal_mask(void) { return 0; } +static int sigaction_many_ap(const struct sigaction *sa, int sig, va_list ap) { + int r = 0; + + /* negative signal ends the list. 0 signal is skipped. */ + + if (sig < 0) + return 0; + + if (sig > 0) { + if (sigaction(sig, sa, NULL) < 0) + r = -errno; + } + + while ((sig = va_arg(ap, int)) >= 0) { + + if (sig == 0) + continue; + + if (sigaction(sig, sa, NULL) < 0) { + if (r >= 0) + r = -errno; + } + } + + return r; +} + int sigaction_many(const struct sigaction *sa, ...) { va_list ap; - int r = 0, sig; + int r; va_start(ap, sa); - while ((sig = va_arg(ap, int)) > 0) - if (sigaction(sig, sa, NULL) < 0) - r = -errno; + r = sigaction_many_ap(sa, 0, ap); va_end(ap); return r; } int ignore_signals(int sig, ...) { + static const struct sigaction sa = { .sa_handler = SIG_IGN, .sa_flags = SA_RESTART, }; - va_list ap; - int r = 0; - if (sigaction(sig, &sa, NULL) < 0) - r = -errno; + va_list ap; + int r; va_start(ap, sig); - while ((sig = va_arg(ap, int)) > 0) - if (sigaction(sig, &sa, NULL) < 0) - r = -errno; + r = sigaction_many_ap(&sa, sig, ap); va_end(ap); return r; } int default_signals(int sig, ...) { + static const struct sigaction sa = { .sa_handler = SIG_DFL, .sa_flags = SA_RESTART, }; - va_list ap; - int r = 0; - if (sigaction(sig, &sa, NULL) < 0) - r = -errno; + va_list ap; + int r; va_start(ap, sig); - while ((sig = va_arg(ap, int)) > 0) - if (sigaction(sig, &sa, NULL) < 0) - r = -errno; + r = sigaction_many_ap(&sa, sig, ap); va_end(ap); return r; } -void sigset_add_many(sigset_t *ss, ...) { - va_list ap; - int sig; +static int sigset_add_many_ap(sigset_t *ss, va_list ap) { + int sig, r = 0; assert(ss); + while ((sig = va_arg(ap, int)) >= 0) { + + if (sig == 0) + continue; + + if (sigaddset(ss, sig) < 0) { + if (r >= 0) + r = -errno; + } + } + + return r; +} + +int sigset_add_many(sigset_t *ss, ...) { + va_list ap; + int r; + va_start(ap, ss); - while ((sig = va_arg(ap, int)) > 0) - assert_se(sigaddset(ss, sig) == 0); + r = sigset_add_many_ap(ss, ap); va_end(ap); + + return r; } int sigprocmask_many(int how, ...) { va_list ap; sigset_t ss; - int sig; + int r; - assert_se(sigemptyset(&ss) == 0); + if (sigemptyset(&ss) < 0) + return -errno; va_start(ap, how); - while ((sig = va_arg(ap, int)) > 0) - assert_se(sigaddset(&ss, sig) == 0); + r = sigset_add_many_ap(&ss, ap); va_end(ap); + if (r < 0) + return r; + if (sigprocmask(how, &ss, NULL) < 0) return -errno; diff --git a/src/shared/signal-util.h b/src/shared/signal-util.h index ddf64cda76..9dc8a28726 100644 --- a/src/shared/signal-util.h +++ b/src/shared/signal-util.h @@ -32,7 +32,7 @@ int ignore_signals(int sig, ...); int default_signals(int sig, ...); int sigaction_many(const struct sigaction *sa, ...); -void sigset_add_many(sigset_t *ss, ...); +int sigset_add_many(sigset_t *ss, ...); int sigprocmask_many(int how, ...); const char *signal_to_string(int i) _const_; diff --git a/src/shared/util.c b/src/shared/util.c index 1442301cd7..a20e7bb2ef 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -2301,8 +2301,8 @@ static int do_execute(char **directories, usec_t timeout, char *argv[]) { /* We fork this all off from a child process so that we can * somewhat cleanly make use of SIGALRM to set a time limit */ - reset_all_signal_handlers(); - reset_signal_mask(); + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); @@ -3344,8 +3344,8 @@ int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *pa /* Make sure we actually can kill the agent, if we need to, in * case somebody invoked us from a shell script that trapped * SIGTERM or so... */ - reset_all_signal_handlers(); - reset_signal_mask(); + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); /* Check whether our parent died before we were able * to set the death signal and unblock the signals */ @@ -4931,15 +4931,11 @@ int bind_remount_recursive(const char *prefix, bool ro) { while ((x = set_steal_first(todo))) { - r = set_put(done, x); - if (r == -EEXIST) { - free(x); + r = set_consume(done, x); + if (r == -EEXIST || r == 0) continue; - } - if (r < 0) { - free(x); + if (r < 0) return r; - } /* Try to reuse the original flag set, but * don't care for errors, in case of @@ -4949,15 +4945,14 @@ int bind_remount_recursive(const char *prefix, bool ro) { orig_flags &= ~MS_RDONLY; if (mount(NULL, x, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0) { + /* Deal with mount points that are * obstructed by a later mount */ - if (errno != ENOENT) { - free(x); + if (errno != ENOENT) return -errno; - } } - free(x); + } } } diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index b3d90d2c33..5075e4e176 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -5189,6 +5189,9 @@ static int enable_sysv_units(const char *verb, char **args) { else if (pid == 0) { /* Child */ + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); + execv(argv[0], (char**) argv); log_error("Failed to execute %s: %m", argv[0]); _exit(EXIT_FAILURE); @@ -5854,6 +5857,9 @@ static int run_editor(char **paths) { unsigned i = 1; size_t argc; + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); + argc = strv_length(paths)/2 + 1; args = newa(const char*, argc + 1); diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h index e6e2ecd0b7..57e46ced8e 100644 --- a/src/systemd/sd-bus.h +++ b/src/systemd/sd-bus.h @@ -299,6 +299,7 @@ int sd_bus_get_name_machine_id(sd_bus *bus, const char *name, sd_id128_t *machin /* Convenience calls */ int sd_bus_call_method(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, sd_bus_message **reply, const char *types, ...); +int sd_bus_call_method_async(sd_bus *bus, sd_bus_slot **slot, const char *destination, const char *path, const char *interface, const char *member, sd_bus_message_handler_t callback, void *userdata, const char *types, ...); int sd_bus_get_property(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, sd_bus_message **reply, const char *type); int sd_bus_get_property_trivial(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, char type, void *ret_ptr); int sd_bus_get_property_string(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, char **ret); /* free the result! */ diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c index 0045ae6824..fce4e81a09 100644 --- a/src/test/test-path-util.c +++ b/src/test/test-path-util.c @@ -312,9 +312,11 @@ static void test_prefix_root(void) { } static void test_path_is_mount_point(void) { - int fd, rt, rf, rlt, rlf; + int fd; char tmp_dir[] = "/tmp/test-path-is-mount-point-XXXXXX"; _cleanup_free_ char *file1 = NULL, *file2 = NULL, *link1 = NULL, *link2 = NULL; + _cleanup_free_ char *dir1 = NULL, *dir1file = NULL, *dirlink1 = NULL, *dirlink1file = NULL; + _cleanup_free_ char *dir2 = NULL, *dir2file = NULL; assert_se(path_is_mount_point("/", AT_SYMLINK_FOLLOW) > 0); assert_se(path_is_mount_point("/", 0) > 0); @@ -328,6 +330,19 @@ static void test_path_is_mount_point(void) { assert_se(path_is_mount_point("/sys", AT_SYMLINK_FOLLOW) > 0); assert_se(path_is_mount_point("/sys", 0) > 0); + /* we'll create a hierarchy of different kinds of dir/file/link + * layouts: + * + * <tmp>/file1, <tmp>/file2 + * <tmp>/link1 -> file1, <tmp>/link2 -> file2 + * <tmp>/dir1/ + * <tmp>/dir1/file + * <tmp>/dirlink1 -> dir1 + * <tmp>/dirlink1file -> dirlink1/file + * <tmp>/dir2/ + * <tmp>/dir2/file + */ + /* file mountpoints */ assert_se(mkdtemp(tmp_dir) != NULL); file1 = path_join(NULL, tmp_dir, "file1"); @@ -352,8 +367,43 @@ static void test_path_is_mount_point(void) { assert_se(path_is_mount_point(link1, AT_SYMLINK_FOLLOW) == 0); assert_se(path_is_mount_point(link1, 0) == 0); - /* this test will only work as root */ + /* directory mountpoints */ + dir1 = path_join(NULL, tmp_dir, "dir1"); + assert_se(dir1); + assert_se(mkdir(dir1, 0755) == 0); + dirlink1 = path_join(NULL, tmp_dir, "dirlink1"); + assert_se(dirlink1); + assert_se(symlink("dir1", dirlink1) == 0); + dirlink1file = path_join(NULL, tmp_dir, "dirlink1file"); + assert_se(dirlink1file); + assert_se(symlink("dirlink1/file", dirlink1file) == 0); + dir2 = path_join(NULL, tmp_dir, "dir2"); + assert_se(dir2); + assert_se(mkdir(dir2, 0755) == 0); + + assert_se(path_is_mount_point(dir1, AT_SYMLINK_FOLLOW) == 0); + assert_se(path_is_mount_point(dir1, 0) == 0); + assert_se(path_is_mount_point(dirlink1, AT_SYMLINK_FOLLOW) == 0); + assert_se(path_is_mount_point(dirlink1, 0) == 0); + + /* file in subdirectory mountpoints */ + dir1file = path_join(NULL, dir1, "file"); + assert_se(dir1file); + fd = open(dir1file, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC, 0664); + assert_se(fd > 0); + close(fd); + + assert_se(path_is_mount_point(dir1file, AT_SYMLINK_FOLLOW) == 0); + assert_se(path_is_mount_point(dir1file, 0) == 0); + assert_se(path_is_mount_point(dirlink1file, AT_SYMLINK_FOLLOW) == 0); + assert_se(path_is_mount_point(dirlink1file, 0) == 0); + + /* these tests will only work as root */ if (mount(file1, file2, NULL, MS_BIND, NULL) >= 0) { + int rt, rf, rlt, rlf, rl1t, rl1f; + + /* files */ + /* capture results in vars, to avoid dangling mounts on failure */ rf = path_is_mount_point(file2, 0); rt = path_is_mount_point(file2, AT_SYMLINK_FOLLOW); rlf = path_is_mount_point(link2, 0); @@ -365,6 +415,33 @@ static void test_path_is_mount_point(void) { assert_se(rt == 1); assert_se(rlf == 0); assert_se(rlt == 1); + + /* dirs */ + dir2file = path_join(NULL, dir2, "file"); + assert_se(dir2file); + fd = open(dir2file, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC, 0664); + assert_se(fd > 0); + close(fd); + + assert_se(mount(dir2, dir1, NULL, MS_BIND, NULL) >= 0); + + rf = path_is_mount_point(dir1, 0); + rt = path_is_mount_point(dir1, AT_SYMLINK_FOLLOW); + rlf = path_is_mount_point(dirlink1, 0); + rlt = path_is_mount_point(dirlink1, AT_SYMLINK_FOLLOW); + /* its parent is a mount point, but not /file itself */ + rl1f = path_is_mount_point(dirlink1file, 0); + rl1t = path_is_mount_point(dirlink1file, AT_SYMLINK_FOLLOW); + + assert_se(umount(dir1) == 0); + + assert_se(rf == 1); + assert_se(rt == 1); + assert_se(rlf == 0); + assert_se(rlt == 1); + assert_se(rl1f == 0); + assert_se(rl1t == 0); + } else printf("Skipping bind mount file test: %m\n"); diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c index 6c782b3130..f7728dcfff 100644 --- a/src/vconsole/vconsole-setup.c +++ b/src/vconsole/vconsole-setup.c @@ -37,6 +37,7 @@ #include "fileio.h" #include "process-util.h" #include "terminal-util.h" +#include "signal-util.h" static bool is_vconsole(int fd) { unsigned char data[1]; @@ -122,6 +123,10 @@ static int keyboard_load_and_wait(const char *vc, const char *map, const char *m if (pid < 0) return log_error_errno(errno, "Failed to fork: %m"); else if (pid == 0) { + + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); + execv(args[0], (char **) args); _exit(EXIT_FAILURE); } @@ -160,6 +165,10 @@ static int font_load_and_wait(const char *vc, const char *font, const char *map, if (pid < 0) return log_error_errno(errno, "Failed to fork: %m"); else if (pid == 0) { + + (void) reset_all_signal_handlers(); + (void) reset_signal_mask(); + execv(args[0], (char **) args); _exit(EXIT_FAILURE); } |