pop-os / popsicle

Multiple USB File Flasher
MIT License
638 stars 77 forks source link

Ideally, the GUI should not be run as root #89

Closed ids1024 closed 4 years ago

ids1024 commented 4 years ago

The .desktop file calls popsicle-pkexec, which executes pkexec /usr/bin/popsicle-gtk. This runs the GUI code as root.

This isn't a huge issue; in theory it should be secure, and GTK seems to handle it fairly gracefully, with the program using the same GTK theme as the running user, etc. But I think this would generally be discouraged, though I can't find a quote from upstream Gnome/GTK specifically saying that.

I suppose the proper solution would be to spawn another process, given root access through polkit, that is seperate from the GUI. It could be a wrapper around he current CLI, perhaps.

ids1024 commented 4 years ago

Fedora Media Write (available as a Flatpak) seems to use Polkit to request permission to write to the disk. Though it uses a confusing prompt (https://github.com/FedoraQt/MediaWriter/issues/119), and if we used a similar method, we would presumably need a prompt for each device we want to flash.

mmstick commented 4 years ago

The CLI currently has machine-readable output when its output is piped, so it wouldn't be too difficult today to change the GTK UI to simply parse these events as a stream. I already have a decoder here https://github.com/pop-os/popsicle/blob/master/src/codec.rs

ids1024 commented 4 years ago

Taking another look, it seems UDisks2 has an appropriate API that didn't exist when Fedora Media Write was create. I've sent them a PR: https://github.com/FedoraQt/MediaWriter/pull/260.

Using a polkit based solution like this seems like the "right way" to do it. It does have the consequence that it would prompt seperately for each device. I suppose we don't want that?

Since we probably just want one prompt, even when flashing multiple device, I suppose wrapping something like pkexec popsicleshould work (which I guess is basically the previous plan).

ids1024 commented 4 years ago

I guess this isn't too bad, because popsicle-gtk actually spawns another thread to run privileged tasks and switches the rest of the program to the uid/gid that called sudo/pkexec. But this is kind of an awkward solution, that seems like it can lead to somewhat odd behavior, and isn't the best practice.

So we want something that's a bit more secure, and something that works in Flatpak (https://github.com/pop-os/popsicle/issues/93).

Possibilities:

  1. The current approach is obviously possible, as mentioned, not ideal and it doesn't work under Flatpak.
  2. Make dbus calls to UDisks2 to open the drives. This works in Flatpak and is secure. The file descriptor is passed over DBus, so we can arbitrary system calls with it once the file is open, without communicating with another process. But it has the disadvantage (or arguably, advantage) that this opens a separate prompt requesting access to every drive the user tries to flash.
  3. Spawn a subprocess running pkexec popsicle. This is a generally good solution, but as far as I'm aware can't work in Flatpak.
  4. Spawn a subprocess running popsicle --udisks2 (or similar), and have that argument make the CLI use UDisks2 to open the drive.

If we're happy always using UDisks2 to open drives, 2 is a good solution. Otherwise, perhaps implement both 3 and 4.

mmstick commented 4 years ago

Using UDisks2 would be fine if that's what it takes to support running Popsicle in a sandbox.