From: Mike Yuan Date: Tue, 23 Jul 2024 14:09:53 +0000 (+0200) Subject: core/dbus-service: refuse bind mounting over /run/credentials/ X-Git-Tag: v257-rc1~686^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F34020%2Fhead;p=thirdparty%2Fsystemd.git core/dbus-service: refuse bind mounting over /run/credentials/ 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. --- diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c index d40bfab5c3b..8a144519086 100644 --- a/src/core/dbus-service.c +++ b/src/core/dbus-service.c @@ -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); diff --git a/src/core/exec-credential.c b/src/core/exec-credential.c index 7772a929f02..bce0ee7968e 100644 --- a/src/core/exec-credential.c +++ b/src/core/exec-credential.c @@ -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, diff --git a/src/core/exec-credential.h b/src/core/exec-credential.h index 88d7f715801..65c9a83b359 100644 --- a/src/core/exec-credential.h +++ b/src/core/exec-credential.h @@ -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); diff --git a/src/core/mount.c b/src/core/mount.c index 61aa8bb590a..3f53b2be7bc 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -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"))