From 52d8ba71b6c1e215e1e99bd1b35c87603cbebc6b Mon Sep 17 00:00:00 2001 From: Mike Yuan Date: Sun, 26 May 2024 04:43:53 +0800 Subject: [PATCH] core: introduce unit_verify_contexts Refuse WorkingDirectory=~ both in that and exec_invoke() when dynamic user is used. --- src/core/exec-invoke.c | 3 +++ src/core/unit.c | 17 ++++++++++++++++- src/test/test-execute.c | 7 ++++++- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/core/exec-invoke.c b/src/core/exec-invoke.c index ee62ff3dd42..e88f524893c 100644 --- a/src/core/exec-invoke.c +++ b/src/core/exec-invoke.c @@ -3600,6 +3600,9 @@ static int acquire_home(const ExecContext *c, const char **home, char **ret_buf) if (!c->working_directory_home) return 0; + if (c->dynamic_user) + return -EADDRNOTAVAIL; + r = get_home_dir(ret_buf); if (r < 0) return r; diff --git a/src/core/unit.c b/src/core/unit.c index 7698f601c74..1dea0db3fe2 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -4217,6 +4217,21 @@ static int user_from_unit_name(Unit *u, char **ret) { return 0; } +static int unit_verify_contexts(const Unit *u, const ExecContext *ec) { + assert(u); + + if (!ec) + return 0; + + if (MANAGER_IS_USER(u->manager) && ec->dynamic_user) + return log_unit_error_errno(u, SYNTHETIC_ERRNO(ENOEXEC), "DynamicUser= enabled for user unit, which is not supported. Refusing."); + + 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."); + + return 0; +} + int unit_patch_contexts(Unit *u) { CGroupContext *cc; ExecContext *ec; @@ -4340,7 +4355,7 @@ int unit_patch_contexts(Unit *u) { } } - return 0; + return unit_verify_contexts(u, ec); } ExecContext *unit_get_exec_context(const Unit *u) { diff --git a/src/test/test-execute.c b/src/test/test-execute.c index 23eefcdf4b0..191741d97c2 100644 --- a/src/test/test-execute.c +++ b/src/test/test-execute.c @@ -987,6 +987,11 @@ static char* private_directory_bad(Manager *m) { } static void test_exec_dynamicuser(Manager *m) { + if (MANAGER_IS_USER(m)) { + log_notice("Skipping %s for user manager", __func__); + return; + } + _cleanup_free_ char *bad = private_directory_bad(m); if (bad) { log_warning("%s: %s has bad permissions, skipping test.", __func__, bad); @@ -998,7 +1003,7 @@ static void test_exec_dynamicuser(Manager *m) { return; } - int status = can_unshare ? 0 : MANAGER_IS_SYSTEM(m) ? EXIT_NAMESPACE : EXIT_GROUP; + int status = can_unshare ? 0 : EXIT_NAMESPACE; test(m, "exec-dynamicuser-fixeduser.service", status, CLD_EXITED); if (check_user_has_group_with_same_name("adm")) -- 2.47.3