From 94edd38e1d2559f6685629eba71669ab24023c5d Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Fri, 8 Apr 2016 21:08:29 -0400 Subject: basic/util: check return value of dup2 in fork_agent() CID #1304689. --- src/basic/util.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'src/basic/util.c') diff --git a/src/basic/util.c b/src/basic/util.c index ea1bed7ceb..f1e3bd5b48 100644 --- a/src/basic/util.c +++ b/src/basic/util.c @@ -419,13 +419,17 @@ int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *pa _exit(EXIT_FAILURE); } - if (!stdout_is_tty) - dup2(fd, STDOUT_FILENO); + if (!stdout_is_tty && dup2(fd, STDOUT_FILENO) < 0) { + log_error_errno(errno, "Failed to dup2 /dev/tty: %m"); + _exit(EXIT_FAILURE); + } - if (!stderr_is_tty) - dup2(fd, STDERR_FILENO); + if (!stderr_is_tty && dup2(fd, STDERR_FILENO) < 0) { + log_error_errno(errno, "Failed to dup2 /dev/tty: %m"); + _exit(EXIT_FAILURE); + } - if (fd > 2) + if (fd > STDERR_FILENO) close(fd); } -- cgit v1.2.3-54-g00ecf From 8612da973d30c5a9530fa1b6b3d449147b5a3324 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 7 Apr 2016 16:15:26 +0200 Subject: core: be more paranoid when mixing umask and fopen() Let's be extra careful with the umask when we use simple fopen(), as this creates files with 0777 by default. --- src/basic/util.c | 4 +++- src/core/machine-id-setup.c | 3 +-- src/core/main.c | 4 +++- 3 files changed, 7 insertions(+), 4 deletions(-) (limited to 'src/basic/util.c') diff --git a/src/basic/util.c b/src/basic/util.c index f1e3bd5b48..6996527ec4 100644 --- a/src/basic/util.c +++ b/src/basic/util.c @@ -55,6 +55,7 @@ #include "string-util.h" #include "strv.h" #include "time-util.h" +#include "umask-util.h" #include "user-util.h" #include "util.h" @@ -781,7 +782,8 @@ int update_reboot_param_file(const char *param) { int r = 0; if (param) { - r = write_string_file(REBOOT_PARAM_FILE, param, WRITE_STRING_FILE_CREATE); + RUN_WITH_UMASK(0022) + r = write_string_file(REBOOT_PARAM_FILE, param, WRITE_STRING_FILE_CREATE); if (r < 0) return log_error_errno(r, "Failed to write reboot param to "REBOOT_PARAM_FILE": %m"); } else diff --git a/src/core/machine-id-setup.c b/src/core/machine-id-setup.c index 7b25349c07..86da16c31e 100644 --- a/src/core/machine-id-setup.c +++ b/src/core/machine-id-setup.c @@ -259,9 +259,8 @@ int machine_id_setup(const char *root, sd_id128_t machine_id) { /* Hmm, we couldn't write it? So let's write it to * /run/machine-id as a replacement */ - RUN_WITH_UMASK(0022) { + RUN_WITH_UMASK(0022) r = write_string_file(run_machine_id, id, WRITE_STRING_FILE_CREATE); - } if (r < 0) { (void) unlink(run_machine_id); return log_error_errno(r, "Cannot write %s: %m", run_machine_id); diff --git a/src/core/main.c b/src/core/main.c index a428e345e0..2912608435 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -81,6 +81,7 @@ #include "strv.h" #include "switch-root.h" #include "terminal-util.h" +#include "umask-util.h" #include "user-util.h" #include "virt.h" #include "watchdog.h" @@ -1237,7 +1238,8 @@ static int write_container_id(void) { if (isempty(c)) return 0; - r = write_string_file("/run/systemd/container", c, WRITE_STRING_FILE_CREATE); + RUN_WITH_UMASK(0022) + r = write_string_file("/run/systemd/container", c, WRITE_STRING_FILE_CREATE); if (r < 0) return log_warning_errno(r, "Failed to write /run/systemd/container, ignoring: %m"); -- cgit v1.2.3-54-g00ecf From 27c06cb516c3b87c34f2a1c2c227152997d05c8c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 7 Apr 2016 16:53:37 +0200 Subject: core: rework reboot parameter logic a bit Always warn if something fails, and clarify that the involved utility functions do so in their name. Drop the REBOOT_PARAM_FILE macro. We don't do this for other flag file paths like this, so don't do this for this one either. The path isn't configurable anyway, hence let's make this easier to read by avoiding this one indirection. --- src/basic/def.h | 2 -- src/basic/util.c | 26 +++++++++++++++++--------- src/basic/util.h | 2 +- src/core/failure-action.c | 14 +++++++------- src/core/shutdown.c | 7 ++++++- src/systemctl/systemctl.c | 12 +++++++++--- 6 files changed, 40 insertions(+), 23 deletions(-) (limited to 'src/basic/util.c') diff --git a/src/basic/def.h b/src/basic/def.h index 963343eb7d..1a7a0f4928 100644 --- a/src/basic/def.h +++ b/src/basic/def.h @@ -41,8 +41,6 @@ #define SIGNALS_CRASH_HANDLER SIGSEGV,SIGILL,SIGFPE,SIGBUS,SIGQUIT,SIGABRT #define SIGNALS_IGNORE SIGPIPE -#define REBOOT_PARAM_FILE "/run/systemd/reboot-param" - #ifdef HAVE_SPLIT_USR #define KBD_KEYMAP_DIRS \ "/usr/share/keymaps/\0" \ diff --git a/src/basic/util.c b/src/basic/util.c index 6996527ec4..957b0e1ff1 100644 --- a/src/basic/util.c +++ b/src/basic/util.c @@ -778,16 +778,24 @@ uint64_t physical_memory(void) { return (uint64_t) mem * (uint64_t) page_size(); } -int update_reboot_param_file(const char *param) { - int r = 0; +int update_reboot_parameter_and_warn(const char *param) { + int r; - if (param) { - RUN_WITH_UMASK(0022) - r = write_string_file(REBOOT_PARAM_FILE, param, WRITE_STRING_FILE_CREATE); - if (r < 0) - return log_error_errno(r, "Failed to write reboot param to "REBOOT_PARAM_FILE": %m"); - } else - (void) unlink(REBOOT_PARAM_FILE); + if (isempty(param)) { + if (unlink("/run/systemd/reboot-param") < 0) { + if (errno == ENOENT) + return 0; + + return log_warning_errno(errno, "Failed to unlink reboot parameter file: %m"); + } + + return 0; + } + + RUN_WITH_UMASK(0022) + r = write_string_file("/run/systemd/reboot-param", param, WRITE_STRING_FILE_CREATE); + if (r < 0) + return log_warning_errno(r, "Failed to write reboot parameter file: %m"); return 0; } diff --git a/src/basic/util.h b/src/basic/util.h index 286db05159..1c032c15c9 100644 --- a/src/basic/util.h +++ b/src/basic/util.h @@ -184,6 +184,6 @@ int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int uint64_t physical_memory(void); -int update_reboot_param_file(const char *param); +int update_reboot_parameter_and_warn(const char *param); int version(void); diff --git a/src/core/failure-action.c b/src/core/failure-action.c index d4aae4b6e7..ddae46190f 100644 --- a/src/core/failure-action.c +++ b/src/core/failure-action.c @@ -61,17 +61,17 @@ int failure_action( case FAILURE_ACTION_REBOOT: log_and_status(m, "Rebooting as result of failure."); - update_reboot_param_file(reboot_arg); - (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_REBOOT_TARGET, - JOB_REPLACE_IRREVERSIBLY, NULL); + (void) update_reboot_parameter_and_warn(reboot_arg); + (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_REBOOT_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL); break; case FAILURE_ACTION_REBOOT_FORCE: log_and_status(m, "Forcibly rebooting as result of failure."); - update_reboot_param_file(reboot_arg); + (void) update_reboot_parameter_and_warn(reboot_arg); m->exit_code = MANAGER_REBOOT; + break; case FAILURE_ACTION_REBOOT_IMMEDIATE: @@ -79,9 +79,10 @@ int failure_action( sync(); - if (reboot_arg) { + if (!isempty(reboot_arg)) { log_info("Rebooting with argument '%s'.", reboot_arg); syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, reboot_arg); + log_warning_errno(errno, "Failed to reboot with parameter, retrying without: %m"); } log_info("Rebooting."); @@ -90,8 +91,7 @@ int failure_action( case FAILURE_ACTION_POWEROFF: log_and_status(m, "Powering off as result of failure."); - (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_POWEROFF_TARGET, - JOB_REPLACE_IRREVERSIBLY, NULL); + (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_POWEROFF_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL); break; case FAILURE_ACTION_POWEROFF_FORCE: diff --git a/src/core/shutdown.c b/src/core/shutdown.c index 96679c920f..e14755d84e 100644 --- a/src/core/shutdown.c +++ b/src/core/shutdown.c @@ -397,9 +397,14 @@ int main(int argc, char *argv[]) { if (!in_container) { _cleanup_free_ char *param = NULL; - if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) { + r = read_one_line_file("/run/systemd/reboot-param", ¶m); + if (r < 0) + log_warning_errno(r, "Failed to read reboot parameter file: %m"); + + if (!isempty(param)) { log_info("Rebooting with argument '%s'.", param); syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, param); + log_warning_errno(errno, "Failed to reboot with parameter, retrying without: %m"); } } diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index b64a97375e..b1c4a84eff 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -3136,7 +3136,7 @@ static int start_special(int argc, char *argv[], void *userdata) { return r; if (a == ACTION_REBOOT && argc > 1) { - r = update_reboot_param_file(argv[1]); + r = update_reboot_parameter_and_warn(argv[1]); if (r < 0) return r; @@ -6949,7 +6949,7 @@ static int halt_parse_argv(int argc, char *argv[]) { } if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) { - r = update_reboot_param_file(argc == optind + 1 ? argv[optind] : NULL); + r = update_reboot_parameter_and_warn(argc == optind + 1 ? argv[optind] : NULL); if (r < 0) return r; } else if (optind < argc) { @@ -7450,6 +7450,7 @@ static int start_with_fallback(void) { } static int halt_now(enum action a) { + int r; /* The kernel will automaticall flush ATA disks and suchlike * on reboot(), but the file systems need to be synce'd @@ -7476,9 +7477,14 @@ static int halt_now(enum action a) { case ACTION_REBOOT: { _cleanup_free_ char *param = NULL; - if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) { + r = read_one_line_file("/run/systemd/reboot-param", ¶m); + if (r < 0) + log_warning_errno(r, "Failed to read reboot parameter file: %m"); + + if (!isempty(param)) { log_info("Rebooting with argument '%s'.", param); (void) syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, param); + log_warning_errno(errno, "Failed to reboot with parameter, retrying without: %m"); } log_info("Rebooting."); -- cgit v1.2.3-54-g00ecf From 78e334b50f12a3ef386fb5de03d0549fa853c692 Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Fri, 8 Apr 2016 22:20:22 -0400 Subject: basic/util: silence stupid gcc warnings about unitialized variable --- src/basic/util.c | 7 ++++--- src/core/machine-id-setup.c | 9 +++++---- src/core/unit.c | 9 +++++---- 3 files changed, 14 insertions(+), 11 deletions(-) (limited to 'src/basic/util.c') diff --git a/src/basic/util.c b/src/basic/util.c index 957b0e1ff1..b70c50047f 100644 --- a/src/basic/util.c +++ b/src/basic/util.c @@ -792,10 +792,11 @@ int update_reboot_parameter_and_warn(const char *param) { return 0; } - RUN_WITH_UMASK(0022) + RUN_WITH_UMASK(0022) { r = write_string_file("/run/systemd/reboot-param", param, WRITE_STRING_FILE_CREATE); - if (r < 0) - return log_warning_errno(r, "Failed to write reboot parameter file: %m"); + if (r < 0) + return log_warning_errno(r, "Failed to write reboot parameter file: %m"); + } return 0; } diff --git a/src/core/machine-id-setup.c b/src/core/machine-id-setup.c index 86da16c31e..9de528b6cf 100644 --- a/src/core/machine-id-setup.c +++ b/src/core/machine-id-setup.c @@ -259,11 +259,12 @@ int machine_id_setup(const char *root, sd_id128_t machine_id) { /* Hmm, we couldn't write it? So let's write it to * /run/machine-id as a replacement */ - RUN_WITH_UMASK(0022) + RUN_WITH_UMASK(0022) { r = write_string_file(run_machine_id, id, WRITE_STRING_FILE_CREATE); - if (r < 0) { - (void) unlink(run_machine_id); - return log_error_errno(r, "Cannot write %s: %m", run_machine_id); + if (r < 0) { + (void) unlink(run_machine_id); + return log_error_errno(r, "Cannot write %s: %m", run_machine_id); + } } /* And now, let's mount it over */ diff --git a/src/core/unit.c b/src/core/unit.c index fb88260d23..49c990c2d7 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -3480,11 +3480,12 @@ int unit_make_transient(Unit *u) { /* Let's open the file we'll write the transient settings into. This file is kept open as long as we are * creating the transient, and is closed in unit_load(), as soon as we start loading the file. */ - RUN_WITH_UMASK(0022) + RUN_WITH_UMASK(0022) { f = fopen(path, "we"); - if (!f) { - free(path); - return -errno; + if (!f) { + free(path); + return -errno; + } } if (u->transient_file) -- cgit v1.2.3-54-g00ecf From 55cdd057b9ab5190150b97ae26a6b7905595ba8a Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Wed, 27 Apr 2016 09:24:59 -0400 Subject: tree-wide: rename hidden_file to hidden_or_backup_file and optimize In standard linux parlance, "hidden" usually means that the file name starts with ".", and nothing else. Rename the function to convey what the function does better to casual readers. Stop exposing hidden_file_allow_backup which is rather ugly and rewrite hidden_file to extract the suffix first. Note that hidden_file_allow_backup excluded files with "~" at the end, which is quite confusing. Let's get rid of it before it gets used in the wrong place. --- src/basic/dirent-util.c | 4 +- src/basic/dirent-util.h | 2 +- src/basic/fd-util.c | 2 +- src/basic/fdset.c | 2 +- src/basic/path-util.c | 52 +++++++++++----------- src/basic/path-util.h | 3 +- src/basic/util.c | 2 +- src/shared/dropin.c | 2 +- .../tty-ask-password-agent.c | 2 +- 9 files changed, 35 insertions(+), 36 deletions(-) (limited to 'src/basic/util.c') diff --git a/src/basic/dirent-util.c b/src/basic/dirent-util.c index 5019882a0a..59067121b7 100644 --- a/src/basic/dirent-util.c +++ b/src/basic/dirent-util.c @@ -52,10 +52,10 @@ int dirent_ensure_type(DIR *d, struct dirent *de) { bool dirent_is_file(const struct dirent *de) { assert(de); - if (hidden_file(de->d_name)) + if (!IN_SET(de->d_type, DT_REG, DT_LNK, DT_UNKNOWN)) return false; - if (!IN_SET(de->d_type, DT_REG, DT_LNK, DT_UNKNOWN)) + if (hidden_or_backup_file(de->d_name)) return false; return true; diff --git a/src/basic/dirent-util.h b/src/basic/dirent-util.h index 6bf099b46c..b91d04908f 100644 --- a/src/basic/dirent-util.h +++ b/src/basic/dirent-util.h @@ -38,7 +38,7 @@ bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) _pu on_error; \ } \ break; \ - } else if (hidden_file((de)->d_name)) \ + } else if (hidden_or_backup_file((de)->d_name)) \ continue; \ else diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c index 3d46d708c7..9130d023d7 100644 --- a/src/basic/fd-util.c +++ b/src/basic/fd-util.c @@ -231,7 +231,7 @@ int close_all_fds(const int except[], unsigned n_except) { while ((de = readdir(d))) { int fd = -1; - if (hidden_file(de->d_name)) + if (hidden_or_backup_file(de->d_name)) continue; if (safe_atoi(de->d_name, &fd) < 0) diff --git a/src/basic/fdset.c b/src/basic/fdset.c index 06f8ecbdbc..527f27bc67 100644 --- a/src/basic/fdset.c +++ b/src/basic/fdset.c @@ -151,7 +151,7 @@ int fdset_new_fill(FDSet **_s) { while ((de = readdir(d))) { int fd = -1; - if (hidden_file(de->d_name)) + if (hidden_or_backup_file(de->d_name)) continue; r = safe_atoi(de->d_name, &fd); diff --git a/src/basic/path-util.c b/src/basic/path-util.c index 25aa355397..100e3f5af2 100644 --- a/src/basic/path-util.c +++ b/src/basic/path-util.c @@ -756,37 +756,37 @@ char *file_in_same_dir(const char *path, const char *filename) { return ret; } -bool hidden_file_allow_backup(const char *filename) { - assert(filename); - - return - filename[0] == '.' || - streq(filename, "lost+found") || - streq(filename, "aquota.user") || - streq(filename, "aquota.group") || - endswith(filename, ".rpmnew") || - endswith(filename, ".rpmsave") || - endswith(filename, ".rpmorig") || - endswith(filename, ".dpkg-old") || - endswith(filename, ".dpkg-new") || - endswith(filename, ".dpkg-tmp") || - endswith(filename, ".dpkg-dist") || - endswith(filename, ".dpkg-bak") || - endswith(filename, ".dpkg-backup") || - endswith(filename, ".dpkg-remove") || - endswith(filename, ".ucf-new") || - endswith(filename, ".ucf-old") || - endswith(filename, ".ucf-dist") || - endswith(filename, ".swp"); -} +bool hidden_or_backup_file(const char *filename) { + const char *p; -bool hidden_file(const char *filename) { assert(filename); - if (endswith(filename, "~")) + if (filename[0] == '.' || + streq(filename, "lost+found") || + streq(filename, "aquota.user") || + streq(filename, "aquota.group") || + endswith(filename, "~")) return true; - return hidden_file_allow_backup(filename); + p = strrchr(filename, '.'); + if (!p) + return false; + + return STR_IN_SET(p + 1, + "rpmnew", + "rpmsave", + "rpmorig", + "dpkg-old", + "dpkg-new", + "dpkg-tmp", + "dpkg-dist", + "dpkg-bak", + "dpkg-backup", + "dpkg-remove", + "ucf-new", + "ucf-old", + "ucf-dist", + "swp"); } bool is_device_path(const char *path) { diff --git a/src/basic/path-util.h b/src/basic/path-util.h index 34d5cd1570..a27c13fcc3 100644 --- a/src/basic/path-util.h +++ b/src/basic/path-util.h @@ -122,7 +122,6 @@ bool path_is_safe(const char *p) _pure_; char *file_in_same_dir(const char *path, const char *filename); -bool hidden_file_allow_backup(const char *filename); -bool hidden_file(const char *filename) _pure_; +bool hidden_or_backup_file(const char *filename) _pure_; bool is_device_path(const char *path); diff --git a/src/basic/util.c b/src/basic/util.c index b70c50047f..756c663be4 100644 --- a/src/basic/util.c +++ b/src/basic/util.c @@ -522,7 +522,7 @@ int on_ac_power(void) { if (!de) break; - if (hidden_file(de->d_name)) + if (hidden_or_backup_file(de->d_name)) continue; device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY); diff --git a/src/shared/dropin.c b/src/shared/dropin.c index cc1acd6f23..b9cd952ac8 100644 --- a/src/shared/dropin.c +++ b/src/shared/dropin.c @@ -160,7 +160,7 @@ static int iterate_dir( if (!de) break; - if (hidden_file(de->d_name)) + if (hidden_or_backup_file(de->d_name)) continue; f = strjoin(path, "/", de->d_name, NULL); diff --git a/src/tty-ask-password-agent/tty-ask-password-agent.c b/src/tty-ask-password-agent/tty-ask-password-agent.c index 7b67831e54..c7ded451a2 100644 --- a/src/tty-ask-password-agent/tty-ask-password-agent.c +++ b/src/tty-ask-password-agent/tty-ask-password-agent.c @@ -481,7 +481,7 @@ static int show_passwords(void) { if (de->d_type != DT_REG) continue; - if (hidden_file(de->d_name)) + if (hidden_or_backup_file(de->d_name)) continue; if (!startswith(de->d_name, "ask.")) -- cgit v1.2.3-54-g00ecf