-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Follow (mostly) POSIX rules for environment variables #17188
Conversation
Humpf, why? This sounds very wrong. Bash functions should stay in bash, I really don't grok why we would accept them as exported env vars? |
I'd look at it the other way around: why should we use bash rules for user variables names for anything else? Actually bash itself depends on the fact that it can export variables with names outside of this set to keep the user envvars and some other things that needs to be exported separate. Other shells have different sets of rules of what they allow as variables (I only checked |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I must say I am not a fan of this. uploading bash functions as env vars into systemd sounds like a really bad idea. I am not sure we should be a transport for something like that.
The two linked usecases seem borked to me. the first one i don#t grok at all... and the second one is strange: it appears they want to patch around in bash' environment to switch between alternatives of implementations of some tools? first of all, this switching doesn't appear to be something you want to do for bash only, if you really want to do that at all... other shells and services spawned by systemd --user probably should be covered too...
So, if they only care about bash: they can import these bash functions into their bash invocations by making them in ~/.bashrc, which would magically make them appear in all instances of bash without uploading them into anything...
if they care about user services, it appears they should use the environment generator stuff instead.
Which makes me wonder why they would need this PR?
if (!e) | ||
return false; | ||
|
||
if (n <= 0) | ||
return false; | ||
|
||
if (e[0] >= '0' && e[0] <= '9') | ||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
urks. this is a security problem... Why this? did anyone ask for this?
Please, let's sanitize data. This is expressly mentioned in POSIX to be problematic and noone asked so far to allow this, so why change this?
DIGITS LETTERS \ | ||
"_" | ||
|
||
static bool env_name_is_valid_n(const char *e, size_t n) { | ||
const char *p; | ||
static bool printable_portable_character(char c) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the function is a misnomer... the portable charset is larger...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestions? nonwhitespace_portable_character
?
src/systemctl/systemctl.c
Outdated
static void invalid_callback(const char *p, void *userdata) { | ||
_cleanup_free_ char *t = cescape(p); | ||
|
||
log_debug("Ignoring invalid environment assignment \"%s\".", strnull(t)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this really just be debug?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I used debug because on my system there's quite a few variables which we refuse to export:
Ignoring invalid environment assignment "LESS_TERMCAP_mb=\033[01;31m".
Ignoring invalid environment assignment "LESS_TERMCAP_md=\033[01;31m".
Ignoring invalid environment assignment "LESS_TERMCAP_me=\033[0m".
Ignoring invalid environment assignment "LESS_TERMCAP_se=\033[0m".
Ignoring invalid environment assignment "LESS_TERMCAP_so=\033[01;44;33m".
Ignoring invalid environment assignment "LESS_TERMCAP_ue=\033[0m".
Ignoring invalid environment assignment "LESS_TERMCAP_us=\033[01;32m".
Logging at non-debug level about all of them would be annoying. So we should either relax our rules to allow the rvalues used here, or keep logging at debug level.
So... I think the more general question is what function is the environment block in systemd is supposed to have. Is it supposed to be like
I think this is a misunderstanding. Why would a variable name with digits be relevant to security? Such variables are special in shell syntax, because of various magic variables with digits there. For that reason it'd also be awkward to require users to set or consume variables with leading digits, for example as a way to modify systemd behaviour. But once exported into the environment block, it seems to me the variable is as safe as any other. I'm not saying that using such variables is a particularly useful thing, but if a user wants to, let them knock themselves out. |
…owed There was some confusion about what POSIX says about variable names: names shall not contain the character '='. For values to be portable across systems conforming to POSIX.1-2008, the value shall be composed of characters from the portable character set (except NUL and as indicated below). i.e. it allows almost all ASCII in variable names (without NUL and DEL and '='). OTOH, it says that *utilities* use a smaller set of characters: Environment variable names used by the utilities in the Shell and Utilities volume of POSIX.1-2008 consist solely of uppercase letters, digits, and the <underscore> ( '_' ) from the characters defined in Portable Character Set and do not begin with a digit. When enforcing variable names in environment blocks, we need to use this first definition, so that we can propagate all valid variables. I think having non-printable characters in variable names is too much, so I took out the whitespace stuff from the first definition. OTOH, when we use *shell syntax*, for example doing variable expansion, it seems enough to support expansion of variables that the shell would allow. Fixes systemd#14878, https://bugzilla.redhat.com/show_bug.cgi?id=1754395, https://bugzilla.redhat.com/show_bug.cgi?id=1879216.
When doing import-environment, we shouldn't fail if some assignment is invalid. OTOH, if the invalid assignment is specified as a positional argument, we should keep failing. This would also fix https://bugzilla.redhat.com/show_bug.cgi?id=1754395, by ignoring certain variables which are not important in that scenario. It seems like the right thing to do in general.
9f323e1
to
a4ccce2
Compare
Rebased. |
I still think Lmod or whatever package actually relies on this, and uploads bash code into the env block is really just broken. They shouldn't do that, and using systemd as a conduit for such terrible things is just sad. That said, it probably is OK if we following POSIX naming rules on this, even though it's really a bad bad idea to pass potentially large pieces of bash-specific code around of this. It's conceptually a bad idea to pass literal, potentially large pieces of code around like this. I really don#t grok why the offending package thinks its fun to dirty every process' env block with large code blobs like this as if they all where bash prorgams. They should just load that into bash (via .bashrc or .bash_profile), and not everything under the sun. Summary: terrible usecase, but will merge this anyway. |
Does this mean that |
Oh, I forgot about |
… are allowed" This reverts commit b45c068. I think the idea was generally sound, but didn't take into account the limitations of show-environment and how it is used. People expect to be able to eval systemctl show-environment output in bash, and no escaping syntax is defined for environment *names* (we only do escaping for *values*). We could skip such problematic variables in 'systemctl show-environment', and only allow them to be inherited directly. But this would be confusing and ugly. The original motivation for this change was that various import operations would fail. a4ccce2 changed systemctl to filter invalid variables in import-environment. https://gitlab.gnome.org/GNOME/gnome-session/-/issues/71 does a similar change in GNOME. So those problematic variables should not cause failures, but just be silently ignored. Finally, the environment block is becoming a dumping ground. In my gnome session 'systemctl show-environment --user' includes stuff like PWD, FPATH (from zsh), SHLVL=0 (no idea what that is). This is not directly related to variable names (since all those are allowed under the stricter rules too), but I think we should start pushing people away from running import-environment and towards importing only select variables. systemd#17188 (comment)
… are allowed" This reverts commit b45c068. I think the idea was generally sound, but didn't take into account the limitations of show-environment and how it is used. People expect to be able to eval systemctl show-environment output in bash, and no escaping syntax is defined for environment *names* (we only do escaping for *values*). We could skip such problematic variables in 'systemctl show-environment', and only allow them to be inherited directly. But this would be confusing and ugly. The original motivation for this change was that various import operations would fail. a4ccce2 changed systemctl to filter invalid variables in import-environment. https://gitlab.gnome.org/GNOME/gnome-session/-/issues/71 does a similar change in GNOME. So those problematic variables should not cause failures, but just be silently ignored. Finally, the environment block is becoming a dumping ground. In my gnome session 'systemctl show-environment --user' includes stuff like PWD, FPATH (from zsh), SHLVL=0 (no idea what that is). This is not directly related to variable names (since all those are allowed under the stricter rules too), but I think we should start pushing people away from running import-environment and towards importing only select variables. systemd#17188 (comment)
… are allowed" This reverts commit b45c068. I think the idea was generally sound, but didn't take into account the limitations of show-environment and how it is used. People expect to be able to eval systemctl show-environment output in bash, and no escaping syntax is defined for environment *names* (we only do escaping for *values*). We could skip such problematic variables in 'systemctl show-environment', and only allow them to be inherited directly. But this would be confusing and ugly. The original motivation for this change was that various import operations would fail. a4ccce2 changed systemctl to filter invalid variables in import-environment. https://gitlab.gnome.org/GNOME/gnome-session/-/issues/71 does a similar change in GNOME. So those problematic variables should not cause failures, but just be silently ignored. Finally, the environment block is becoming a dumping ground. In my gnome session 'systemctl show-environment --user' includes stuff like PWD, FPATH (from zsh), SHLVL=0 (no idea what that is). This is not directly related to variable names (since all those are allowed under the stricter rules too), but I think we should start pushing people away from running import-environment and towards importing only select variables. systemd#17188 (comment)
… are allowed" This reverts commit b45c068dd8fac7661a15e99e7cf699ff06010b13. I think the idea was generally sound, but didn't take into account the limitations of show-environment and how it is used. People expect to be able to eval systemctl show-environment output in bash, and no escaping syntax is defined for environment *names* (we only do escaping for *values*). We could skip such problematic variables in 'systemctl show-environment', and only allow them to be inherited directly. But this would be confusing and ugly. The original motivation for this change was that various import operations would fail. a4ccce22d9552dc74b6916cc5ec57f2a0b686b4f changed systemctl to filter invalid variables in import-environment. https://gitlab.gnome.org/GNOME/gnome-session/-/issues/71 does a similar change in GNOME. So those problematic variables should not cause failures, but just be silently ignored. Finally, the environment block is becoming a dumping ground. In my gnome session 'systemctl show-environment --user' includes stuff like PWD, FPATH (from zsh), SHLVL=0 (no idea what that is). This is not directly related to variable names (since all those are allowed under the stricter rules too), but I think we should start pushing people away from running import-environment and towards importing only select variables. systemd/systemd#17188 (comment)
… are allowed" This reverts commit b45c068. I think the idea was generally sound, but didn't take into account the limitations of show-environment and how it is used. People expect to be able to eval systemctl show-environment output in bash, and no escaping syntax is defined for environment *names* (we only do escaping for *values*). We could skip such problematic variables in 'systemctl show-environment', and only allow them to be inherited directly. But this would be confusing and ugly. The original motivation for this change was that various import operations would fail. a4ccce2 changed systemctl to filter invalid variables in import-environment. https://gitlab.gnome.org/GNOME/gnome-session/-/issues/71 does a similar change in GNOME. So those problematic variables should not cause failures, but just be silently ignored. Finally, the environment block is becoming a dumping ground. In my gnome session 'systemctl show-environment --user' includes stuff like PWD, FPATH (from zsh), SHLVL=0 (no idea what that is). This is not directly related to variable names (since all those are allowed under the stricter rules too), but I think we should start pushing people away from running import-environment and towards importing only select variables. systemd/systemd#17188 (comment) (cherry picked from commit ff46157)
No description provided.