]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: make StateDirectory= or friends works with DynamicUser= and RootDirectory=...
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 25 May 2018 08:25:17 +0000 (17:25 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 25 May 2018 08:25:17 +0000 (17:25 +0900)
The symbolic links to private directories specified by StateDirectory=
or its friends are created on the host. So, when DynamicUser= and
RootDirectory=/RootImage= are set, then the executed process cannot
access private directory.
This makes the private directories are mounted on the non-private place
when both DynamicUser= and RootDirectory=/RootImage= are set.

Fixes #8965.

src/core/execute.c

index 939bc12b565000177f87378df0b8f8a0750be7de..285fe5bf397d7aec6fc9e5565d82b0dd89b6c56c 100644 (file)
@@ -2220,7 +2220,8 @@ static int compile_bind_mounts(
                         continue;
 
                 if (context->dynamic_user &&
-                    !IN_SET(t, EXEC_DIRECTORY_RUNTIME, EXEC_DIRECTORY_CONFIGURATION)) {
+                    !IN_SET(t, EXEC_DIRECTORY_RUNTIME, EXEC_DIRECTORY_CONFIGURATION) &&
+                    !(context->root_directory || context->root_image)) {
                         char *private_root;
 
                         /* So this is for a dynamic user, and we need to make sure the process can access its own
@@ -2251,7 +2252,15 @@ static int compile_bind_mounts(
                                 goto finish;
                         }
 
-                        d = strdup(s);
+                        if (context->dynamic_user &&
+                            !IN_SET(t, EXEC_DIRECTORY_RUNTIME, EXEC_DIRECTORY_CONFIGURATION) &&
+                            (context->root_directory || context->root_image))
+                                /* When RootDirectory= or RootImage= are set, then the symbolic link to the private
+                                 * directory is not created on the root directory. So, let's bind-mount the directory
+                                 * on the 'non-private' place. */
+                                d = strjoin(params->prefix[t], "/", *suffix);
+                        else
+                                d = strdup(s);
                         if (!d) {
                                 free(s);
                                 r = -ENOMEM;