Thread (31 messages) 31 messages, 5 authors, 2014-12-13

Re: [systemd-devel] Supporting U2F over HID on Linux?

From: Andy Lutomirski <luto@amacapital.net>
Date: 2014-12-11 17:36:50

On Thu, Dec 11, 2014 at 12:49 AM, David Herrmann [off-list ref] wrote:
Hi

On Wed, Dec 10, 2014 at 6:07 PM, Andy Lutomirski [off-list ref] wrote:
quoted
On Tue, Dec 9, 2014 at 12:46 PM, Andy Lutomirski [off-list ref] wrote:
quoted
On Mon, Nov 3, 2014 at 12:41 PM, Andy Lutomirski [off-list ref] wrote:
quoted
On Mon, Nov 3, 2014 at 12:21 PM, Jiri Kosina [off-list ref] wrote:
quoted
On Mon, 3 Nov 2014, David Herrmann wrote:
quoted
quoted
Agreed, mostly.  My only real concern is that this could be annoying
for the userspace developers who will need to target Linux and HIDAPI
separately.  Admittedly the Linux support will be trivial.
I see. I'll not stop you from using hidraw, I'd just not recommend it.
Especially for security stuff I dislike exposing the whole HID device
writable. But yeah, I guess you got my point.
Alright, I am basically thinking loudly now, but how about we allow HID
drivers that would override default hidraw interface?

I am very well aware of the fact that this could be opening a can of
worms, so we'll have to make it very restrictive. How about, let's say, we
allow HID drivers to provide custom hidraw interface (completely
overriding the one that HID core would normally create) only for cases
such as:

- the intent is to expose only certain parts of a combined device
- the intent is to introduce some level of access control

I.e. still no interference of kernel with data parsing allowed.
Hmm.  Would this be like a filter on hidraw actions?

How would udev distinguish these special hidraw devices from normal
hidraw devices?

Also, for U2F, this could be a little awkward.  There's some crazy
fragmentation stuff to allow a U2F request to be split across HID
requests, and I think a kernel driver would much rather get the
original unfragmented application request.
I started writing a driver for this.  I got enumeration working.  I
assume I should create a "u2f" device class, and then... ?

Where am I supposed to get my character device from?  Do I register my
own chrdev major?  Do I use misc?  Is there some input thing I'm
supposed to use?
Another question:

I'm hitting this in hid_input_report:

    if (down_trylock(&hid->driver_input_lock)) {
        pr_err("HID: trylock failed\n");  // I added this
        return -EBUSY;
    }

This is a problem for u2f: u2f reports are actual protocol messages,
and there isn't a retransmit mechanism.  Losing messages randomly
causes the handshake to fail, and then nothing works.

I *think* that the only way I can hit that failure is during probe (or
if the USB stack somehow completes two transfers at once). This still
makes it quite awkward to start IO from the probe routine.

I could start a work item to take driver_input_lock, release it again,
and then start the handshake, but that sucks.
HID reports are ordered. It's the responsibility of the
transport-layer to not provide multiple reports in parallel. The
reason we have this down_trylock() is to drop packages if no driver is
loaded, yet. I wonder how you can trigger this? Does this happen
during runtime or only driver load? Do you send GET_REPORT requests to
the device?
It happens during driver probe.  I don't set GET_REPORT to my device
-- the protocol consists solely of SET_REPORT from the driver followed
by an asynchronous (but generally reasonably quick) report back from
the device.

During probe, I set INIT, and the device responds by saying "I'm a
device.  I speak this version of the protocol.

Shouldn't that code be more like:

mutex_lock(whatever);
if (driver loaded)
  deliver the report;
mutex_unlock(whatever);

and then the core could hold the lock briefly as well when probing or
in hid_hw_open/hid_hw_close.

(Also, shouldn't hid_hw_open have some kind of reference counting to
avoid interference between hidraw and real drivers?  Or does that
already work correctly somehow?)

--Andy
Thanks
David


-- 
Andy Lutomirski
AMA Capital Management, LLC
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help