Allow ubuntu-system-settings to set a device's firmware

Bug #1426923 reported by Jonas G. Drange
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
lxc-android-config (Ubuntu)
Fix Released
High
Alfonso Sanchez-Beato

Bug Description

Background:
To do Wi-Fi hotspots on krillin, we need to poke wifi by doing a call to wpa_supplicant's (undocumented/local) SetInterfaceFirmware method. See [1] for details.

Rationale:
Ubuntu System Settings needs to do the same things as aforementioned script, but via dbus [2], as phablet/current non-privileged user and unconfined.

What happens:
If phablet runs [2], this error message [3] is produced, which I interpret to be equivalent with "you're not welcome here".

What should happen instead:
Ubuntu System Settings should be able to make the call to wpa.

[1] http://bazaar.launchpad.net/~mathieu-tl/+junk/touch-hotspot/view/head:/hotspot.py
[2] gdbus call --system -d fi.w1.wpa_supplicant1 -o /fi/w1/wpa_supplicant1 -m fi.w1.wpa_supplicant1.SetInterfaceFirmware / ap
[3] http://pastebin.ubuntu.com/10489519/

description: updated
no longer affects: dbus (Ubuntu)
Revision history for this message
Jonas G. Drange (jonas-drange) wrote :

I'm currently only succeeding with the following policy:

        <policy user="jonas">
                <allow send_destination="fi.w1.wpa_supplicant1"/>
                <allow receive_sender="fi.w1.wpa_supplicant1"/>
        </policy>

Being more specific, e.g. adding interface and send_member, gives me errors that I should not get: Error: GDBus.Error:org.freedesktop.DBus.Error.InvalidArgs: Error return with empty body:

Do we have to blanket OK phablet's access to fi.w1.wpa_supplicant1?

description: updated
Revision history for this message
Jamie Strandboge (jdstrand) wrote :

Jonas asked me to take a look at the security implications of this. Some observations:
* on touch, /var/lib/polkit-1/localauthority/10-vendor.d/com.ubuntu.touch.NetworkManager.pkla allows anyone in the 'sudo' group to access all of NetworkManager. This is not ideal but was the decision taken while we don't have proper PK support on the phone
* /usr/share/polkit-1/actions/org.freedesktop.urfkill.policy allows the active seat to call Block. This is probably more permissive than it has to be, but would need someone familiar with urfkill to comment
* wpasupplicant (from the 'wpa' source package) ships /etc/dbus-1/system.d/wpa_supplicant.conf and it by default disallows all connections by non-root
* wpasupplicant does not ship a policykit file and doesn't seem to have policykit support
* http://bazaar.launchpad.net/~mathieu-tl/+junk/touch-hotspot/view/head:/hotspot.py only uses wpas.SetInterfaceFirmware("/", "ap") - I think there might be a bug here: shouldn't disable() put it back to what it was before calling enable()?
* wpas_dbus_handler_set_interface_firmware() from wpa_supplicant/dbus/dbus_new_handlers.c has good input validation and only allows setting "ap", "sta" and "p2p" and nothing else

Considering the current policy with NM and the phablet user on Touch, I think it is tolerable to give the phablet user the ability to use SetInterfaceFirmware(). As I see it, there are two paths forward (not listed in any particular order):
1. add policykit support to wpasupplicant, ship a policykit policy file that is very strict, then override on touch similar to how we do in /var/lib/polkit-1/localauthority/10-vendor.d/com.ubuntu.touch.NetworkManager.pkla, but only for SetInterfaceFirmware()
2. use a proxy service that runs as root on the system bus that can make this call on our behalf. This proxy service could be written from scratch, extend NetworkManager, use the connectivity-api, or something else

I think '2' is the path of least resistance. It probably makes sense to use something like connectivity-api and have it have methods like: SetAP(), SetSTA(), SetP2P(), each of which talks to wpasupplicant. I suggest talking to the connectivity-api folks for ideas on API and where to best put this.

Changed in wpasupplicant (Ubuntu):
status: New → Invalid
summary: - Allow ubuntu-system-settings to set a device's firmware through
- wpa_supplicant
+ Allow ubuntu-system-settings to set a device's firmware through the
+ private Connectivity API
description: updated
Revision history for this message
Tony Espy (awe) wrote : Re: Allow ubuntu-system-settings to set a device's firmware through the private Connectivity API

Thanks for the feedback Jamie!

A couple of comments in return...

1. NetworkManager polkit allows full access to sudo: I assume you meant that the decision was taken *before* we had proper polkit support on the phone?

2. urfkill polkit - allows active seat to call Block: The policy also allows BlockIdx ( ie. by index, whereas Block is by type ), and FlightMode by the active seat. How is this more permissive than needed? I'm not familiar enough with polkit to grok how this could be made more restrictive?

3. Regarding your proposed solution, why is polkit necessary when all non-system processes that run as 'phablet' are confined ( ie. can't make raw DBus calls anyways )?

4. Do you really think that adding polkit support to wpa_supplicant for a single DBus method is more work than creating a new proxy service? Also, I assume the proxy service would handle the polkit logic, and then fwd the call(s)?

-

Revision history for this message
Jamie Strandboge (jdstrand) wrote :

Yikes, sorry for just getting back to this now.

"1. NetworkManager polkit allows full access to sudo: I assume you meant that the decision was taken *before* we had proper polkit support on the phone?"

AFAIK, we don't have polkit prompting on the phone still. It doesn't really matter-- we don't want to go that route anyway because it is a poor user experience.

"2. urfkill polkit - allows active seat to call Block: The policy also allows BlockIdx ( ie. by index, whereas Block is by type ), and FlightMode by the active seat. How is this more permissive than needed? I'm not familiar enough with polkit to grok how this could be made more restrictive?"

I am not familiar with what Block and BlockIdx are supposed to do (which is why having someone more familiar like yourself comment is great :), but will trust your judgement that active seat is fine for these. FlightMode for active seat seems fine.

"3. Regarding your proposed solution, why is polkit necessary when all non-system processes that run as 'phablet' are confined ( ie. can't make raw DBus calls anyways )?"

It is true that click apps are confined and we have DBus mediation which will block access to wpasupplicant. Those aren't the problem. I'm concerned about the other things that run as the phablet user that are not click apps that are unconfined and providing security in depth. With polkit, we can make sure that just SetInterfaceFirmware() is available to the active seat and deny all others (the intended policy from /etc/dbus-1/system.d/wpa_supplicant.conf is to only allow root processes to talk to wpasupplicant over DBus-- changing this policy may break assumptions in the implementation and introduce security issues. I'm ok poking a hole for SetInterfaceFirmware() (through the use of polkit, leaving the defaults as they are but then adding an override in /var/lib/polkit-1/localauthority/10-vendor.d/... for SetInterfaceFirmware() on Touch), but not ok with opening all of wpasupplicant to the phablet user.

"4. Do you really think that adding polkit support to wpa_supplicant for a single DBus method is more work than creating a new proxy service? Also, I assume the proxy service would handle the polkit logic, and then fwd the call(s)?"

I was leaving the choice of what was easier up to you. We control connectivity-api but don't control wpasupplicant. My thinking was perhaps there are other hotspot related items that could be used in the proxy service instead of patches multiple sources and I was suggesting using the existing connectivity-api service to add a single API call for this. Eg, /com/ubuntu/connectivity1/Something. I looked at this a bit just now and it seems that the com.ubuntu.connectivity1 service is a session service implemented in network-indicator, which runs as phablet, which means that you won't save any time using connectivity-api since you'd have to still do the polkit stuff for wpasupplicant to poke a hole for SetInterfaceFirmware().

I'll leave whether to use connectivity-api for API design reasons up to you as an implementation detail.

no longer affects: indicator-network (Ubuntu)
summary: - Allow ubuntu-system-settings to set a device's firmware through the
- private Connectivity API
+ Allow ubuntu-system-settings to set a device's firmware
description: updated
Changed in wpasupplicant (Ubuntu):
status: Invalid → Confirmed
Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

Adding

        <policy user="phablet">
                <allow send_destination="fi.w1.wpa_supplicant1"
                       send_interface="org.freedesktop.DBus.Introspectable"
                       send_member="Introspect"
                       send_type="method_call"
                       send_path="/fi/w1/wpa_supplicant1"/>
                <allow receive_sender="fi.w1.wpa_supplicant1"
                       receive_type="method_return"/>
                <allow send_destination="fi.w1.wpa_supplicant1"
                       send_interface="fi.w1.wpa_supplicant1"
                       send_member="SetInterfaceFirmware"
                       send_type="method_call"
                       send_path="/fi/w1/wpa_supplicant1"/>
        </policy>

to /etc/dbus-1/system.d/wpa_supplicant.conf makes hotspot.py work. This would make sure that only the needed methods are accessible from unconfined applications.

Revision history for this message
Jamie Strandboge (jdstrand) wrote :

From comment #2: "Considering the current policy with NM and the phablet user on Touch, I think it is tolerable to give the phablet user the ability to use SetInterfaceFirmware()". This dbus bus policy does this and so it is 'ok'.

That said, it is rather inflexible, is touch-specific and does not address when we have multiuser on devices-- policykit would handle that better because you can allow it to the active seat. You could do this, but this is likely going to have to be revisited within the next year.

Revision history for this message
Tony Espy (awe) wrote :

@Jamie

I asked Alfosno to prototype granting access with a DBus configuration change alone as proof-of-concept. Note, as the script we've been using for testing is a Python script, the "Introspectable" fragment was needed. As system settings is Qt-based, this may not be needed. We'll need Jonas to confirm.

As this approach works, I'm not sure whether or not the added polkit layer actually buys us much more security. As previously mentioned, all non-core click apps are confined, and cannot access DBus on their own. The only way an unconfined phablet processes could land on the phone ( besides our core apps ) is if a user enables developer-mode and installs the app via dpkg or directly via a binary installer, which means the extra polkit protection could easily be circumvented.

I think a developer would also discover pretty quickly that a new app was malicious if the WiFi hardware stopped working as a client, due to it's being put into hotspot mode.

Tony Espy (awe)
Changed in wpasupplicant (Ubuntu):
importance: Undecided → High
assignee: nobody → Alfonso Sanchez-Beato (alfonsosanchezbeato)
status: Confirmed → In Progress
Revision history for this message
Jamie Strandboge (jdstrand) wrote :

policykit doesn't give you much more over the bus policy as described here for a single user system, since the policykit configuration would also simply allow access to SetInterfaceFirmware without password. It can give you more protection for remote shells (ssh or exploit in installed software-- note, webbrowser-app (but not store webapps of course) currently runs unconfined). Policykit may prove more flexible down the line with multiuser as well.

Like I said, this dbus bus policy is ok for now, but I have a strong suspicion it will need to be revisited for multiuser.

affects: wpasupplicant (Ubuntu) → lxc-android-config (Ubuntu)
Revision history for this message
Jonas G. Drange (jonas-drange) wrote :

In silo 13.

Revision history for this message
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package lxc-android-config - 0.226

---------------
lxc-android-config (0.226) wily; urgency=medium

  [ Ricardo Salveti de Araujo ]
  * etc/dbus-1/system.d/wpa_supplicant_touch.conf: exporting
    SetInterfaceFirmware to the phablet user, so it can be used to
    enable hotspot (LP: #1426923)

 -- Ken VanDine <email address hidden> Wed, 10 Jun 2015 14:15:44 -0400

Changed in lxc-android-config (Ubuntu):
status: In Progress → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.