]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core/dbus-service: refuse bind mounting over /run/credentials/ 34020/head
authorMike Yuan <me@yhndnzj.com>
Tue, 23 Jul 2024 14:09:53 +0000 (16:09 +0200)
committerMike Yuan <me@yhndnzj.com>
Sat, 17 Aug 2024 16:16:20 +0000 (18:16 +0200)
The credential mounts should be managed singlehandedly by pid1.
Preparation for the future introduction of RefreshOnReload=credential,
where refreshing creds will be properly supported on reload.

src/core/dbus-service.c
src/core/exec-credential.c
src/core/exec-credential.h
src/core/mount.c

index d40bfab5c3b319b66f15e7ab61c1acb80011456b..8a144519086b9dd0c30f551d060411530942cea4 100644 (file)
@@ -13,6 +13,7 @@
 #include "dbus-service.h"
 #include "dbus-util.h"
 #include "execute.h"
+#include "exec-credential.h"
 #include "exit-status.h"
 #include "fd-util.h"
 #include "fileio.h"
@@ -191,6 +192,9 @@ static int bus_service_method_mount(sd_bus_message *message, void *userdata, sd_
         if (!exec_needs_mount_namespace(c, NULL, unit_get_exec_runtime(u)))
                 return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Unit not running in private mount namespace, cannot activate bind mount");
 
+        if (mount_point_is_credentials(u->manager->prefix[EXEC_DIRECTORY_RUNTIME], dest))
+                return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Refusing to bind mount over credential mounts");
+
         /* If it would be dropped at startup time, return an error. */
         if (path_startswith_strv(dest, c->inaccessible_paths))
                 return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "%s is not accessible to this unit", dest);
index 7772a929f022a265292e93d5add6dc6061b5b288..bce0ee7968e71637b15354655a5a8d7a8fe01403 100644 (file)
@@ -242,6 +242,19 @@ bool exec_context_has_encrypted_credentials(const ExecContext *c) {
         return false;
 }
 
+bool mount_point_is_credentials(const char *runtime_prefix, const char *path) {
+        const char *e;
+
+        assert(runtime_prefix);
+        assert(path);
+
+        e = path_startswith(path, runtime_prefix);
+        if (!e)
+                return false;
+
+        return path_startswith(e, "credentials");
+}
+
 static int get_credential_directory(
                 const char *runtime_prefix,
                 const char *unit,
index 88d7f715801f5caa3745133be105db734679eb7f..65c9a83b359ac9893ff299fabce791fa352169e5 100644 (file)
@@ -67,3 +67,5 @@ int exec_setup_credentials(
                 const char *unit,
                 uid_t uid,
                 gid_t gid);
+
+bool mount_point_is_credentials(const char *runtime_prefix, const char *path);
index 61aa8bb590ae74a7d6d37725a4e4d07139a178cb..3f53b2be7bcb66a088ac90442369b6071c5c781a 100644 (file)
@@ -11,6 +11,7 @@
 #include "dbus-mount.h"
 #include "dbus-unit.h"
 #include "device.h"
+#include "exec-credential.h"
 #include "exit-status.h"
 #include "format-util.h"
 #include "fs-util.h"
@@ -425,22 +426,6 @@ static bool mount_is_extrinsic(Unit *u) {
         return false;
 }
 
-static bool mount_point_is_credentials(Manager *manager, const char *path) {
-        const char *e;
-
-        assert(manager);
-        assert(path);
-
-        /* Returns true if this is a credentials mount. We don't want to generate mount units for them,
-         * since their lifetime is strictly bound to services. */
-
-        e = path_startswith(path, manager->prefix[EXEC_DIRECTORY_RUNTIME]);
-        if (!e)
-                return false;
-
-        return !isempty(path_startswith(e, "credentials"));
-}
-
 static int mount_add_default_ordering_dependencies(Mount *m, MountParameters *p, UnitDependencyMask mask) {
         const char *after, *before, *e;
         int r;
@@ -581,7 +566,7 @@ static int mount_verify(Mount *m) {
                 return log_unit_error_errno(UNIT(m), SYNTHETIC_ERRNO(ENOEXEC),
                                             "Cannot create mount unit for API file system '%s'. Refusing.", m->where);
 
-        if (mount_point_is_credentials(UNIT(m)->manager, m->where))
+        if (mount_point_is_credentials(UNIT(m)->manager->prefix[EXEC_DIRECTORY_RUNTIME], m->where))
                 return log_unit_error_errno(UNIT(m), SYNTHETIC_ERRNO(ENOEXEC),
                                             "Cannot create mount unit for credential mount '%s'. Refusing.", m->where);
 
@@ -1830,8 +1815,10 @@ static int mount_setup_unit(
         assert(fstype);
 
         /* Ignore API and credential mount points. They should never be referenced in dependencies ever.
-         * Also check the comment for mount_point_is_credentials(). */
-        if (mount_point_is_api(where) || mount_point_ignore(where) || mount_point_is_credentials(m, where))
+         * Furthermore, the lifetime of credential mounts is strictly bound to the owning services,
+         * so mount units make little sense for them. */
+        if (mount_point_is_api(where) || mount_point_ignore(where) ||
+            mount_point_is_credentials(m->prefix[EXEC_DIRECTORY_RUNTIME], where))
                 return 0;
 
         if (streq(fstype, "autofs"))