summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2020-08-19 17:42:33 +0200
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2020-09-02 11:49:08 +0200
commitdc2e82af332b39a2dc615b5f29220df22dfe4e77 (patch)
tree916da1703823c3214b467dcb65c1614311afa667
parent0b3c497347028bbcc3c6f911967c205b6d0f275f (diff)
downloadsystemd-246.4.tar.gz
core: create per-user inaccessible node from the service managerv246.4
Previously, we'd create them from user-runtime-dir@.service. That has one benefit: since this service runs privileged, we can create the full set of device nodes. It has one major drawback though: it security-wise problematic to create files/directories in directories as privileged user in directories owned by unprivileged users, since they can use symlinks to redirect what we want to do. As a general rule we hence avoid this logic: only unpriv code should populate unpriv directories. Hence, let's move this code to an appropriate place in the service manager. This means we lose the inaccessible block device node, but since there's already a fallback in place, this shouldn't be too bad. (cherry picked from commit 3242980582d501ec2adbcc0f794c7161056812e8)
-rw-r--r--src/core/main.c16
-rw-r--r--src/login/user-runtime-dir.c8
2 files changed, 18 insertions, 6 deletions
diff --git a/src/core/main.c b/src/core/main.c
index 4a376976e9..9a834a875e 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -32,6 +32,7 @@
#include "dbus-manager.h"
#include "dbus.h"
#include "def.h"
+#include "dev-setup.h"
#include "efi-random.h"
#include "efivars.h"
#include "emergency-action.h"
@@ -53,6 +54,7 @@
#include "loopback-setup.h"
#include "machine-id-setup.h"
#include "manager.h"
+#include "mkdir.h"
#include "mount-setup.h"
#include "os-util.h"
#include "pager.h"
@@ -2073,6 +2075,20 @@ static int initialize_runtime(
if (r < 0)
log_warning_errno(r, "Failed to set watchdog device to %s, ignoring: %m", arg_watchdog_device);
}
+ } else {
+ _cleanup_free_ char *p = NULL;
+
+ /* Create the runtime directory and place the inaccessible device nodes there, if we run in
+ * user mode. In system mode mount_setup() already did that. */
+
+ r = xdg_user_runtime_dir(&p, "/systemd");
+ if (r < 0) {
+ *ret_error_message = "$XDG_RUNTIME_DIR is not set";
+ return log_emergency_errno(r, "Failed to determine $XDG_RUNTIME_DIR path: %m");
+ }
+
+ (void) mkdir_p(p, 0755);
+ (void) make_inaccessible_nodes(p, UID_INVALID, GID_INVALID);
}
if (arg_timer_slack_nsec != NSEC_INFINITY)
diff --git a/src/login/user-runtime-dir.c b/src/login/user-runtime-dir.c
index fcddbc7df6..03c60f90b3 100644
--- a/src/login/user-runtime-dir.c
+++ b/src/login/user-runtime-dir.c
@@ -54,7 +54,6 @@ static int user_mkdir_runtime_path(
uint64_t runtime_dir_size,
uint64_t runtime_dir_inodes) {
- const char *p;
int r;
assert(runtime_path);
@@ -89,7 +88,8 @@ static int user_mkdir_runtime_path(
goto fail;
}
- log_debug_errno(errno, "Failed to mount per-user tmpfs directory %s.\n"
+ log_debug_errno(errno,
+ "Failed to mount per-user tmpfs directory %s.\n"
"Assuming containerized execution, ignoring: %m", runtime_path);
r = chmod_and_chown(runtime_path, 0700, uid, gid);
@@ -104,10 +104,6 @@ static int user_mkdir_runtime_path(
log_warning_errno(r, "Failed to fix label of \"%s\", ignoring: %m", runtime_path);
}
- /* Set up inaccessible nodes now so they're available if we decide to use them with user namespaces. */
- p = strjoina(runtime_path, "/systemd");
- (void) mkdir(p, 0755);
- (void) make_inaccessible_nodes(p, uid, gid);
return 0;
fail: