core: disable mounting disconnected private tmpfs on /var/tmp/ when DefaultDependencies=no
If DefaultDependencies=no, /var/ may not be mounted yet when the service is being started. Previously, In such case, if the service has PrivateTmp=disconnected, the service manager created /var/tmp/ on the root filesystem and mounted the disconnected private tmpfs there. That poluted the root filesystem and disturbed gpt-auto-generator on next boot, as /var/ would not be empty anymore. See issue #37258. This changes PrivateTmp=disconnected as the following: - If DefaultDependencies=no and RootDirectory=/RootImage= are not set, then a private tmpfs is mounted _only_ on /tmp/, and set $TMPDIR=/tmp environment variable to suggest the service to use /tmp/. - If DefaultDependencies=yes and RootDirectory=/RootImage= are not set, then implies RequiresMountsFor=/var/, though that is typically redundant, but anyway. Hence, we can safely mount /var/tmp/. - Otherwise, i.e. when one of RootDirectory=/RootImage= is set, behaves as the same as the previous, as the private root filesystem for the service is explicitly prepared by the service manager, and we can safely mount a private tmpfs on /var/tmp/ without any extra dependencies. Fixes #37258. Co-authored-by: Mike Yuan <me@yhndnzj.com>
This commit is contained in:
+17
-1
@@ -1921,7 +1921,7 @@ static int build_environment(
|
||||
assert(cgroup_context);
|
||||
assert(ret);
|
||||
|
||||
#define N_ENV_VARS 21
|
||||
#define N_ENV_VARS 22
|
||||
our_env = new0(char*, N_ENV_VARS + _EXEC_DIRECTORY_TYPE_MAX);
|
||||
if (!our_env)
|
||||
return -ENOMEM;
|
||||
@@ -2181,6 +2181,21 @@ static int build_environment(
|
||||
our_env[n_env++] = x;
|
||||
}
|
||||
|
||||
assert(c->private_var_tmp >= 0 && c->private_var_tmp < _PRIVATE_TMP_MAX);
|
||||
if (c->private_tmp != c->private_var_tmp) {
|
||||
assert(c->private_tmp == PRIVATE_TMP_DISCONNECTED);
|
||||
assert(c->private_var_tmp == PRIVATE_TMP_NO);
|
||||
|
||||
/* When private tmpfs is enabled only on /tmp/, then explicitly set $TMPDIR to suggest the
|
||||
* service to use /tmp/. */
|
||||
|
||||
x = strdup("TMPDIR=/tmp");
|
||||
if (!x)
|
||||
return -ENOMEM;
|
||||
|
||||
our_env[n_env++] = x;
|
||||
}
|
||||
|
||||
assert(n_env < N_ENV_VARS + _EXEC_DIRECTORY_TYPE_MAX);
|
||||
#undef N_ENV_VARS
|
||||
|
||||
@@ -3589,6 +3604,7 @@ static int apply_mount_namespace(
|
||||
.private_ipc = needs_sandboxing && exec_needs_ipc_namespace(context),
|
||||
.private_pids = needs_sandboxing && exec_needs_pid_namespace(context) ? context->private_pids : PRIVATE_PIDS_NO,
|
||||
.private_tmp = needs_sandboxing ? context->private_tmp : PRIVATE_TMP_NO,
|
||||
.private_var_tmp = needs_sandboxing ? context->private_var_tmp : PRIVATE_TMP_NO,
|
||||
|
||||
.mount_apivfs = needs_sandboxing && exec_context_get_effective_mount_apivfs(context),
|
||||
.bind_log_sockets = needs_sandboxing && exec_context_get_effective_bind_log_sockets(context),
|
||||
|
||||
Reference in New Issue
Block a user