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

simplify the support of USB headsets #8956

Open
rjrizzuto opened this issue Feb 22, 2024 · 18 comments
Open

simplify the support of USB headsets #8956

rjrizzuto opened this issue Feb 22, 2024 · 18 comments
Labels
C: audio C: usb proxy hardware support P: default Priority: default. Default priority for new issues, to be replaced given sufficient information. T: enhancement Type: enhancement. A new feature that does not yet exist or improvement of existing functionality. ux User experience

Comments

@rjrizzuto
Copy link

How to file a helpful issue

The problem you're addressing (if any)

Being able to connect a USB headset to Qubes for teleconferencing should be as simple as plugging the headset in. I.e. no harder than using an aux port. The docs I have seen are many obtuse steps long. Plugging in a USB headset and attempting to assign the device to a qube also doesn't work. It gives the attached error messages.

Screenshot_2024-02-21_20-52-30

The solution you'd like

It should be easy to connect and use a usb headset. I.e. connect it, and select it as an additional audio device, just like other supported audio devices.

The value to a user, and who that user might be

@rjrizzuto rjrizzuto added P: default Priority: default. Default priority for new issues, to be replaced given sufficient information. T: enhancement Type: enhancement. A new feature that does not yet exist or improvement of existing functionality. labels Feb 22, 2024
@andrewdavidwong
Copy link
Member

Possible duplicate of #8504.

@rjrizzuto
Copy link
Author

I am not sure it is a duplicate - the other ticket talks about an sys-audio qube, which may be an implementation detail. The goal seems the same - to easily use USB audio. There is a similar ticket for bluetooth audio, so there may be synergies.

@ben-grande
Copy link

simplify the support of USB headsets

This is not specific to USB headset, but to any USB device you want persistently attached.

  1. do not attach USB devices to dom0, create sys-usb (I don't know if your system allows that)
  2. start sys-usb and connect the USB device
  3. from dom0, attach persistently the USB device to the client qube
  4. before starting the client qube on next boot, you need to start sys-usb

So, after this is done, on the next start of your system, startinng sys-usb and the client qube will be enough to have the client with the headsets attached.

From the instructions, you can notice it can be any USB device, because of this, I believe it is a duplicate of:

With the new UX device flow, it will be easier to attach headsets and every other USB device.

@rjrizzuto
Copy link
Author

FYI, I am running 4.2, and it has a sys-usb. already. Can I do step 3 via the gui?

@DemiMarie
Copy link

An alternative option is to set sys-usb as the AudioVM of the VM you want.

@ben-grande
Copy link

FYI, I am running 4.2, and it has a sys-usb. already. Can I do step 3 via the gui?

No, but with Demi's advice, you can skip attaching to the client.
You still need to boot the Audio Server sys-usb before the client, else you will need to restart pipewire on the client.

But to answer your question, there is no way to persistently attach a device with the GUI currently.

@rjrizzuto
Copy link
Author

rjrizzuto commented Feb 23, 2024 via email

@DemiMarie
Copy link

@rjrizzuto Are you suggesting that the headset should show up as if it were in dom0?

@andrewdavidwong andrewdavidwong added the ux User experience label Feb 23, 2024
@rjrizzuto
Copy link
Author

I am not saying anything about implementation. What I am suggesting is how it should work for the user. Basically, I think it should work something like:

  • user plugs in USB headset
  • Qubes prompts user to allow the headset for audio output and/or input.
  • User gives permission(s)
  • User can direct all output to the headset (or per-qube?)
  • User can attach the headset mic to a qube
  • User unplugs USB headset
  • Qubes restores prior audio output device, disconnects headset mic

@DemiMarie
Copy link

@marmarta thoughts on the UX?

@bi0shacker001
Copy link

As DemiMarie pointed out, this is readily solved by making sys-usb an audiovm, but it looks like the issue mentioned in the screenshot is specifically someone who has manually tagged a device as a persistent usb connection. Usb device numbering is non-persistent, and is in order of enumeration, so this seems to be a flaw in the usb scheme, and is also one of the expected tradeoffs we get with qubes

A maybe solution is to hold a database of usbids and their purposes, like udev already does, and allow a proposed gui/perssirent attachment system to list devices based on that? It'd probably be more stable than our current system, and would still allow devices to be numbered the same way in the backend (as I think right now we literally just use the device root-port numbering from the USB subsystem)

@DemiMarie
Copy link

As DemiMarie pointed out, this is readily solved by making sys-usb an audiovm, but it looks like the issue mentioned in the screenshot is specifically someone who has manually tagged a device as a persistent usb connection. Usb device numbering is non-persistent, and is in order of enumeration, so this seems to be a flaw in the usb scheme, and is also one of the expected tradeoffs we get with qubes

This is a serious problem. Qubes OS requires the numbering to be persistent, because it is the only way to identify a device that is not under the control of the device itself.

A maybe solution is to hold a database of usbids and their purposes, like udev already does, and allow a proposed gui/perssirent attachment system to list devices based on that? It'd probably be more stable than our current system, and would still allow devices to be numbered the same way in the backend (as I think right now we literally just use the device root-port numbering from the USB subsystem)

This would be a security vulnerability. In Qubes OS, USB devices are assumed to be potentially be attempting to maliciously impersonating other devices. The port number is the only information we have about a device that is not under the control of the device.

Is there some way (maybe a Linux kernel change?) to force device root port numbers to be persistant?

@bi0shacker001
Copy link

bi0shacker001 commented Mar 19, 2024

This would be a security vulnerability. In Qubes OS, USB devices are assumed to be potentially be attempting to maliciously impersonating other devices. The port number is the only information we have about a device that is not under the control of the device.

The idea isn't "Trust a device explicitly based on its USB id", and is instead "this is some information, we can use it to make a pretty list to tell users "Hey, you're trying to add a headset to this qube, these devices say they're headsets", and give the users the option. It's a means of making a frontend easier, rather than a line of defense.

Is there some way (maybe a Linux kernel change?) to force device root port numbers to be persistant?

I don't... BELIEVE so?
IIRC, you run the risk of non-persistent numbers regardless of what you do, because of hubs. Like, you could... theoretically, rely on the usb device tree, and generate a number like usb 1-1-1-2 (for, like, root 1, port 1, first port on a hub, second device on that port), but since USB device configuration possibilities are potentially infinite (given nested hubs, etc), I don't believe any infrastructure exists for doing so with standardized numbering/length, as USB device IDs are an infinitely less complicated method of detecting and working with them.
The closest you could get to having that information is the usb device tree (you can see it with lsusb --tree), and I THINK hubs report accurate device numbers, but that's, again, trusting the device again (in this case, the hub). That would also rely on the user plugging the device into the same device configuration every time (for instance, they'd have to use the same front-left USB port on their computer every time, and if they plug something else in there, it'd be auto-mapped instead, for instance)

(also, take all this information with a grain of salt. While I do understand the things I'm explicitly saying, I'm not a kernel dev, and can't pretend to understand everything surrounding the USB stack)

@DemiMarie
Copy link

The closest you could get to having that information is the usb device tree (you can see it with lsusb --tree), and I THINK hubs report accurate device numbers, but that's, again, trusting the device again (in this case, the hub).

I think the USB device tree is actually the answer here. Obviously, one must trust a hub to correctly enumerate the devices behind that hub, but the hub cannot impersonate any device that is not attached to that hub, and that’s both the best that can be done and quite useful in practice. For instance, I can ensure that none of the devices attached to an untrusted hub can impersonate a trusted device.

That would also rely on the user plugging the device into the same device configuration every time (for instance, they'd have to use the same front-left USB port on their computer every time, and if they plug something else in there, it'd be auto-mapped instead, for instance)

Could the GUI warn about that? Perhaps something like, “A device claiming to be ABC was previously in port 1, but now is in port 2. This is usually because the device was unplugged and plugged back in at a different location, but could also be due to an attack. Only say “Yes” if you actually moved the device.”

@bi0shacker001
Copy link

That would also rely on the user plugging the device into the same device configuration every time (for instance, they'd have to use the same front-left USB port on their computer every time, and if they plug something else in there, it'd be auto-mapped instead, for instance)

Could the GUI warn about that? Perhaps something like, “A device claiming to be ABC was previously in port 1, but now is in port 2. This is usually because the device was unplugged and plugged back in at a different location, but could also be due to an attack. Only say “Yes” if you actually moved the device.”

The only real way to know what device is what is to use USB IDs, unfortunately (as that's the USB spec standard to identify a device). But that's still useful from a security perspective. if a user maps (usb id) at (port location), and then (different usb id) is located at (port location) or (original usb id) is located at (different port location), that could be a good time to ask the user about that. You can't trust malicious devices to not say they're something different (so obviously deviceid spoofing would be a possible issue), but if a user says "this device is this, and I want it here" and then if that exact port isn't that exact id, it probably shouldn't be mapped

@rjrizzuto
Copy link
Author

rjrizzuto commented Mar 19, 2024 via email

@marmarek
Copy link
Member

theoretically, rely on the usb device tree, and generate a number like usb 1-1-1-2 (for, like, root 1, port 1, first port on a hub, second device on that port),

This is how the current device id is generated. The only issue is that the bus number (the first digit) might change if you have multiple controllers and they are detected by Linux in different order. Other numbers are stable (for a given port in a given hub etc).

I think this can be solved by replacing the bus number with something that we can make stable - for example VM-side BDF of the controller (QubesOS/qubes-core-admin#559 made it mostly stable). But since one PCI device can show as multiple buses (for example one for USB 2.0 and one for USB 3.0) it needs something at bit smarter.

but since USB device configuration possibilities are potentially infinite (given nested hubs, etc),

Not really, the limit AFAIR is 7.

The user might plug the same headset into a different port the next time.

Yes, and this will need some explicit handling - with user confirmation. It might be really the same device (in which case the user would approve), but it could be also another device pretending to be your headset this time.

@bi0shacker001
Copy link

theoretically, rely on the usb device tree, and generate a number like usb 1-1-1-2 (for, like, root 1, port 1, first port on a hub, second device on that port),

This is how the current device id is generated. The only issue is that the bus number (the first digit) might change if you have multiple controllers and they are detected by Linux in different order. Other numbers are stable (for a given port in a given hub etc).

I've tested thid, and if I unplug a device and plug it back in, it gets a new id.

I think this can be solved by replacing the bus number with something that we can make stable - for example VM-side BDF of the controller (QubesOS/qubes-core-admin#559 made it mostly stable). But since one PCI device can show as multiple buses (for example one for USB 2.0 and one for USB 3.0) it needs something at bit smarter.

but since USB device configuration possibilities are potentially infinite (given nested hubs, etc),

Not really, the limit AFAIR is 7.

The user might plug the same headset into a different port the next time.

Yes, and this will need some explicit handling - with user confirmation. It might be really the same device (in which case the user would approve), but it could be also another device pretending to be your headset this time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C: audio C: usb proxy hardware support P: default Priority: default. Default priority for new issues, to be replaced given sufficient information. T: enhancement Type: enhancement. A new feature that does not yet exist or improvement of existing functionality. ux User experience
Projects
None yet
Development

No branches or pull requests

6 participants