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

Enhancement: USB lockout #2811

Open
Rudd-O opened this issue May 16, 2017 · 10 comments
Open

Enhancement: USB lockout #2811

Rudd-O opened this issue May 16, 2017 · 10 comments
Labels
C: core help wanted This issue will probably not get done in a timely fashion without help from community contributors. P: default Priority: default. Default priority for new issues, to be replaced given sufficient information. security This issue pertains to the security of Qubes OS. T: enhancement Type: enhancement. A new feature that does not yet exist or improvement of existing functionality.

Comments

@Rudd-O
Copy link

Rudd-O commented May 16, 2017

It'd be ideal if Qubes OS had a small service that would disable USB ports (via the grsecurity deny_new_usb feature) when the session was locked.

Something like this: https://github.com/subgraph/usblockout

The design of the feature that I have envisioned could be as follows:


There is a system-wide daemon in dom0. This daemon is connected to the system bus. This daemon is socket-activated and also starts on boot if its state file (see below) already exists.

This daemon monitors the signals SessionNew and SessionRemoved of the org.freedesktop.login1 bus owner.

For each session that appears (through the previous monitoring mechanism) and all the sessions that existed when the daemon started, the daemon monitors the two signals LockedHint ( https://bugzilla.redhat.com/show_bug.cgi?id=1329803 ) and Active.

(LockedHint support must be tested against both XFCE and KDE. If necessary, Qubes OS may want to patch these DEs to support the LockedHint signal. Upstream D-Bus already supports it via the patch mentioned above.)

The main loop of the daemon acts as follows:

  • When the Active session flips LockedHint to True, the daemon triggers its own method ApplyLockoutPolicy(session's UID, True).
  • When the Active session flips LockedHint to False, the daemon triggers its own method ApplyLockoutPolicy(session's UID, False).
  • When the Active session changes to a new session (not a new seat — a new session, with an associated UID), the daemon triggers its own method ApplyLockoutPolicy(new session's UID, new session's LockedHint).

See below for the algorithm of ApplyLockoutPolicy.

The daemon also exposes one method call SetLockoutPolicy, which can be called with a three-state value:

(a) do not disable new USB devices (the default Linux kernel policy)
(b) disable new USB devices when screen is locked
(c) disable new USB devices

This SetLockoutPolicy method is protected by a polkit permission which, as shipped by default, allows people on the active session/seat to set the value, and requires admin password to set the value from any context other than the active session/seat. When this method is called, the policy and the calling UID are persisted on disk in a state file containing a table of (UID, policy), which may also be kept in RAM. Then, if the active session's UID matches the caller's UID, ApplyLockoutPolicy is called with the active session's UID, and its locked hint.

Evidently, the daemon will also expose a GetLockoutPolicy, which looks up the policy based on the calling user's UID, and returns it to the caller.

In its default implementation, ApplyLockoutPolicy looks up the policy for the passed UID and its second parameter (the locked parameter). Its algorithm is roughly like this:

if locked:
    if policy in [disable new USB devices, disable new USB devices when screen is locked]:
        set deny_new_usb to true 
    else if policy == do not disable new USB devices:
        set deny_new_usb to false
else:
    if policy == disable new USB devices:
        set deny_new_usb to true 
    else if policy in [do not disable new USB devices , disable new USB devices when screen is locked]:
        set deny_new_usb to false

When executed in the Qubes OS environment, the ApplyLockoutPolicy command would also apply the same policies to any VM that has USB devices assigned to it. This can be accomplished by running a /usr/libexec/qubes command only when it is present — this command, behind the scenes, figures out which USB VMs exist and are running, and then uses a qrexec service to actuate the policy on all of them. Of course, when a USB VM starts, the policy should be applied as soon as qrexec is ready to receive commands.

There will be both a CLI and a GUI to toggle this feature. Both the CLI and the GUI will use the D-Bus interface to manipulate its value.


Note that this would require packaging the grsecurity enhancement in both the dom0 and the domU's kernels.

Note, additionally, that this enhancement, as designed, would work on pretty much any modern Linux system, so it would be seen as a phenomenal security addition to the entire desktop ecosystem. The only Qubes OS-specific part is the actuation on USB VMs. Thus we can envision a lockout and a lockout-dom0 package separation.

Also note that, since the session is usually locked right before suspend, our daemon has the opportunity to enable lockout right before suspend/hibernate (if the policy so requires). There's the hairy part of ensuring that we have enough time to execute all the update operations (in dom0 and in the USB VMs), and I am not sure how to accomplish that. This has some info https://www.freedesktop.org/wiki/Software/systemd/inhibit/ and, since the session LockedHint should arrive fast enough to at least start executing ApplyLockoutPolicy, it may be possible to simply execute ApplyLockedPolicy wrapped in an inhibitor delay lock. Actuating both dom0 and the USB VMs in parallel may be necessary for high suspend performance (as it takes about a quarter of a second for a qrexec RPC call to be authorized).

Also note that the design explicitly does not disable USB before login, which makes it compatible with two-factor authentication upon login. I only foresee a problem for two-factor screen unlocking, if the user forgets to connect the two-factor USB device before locking or suspending the system. This should be pointed out in the GUI and in the documentation for the feature.

@marmarek
Copy link
Member

It'd be ideal if Qubes OS had a small service that would disable USB ports (via the grsecurity deny_new_usb feature) when the session was locked.

How grsecurity deny_new_usb is different from standard authorized_default?

Also, while indeed could be useful, it would break unlocking with some 2FA (yubikey for example). But it isn't a reason to not implement this feature.

@Rudd-O
Copy link
Author

Rudd-O commented May 16, 2017

I believe they are equivalent, so we are go on the implementation.

I also noted that it would break unlocking with 2FA unless the device is connected before locking/suspending.

@marmarek
Copy link
Member

I also noted that it would break unlocking with 2FA unless the device is connected before locking/suspending.

Well, keeping the device connected when locked doesn't really make sense...

@Rudd-O
Copy link
Author

Rudd-O commented May 16, 2017

That's correct. But it does make a bit more sense (just a tiny bit) to connect it, close the lid, then disconnect after suspend, then connect it before opening the lid.

@andrewdavidwong
Copy link
Member

Use case description from the USB Lockout README:

You're in a place that is relatively safe, say your local hackerspace. You need to leave your computer out of sight for a small amount of time, the space is safe enough that you are not worried about it being stolen, but not enough that someone couldn't attempt a quick drive-by usb attack.

I already have a USB VM, so, in that scenario, I'm not worried.

Is there a scenario where I'd need this even though I already have a USB VM?

@andrewdavidwong
Copy link
Member

Use case description from the USB Lockout README:

You're in a place that is relatively safe, say your local hackerspace. You need to leave your computer out of sight for a small amount of time, the space is safe enough that you are not worried about it being stolen, but not enough that someone couldn't attempt a quick drive-by usb attack.

I already have a USB VM, so, in that scenario, I'm not worried.

Is there a scenario where I'd need this even though I already have a USB VM?

Maybe this is one: I only have one USB controller, and some semi-sensitive stuff is necessarily attached to it, like my webcam.

@andrewdavidwong andrewdavidwong added C: core T: enhancement Type: enhancement. A new feature that does not yet exist or improvement of existing functionality. labels May 17, 2017
@andrewdavidwong andrewdavidwong added this to the Far in the future milestone May 17, 2017
@Rudd-O
Copy link
Author

Rudd-O commented May 17, 2017 via email

@Rudd-O
Copy link
Author

Rudd-O commented May 17, 2017 via email

@andrewdavidwong
Copy link
Member

This increases the likelihood that an exploit against the USB VM will fail.

That reduces the chance that a chained exploit would succeed.

Ok, so intra-VM hardening. 👍

Is this something you want to work on?

@Rudd-O
Copy link
Author

Rudd-O commented May 21, 2017 via email

@andrewdavidwong andrewdavidwong added the help wanted This issue will probably not get done in a timely fashion without help from community contributors. label May 21, 2017
@andrewdavidwong andrewdavidwong added the security This issue pertains to the security of Qubes OS. label Apr 27, 2018
@andrewdavidwong andrewdavidwong removed this from the Release TBD milestone Aug 13, 2023
@andrewdavidwong andrewdavidwong added the P: default Priority: default. Default priority for new issues, to be replaced given sufficient information. label Aug 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C: core help wanted This issue will probably not get done in a timely fashion without help from community contributors. P: default Priority: default. Default priority for new issues, to be replaced given sufficient information. security This issue pertains to the security of Qubes OS. 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

3 participants