Grant full admin privileges to sys-gui/sys-gui-gpu

I’ve been able to install sys-gui and sys-gui-gpu on my laptop (Librem 14v1, Intel UHD Graphics 620) following the different guides on the documentation, forum and qubes-issues. It seems to boot correctly with no UI issues, but I still have permission errors for some tasks. I have the same behavior on sys-gui and sys-gui-gpu.

After login, with blueman (maybe because I didn’t configured an audioVM):

KillSwitch.py:61:on_load:gi.repository.GLib.GError: g-file-error-quark: Permission denied (2)
Details
backtrace

KillSwitch.py:61:on_load:gi.repository.GLib.GError: g-file-error-quark: Permission denied (2)

Traceback (most recent call last):
  File "/usr/bin/blueman-applet", line 40, in <module>
    app = BluemanApplet()
          ^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/blueman/main/Applet.py", line 44, in __init__
    self.Plugins.load_plugin()
  File "/usr/lib/python3.11/site-packages/blueman/main/PluginManager.py", line 125, in load_plugin
    self.__load_plugin(cls)
  File "/usr/lib/python3.11/site-packages/blueman/main/PluginManager.py", line 163, in __load_plugin
    inst._load()
  File "/usr/lib/python3.11/site-packages/blueman/plugins/AppletPlugin.py", line 51, in _load
    super()._load()
  File "/usr/lib/python3.11/site-packages/blueman/plugins/BasePlugin.py", line 77, in _load
    self.on_load()
  File "/usr/lib/python3.11/site-packages/blueman/plugins/applet/KillSwitch.py", line 61, in on_load
    channel = GLib.IOChannel.new_file("/dev/rfkill", "r")
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
gi.repository.GLib.GError: g-file-error-quark: Permission denied (2)

Local variables in innermost frame:
self: <blueman.plugins.applet.KillSwitch.KillSwitch object at 0x7d793fa74ed0>

crash_function
on_load

cmdline
/usr/bin/python3 -sPE /usr/bin/blueman-applet

executable
/usr/bin/blueman-applet

when opening Qubes Updates, with qubes-desktop-linux-manager:

__init__.py:1213:_open:PermissionError: [Errno 13] Permission denied: '/var/log/qubes/qui.updater.log'
Details
backtrace
__init__.py:1213:_open:PermissionError: [Errno 13] Permission denied: '/var/log/qubes/qui.updater.log'

Traceback (most recent call last):
  File "/usr/bin/qubes-update-gui", line 33, in <module>
    sys.exit(load_entry_point('qui==0.1', 'gui_scripts', 'qubes-update-gui')())
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/qui/updater/updater.py", line 303, in main
    app = QubesUpdater(qapp, cliargs)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/qui/updater/updater.py", line 47, in __init__
    log_handler = logging.FileHandler(
                  ^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.11/logging/__init__.py", line 1181, in __init__
    StreamHandler.__init__(self, self._open())
                                 ^^^^^^^^^^^^
  File "/usr/lib64/python3.11/logging/__init__.py", line 1213, in _open
    return open_func(self.baseFilename, self.mode,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PermissionError: [Errno 13] Permission denied: '/var/log/qubes/qui.updater.log'

Local variables in innermost frame:

crash_function
_open

cmdline
/usr/bin/python3 /usr/bin/qubes-update-gui

executable
/usr/bin/qubes-update-gui

When opening Qubes Policy Editor:

subprocess.py:571:run:subprocess.CalledProcessError: Command '['/usr/bin/qrexec-client-vm', 'dom0', 'policy.include.List']' returned non-zero exit status 126.
Details
backtrace
subprocess.py:571:run:subprocess.CalledProcessError: Command '['/usr/bin/qrexec-client-vm', 'dom0', 'policy.include.List']' returned non-zero exit status 126.

Traceback (most recent call last):
  File "/usr/lib/python3.11/site-packages/qubes_config/policy_editor/policy_editor.py", line 160, in do_activate
    self.perform_setup()
  File "/usr/lib/python3.11/site-packages/qubes_config/policy_editor/policy_editor.py", line 177, in perform_setup
    self.file_select_handler = OpenDialogHandler(self.builder,
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/qubes_config/policy_editor/policy_editor.py", line 71, in __init__
    for file in self.policy_client.policy_list():
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/qubes_config/policy_editor/policy_editor.py", line 122, in policy_list
    self.policy_client.policy_include_list()])
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/qrexec/policy/admin_client.py", line 46, in policy_include_list
    return self.call("policy.include.List").rstrip("\n").split("\n")
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/qrexec/policy/admin_client.py", line 74, in call
    return call("dom0", service_name, arg, input=payload)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/qrexec/client.py", line 53, in call
    return subprocess.check_output(
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.11/subprocess.py", line 466, in check_output
    return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.11/subprocess.py", line 571, in run
    raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['/usr/bin/qrexec-client-vm', 'dom0', 'policy.include.List']' returned non-zero exit status 126.

Local variables in innermost frame:
input: b''
capture_output: False
timeout: None
check: True
popenargs: (['/usr/bin/qrexec-client-vm', 'dom0', 'policy.include.List'],)
kwargs: {'stdout': -1, 'stdin': -1}
process: <Popen: returncode: 126 args: ['/usr/bin/qrexec-client-vm', 'dom0', 'policy....>
stdout: b''
stderr: None
retcode: 126

crash_function
run

cmdline
/usr/bin/python3 /usr/bin/qubes-policy-editor-gui

executable
/usr/bin/qubes-policy-editor-gui

I’m still not sure to fully understand how these GuiVMs are supposed to sit on dom0. Not having full admin privileges might not be a big deal in sys-gui because we can still access dom0 with Ctrl+Alt+F2 or login back to dom0’s XFCE session, but with sys-gui-gpu we don’t have any access to dom0 because the GPU is not attached to it.

  • If the GuiVM is not supposed to have full privileges, how can we access dom0 from it?
  • If the GuiVM is supposed to have full privileges, what the current configuration is missing? Should we add new policy rules?
  • Should we create a new adminVM to perform all admin tasks like in dom0?

Thanks!

1 Like

While I’m not employed at Invisible Things Lab and can’t speak on behalf of the company, I suppose this will be the case in the final release, i.e. sys-gui-gpu having some ability to interact with dom0 via well-crafted policies.

If you have more spare time than me, you can play around with them and write your own ones, contributing to the system development. Any would count, even as simple as one that lets a user gracefully shutdown their machine (right now there’s only a forced shutdown available through holding down the power button).

Last month I also published a list of what works and what does not after experimenting on my own.

1 Like

Thanks for your reply, your posts were part of my investigations in the last few days!

I’d love to try if I can, but I guess first would be to clarify the goals to stay on the good track and list the main missing rules with a way to add them progressively if it doesn’t already exists.

Any idea who can help us on that theoretical part first?

I think our best bet is to file (an) issue(s) at Issues · QubesOS/qubes-issues · GitHub, so we can track what’s to be worked on.

It’s up to the reporter to manage, how to divide the big thing into smaller pieces, like:

  • writing custom policies, so sys-gui can act in the context of dom0
  • improving Salt states, so the i915 gets denylisted as part of sys-gui-gpu creation
  • improving Salt states, so audiovm gets properly assigned
  • other bug reports encountered as part of testing things out

Please keep in mind that this list is just an example that I’m writing about in real-time. The better the problems gets divided into smaller pieces, the better the work on it can be tracked.

1 Like

Spot on. I tried myself last month, on R4.2, and ended up with the same conundrum. See the newer posts in How to enable the (new) GUI VM?
None of the two sys-gui constructs are production-ready.

EDIT: they are actually in what I think of an “alpha” stage, even.

You both right, thanks for your help!

I totally understand that the current state is alpha and that a lot of work is still necessary to make it production-ready. My post is not about fixing all sys-gui/sys-gui-gpu issues, but is focused only on this admin privileges part to clarify it.

My last thoughts on the topic are the followings:

  • we can’t access dom0 from domU qubes for security reasons, it’s only about grant them access rights.
  • we need a way to get full admin privileges from a GuiVM.
  • we can have multiple GuiVMs, for a multi-user scenario or single-user with multiple desktop environments for example.
  • we can first create an AdminVM to have the same privileges than dom0, accessible from the GuiVM, then maybe split it into multiple AdminVMs to improve security and compartmentalization.

I will open a Github issue specifically for the permission errors I’ve shared on my first post, then send an email on the qubes-devel mailing list to clarify the path to follow with the dev team.

I’ll post updates here!

1 Like

I created an issue here: Unable to use Qubes Updates on `sys-gui`: [Errno 13] Permission denied · Issue #8934 · QubesOS/qubes-issues · GitHub

1 Like

I sent a mail to qubes-devel, marmarek clarified things: https://groups.google.com/g/qubes-devel/c/iwhBP0PSi0Y

TL;DR: The goal is to have specific qrexec services for everything
that needs dom0 action, and then grant access to those. It shouldn’t be necessary to access dom0 shell at all.

1 Like

It’s not only about actions, but also about dom0 config management (i.e. creating new qrexec calls and associated policies). If you allow someone to create a new rpc through a generic qrexec interface than this is as good as allowing a shell, since the rpc could be (ab)used to tunnel a shell too.