]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: create per-user inaccessible node from the service manager 16543/head
authorLennart Poettering <lennart@poettering.net>
Wed, 19 Aug 2020 15:42:33 +0000 (17:42 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 20 Aug 2020 08:18:02 +0000 (10:18 +0200)
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.

src/core/main.c
src/login/user-runtime-dir.c

index 8d53c0bf85988964731fa45998dc84d58ad3ab34..4812f309f272948cc783936a36d2bdda54b84da5 100644 (file)
@@ -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)
index a56c527df8ad8e1b425a8900e7366cb01d8c70f6..c5d27b215dd7165bbf8fd1d302372b1a96728ce4 100644 (file)
@@ -49,7 +49,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);
@@ -84,7 +83,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);
@@ -99,10 +99,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: