summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/dbus-execute.c4
-rw-r--r--src/core/dbus-manager.c4
-rw-r--r--src/core/exec-invoke.c24
-rw-r--r--src/core/load-fragment.c7
-rw-r--r--src/core/manager.c70
-rw-r--r--src/core/namespace.c10
-rw-r--r--src/core/unit.c9
7 files changed, 73 insertions, 55 deletions
diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
index 21c260b..b0d9402 100644
--- a/src/core/dbus-execute.c
+++ b/src/core/dbus-execute.c
@@ -2743,10 +2743,6 @@ int bus_exec_context_set_transient_property(
if (!path_is_normalized(simplified))
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS,
"WorkingDirectory= expects a normalized path or '~'");
-
- if (path_below_api_vfs(simplified))
- return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS,
- "WorkingDirectory= may not be below /proc/, /sys/ or /dev/");
}
}
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
index 2515f54..7da35a8 100644
--- a/src/core/dbus-manager.c
+++ b/src/core/dbus-manager.c
@@ -1708,6 +1708,10 @@ static int method_soft_reboot(sd_bus_message *message, void *userdata, sd_bus_er
assert(message);
+ if (!MANAGER_IS_SYSTEM(m))
+ return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED,
+ "Soft reboot is only supported by system manager.");
+
r = verify_run_space_permissive("soft reboot may fail", error);
if (r < 0)
return r;
diff --git a/src/core/exec-invoke.c b/src/core/exec-invoke.c
index ee8db04..09f98d3 100644
--- a/src/core/exec-invoke.c
+++ b/src/core/exec-invoke.c
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#include <linux/sched.h>
#include <sys/eventfd.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
@@ -44,6 +45,7 @@
#include "journal-send.h"
#include "missing_ioprio.h"
#include "missing_prctl.h"
+#include "missing_sched.h"
#include "missing_securebits.h"
#include "missing_syscall.h"
#include "mkdir-label.h"
@@ -1439,6 +1441,13 @@ static int apply_syscall_filter(const ExecContext *c, const ExecParameters *p, b
return r;
}
+ /* Sending over exec_fd or handoff_timestamp_fd requires write() syscall. */
+ if (p->exec_fd >= 0 || p->handoff_timestamp_fd >= 0) {
+ r = seccomp_filter_set_add_by_name(c->syscall_filter, c->syscall_allow_list, "write");
+ if (r < 0)
+ return r;
+ }
+
return seccomp_load_syscall_filter_set_raw(default_action, c->syscall_filter, action, false);
}
@@ -3775,7 +3784,7 @@ static int get_open_file_fd(const ExecContext *c, const ExecParameters *p, const
else if (FLAGS_SET(of->flags, OPENFILE_TRUNCATE))
flags |= O_TRUNC;
- fd = fd_reopen(ofd, flags | O_CLOEXEC);
+ fd = fd_reopen(ofd, flags|O_NOCTTY|O_CLOEXEC);
if (fd < 0)
return log_exec_error_errno(c, p, fd, "Failed to reopen file '%s': %m", of->path);
@@ -4011,7 +4020,7 @@ static int send_handoff_timestamp(
dual_timestamp dt;
dual_timestamp_now(&dt);
- if (send(p->handoff_timestamp_fd, (const usec_t[2]) { dt.realtime, dt.monotonic }, sizeof(usec_t) * 2, 0) < 0) {
+ if (write(p->handoff_timestamp_fd, (const usec_t[2]) { dt.realtime, dt.monotonic }, sizeof(usec_t) * 2) < 0) {
if (reterr_exit_status)
*reterr_exit_status = EXIT_EXEC;
return log_exec_error_errno(c, p, errno, "Failed to send handoff timestamp: %m");
@@ -4402,15 +4411,14 @@ int exec_invoke(
}
if (context->cpu_sched_set) {
- struct sched_param param = {
+ struct sched_attr attr = {
+ .size = sizeof(attr),
+ .sched_policy = context->cpu_sched_policy,
.sched_priority = context->cpu_sched_priority,
+ .sched_flags = context->cpu_sched_reset_on_fork ? SCHED_FLAG_RESET_ON_FORK : 0,
};
- r = sched_setscheduler(0,
- context->cpu_sched_policy |
- (context->cpu_sched_reset_on_fork ?
- SCHED_RESET_ON_FORK : 0),
- &param);
+ r = sched_setattr(/* pid= */ 0, &attr, /* flags= */ 0);
if (r < 0) {
*exit_status = EXIT_SETSCHEDULER;
return log_exec_error_errno(context, params, errno, "Failed to set up CPU scheduling: %m");
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index 5ae6888..a1a116a 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -2634,7 +2634,8 @@ int config_parse_working_directory(
return missing_ok ? 0 : -ENOEXEC;
}
- r = path_simplify_and_warn(k, PATH_CHECK_ABSOLUTE|PATH_CHECK_NON_API_VFS|(missing_ok ? 0 : PATH_CHECK_FATAL), unit, filename, line, lvalue);
+ r = path_simplify_and_warn(k, PATH_CHECK_ABSOLUTE|(missing_ok ? 0 : PATH_CHECK_FATAL),
+ unit, filename, line, lvalue);
if (r < 0)
return missing_ok ? 0 : -ENOEXEC;
@@ -5396,7 +5397,7 @@ int config_parse_mount_images(
continue;
}
- r = path_simplify_and_warn(sresolved, PATH_CHECK_ABSOLUTE|PATH_CHECK_NON_API_VFS, unit, filename, line, lvalue);
+ r = path_simplify_and_warn(sresolved, PATH_CHECK_ABSOLUTE|PATH_CHECK_NON_API_VFS_DEV_OK, unit, filename, line, lvalue);
if (r < 0)
continue;
@@ -5412,7 +5413,7 @@ int config_parse_mount_images(
continue;
}
- r = path_simplify_and_warn(dresolved, PATH_CHECK_ABSOLUTE|PATH_CHECK_NON_API_VFS, unit, filename, line, lvalue);
+ r = path_simplify_and_warn(dresolved, PATH_CHECK_ABSOLUTE|PATH_CHECK_NON_API_VFS_DEV_OK, unit, filename, line, lvalue);
if (r < 0)
continue;
diff --git a/src/core/manager.c b/src/core/manager.c
index 90e72b0..5997ef0 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -3086,41 +3086,43 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
default: {
- /* Starting SIGRTMIN+0 */
- static const struct {
- const char *target;
- JobMode mode;
- } target_table[] = {
- [0] = { SPECIAL_DEFAULT_TARGET, JOB_ISOLATE },
- [1] = { SPECIAL_RESCUE_TARGET, JOB_ISOLATE },
- [2] = { SPECIAL_EMERGENCY_TARGET, JOB_ISOLATE },
- [3] = { SPECIAL_HALT_TARGET, JOB_REPLACE_IRREVERSIBLY },
- [4] = { SPECIAL_POWEROFF_TARGET, JOB_REPLACE_IRREVERSIBLY },
- [5] = { SPECIAL_REBOOT_TARGET, JOB_REPLACE_IRREVERSIBLY },
- [6] = { SPECIAL_KEXEC_TARGET, JOB_REPLACE_IRREVERSIBLY },
- [7] = { SPECIAL_SOFT_REBOOT_TARGET, JOB_REPLACE_IRREVERSIBLY },
- };
-
- /* Starting SIGRTMIN+13, so that target halt and system halt are 10 apart */
- static const ManagerObjective objective_table[] = {
- [0] = MANAGER_HALT,
- [1] = MANAGER_POWEROFF,
- [2] = MANAGER_REBOOT,
- [3] = MANAGER_KEXEC,
- [4] = MANAGER_SOFT_REBOOT,
- };
-
- if ((int) sfsi.ssi_signo >= SIGRTMIN+0 &&
- (int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(target_table)) {
- int idx = (int) sfsi.ssi_signo - SIGRTMIN;
- manager_start_special(m, target_table[idx].target, target_table[idx].mode);
- break;
- }
+ if (MANAGER_IS_SYSTEM(m)) {
+ /* Starting SIGRTMIN+0 */
+ static const struct {
+ const char *target;
+ JobMode mode;
+ } target_table[] = {
+ [0] = { SPECIAL_DEFAULT_TARGET, JOB_ISOLATE },
+ [1] = { SPECIAL_RESCUE_TARGET, JOB_ISOLATE },
+ [2] = { SPECIAL_EMERGENCY_TARGET, JOB_ISOLATE },
+ [3] = { SPECIAL_HALT_TARGET, JOB_REPLACE_IRREVERSIBLY },
+ [4] = { SPECIAL_POWEROFF_TARGET, JOB_REPLACE_IRREVERSIBLY },
+ [5] = { SPECIAL_REBOOT_TARGET, JOB_REPLACE_IRREVERSIBLY },
+ [6] = { SPECIAL_KEXEC_TARGET, JOB_REPLACE_IRREVERSIBLY },
+ [7] = { SPECIAL_SOFT_REBOOT_TARGET, JOB_REPLACE_IRREVERSIBLY },
+ };
+
+ /* Starting SIGRTMIN+13, so that target halt and system halt are 10 apart */
+ static const ManagerObjective objective_table[] = {
+ [0] = MANAGER_HALT,
+ [1] = MANAGER_POWEROFF,
+ [2] = MANAGER_REBOOT,
+ [3] = MANAGER_KEXEC,
+ [4] = MANAGER_SOFT_REBOOT,
+ };
+
+ if ((int) sfsi.ssi_signo >= SIGRTMIN+0 &&
+ (int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(target_table)) {
+ int idx = (int) sfsi.ssi_signo - SIGRTMIN;
+ manager_start_special(m, target_table[idx].target, target_table[idx].mode);
+ break;
+ }
- if ((int) sfsi.ssi_signo >= SIGRTMIN+13 &&
- (int) sfsi.ssi_signo < SIGRTMIN+13+(int) ELEMENTSOF(objective_table)) {
- m->objective = objective_table[sfsi.ssi_signo - SIGRTMIN - 13];
- break;
+ if ((int) sfsi.ssi_signo >= SIGRTMIN+13 &&
+ (int) sfsi.ssi_signo < SIGRTMIN+13+(int) ELEMENTSOF(objective_table)) {
+ m->objective = objective_table[sfsi.ssi_signo - SIGRTMIN - 13];
+ break;
+ }
}
switch (sfsi.ssi_signo - SIGRTMIN) {
diff --git a/src/core/namespace.c b/src/core/namespace.c
index 6c0dc94..a9b98bc 100644
--- a/src/core/namespace.c
+++ b/src/core/namespace.c
@@ -1695,11 +1695,11 @@ static int apply_one_mount(
(void) mkdir_parents(mount_entry_path(m), 0755);
q = make_mount_point_inode_from_path(what, mount_entry_path(m), 0755);
- if (q < 0) {
- if (q != -EEXIST) // FIXME: this shouldn't be logged at LOG_WARNING, but be bubbled up, and logged there to avoid duplicate logging
- log_warning_errno(q, "Failed to create destination mount point node '%s', ignoring: %m",
- mount_entry_path(m));
- } else
+ if (q < 0 && q != -EEXIST)
+ // FIXME: this shouldn't be logged at LOG_WARNING, but be bubbled up, and logged there to avoid duplicate logging
+ log_warning_errno(q, "Failed to create destination mount point node '%s', ignoring: %m",
+ mount_entry_path(m));
+ else
try_again = true;
}
diff --git a/src/core/unit.c b/src/core/unit.c
index 2d40618..852926b 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -41,6 +41,7 @@
#include "logarithm.h"
#include "macro.h"
#include "mkdir-label.h"
+#include "mountpoint-util.h"
#include "path-util.h"
#include "process-util.h"
#include "rm-rf.h"
@@ -1405,11 +1406,13 @@ int unit_load_fragment_and_dropin(Unit *u, bool fragment_required) {
u->load_state = UNIT_LOADED;
}
+ u = unit_follow_merge(u);
+
/* Load drop-in directory data. If u is an alias, we might be reloading the
* target unit needlessly. But we cannot be sure which drops-ins have already
* been loaded and which not, at least without doing complicated book-keeping,
* so let's always reread all drop-ins. */
- r = unit_load_dropin(unit_follow_merge(u));
+ r = unit_load_dropin(u);
if (r < 0)
return r;
@@ -4234,6 +4237,10 @@ static int unit_verify_contexts(const Unit *u, const ExecContext *ec) {
if (ec->dynamic_user && ec->working_directory_home)
return log_unit_error_errno(u, SYNTHETIC_ERRNO(ENOEXEC), "WorkingDirectory=~ is not allowed under DynamicUser=yes. Refusing.");
+ if (ec->working_directory && path_below_api_vfs(ec->working_directory) &&
+ exec_needs_mount_namespace(ec, /* params = */ NULL, /* runtime = */ NULL))
+ return log_unit_error_errno(u, SYNTHETIC_ERRNO(ENOEXEC), "WorkingDirectory= may not be below /proc/, /sys/ or /dev/ when using mount namespacing. Refusing.");
+
return 0;
}