core: apply UnsetEnvironment= after command line expansion
UnsetEnvironment= was applied to the environment block before the
command line was expanded. Since the expansion looks the variables up
in that same block, any variable listed in UnsetEnvironment= was
already gone when $VAR in ExecStart= and friends was expanded, and a
whole-word $VAR reference was dropped from the command line.
Let the expansion see the full environment block, and apply the
unsetting only to the environment block passed to the executed
process. This way UnsetEnvironment= can hide variables from the
executed process without breaking command lines that reference them.
Extend the exec-unsetenvironment test accordingly: the whole-word
$VAR6 argument must be expanded into a positional parameter for the
shell, while ${VAR6-X} must evaluate to X in the executed process.
Also document in both the UnsetEnvironment= description and the
"Environment Variables in Spawned Processes" section that the
unsetting happens after command line variable expansion.
Fixes: #43343
This commit is contained in:
+15
-12
@@ -6665,18 +6665,6 @@ int exec_invoke(
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!strv_isempty(context->unset_environment)) {
|
||||
char **ee = NULL;
|
||||
|
||||
ee = strv_env_delete(accum_env, 1, context->unset_environment);
|
||||
if (!ee) {
|
||||
*exit_status = EXIT_MEMORY;
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
strv_free_and_replace(accum_env, ee);
|
||||
}
|
||||
|
||||
_cleanup_strv_free_ char **replaced_argv = NULL, **argv_via_shell = NULL;
|
||||
char **final_argv = FLAGS_SET(command->flags, EXEC_COMMAND_VIA_SHELL) ? strv_skip(command->argv, 1) : command->argv;
|
||||
|
||||
@@ -6701,6 +6689,21 @@ int exec_invoke(
|
||||
}
|
||||
}
|
||||
|
||||
/* Apply UnsetEnvironment= after the command line has been expanded, so that the variables it
|
||||
* removes are still available for expansion. Only the environment block passed to the executed
|
||||
* process is affected, not the expansion. */
|
||||
if (!strv_isempty(context->unset_environment)) {
|
||||
char **ee = NULL;
|
||||
|
||||
ee = strv_env_delete(accum_env, 1, context->unset_environment);
|
||||
if (!ee) {
|
||||
*exit_status = EXIT_MEMORY;
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
strv_free_and_replace(accum_env, ee);
|
||||
}
|
||||
|
||||
if (FLAGS_SET(command->flags, EXEC_COMMAND_VIA_SHELL)) {
|
||||
r = strv_extendf(&argv_via_shell, "%s%s", command->argv[0][0] == '-' ? "-" : "", path);
|
||||
if (r < 0) {
|
||||
|
||||
Reference in New Issue
Block a user