Bug 67728 - allow_active/inactive match against the active session not the active user
Summary: allow_active/inactive match against the active session not the active user
Status: RESOLVED FIXED
Alias: None
Product: PolicyKit
Classification: Unclassified
Component: daemon (show other bugs)
Version: unspecified
Hardware: Other All
: medium normal
Assignee: David Zeuthen (not reading bugmail)
QA Contact: David Zeuthen (not reading bugmail)
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-08-04 03:57 UTC by Steven Allen
Modified: 2016-10-18 01:22 UTC (History)
6 users (show)

See Also:
i915 platform:
i915 features:


Attachments

Description Steven Allen 2013-08-04 03:57:24 UTC
Currently, allow_active/inactive determine a program's privileges based on whether or not it was launched from an active session. This causes two problems:

1. Programs launched under an active session as a different user pass the allow_active/inactive tests. This problematic because launching a program under a different user is a common method for reducing privileges and one would generally not expect these programs to be given active user privileges.

2. Programs launched outside of the active session by the active user (owner of the active session) do not pass the allow_active/inactive tests. This means programs running under a user service manager (such as systemd --user) are not granted active console privileges even if the active session is owned by the same user. This makes it impossible for the active user to, for example, setup session-independent scheduled shutdowns and disk automounters (using udisks).

Here are a couple of reasonable solutions:
1. Make allow_* track the active user instead of the active session.
2. Add allow_*_user tests.
3. Have separate allow_*_user and allow_*_session tests and make allow_* a shortcut for both (best compatibility).
Comment 1 Colin Walters 2013-08-04 14:10:01 UTC
Yeah, I've been hacking on porting GNOME to systemd user@, and this came up.  I'm not so concerned about 1) - it's something where the semantics could go either way.  The right way to reduce privileges is SELinux or the like.  Basically we don't do the uid separation that Android does because we have a shared filesystem, among other things.

I don't see a problem offhand with redefining allow_active to be whether the user is active.
Comment 2 Steven Allen 2013-08-04 21:48:50 UTC
(In reply to comment #1)
> Yeah, I've been hacking on porting GNOME to systemd user@, and this came up.
> I'm not so concerned about 1) - it's something where the semantics could go
> either way.  The right way to reduce privileges is SELinux or the like. 
> Basically we don't do the uid separation that Android does because we have a
> shared filesystem, among other things.

Assuming that everyone will use the "right" (not always cut and dry) setup is generally a bad idea. For example, a user (not using systemd) could run a server under a special purpose user from his or her login session. This user would generally not expect this daemon to be able to shut his or her computer off. This is not the "right" way to do things but one would not expect it to be particularly insecure either.

While you might not use uid separation this is still the most common method for reducing privileges on servers.

However, I do agree that this is not *that* important of an issue as most (if not all) users will not be running servers from login sessions on machines that have polkit installed.

Basically this comes down to the principal of least surprise.
Comment 3 Colin Walters 2013-08-05 16:19:42 UTC
(In reply to comment #2)

> Assuming that everyone will use the "right" (not always cut and dry) setup
> is generally a bad idea. For example, a user (not using systemd) could run a
> server under a special purpose user from his or her login session. This user
> would generally not expect this daemon to be able to shut his or her
> computer off.

It's a fair point; but say we changed polkit to deny requests from uids that do not match the session owner - what would break?  Probably not much...you'd have to e.g. do sudo -u otheruser virt-manager, which is a pretty bizarre case.  Particularly if we whitelisted uid 0.
Comment 4 Miloslav Trmac 2013-08-06 21:17:34 UTC
polkit(8) clearly states "Implicit authorizations that apply to clients in {inn}active sessions on local consoles"; breaking this documented behavior is really not attractive to me.

My reading of the motivation in comment #0, especially case 2, boils down to "systemd/logind gets the tracking of active sessions wrong".


The motivation for allow_{active,inactive} is that users with physical access have same unavoidable ways to compromise the system, so letting the system services do more similar actions for them is not a problem.  Note that this principle doesn't at all depend on _which_ user has physical access; the policy is allow_active, not, say, allow_active_user_mitr, or allow_active_user_that_has_installed_this_machine.

With this in mind, if, in case 2, an active session at the physical console runs systemd --user, which starts some (sub)services, these should be treated exactly the same as any other program running within the session.


Same for case 1 - the programs have been started with an appropriately privileged users, so they have more privilege.  Yes, it might make sense to allow the user to "detach" a program from the active session in principle, but in practice I'm not sure this is really needed: an administrator using (systemctl start) to talk to the system instance of systemd will cause a service to start outside of the active session; are there real cases where one would want to start a process within a session and dissociate it?


I might very well be missing something about the systemd --user case; am I?
Comment 5 Steven Allen 2013-08-07 00:00:24 UTC
(In reply to comment #4)
> polkit(8) clearly states "Implicit authorizations that apply to clients in
> {inn}active sessions on local consoles"; breaking this documented behavior
> is really not attractive to me.

This proposal does not change this. The user performing the action must be logged into the active, local console. The only difference is that the process performing the action does not need to be a child of the active session.

> My reading of the motivation in comment #0, especially case 2, boils down to
> "systemd/logind gets the tracking of active sessions wrong".

Systemd tracks the active session correctly but allows programs to persist across sessions in under the systemd user instance.


> The motivation for allow_{active,inactive} is that users with physical
> access have same unavoidable ways to compromise the system, so letting the
> system services do more similar actions for them is not a problem.  Note
> that this principle doesn't at all depend on _which_ user has physical
> access; the policy is allow_active, not, say, allow_active_user_mitr, or
> allow_active_user_that_has_installed_this_machine.

Again, the user performing the action must still be the user sitting at the console. 

> With this in mind, if, in case 2, an active session at the physical console
> runs systemd --user, which starts some (sub)services, these should be
> treated exactly the same as any other program running within the session.
> 
> 
> Same for case 1 - the programs have been started with an appropriately
> privileged users, so they have more privilege.  Yes, it might make sense to
> allow the user to "detach" a program from the active session in principle,
> but in practice I'm not sure this is really needed: an administrator using
> (systemctl start) to talk to the system instance of systemd will cause a
> service to start outside of the active session; are there real cases where
> one would want to start a process within a session and dissociate it?

As I mentioned before, this comes down to the principal of least surprise. A real world use case is someone running a custom server (under a different user) from their login session because they are too lazy/don't know how to set it up correctly. While this isn't a good setup, as a user, I wouldn't expect this server to inherit my ability to shut the computer down.

> I might very well be missing something about the systemd --user case; am I?

Just to clarify, systemd --user is launched by systemd when a user first logs in but does not run under the login session. It's purpose (unless I am mistaken) is to run programs that should span multiple sessions and should only be run once per user.

As for my actual, real-world use case, I run tmux under systemd --user so that a single tmux server can cleanly span multiple sessions. However, if I try to issue a privileged command under a tmux session it fails because the tmux server is running under systemd --user which is not running under the current session.
Comment 6 Colin Walters 2013-08-07 14:03:48 UTC
A patch for policykit exists here:

https://people.gnome.org/~walters/user-session-patches/

Along with lots of other things to make GNOME launch using systemd --user.  I'm not attaching the polkit patch here because it depends on (currently) non-upstream systemd API, and the design might still be changed.

(But please do try the patches!)
Comment 7 Steven Allen 2013-08-07 14:30:11 UTC
(In reply to comment #6)
> A patch for policykit exists here:
> 
> https://people.gnome.org/~walters/user-session-patches/
> 
> Along with lots of other things to make GNOME launch using systemd --user. 
> I'm not attaching the polkit patch here because it depends on (currently)
> non-upstream systemd API, and the design might still be changed.
> 
> (But please do try the patches!)

I've seen them but I still don't understand the point of having a primary session. The only reason I can think of is prompting the user. If that is the case, shouldn't you just prompt all (active?) sessions and take the first answer?

Also, your xorg patches are interesting but will break things that use DISPLAY to determine if they are running under X. Another approach is to add a special "primary" or "systemd" DISPLAY value. This would be consistent Xorg's current launchd support.
Comment 8 Simon McVittie 2015-03-31 07:57:41 UTC
See also Bug #76358.
Comment 9 Simon McVittie 2015-03-31 08:07:43 UTC
(In reply to Steven Allen from comment #0)
> 1. Programs launched under an active session as a different user pass the
> allow_active/inactive tests.

Doing as requested on Bug #76358 would solve this.

> 2. Programs launched outside of the active session by the active user (owner
> of the active session) do not pass the allow_active/inactive tests.

Closing Bug #78905 has sort of half solved this, by associating non-session-bound programs with the graphical session if there is one.

Doing as requested on Bug #76358 would fully solve this.

> 1. Make allow_* track the active user instead of the active session.

That's what Lennart proposes on Bug #76358.

(In reply to Miloslav Trmac from comment #4)
> My reading of the motivation in comment #0, especially case 2, boils down to
> "systemd/logind gets the tracking of active sessions wrong".

systemd --user cannot be part of a particular session, because its lifetime is allowed to be longer than the lifetime of the session for which it was started. It is defined to have the same lifetime as a set of overlapping sessions:

    ==> increasing time

    |----- GUI session on tty7 -------|
         |----- text session on tty1 ----|
                                             |----- GUI session on tty8 ----|
    |------- systemd --user -------------|   |-------- systemd --user ------|

(assume all those sessions are for the same uid)
Comment 10 Simon McVittie 2015-03-31 08:15:24 UTC
(In reply to Miloslav Trmac from comment #4)
> The motivation for allow_{active,inactive} is that users with physical
> access have same unavoidable ways to compromise the system, so letting the
> system services do more similar actions for them is not a problem.

Indeed. However, in the absence of doing fancy things with LSMs, non-session processes belonging to uid smcv can subvert session processes belonging to uid smcv (e.g. ptrace them, or edit their configuration files to tell them to run a different shell command for something); so my non-session processes are just as privileged as my session processes, and if my session processes are able to mount removable disks, shut down the system, etc., on this (entirely reasonable) basis, then so are my non-session processes. It does not seem particularly productive for polkit to behave as if this was not true.

(If you *are* doing fancy things with LSMs, then you can also use them to control D-Bus access to system services, preventing polkit from needing to get involved - dbus-daemon currently has support for doing that via either SELinux or AppArmor.)
Comment 11 Steven Allen 2016-10-18 01:22:09 UTC
This appears to have been fixed in 0.113.


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.