Re: [PATCH] newrole: preserve environment variable XDG_RUNTIME_DIR

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Nicolas Iooss <nicolas.iooss@xxxxxxx> writes:

> On Wed, Jan 6, 2021 at 2:36 PM Christian Göttsche
> <cgzones@xxxxxxxxxxxxxx> wrote:
>>
>> XDG_RUNTIME_DIR is required for systemctl --user to work.
>> See https://github.com/systemd/systemd/issues/15231
>>
>> Signed-off-by: Christian Göttsche <cgzones@xxxxxxxxxxxxxx>
>> ---
>>  policycoreutils/newrole/newrole.c | 20 +++++++++++++++-----
>>  1 file changed, 15 insertions(+), 5 deletions(-)
>>
>> diff --git a/policycoreutils/newrole/newrole.c b/policycoreutils/newrole/newrole.c
>> index 36e2ba9c..500969e0 100644
>> --- a/policycoreutils/newrole/newrole.c
>> +++ b/policycoreutils/newrole/newrole.c
>> @@ -466,7 +466,7 @@ static int extract_pw_data(struct passwd *pw_copy)
>>   * Either restore the original environment, or set up a minimal one.
>>   *
>>   * The minimal environment contains:
>> - * TERM, DISPLAY and XAUTHORITY - if they are set, preserve values
>> + * TERM, DISPLAY, XAUTHORITY and XDG_RUNTIME_DIR - if they are set, preserve values
>>   * HOME, SHELL, USER and LOGNAME - set to contents of /etc/passwd
>>   * PATH - set to default value DEFAULT_PATH
>>   *
>> @@ -478,9 +478,11 @@ static int restore_environment(int preserve_environment,
>>         char const *term_env;
>>         char const *display_env;
>>         char const *xauthority_env;
>> -       char *term = NULL;      /* temporary container */
>> -       char *display = NULL;   /* temporary container */
>> +       char const *xdg_runtime_dir_env;
>> +       char *term = NULL;              /* temporary container */
>> +       char *display = NULL;           /* temporary container */
>>         char *xauthority = NULL;        /* temporary container */
>> +       char *xdg_runtime_dir = NULL;   /* temporary container */
>>         int rc;
>>
>>         environ = old_environ;
>> @@ -491,6 +493,7 @@ static int restore_environment(int preserve_environment,
>>         term_env = getenv("TERM");
>>         display_env = getenv("DISPLAY");
>>         xauthority_env = getenv("XAUTHORITY");
>> +       xdg_runtime_dir_env = getenv("XDG_RUNTIME_DIR");        /* needed for `systemd --user` operations */
>>
>>         /* Save the variable values we want */
>>         if (term_env)
>> @@ -499,8 +502,12 @@ static int restore_environment(int preserve_environment,
>>                 display = strdup(display_env);
>>         if (xauthority_env)
>>                 xauthority = strdup(xauthority_env);
>> -       if ((term_env && !term) || (display_env && !display) ||
>> -           (xauthority_env && !xauthority)) {
>> +       if (xdg_runtime_dir_env)
>> +               xdg_runtime_dir = strdup(xdg_runtime_dir_env);
>> +       if ((term_env && !term) ||
>> +           (display_env && !display) ||
>> +           (xauthority_env && !xauthority) ||
>> +           (xdg_runtime_dir_env && !xdg_runtime_dir)) {
>>                 rc = -1;
>>                 goto out;
>>         }
>> @@ -518,6 +525,8 @@ static int restore_environment(int preserve_environment,
>>                 rc |= setenv("DISPLAY", display, 1);
>>         if (xauthority)
>>                 rc |= setenv("XAUTHORITY", xauthority, 1);
>> +       if (xdg_runtime_dir)
>> +               rc |= setenv("XDG_RUNTIME_DIR", xdg_runtime_dir, 1);
>>         rc |= setenv("HOME", pw->pw_dir, 1);
>>         rc |= setenv("SHELL", pw->pw_shell, 1);
>>         rc |= setenv("USER", pw->pw_name, 1);
>> @@ -527,6 +536,7 @@ static int restore_environment(int preserve_environment,
>>         free(term);
>>         free(display);
>>         free(xauthority);
>> +       free(xdg_runtime_dir);
>>         return rc;
>>  }
>
> Hello,
> I am quite uncomfortable with this approach of keeping only one more
> variable: why is only XDG_RUNTIME_DIR added, and not also
> XDG_DATA_DIRS, XDG_SESSION_ID, XDG_SESSION_PATH, etc.? For example
> someone pointed out in
> https://github.com/systemd/systemd/issues/18301#issuecomment-763933678
> that DBUS_SESSION_BUS_ADDRESS could also need to be preserved, so
> there seem to be a long list of items.
>
> Moreover I am wondering whether this would be fine to keep such
> environment variables while newrole uses the information from another
> user (i.e. when newrole is built with USE_AUDIT and
> audit_getloginuid() != getuid() because the user changed their UID ;
> in such a situation newrole resets $HOME and $SHELL to the HOME of
> audit_getloginuid()).
>
> In my humble opinion, I also do not understand why TERM, DISPLAY and
> XAUTHORITY are kept but not LANG, LC_ALL, and all other LC_...
> variables. I understand that there exist dangerous environment
> variables (LD_LIBRARY_PATH, LD_PRELOAD, ...), that resetting the
> environment to a minimal one is nice, and that using "newrole
> --preserve-environment" could seem dangerous. For information, sudo
> has been maintaining a list of "bad" variables, of variables with
> potential dangerous values and of variables preserved by default, in
> https://github.com/sudo-project/sudo/blob/SUDO_1_9_5p1/plugins/sudoers/env.c#L134-L228.
>
> This being said, I have never really used newrole but to expose a bug
> in "sudo -r" a few years ago
> (https://bugzilla.sudo.ws/show_bug.cgi?id=611 "root user can change
> its SELinux context without password"). Since then I have always used
> sudo to change role, with the advantage that it can be configured to
> keep some environment variables, so I am not really the best reviewer
> for such a patch (and also I am a little bit confused about the
> "isolation guarantees" that newrole implements, and I am not sure
> whether keeping XDG_RUNTIME_DIR would not break such guarantees).
>
> TL;DR: can another maintainer more familiar with newrole review this
> patch, please?
>
> Thanks,
> Nicolas

I think it does not make much sense to keep XDG_RUNTIME_DIR

When you change a role, type or level, it's like changing a
linux user and it should be completely new session.

In Fedora, sysadm_t is not even allow to get status of
staff_t units:

    [staff@rawhide ~]$ echo $XDG_RUNTIME_DIR
    /run/user/1001
    [staff@rawhide ~]$ newrole -r sysadm_r
    Password: 
    [staff@rawhide ~]$ export XDG_RUNTIME_DIR=/run/user/1001
    [staff@rawhide ~]$ systemctl --user list-units
    Failed to list units: Access denied

    systemd[33326]: selinux: avc:  denied  { status } for auid=n/a uid=1001 gid=1001 cmdline="" scontext=staff_u:sysadm_r:sysadm_t:s0-s0:c0.c1023 tcontext=staff_u:staff_r:staff_t:s0-s0:c0.c1023 tclass=system permissive=0
    systemd[33326]: selinux: avc:  denied  { status } for auid=n/a uid=1001 gid=1001 cmdline="" scontext=staff_u:sysadm_r:sysadm_t:s0-s0:c0.c1023 tcontext=staff_u:staff_r:staff_t:s0-s0:c0.c1023 tclass=system permissive=0

There's also question why one would use newrole to control their a
systemd user session when it's possible to control it directly. 





[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux