Bug 89501

Summary: rules for devices on this seat / other seat interact poorly with systemd user-sessions
Product: udisks Reporter: Simon McVittie <smcv>
Component: generalAssignee: Martin Pitt <martin.pitt>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: medium CC: bugzilla
Version: unspecified   
Hardware: Other   
OS: All   
Whiteboard:
i915 platform: i915 features:
Attachments: Decide whether devices are on the same seat by uid, not pid

Description Simon McVittie 2015-03-09 12:27:11 UTC
This is Debian bug <https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=780004>. I'm about to write to the udisks mailing list to check my assumptions.

Background
----------

In systemd user sessions, some of a user's processes can exist outside
the scope of any particular login session:

└─user.slice
  └─user-1000.slice
    ├─user@1000.service
    │ ├─2089 /lib/systemd/systemd --user
    │ └─dbus.service
    │   ├─ 2233 /usr/bin/dbus-daemon …
    │   ├─ 2297 /usr/lib/gvfs/gvfsd
    │   …
    └─session-2.scope
      ├─ 2102 gnome-session
      ├─ 2376 /usr/bin/gnome-shell
      …

This model is currently a non-default opt-in thing if you use dbus-daemon: you have to either use dbus 1.9.x and --enable-user-session, or install third-party bits and pieces like user-session-units, or install the dbus-user-session binary package in Debian or its derivatives. However, I hope to make it the default one day, and it is the only model supported by kdbus. The systemd/kdbus developers have indicated that they have no interest in supporting the traditional "D-Bus session bus per login session" model.

If processes outside login sessions don't have access to devices on those login sessions' seats, then gvfsd won't be able to mount devices. Conversely, there is no privilege boundary between the login sessions  and the same user's non-login-session processes - in particular, the user's processes can usually ptrace each other and write to each other's configuration files - so isolating them doesn't make a great deal of sense.

How udisks works now
--------------------

udisks currently has this pseudocode to determine whether I may mount a device, and similar logic for other operations:

    let requesting_seat = requesting process->login_session->seat
    let device_seat = device->seat
    if (device_seat && requesting_seat &&
            requesting_seat == device_seat) {
        use a polkit rule like org.freedesktop.udisks2.filesystem-mount
            (by default, requires either an active login session or
            admin authentication)
    } else {
        use a polkit rule like
        org.freedesktop.udisks2.filesystem-mount-other-seat
            (by default, requires admin authentication regardless)
    }

However, that breaks down for the user-session model: in particular, shared processes like gvfsd live outside the scope of any particular login session. When gnome-disks asks gvfsd to ask udisks to mount a disk, udisks sees that the request came from gvfsd, sees that gvfsd is not in a login session, and uses the more strictly-controlled filesystem-mount-other-seat action. The practical result is that I can't mount removable media without entering my password.

How I propose it should work
----------------------------

I propose to change it to this pseudocode, for which I'm developing a patch:

    let device_seat = device->seat

    if (device_seat) {
        let active_sessions = requesting uid's active login sessions

        foreach session in active_sessions {
            if session->seat && session->seat == device_seat {
                use a polkit rule like
                    org.freedesktop.udisks2.filesystem-mount
                return
            }
        }
    }

    use a polkit rule like
        org.freedesktop.udisks2.filesystem-mount-other-seat

I'm specifically looking for one or more *active* sessions on the device's seat because in a situation like this:

…
├─ alice
│  ├─ graphical session on seat0, tty7, active
│  └─ system --user
├─ bob
│  ├─ graphical session on seat0, tty8, inactive
│  ├─ graphical session on seat1, active
│  └─ systemd --user
└─ chris
   ├─ ssh session on no seat, active
   └─ systemd --user

I think the desired behaviour is that alice controls seat0 devices and bob controls seat1 devices, corresponding to their respective physically-present locations; bob should not have control over seat0 devices until he returns to seat0, and chris should not have control over either.
Comment 1 Simon McVittie 2015-03-09 12:36:12 UTC
Created attachment 114161 [details] [review]
Decide whether devices are on the same seat by uid, not pid

(long commit message omitted here, see the actual patch)

---

This is what I propose to do if my assumptions are correct. This is a respin of the patch on the Debian bug, correcting some minor things my colleague Philip Withnall spotted: I'll test this one next.
Comment 2 Simon McVittie 2015-03-11 12:55:13 UTC
(In reply to Simon McVittie from comment #1)
> This is what I propose to do if my assumptions are correct. This is a respin
> of the patch on the Debian bug, correcting some minor things my colleague
> Philip Withnall spotted: I'll test this one next.

That patch appears to work fine, so I would very much appreciate an opinion on whether this is the right direction to be going / a reasonable representation of udisks' security model, even if there isn't time for a detailed review of the implementation right now.
Comment 3 Simon McVittie 2015-03-31 11:34:20 UTC
See also Bug #76358, which is a similar thing in polkit, and David Hermann's message at <http://lists.freedesktop.org/archives/systemd-devel/2015-March/029322.html>.

Based on David's feedback, I'm going to ship this patch in Debian soon, unless someone from udisks has a reason to veto it.
Comment 4 Martin Pitt 2015-06-30 05:53:41 UTC
Sorry for the delay! I agree that this makes sense in an user bus world, and I don't see a realistic breakage in the session bus world too. Applied, thanks!

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.