Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shutdown/suspend inactive VMs #832

Closed
marmarek opened this issue Mar 8, 2015 · 65 comments
Closed

Shutdown/suspend inactive VMs #832

marmarek opened this issue Mar 8, 2015 · 65 comments
Labels
C: core P: major Priority: major. Between "default" and "critical" in severity. T: enhancement Type: enhancement. A new feature that does not yet exist or improvement of existing functionality.
Milestone

Comments

@marmarek
Copy link
Member

marmarek commented Mar 8, 2015

Reported by joanna on 27 Apr 2014 12:29 UTC
If a VM is open but not "active" for some time (e.g. 1h) then we might consider pausing/suspending it to save on resources (RAM in case of laptop, etc).

The specific action (suspend, pause, etc) should be VMM-specific.

Migrated-From: https://wiki.qubes-os.org/ticket/832

@marmarek marmarek added this to the Release 3 milestone Mar 8, 2015
@marmarek marmarek added T: enhancement Type: enhancement. A new feature that does not yet exist or improvement of existing functionality. C: core P: major Priority: major. Between "default" and "critical" in severity. labels Mar 8, 2015
@marmarek
Copy link
Member Author

marmarek commented Mar 8, 2015

Comment by marmarek on 27 Apr 2014 21:00 UTC
What is "inactive" VM? That UsbVM running in the background without any active window, but serving some block devices to other VMs?

But ok, some VMs (all AppVMs by default?) can be selected for such mechanism.

Perhaps if "inactive" means "without any visible window" (no user application is running), the VM can be simply shut off. VM startup (especially Linux) is rather fast.
For Xen case, alternatives are problematic:

  • pause do not release memory
  • suspend (save state to disk) do not work for all cases - some VMs (>=4GB RAM, >1CPU) crashes after resume

@v6ak
Copy link

v6ak commented May 7, 2015

I think that such VM can be also shut down. This would be especially useful if there is low free RAM. But I agree that the largest issue now is determining if the VM is active.

I hope that detection by no active window (or systray icon or something like it) will work for most VMs. At the start, it can be opt-in, so users wanting the feature (like me) would enable it maybe in all VMs except sys-firewall and USBVM and some similar VMs. (Note that even sys-net has systray icon by default.)

@marmarek
Copy link
Member Author

If listing active windows would be enough, it should be simple to write
a script which will periodically iterate over windows and shutdown VMs
with no windows (after some time). You can use for example xdotool for
that:

xdotool search --class <VMNAME>

I'm not sure why, but it looks like there is always at least one window,
with default title VMapp command, so probably you can check if there
are at least two windows - and if not (for some time) - shutdown the VM.
If you issue simple qvm-shutdown it will refuse to stop NetVM/ProxyVM
used by some other VMs, so this case will be covered automatically.

Best Regards,
Marek Marczykowski-Górecki
Invisible Things Lab
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?

@marmarek marmarek modified the milestones: Release 3.1, Release 3.0 May 13, 2015
@v6ak
Copy link

v6ak commented May 15, 2015

I don't see the windows for some apps. There are some hidden windows with unknown purpose, but they can be excluded by --onlyvisible.

I've hacked a bash script for this purpose. Creating a simple working script is easy. Handling some edge cases, especially race conditions, requires some tight cooperation with qragent. There is the script with my more detailed notes about challenges: https://github.com/v6ak/qubes-vm-autoshutdown I hope you will find it useful.

If something is unclear, do not hesitate to ask.

@v6ak
Copy link

v6ak commented May 15, 2015

I haven't implemented automatic pause, only automatic shutdown. If everything is implemented well, the automatic pause should not be needed, because inactive VM should consume almost no CPU. Moreover, a paused VM can't return any memory to Dom0 without unpausing, so pausing a VM with good memory conditions might cause worse memory conditions later. This could be improved, but it should be a separate issue.

@v6ak
Copy link

v6ak commented May 25, 2015

So, my approach with --onlyvisible does not work correctly when using multiple Activities (or possibly virtual desktops or maybe minimized windows), as it excludes these windows… Statusbar icons are also often invisible when using autohide. I'll try to fix that by excluding the VMapp commands, but I feel this like a hack.

@marmarek
Copy link
Member Author

Maybe you can enumerate the windows inside the VM - it looks to be not
affected by switching to another desktop.

Best Regards,
Marek Marczykowski-Górecki
Invisible Things Lab
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?

@marmarek
Copy link
Member Author

Hmm, actually the whole script can run inside VM - check if there are
some windows, and if not (for some time), then shutdown itself. It would
be trivial to enable it only for some VMs (using qvm-service framework).

Best Regards,
Marek Marczykowski-Górecki
Invisible Things Lab
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?

@v6ak
Copy link

v6ak commented May 25, 2015

It seems to bring more issues than solves. First, it requires xdotool having installed on all such VMs, but that might be OK. However, maybe delegating strategy for “Am I active?” to particular VMs would be cleaner than checking it from dom0. But while I get rid of “VMapp command” windows, I get some windows like this one (slightly modified xprop dump):

AT_SPI_BUS(STRING) = "unix:abstract=/tmp/dbus-asdfghjkl;,guid=0123456789abcdef0123456789abcdef"
PULSE_COOKIE(STRING) = "01234567890…………
PULSE_SERVER(STRING) = "{01234567890abcdef…}unix:/run/user/1000/pulse/native"
PULSE_SESSION_ID(STRING) = "c1"
PULSE_ID(STRING) = "1000@01234567890abcdef…/815"
RESOURCE_MANAGER(STRING) = "*customization:\t-color\nXft.antialias:\t1\nXft.hinting:\t1\nXft.hintstyle:\thintslight\nXft.lcdfilter:\tlcddefault\nXft.rgba:\trgb\n"
_NET_SUPPORTED(ATOM) = _NET_SUPPORTED, _NET_SUPPORTING_WM_CHECK, _NET_WM_MOVERESIZE, _NET_WM_STATE, _NET_WM_STATE_FULLSCREEN, _NET_WM_STATE_DEMANDS_ATTENTION
_NET_SUPPORTING_WM_CHECK(WINDOW): window id # 0x200002
_XKB_RULES_NAMES(STRING) = "evdev", "pc105", "us", "", ""
XFree86_has_VT(INTEGER) = 1
XFree86_VT(INTEGER) = 7
VFB_IDENT(STRING) = "TRUE"

Maybe there is something that tells us that the window is unused. If so, it would be cleaner to blacklist these windows than to blacklist some windows based on their title.

@marmarek
Copy link
Member Author

Isn't this root window? When I execute xdotool search --onlyvisible ., I get only real application windows. Some applications are even
exposing last user activity time in _NET_WM_USER_TIME property.

Best Regards,
Marek Marczykowski-Górecki
Invisible Things Lab
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?

@v6ak
Copy link

v6ak commented May 25, 2015

It may be something like that, I am not sure. But I see that “window” even with --onlyvisible, just after the VM start. It might be some difference between Fedora and Debian (tested with Jessie).

I've, however tested that windows are considered in AppVM as “visible” even if they are minimized. When I call xdotool windowminimize in the AppVM for a window, it is just ignored and the window is still “visible”. that's good for implementing reporting activity status from the AppVM itself, but I am not sure if I can rely on it.

@adrelanos
Copy link
Member

I think this is a possible usability issue. One would wonder if one detached a job (& disown), closed the console window, and later the VM was shut down, therefore the job unexpectedly interrupted, just because it had no more graphical applications running. Or if that VM was running a server service or whatever else background processes one might run. If you want to implement this, please have a checkbox in QVMM something along the lines of "automatically shut down VM when there is no more graphical windows for 1 hour".

@bnvk
Copy link

bnvk commented Nov 21, 2015

Hrm, I wonder if from a usability standpoint, we might want to ask the user to decide when certain criteria is met, for instance:

  1. If VM has not been used in 30 minutes AND it DOES NOT have background services running
    2: Prompt user with passive tray notification "Want to put the VM 'Work' to sleep? It looks like you haven't used it in awhile"
  2. Offer buttons [Don't Ask Again] [Yes]

That way a user can use their brain to determine "no, I have some sort of thing going on in that VM" or "I need to toggle back to it once I finish task in other VM"

@adrelanos
Copy link
Member

If you must add this, I suggest another IF.

  1. If there is actually need to save RAM. When there is still enough free RAM, don't bother asking for optimizing.

That would be dialogs popping out of nowhere interrupting whatever the user is currently doing. And 4 inactive VMs (ex: vault, social, bank, private) would result in 4 such dialogs. So I guess these notifications should be accumulated into a single dialog. [or less optimal, be in a queue, not all pop up at the same time]

Another perhaps good place (maybe not for the first, but second iteration of this) might be the global Qubes [security] status systray icon. Instead of "green" it could perhaps still glow "green" but with a small additional info symbol. And once users are curios and click it, this VM shutdown questions are shown.

@marmarek
Copy link
Member Author

  1. If VM has not been used in 30 minutes AND it DOES NOT have background services running

Actually it is really tricky to check for background services. Every
Linux system have some background services and it isn't obvious which
are actually used by the user.

  1. If there is actually need to save RAM. When there is still enough free RAM, don't bother asking for optimizing.

I don't think it's necessary. Even if not for RAM saving, shutting down
unused VMs will lower CPU usage -> more battery time.

I think it's better to have this feature being optional. So it can be
for example enabled for VM used only for web browser, but disabled for
VPN VM, printing VM etc.
We can start with opt-in approach, then decide about some other
defaults.

Best Regards,
Marek Marczykowski-Górecki
Invisible Things Lab
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?

@adrelanos
Copy link
Member

adrelanos commented Nov 22, 2015 via email

@v6ak
Copy link

v6ak commented Nov 23, 2015

I don't think that unused VMs consume considerable amount of power. They, however, consume some RAM which could be used for caches and so on.

If VM pausing will be implemented, it would be useful if RAM footprint is reduced before the pause, because the paused VM can't participate in memory balancing. Without this, paused VM could have worse effect on amount of available RAM than a running VM. I am not sure if pausing will be a simple task.

There might be some grey zone. Consider a VM with tasks or calendar. When I minimize it, I don't need it and it might be shut down (like in Android). However, this will work better after some raise-or-run mechanism is implemented.

I will probably have some motivation for improving the script (mainly offloading the “active VM” strategy from dom0 to domU) soon, because I'll have to downgrade my RAM due to some RAM failure…

@marmarek marmarek changed the title Pause/suspend inactive VMs Shutdown/suspend inactive VMs Nov 23, 2015
@marmarek
Copy link
Member Author

Actually this task (as in description) is about shutting down the VMs (or some other means of releasing RAM). Updated title to less confusing.

@v6ak
Copy link

v6ak commented Nov 23, 2015

I see both options, suspend and shutdown. (I am actually not sure if suspend is something different from pause.) I have commented something about chalenges of VM suspending, but I am not going to implement it, at least not now. I will rather implement the autoshutdown, because it is simpler to implement and it IMHO gives more benefit.

@marmarek
Copy link
Member Author

Yes, in case of Xen (we don't have other cases right now ;) ), probably the easiest and most beneficial way would be to shutdown unused VMs.

@v6ak
Copy link

v6ak commented Nov 28, 2015

Hmm, I can call RPC from domU… But, is there any way to call it from dom0? I haven't found it at https://www.qubes-os.org/doc/qrexec3/ .

However, this brings me some idea: The design might be reversed: AppVMs would inform dom0 about being unused. Any call of RPC would clear the unused flag and the AppVM would have to send it again (if desired).

@marmarek
Copy link
Member Author

On Sat, Nov 28, 2015 at 06:35:59AM -0800, Vít Šesták wrote:

Hmm, I can call RPC from domU… But, is there any way to call it from dom0? I haven't found it at https://www.qubes-os.org/doc/qrexec3/ .

Not a nice API, but you can call RPC with:

qvm-run -p some-vm 'QUBESRPC name-of-service dom0'

However, this brings me some idea: The design might be reversed: AppVMs would inform dom0 about being unused. Any call of RPC would clear the unused flag and the AppVM would have to send it again (if desired).

What about simply shutting down unused VM from within?
So you would have a service in VM (enabled/disabled by qvm-service
framework[1]), which checks if the VM is unused for some configured time
period. And if so, simply call poweroff.

[1] https://www.qubes-os.org/doc/qubes-service/

Best Regards,
Marek Marczykowski-Górecki
Invisible Things Lab
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?

@jpouellet
Copy link
Contributor

@mfc
Copy link
Member

mfc commented Mar 12, 2017

Is there a reason we are not considering hibernation (#2273) rather than shutdown of inactive VMs?

@marmarek
Copy link
Member Author

Yes, shutdown is much easier to implement. For suspend/restore you need not only to restore VM internal state (memory etc - handled by Xen tools), but also all related VM connections - networking, GUI, qrexec services running when VM was hibernated etc.
Also, VM suspend support in Xen/Linux historically was quite buggy - this is for example why Disposable VMs have only 1 vCPU assigned, otherwise it crashed frequently. Probably situation have improved since previous tests, but still I suspect it will be less stable.

@v6ak
Copy link

v6ak commented Mar 12, 2017

Shutdown:

  • is much better for making VM up-to-date: When you update a VM, you have to restart it. If a VM hibernates, it would have to be restored to the old state. Consider a following scenario: You start a banking VM, then you close the browser. It gets hibernated. Then you update the TemplateVM. Then you might even reboot your computer. And even in this case, the banking VM will still use the outdated template. Not nice.
  • is probably less resource-intensive (at least for I/O) than hibernate
  • does not break potential anti-forensic nature like hibernate would do
  • the reverse process (i.e., VM start) might take slightly more time than with hibernation (i.e., VM restore)

I know there can be some arguments for preserving the state. But if you need it, you probably use Qubes wrong. And keeping outdated VMs (i.e., making it worse than today) is a great argument against use of hibernation here, I believe.

@grey-olli
Copy link

grey-olli commented Mar 24, 2017 via email

@v6ak
Copy link

v6ak commented Mar 24, 2017 via email

@maximilize
Copy link

I just created a small python script which fulfils my needs. It needs to run in dom0 and the guest VM's need the tool xwininfo installed. If it is not present, the VM is not automatically shut down.

The script ignores

  • Autostart VM's
  • VM's which are in use by another VM

https://gist.github.com/maximilize/62071aed9d7b55f4a887cc56a6d91785

marmarek added a commit to marmarek/qubes-builder that referenced this issue Nov 3, 2018
@marmarek
Copy link
Member Author

marmarek commented Nov 9, 2018

Status update: the script shutting down idle VM from within is packaged here: https://github.com/QubesOS/qubes-app-shutdown-idle
It require explicit enabling (opt-in approach). Details in the readme in that repo (will be added to qubes doc too). Right now it monitor two things to consider the VM idle:

  • visible windows
  • downstream network interfaces (VM providing network for another VMs)
    Both need to say "idle" for 15 minutes, to shutdown the VM.

But @n1m1 reported in #4490 that it doesn't work.

@n1m1
Copy link

n1m1 commented Nov 11, 2018

Status update: the script shutting down idle VM from within is packaged here: https://github.com/QubesOS/qubes-app-shutdown-idle
It require explicit enabling (opt-in approach). Details in the readme in that repo (will be added to qubes doc too). Right now it monitor two things to consider the VM idle:

* visible windows

* downstream network interfaces (VM providing network for another VMs)
  Both need to say "idle" for 15 minutes, to shutdown the VM.

But @n1m1 reported in #4490 that it doesn't work.

Hi, few more details about the problem I reported.

I've done another test, creating 3 new qubes: test_f28 (based on fedora-28), test_d9 (based on debian 9) and test_ws14 (based on whonix-ws-14). On test_f28 the script is working perfectly while it is not working on test_d9 and test_ws14 .

Thanks and tell me if there is something I can do in order to provide more helpful information to solve this problem.

@marmarek
Copy link
Member Author

Check ~/.xsession-errors in that qube - maybe the script crashed? If not, maybe there are some unexpected windows? You can check that by:

  1. from dom0, acccess qube's console with sudo xl console test_d9
  2. login as root (no password), switch to user with su - user
  3. enumerate windows with xdotool search --onlyvisible ''
  4. for each window id, check what it with xwininfo -id WINDOW_ID

(you may need to install xdotool and x11-utils first)

@n1m1
Copy link

n1m1 commented Nov 12, 2018

Hi @marmarek and thanks for your answer.

Here is my test_d9 ~/.xsession-errors (the shutdown-idle script is not working in this VM):

X.Org X Server 1.19.2
Release Date: 2017-03-02
X Protocol Version 11, Revision 0
Build Operating System: Linux 4.9.0-8-amd64 x86_64 Debian
Current Operating System: Linux localhost 4.18.13-3.pvops.qubes.x86_64 #1 SMP Sun Oct 14 04:41:32 UTC 2018 x86_64
Kernel command line: root=/dev/mapper/dmroot ro nomodeset console=hvc0 rd_NO_PLYMOUTH rd.plymouth.enable=0 plymouth.enable=0 nopat
Build Date: 03 November 2018  03:09:11AM
xorg-server 2:1.19.2-1+deb9u5 (https://www.debian.org/support) 
Current version of pixman: 0.34.0
	Before reporting problems, check http://wiki.x.org
	to make sure that you have the latest version.
Markers: (--) probed, (**) from config file, (==) default setting,
	(++) from command line, (!!) notice, (II) informational,
	(WW) warning, (EE) error, (NI) not implemented, (??) unknown.
(==) Log file: "/home/user/.local/share/xorg/Xorg.0.log", Time: Mon Nov 12 16:52:13 2018
(++) Using config file: "/etc/X11/xorg-qubes.conf"
(==) Using system config directory "/usr/share/X11/xorg.conf.d"
Xsession: X session started for user at Mon Nov 12 16:52:13 GMT 2018
dbus-update-activation-environment: setting DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
dbus-update-activation-environment: setting DISPLAY=:0
xsettingsd: Loaded 17 settings from /home/user/.xsettingsd
xsettingsd: Created window 0x600001 on screen 0 with timestamp 14735
xsettingsd: Selection _XSETTINGS_S0 is owned by 0x0
xsettingsd: Took ownership of selection _XSETTINGS_S0
localuser:user being added to access control list
dbus-update-activation-environment: setting QT_ACCESSIBILITY=1
OpenGL version: 3.
Warning:          Key <OUTP> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <KITG> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <KIDN> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <KIUP> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <RO> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <I192> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <I193> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <I194> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <I195> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <I196> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <I255> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          No symbols defined for <AB11> (keycode 97)
Warning:          No symbols defined for <JPCM> (keycode 103)
Warning:          No symbols defined for <I120> (keycode 120)
Warning:          No symbols defined for <AE13> (keycode 132)
Warning:          No symbols defined for <I149> (keycode 149)
Warning:          No symbols defined for <I154> (keycode 154)
Warning:          No symbols defined for <I168> (keycode 168)
Warning:          No symbols defined for <I178> (keycode 178)
Warning:          No symbols defined for <I183> (keycode 183)
Warning:          No symbols defined for <I184> (keycode 184)
Warning:          No symbols defined for <FK19> (keycode 197)
Warning:          No symbols defined for <FK24> (keycode 202)
Warning:          No symbols defined for <I217> (keycode 217)
Warning:          No symbols defined for <I219> (keycode 219)
Warning:          No symbols defined for <I221> (keycode 221)
Warning:          No symbols defined for <I222> (keycode 222)
Warning:          No symbols defined for <I230> (keycode 230)
Warning:          No symbols defined for <I247> (keycode 247)
Warning:          No symbols defined for <I248> (keycode 248)
Warning:          No symbols defined for <I249> (keycode 249)
Warning:          No symbols defined for <I250> (keycode 250)
Warning:          No symbols defined for <I251> (keycode 251)
Warning:          No symbols defined for <I252> (keycode 252)
Warning:          No symbols defined for <I253> (keycode 253)
dbus-update-activation-environment: setting MAIL=/var/mail/user
dbus-update-activation-environment: setting USER=user
dbus-update-activation-environment: setting SHLVL=1
dbus-update-activation-environment: setting HOME=/home/user
dbus-update-activation-environment: setting DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
dbus-update-activation-environment: setting LOGNAME=user
dbus-update-activation-environment: setting _=/usr/bin/xinit
dbus-update-activation-environment: setting GNOME_DESKTOP_SESSION_ID=c1
dbus-update-activation-environment: setting QT_X11_NO_MITSHM=1
dbus-update-activation-environment: setting WINDOWPATH=7
dbus-update-activation-environment: setting PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
dbus-update-activation-environment: setting XDG_RUNTIME_DIR=/run/user/1000
dbus-update-activation-environment: setting DISPLAY=:0
dbus-update-activation-environment: setting LANG=en_US.UTF-8
dbus-update-activation-environment: setting SHELL=/bin/bash
dbus-update-activation-environment: setting QT_ACCESSIBILITY=1
dbus-update-activation-environment: setting GPG_AGENT_INFO=/run/user/1000/gnupg/S.gpg-agent:0:1
dbus-update-activation-environment: setting PWD=/home/user
** Message: couldn't access control socket: /run/user/1000/keyring/control: No such file or directory
** Message: couldn't access control socket: /run/user/1000/keyring/control: No such file or directory
** Message: couldn't access control socket: /run/user/1000/keyring/control: No such file or directory
SSH_AUTH_SOCK=/run/user/1000/keyring/ssh
Warning:          Key <OUTP> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <KITG> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <KIDN> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <KIUP> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <RO> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <I192> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <I193> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <I194> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <I195> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <I196> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <I255> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          No symbols defined for <AB11> (keycode 97)
Warning:          No symbols defined for <JPCM> (keycode 103)
Warning:          No symbols defined for <I120> (keycode 120)
Warning:          No symbols defined for <AE13> (keycode 132)
Warning:          No symbols defined for <I149> (keycode 149)
Warning:          No symbols defined for <I154> (keycode 154)
Warning:          No symbols defined for <I168> (keycode 168)
Warning:          No symbols defined for <I178> (keycode 178)
Warning:          No symbols defined for <I183> (keycode 183)
Warning:          No symbols defined for <I184> (keycode 184)
Warning:          No symbols defined for <FK19> (keycode 197)
Warning:          No symbols defined for <FK24> (keycode 202)
Warning:          No symbols defined for <I217> (keycode 217)
Warning:          No symbols defined for <I219> (keycode 219)
Warning:          No symbols defined for <I221> (keycode 221)
Warning:          No symbols defined for <I222> (keycode 222)
Warning:          No symbols defined for <I230> (keycode 230)
Warning:          No symbols defined for <I247> (keycode 247)
Warning:          No symbols defined for <I248> (keycode 248)
Warning:          No symbols defined for <I249> (keycode 249)
Warning:          No symbols defined for <I250> (keycode 250)
Warning:          No symbols defined for <I251> (keycode 251)
Warning:          No symbols defined for <I252> (keycode 252)
Warning:          No symbols defined for <I253> (keycode 253)
Cannot read '/var/log/kern.log'
executed (nowait) QUBESRPC qubes.StartApp+org.gnome.Terminal dom0 pid 871
send exit code 0
Activating service name='org.a11y.atspi.Registry'
Successfully activated service 'org.a11y.atspi.Registry'

** (gnome-settings-daemon:833): WARNING **: You can only run one xsettings manager at a time; exiting

** (gnome-settings-daemon:833): WARNING **: Unable to start gnome_xsettings manager: Could not initialize xsettings manager.

(nm-applet:811): nm-applet-WARNING **: NetworkManager is not running

(gnome-settings-daemon:833): GLib-GIO-CRITICAL **: g_dbus_connection_call_internal: assertion 'G_IS_DBUS_CONNECTION (connection)' failed

(gnome-settings-daemon:833): GLib-GIO-CRITICAL **: g_dbus_connection_call_internal: assertion 'G_IS_DBUS_CONNECTION (connection)' failed

(gnome-settings-daemon:833): GLib-GIO-CRITICAL **: g_dbus_connection_call_internal: assertion 'G_IS_DBUS_CONNECTION (connection)' failed

** (gnome-settings-daemon:833): WARNING **: Unable to register client: GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown: The name org.gnome.SessionManager was not provided by any .service files

(gnome-settings-daemon:833): GLib-GIO-CRITICAL **: g_task_return_error: assertion 'error != NULL' failed

(gnome-settings-daemon:833): Gvc-WARNING **: Sync_devices: Failed to match stream id: 1, description: 'Qubes vchan Output', origin: 'Qubes VCHAN sink'

(gnome-settings-daemon:833): Gvc-CRITICAL **: gvc_mixer_ui_device_get_id: assertion 'GVC_IS_MIXER_UI_DEVICE (device)' failed

(gnome-settings-daemon:833): Gvc-WARNING **: Sync_devices: Failed to match stream id: 2, description: 'Qubes vchan Input', origin: 'Qubes VCHAN source'

(gnome-settings-daemon:833): Gvc-CRITICAL **: gvc_mixer_ui_device_get_id: assertion 'GVC_IS_MIXER_UI_DEVICE (device)' failed

** (process:946): WARNING **: GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown: The name org.gnome.SessionManager was not provided by any .service files

If I type xdotool search --onlyvisible '' in test_d9 console from dom0 I get 2 different window_id, i.e:

638
2097154

Running xwininfo -id WINDOW_ID in test_d9 console from dom0 I get:

user@localhost:~$ xwininfo -id 638

xwininfo: Window id: 0x27e (the root window) (has no name)

  Absolute upper-left X:  0
  Absolute upper-left Y:  0
  Relative upper-left X:  0
  Relative upper-left Y:  0
  Width: 2048
  Height: 1152
  Depth: 24
  Visual: 0x21
  Visual Class: TrueColor
  Border width: 0
  Class: InputOutput
  Colormap: 0x20 (installed)
  Bit Gravity State: ForgetGravity
  Window Gravity State: NorthWestGravity
  Backing Store State: NotUseful
  Save Under State: no
  Map State: IsViewable
  Override Redirect State: no
  Corners:  +0+0  -0+0  -0-0  +0-0
  -geometry 2048x1152+0+0

and

user@localhost:~$ xwininfo -id 2097154

xwininfo: Window id: 0x200002 "Qubes"

  Absolute upper-left X:  2007
  Absolute upper-left Y:  58
  Relative upper-left X:  2007
  Relative upper-left Y:  58
  Width: 1
  Height: 1
  Depth: 24
  Visual: 0x21
  Visual Class: TrueColor
  Border width: 0
  Class: InputOutput
  Colormap: 0x20 (installed)
  Bit Gravity State: ForgetGravity
  Window Gravity State: NorthWestGravity
  Backing Store State: NotUseful
  Save Under State: no
  Map State: IsViewable
  Override Redirect State: no
  Corners:  +2007+58  -40+58  -40-1093  +2007-1093
  -geometry 1x1-40+58

Here is my test_f28 ~/.xsession-errors (the shutdown-idle script is working in this VM):

X.Org X Server 1.19.6
Release Date: 2017-12-20
X Protocol Version 11, Revision 0
Build Operating System:  4.18.10-200.fc28.x86_64 
Current Operating System: Linux localhost 4.18.13-3.pvops.qubes.x86_64 #1 SMP Sun Oct 14 04:41:32 UTC 2018 x86_64
Kernel command line: root=/dev/mapper/dmroot ro nomodeset console=hvc0 rd_NO_PLYMOUTH rd.plymouth.enable=0 plymouth.enable=0 nopat
Build Date: 01 November 2018  04:04:19PM
Build ID: xorg-x11-server 1.19.6-10.fc28 
Current version of pixman: 0.34.0
	Before reporting problems, check http://wiki.x.org
	to make sure that you have the latest version.
Markers: (--) probed, (**) from config file, (==) default setting,
	(++) from command line, (!!) notice, (II) informational,
	(WW) warning, (EE) error, (NI) not implemented, (??) unknown.
(==) Log file: "/home/user/.local/share/xorg/Xorg.0.log", Time: Mon Nov 12 17:09:13 2018
(++) Using config file: "/etc/X11/xorg-qubes.conf"
(==) Using system config directory "/usr/share/X11/xorg.conf.d"
Warning:          Key <OUTP> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <KITG> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <KIDN> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <KIUP> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <RO> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <I192> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <I193> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <I194> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <I195> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <I196> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          No symbols defined for <AB11> (keycode 97)
Warning:          No symbols defined for <JPCM> (keycode 103)
Warning:          No symbols defined for <I120> (keycode 120)
Warning:          No symbols defined for <AE13> (keycode 132)
Warning:          No symbols defined for <I149> (keycode 149)
Warning:          No symbols defined for <I154> (keycode 154)
Warning:          No symbols defined for <I168> (keycode 168)
Warning:          No symbols defined for <I178> (keycode 178)
Warning:          No symbols defined for <I183> (keycode 183)
Warning:          No symbols defined for <I184> (keycode 184)
Warning:          No symbols defined for <FK19> (keycode 197)
Warning:          No symbols defined for <FK24> (keycode 202)
Warning:          No symbols defined for <I217> (keycode 217)
Warning:          No symbols defined for <I219> (keycode 219)
Warning:          No symbols defined for <I221> (keycode 221)
Warning:          No symbols defined for <I222> (keycode 222)
Warning:          No symbols defined for <I230> (keycode 230)
Warning:          No symbols defined for <I247> (keycode 247)
Warning:          No symbols defined for <I248> (keycode 248)
Warning:          No symbols defined for <I249> (keycode 249)
Warning:          No symbols defined for <I250> (keycode 250)
Warning:          No symbols defined for <I251> (keycode 251)
Warning:          No symbols defined for <I252> (keycode 252)
Warning:          No symbols defined for <I253> (keycode 253)
** Message: 17:09:14.747: couldn't access control socket: /run/user/1000/keyring/control: No such file or directory
** Message: 17:09:14.748: couldn't access control socket: /run/user/1000/keyring/control: No such file or directory
SSH_AUTH_SOCK=/run/user/1000/keyring/ssh
SSH_AUTH_SOCK=/run/user/1000/keyring/ssh
SSH_AUTH_SOCK=/run/user/1000/keyring/ssh
Warning:          Key <OUTP> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <KITG> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <KIDN> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <KIUP> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <RO> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <I192> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <I193> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <I194> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <I195> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          Key <I196> not found in evdev+aliases(qwerty) keycodes
                  Symbols ignored
Warning:          No symbols defined for <AB11> (keycode 97)
Warning:          No symbols defined for <JPCM> (keycode 103)
Warning:          No symbols defined for <I120> (keycode 120)
Warning:          No symbols defined for <AE13> (keycode 132)
Warning:          No symbols defined for <I149> (keycode 149)
Warning:          No symbols defined for <I154> (keycode 154)
Warning:          No symbols defined for <I168> (keycode 168)
Warning:          No symbols defined for <I178> (keycode 178)
Warning:          No symbols defined for <I183> (keycode 183)
Warning:          No symbols defined for <I184> (keycode 184)
Warning:          No symbols defined for <FK19> (keycode 197)
Warning:          No symbols defined for <FK24> (keycode 202)
Warning:          No symbols defined for <I217> (keycode 217)
Warning:          No symbols defined for <I219> (keycode 219)
Warning:          No symbols defined for <I221> (keycode 221)
Warning:          No symbols defined for <I222> (keycode 222)
Warning:          No symbols defined for <I230> (keycode 230)
Warning:          No symbols defined for <I247> (keycode 247)
Warning:          No symbols defined for <I248> (keycode 248)
Warning:          No symbols defined for <I249> (keycode 249)
Warning:          No symbols defined for <I250> (keycode 250)
Warning:          No symbols defined for <I251> (keycode 251)
Warning:          No symbols defined for <I252> (keycode 252)
Warning:          No symbols defined for <I253> (keycode 253)
executed (nowait) QUBESRPC qubes.StartApp+org.gnome.Nautilus dom0 pid 746
send exit code 0

(gsd-xsettings:648): xsettings-plugin-WARNING **: 17:09:15.460: Failed to get current display configuration state: GDBus.Error:org.freedesktop.DBus.Error.NameHasNoOwner: Name "org.gnome.Mutter.DisplayConfig" does not exist

(gsd-xsettings:648): xsettings-plugin-WARNING **: 17:09:15.767: Unable to register client: GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown: The name org.gnome.SessionManager was not provided by any .service files

(nm-applet:650): nm-applet-WARNING **: 17:09:15.801: NetworkManager is not running
executed QUBESRPC qubes.WaitForSession dom0 pid 936
send exit code 0
pid 936 exited with 0
executed (nowait) QUBESRPC qubes.StartApp+org.gnome.Nautilus dom0 pid 992
send exit code 0
executed QUBESRPC qubes.WaitForSession dom0 pid 1114
send exit code 0
pid 1114 exited with 0
executed (nowait) QUBESRPC qubes.StartApp+org.gnome.Terminal dom0 pid 1170
send exit code 0

If I type xdotool search --onlyvisible '' in test_f28 console from dom0 I get 2 different window_id, i.e:

698
2097154

Running xwininfo -id WINDOW_ID in test_f28 console from dom0 I get:

[user@localhost ~]$ xwininfo -id 698
xwininfo: Window id: 0x2ba (the root window) (has no name)

  Absolute upper-left X:  0
  Absolute upper-left Y:  0
  Relative upper-left X:  0
  Relative upper-left Y:  0
  Width: 2048
  Height: 1152
  Depth: 24
  Visual: 0x21
  Visual Class: TrueColor
  Border width: 0
  Class: InputOutput
  Colormap: 0x20 (installed)
  Bit Gravity State: ForgetGravity
  Window Gravity State: NorthWestGravity
  Backing Store State: NotUseful
  Save Under State: no
  Map State: IsViewable
  Override Redirect State: no
  Corners:  +0+0  -0+0  -0-0  +0-0
  -geometry 2048x1152+0+0

and

[user@localhost ~]$ xwininfo -id 2097154

xwininfo: Window id: 0x200002 "Qubes"

  Absolute upper-left X:  877
  Absolute upper-left Y:  543
  Relative upper-left X:  877
  Relative upper-left Y:  543
  Width: 1
  Height: 1
  Depth: 24
  Visual: 0x21
  Visual Class: TrueColor
  Border width: 0
  Class: InputOutput
  Colormap: 0x20 (installed)
  Bit Gravity State: ForgetGravity
  Window Gravity State: NorthWestGravity
  Backing Store State: NotUseful
  Save Under State: no
  Map State: IsViewable
  Override Redirect State: no
  Corners:  +877+543  -1170+543  -1170-608  +877-608
  -geometry 1x1+877+543

Hope this is helpful.

@dakka2
Copy link

dakka2 commented Nov 16, 2018

Please consider building this and putting it in testing for debian.
Thank!

@marmarek
Copy link
Member Author

@dakka2 it is already there: QubesOS/updates-status#782

@t4777sd
Copy link

t4777sd commented Jan 26, 2019

@marmarek I am just curious why wasn't the tool made to be a script in dom0 that is enabled per qube via qvm-prefs?

At least for the windows it seems dom0 has all the information needed and it will work for any type of domain (even windows).

@marmarek
Copy link
Member Author

It's mostly about reducing complexity in dom0. One can easily think of expanding this tool based on various VM behaviors (like "if process X is running" or "is some TCP connection active"), where you'd need to extract data from within the VM anyway. Avoiding the need to parse something coming from VM in dom0 is almost always an improvement. Even with the current two conditions, it's easier to have more complete look for the active windows than from dom0 - for example you could easily exclude some applications, while in dom0 you'd need to guess based on window title or such.

@andrewdavidwong
Copy link
Member

On #5292, @unman wrote:

I'm not sure why that issue is still open since the tool as developed works fine bar this packaging error in Debian

@marmarek, should this be closed?

@marmarek
Copy link
Member Author

marmarek commented Sep 5, 2019

Since Debian problem got a separate issue, closing this now.

@3hhh
Copy link

3hhh commented Aug 29, 2020

Dom0 alternative: https://github.com/3hhh/qidle

@v6ak
Copy link

v6ak commented Aug 29, 2020 via email

@3hhh
Copy link

3hhh commented Aug 30, 2020

I am a bit skeptical about one of your advertised advantages. You mention the VM cannot prevent the shutdown. I am afraid this can be bypassed easily.

I like people who think like attackers. :-)

Anyway it's not so easily as you mention, but let's see:

a. VM occasionally performs some formal activity like opening a 1*1 window for 10ms.

In theory you could prevent the VM idle that way, not the user idle. So while the user is not idle, s/he should notice flickering windows.

In practice your 10ms is not enough as I discretely measure the VM idle only 3 times or so during the period (assuming a 60s "period" I e.g. discretely measure at 0s, 30s and 60s.) and the attacker doesn't know the exact points in time. Also, 1x1 won't be enough as the user probably configured such small windows to be ignored (cf. default config @ https://github.com/3hhh/qidle/blob/master/qidled.conf#L40-L43).

b. When shutdown is initiated, do you ensure it is finished?

Not by myself, no. Qubes OS qvm-shutdown has a kill timeout via --timeout by default though (https://github.com/3hhh/qidle/blob/master/qidled.conf#L91). So if that doesn't work, it would be a Qubes OS bug. ;-)

Anyway if you have a test machine, I'd recommend trying the attacks yourself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C: core P: major Priority: major. Between "default" and "critical" in severity. T: enhancement Type: enhancement. A new feature that does not yet exist or improvement of existing functionality.
Projects
None yet
Development

No branches or pull requests