QubesOS / qubes-issues

The Qubes OS Project issue tracker
https://www.qubes-os.org/doc/issue-tracking/
541 stars 48 forks source link

USB keyboard media keys only work when connected directly to dom0, not when used through USB qube #2781

Closed ilyvion closed 7 years ago

ilyvion commented 7 years ago

Qubes OS version (e.g., R3.2):

R3.2

Affected TemplateVMs (e.g., fedora-23, if applicable):


Expected behavior:

USB keyboard media keys (volume up/volume down, etc.) should work, even when input is protected through sys-usb qube.

Actual behavior:

USB keyboard media keys only work when connected directly to dom0.

Steps to reproduce the behavior:

Install Qubes while a USB keyboard with media keys is connected, so a USB qube isn't created. Verify that media keys work. Enable USB qube by following these instructions. Notice that media keys' functionality ceases.

General notes:

I feel like this should be possible to achieve; my USB mouse's extra buttons (go-back/go-forward) work despite being used through the USB qube, so it's not like special functionality is necessarily prevented by its use.


Related issues:

marmarek commented 7 years ago

There is a whitelist of allowed event for each device type: https://github.com/QubesOS/qubes-app-linux-input-proxy/blob/master/src/input-proxy-receiver.c#L380-L386

In theory all keys are allowed for "keyboard" device type. And indeed I've just checked and it works for me (at least for volume up/down).

There is a helpful debugging tool: evtest Can you install it and try to look what events your keyboard produce (in both configurations: directly to dom0 and through USB qube)?

ilyvion commented 7 years ago

All right, I installed and ran evtest in both configurations, the outputs are attached below:

dom0-evtest1.txt dom0-evtest2.txt usb-evtest1.txt usb-evtest2.txt

What's clear to me is that most of my special keys (the evtest2 files) disappear when the keyboard goes through the USB qube. And it's even quite accurate, the only feature that still works through the USB qube is the keyboard's "mouse wheel" (EV_REL / REL_WHEEL).

This is my keyboard, should it matter; the remaining functional "mousewheel" is left of the TAB key: 26-md-elite520

marmarek commented 7 years ago

Ah, I see. Your keyboard expose two devices - one for a standard keyboard and another one for all the multimedia keys. And since the other one lack of "normal keyboard keys" (letters etc), it isn't identified as a keyboard and is connected as a mouse... So, only things that are allowed for mouse works - mouse wheel in this case.

Here is how you can "fix" it manually, after connecting the keyboard:

sys-usb# systemctl |grep qubes-input-sender-mouse
(note `eventX` name in the service name, and use it in two commands below)
sys-usb# systemctl stop qubes-input-sender-mouse@eventX
sys-usb# systemctl start qubes-input-sender-keyboard@eventX

But I have no idea (yet) how to fix autodetection here. You can gather some more information about the device using udevadm info -q all -n input/eventX. Currently udev rules use ID_INPUT_KEYBOARD=1 to identify keyboard.

ilyvion commented 7 years ago

Yup, your "fix" indeed made my media keys work again. Here's the udevadm info for the "media keys" device:

[user@sys-usb ~]$ udevadm info -q all -n input/event3
P: /devices/pci-0/pci0000:00/0000:00:01.0/usb3/3-1/3-1.2/3-1.2:1.1/0003:046D:C30A.0006/input/input3/event3
N: input/event3
S: input/by-id/usb-Logitech_Logitech_USB_Keyboard-if01-event-mouse
S: input/by-path/xen-pci-0-pci-0000:00:01.0-usb-0:1.2:1.1-event-mouse
E: DEVLINKS=/dev/input/by-path/xen-pci-0-pci-0000:00:01.0-usb-0:1.2:1.1-event-mouse /dev/input/by-id/usb-Logitech_Logitech_USB_Keyboard-if01-event-mouse
E: DEVNAME=/dev/input/event3
E: DEVPATH=/devices/pci-0/pci0000:00/0000:00:01.0/usb3/3-1/3-1.2/3-1.2:1.1/0003:046D:C30A.0006/input/input3/event3
E: ID_BUS=usb
E: ID_INPUT=1
E: ID_INPUT_KEY=1
E: ID_INPUT_MOUSE=1
E: ID_MODEL=Logitech_USB_Keyboard
E: ID_MODEL_ENC=Logitech\x20USB\x20Keyboard
E: ID_MODEL_ID=c30a
E: ID_PATH=xen-pci-0-pci-0000:00:01.0-usb-0:1.2:1.1
E: ID_PATH_TAG=xen-pci-0-pci-0000_00_01_0-usb-0_1_2_1_1
E: ID_REVISION=1500
E: ID_SERIAL=Logitech_Logitech_USB_Keyboard
E: ID_TYPE=hid
E: ID_USB_DRIVER=usbhid
E: ID_USB_INTERFACES=:030101:030000:
E: ID_USB_INTERFACE_NUM=01
E: ID_VENDOR=Logitech
E: ID_VENDOR_ENC=Logitech
E: ID_VENDOR_ID=046d
E: LIBINPUT_DEVICE_GROUP=3/46d/c30a/110:usb-0000:00:01.0-1
E: MAJOR=13
E: MINOR=67
E: SUBSYSTEM=input
E: USEC_INITIALIZED=3576051

Here's what I noticed: My USB mouse only has ID_INPUT_MOUSE=1, my USB keyboard has ID_INPUT_KEY=1 and ID_INPUT_KEYBOARD=1, and my USB "media keyboard" has ID_INPUT_KEY=1 and ID_INPUT_MOUSE=1.

If you look in the /lib/udev/rules.d/70-touchpad-quirks.rules file, there are some rules that are specific down to a single device model. So I don't suppose it would be entirely unreasonable to make a rule that looks for the correct combination of ID_MODEL, ID_INPUT_KEY and ID_INPUT_MOUSE and forces it to be recognized as a keyboard?

Unfortunately I'm not familiar enough with udev to really think of how to go about doing this myself.

marmarek commented 7 years ago

Maybe the right thing to do is use ID_INPUT_KEY=1 instead of ID_INPUT_KEYBOARD=1 to detect "keyboard"? Try changing it in /lib/udev/rules.d/90-qubes-input-proxy.rules in all 3 places (directly in USB VM, so you can easily revert by just restarting it). You need to reload udev after: sudo udevadm control -R

ilyvion commented 7 years ago

It didn't do anything right away, but by unplugging and plugging the keyboard back in afterwards, that change made an effect and the media keys now work as expected.

The "media key device" was detected as a keyboard-mouse device. Which makes sense, to be fair, since it's a keyboard which also has a mouse wheel:

[user@sys-usb ~]$ systemctl | grep qubes-input
qubes-input-sender-keyboard-mouse@event3.service  loaded active     running   Qubes input proxy sender (keyboard, fallback to mouse)
qubes-input-sender-keyboard@event2.service        loaded active     running   Qubes input proxy sender (keyboard)
qubes-input-sender-mouse@event1.service           loaded active     running   Qubes input proxy sender (mouse)
v6ak commented 7 years ago

Marek, I can confirm that using ID_INPUT_KEY=1 instead of ID_INPUT_KEYBOARD=1 has fixed the issue for me. I have a different keyboard (Ergodox with TMK firmware) that was identified as two keyboards and two mice. After the fix, it identifies itself as three keyboards (WTF-lol) and one mouse (that's OK), but it works.

I hope it does not break anything else...

marmarek commented 7 years ago

Ok, lets see how it will work on a larger scale. I'll upload a package to testing repo soon.

v6ak commented 7 years ago

Well, it now tries to connect my internal webcam as a keyboard. While it is better, it is not optimal...

marmarek commented 7 years ago

On Mon, May 15, 2017 at 01:07:32PM -0700, Vít Šesták wrote:

Well, it now tries to connect my internal webcam as a keyboard. While it is better, it is not optimal...

Well, your internal webcam probably do expose some key events. Mine do:

Supported events:
  Event type 0 (EV_SYN)
  Event type 1 (EV_KEY)
    Event code 212 (KEY_CAMERA)
Properties:

This is very interesting, I have no idea where this button physically is. But I've seen a button on some external USB cameras, so maybe it's simply the same hardware in a different chassis... Maybe @Rudd-O idea in #2783 is the way to go?

-- 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?

Rudd-O commented 7 years ago

Yay! -- Sent from my Android device with K-9 Mail. Please excuse my brevity.

v6ak commented 7 years ago

Well, your internal webcam probably do expose some key events. Mine do:

Mine looks similar.

Well, if it really exposes keys, it can be considered as a feature (though annoying) rather than as a bug.

This is very interesting, I have no idea where this button physically is. But I've seen a button on some external USB cameras, so maybe it's simply the same hardware in a different chassis...

Or different hardware with the same firmware…

Maybe @Rudd-O idea in #2783 is the way to go?

That sounds like the right way.

Rudd-O commented 7 years ago

It would also be excellent if the usbvm could present a tray icon showing the status of the deny_new_usb toggle in /sys, and allowing one to toggle it on and off. I am on email so I cannot open a ticket, but this would to be phenomenal to add as a new ticket.

On May 15, 2017 10:20:41 PM GMT+02:00, "Marek Marczykowski-Górecki" notifications@github.com wrote:

On Mon, May 15, 2017 at 01:07:32PM -0700, Vít Šesták wrote:

Well, it now tries to connect my internal webcam as a keyboard. While it is better, it is not optimal...

Well, your internal webcam probably do expose some key events. Mine do:

Supported events:
 Event type 0 (EV_SYN)
 Event type 1 (EV_KEY)
   Event code 212 (KEY_CAMERA)
Properties:

This is very interesting, I have no idea where this button physically is. But I've seen a button on some external USB cameras, so maybe it's simply the same hardware in a different chassis... Maybe @Rudd-O idea in #2783 is the way to go?

-- 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?

-- You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub: https://github.com/QubesOS/qubes-issues/issues/2781#issuecomment-301592861

--

Rudd-O

http://rudd-o.com/