]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: verify WorkingDirectory= is outside of API VFS only under mount namespacing 33454/head
authorMike Yuan <me@yhndnzj.com>
Sun, 23 Jun 2024 16:12:33 +0000 (18:12 +0200)
committerMike Yuan <me@yhndnzj.com>
Mon, 24 Jun 2024 14:01:07 +0000 (16:01 +0200)
The purpose of the check is to prevent leaking API VFS fds
from host into a mount namespace/container. When mountns
is not used at all, the check is pointless and causes
inconvenience. E.g. file managers might need to be spawned
under those directories, and they surely won't run in mountns.

Suggested in https://github.com/systemd/systemd/pull/33454#issuecomment-2186351467
Fixes #33361

src/core/dbus-execute.c
src/core/load-fragment.c
src/core/unit.c

index 0346ee1478a52a47e3de83fdd07e053a71650e21..df5168caaf3d44e46f227b0fab503c88e7ad5948 100644 (file)
@@ -2799,10 +2799,6 @@ int bus_exec_context_set_transient_property(
                                 if (!path_is_normalized(simplified))
                                         return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS,
                                                                 "WorkingDirectory= expects a normalized path or '~'");
-
-                                if (path_below_api_vfs(simplified))
-                                        return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS,
-                                                                "WorkingDirectory= may not be below /proc/, /sys/ or /dev/");
                         }
                 }
 
index a0b20a8d919c2055f4d372609df92e437754d28e..e2a528a629fc2908a92ee741e6a1217381b1e050 100644 (file)
@@ -2635,7 +2635,8 @@ int config_parse_working_directory(
                         return missing_ok ? 0 : -ENOEXEC;
                 }
 
-                r = path_simplify_and_warn(k, PATH_CHECK_ABSOLUTE|PATH_CHECK_NON_API_VFS|(missing_ok ? 0 : PATH_CHECK_FATAL), unit, filename, line, lvalue);
+                r = path_simplify_and_warn(k, PATH_CHECK_ABSOLUTE|(missing_ok ? 0 : PATH_CHECK_FATAL),
+                                           unit, filename, line, lvalue);
                 if (r < 0)
                         return missing_ok ? 0 : -ENOEXEC;
 
index e8b32e862d7598ea6039fd6a34027a0684309136..0e931be484665549fdc5d61623c2f7216bc69845 100644 (file)
@@ -41,6 +41,7 @@
 #include "logarithm.h"
 #include "macro.h"
 #include "mkdir-label.h"
+#include "mountpoint-util.h"
 #include "path-util.h"
 #include "process-util.h"
 #include "rm-rf.h"
@@ -4224,6 +4225,10 @@ static int unit_verify_contexts(const Unit *u, const ExecContext *ec) {
         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.");
 
+        if (ec->working_directory && path_below_api_vfs(ec->working_directory) &&
+            exec_needs_mount_namespace(ec, /* params = */ NULL, /* runtime = */ NULL))
+                return log_unit_error_errno(u, SYNTHETIC_ERRNO(ENOEXEC), "WorkingDirectory= may not be below /proc/, /sys/ or /dev/ when using mount namespacing. Refusing.");
+
         return 0;
 }