Commit Graph

19 Commits

Author SHA1 Message Date
Andrey Konovalov 45285dba03 usb: raw-gadget: properly handle interrupted requests
commit e8033bde451eddfb9b1bbd6e2d848c1b5c277222 upstream.

Currently, if a USB request that was queued by Raw Gadget is interrupted
(via a signal), wait_for_completion_interruptible returns -ERESTARTSYS.
Raw Gadget then attempts to propagate this value to userspace as a return
value from its ioctls. However, when -ERESTARTSYS is returned by a syscall
handler, the kernel internally restarts the syscall.

This doesn't allow userspace applications to interrupt requests queued by
Raw Gadget (which is required when the emulated device is asked to switch
altsettings). It also violates the implied interface of Raw Gadget that a
single ioctl must only queue a single USB request.

Instead, make Raw Gadget do what GadgetFS does: check whether the request
was interrupted (dequeued with status == -ECONNRESET) and report -EINTR to
userspace.

Fixes: f2c2e71764 ("usb: gadget: add raw-gadget interface")
Cc: stable <stable@kernel.org>
Signed-off-by: Andrey Konovalov <andreyknvl@gmail.com>
Link: https://lore.kernel.org/r/0db45b1d7cc466e3d4d1ab353f61d63c977fbbc5.1698350424.git.andreyknvl@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-11-08 11:56:22 +01:00
Zqiang 83e30f2bf8 USB: gadget: Fix the memory leak in raw_gadget driver
Currently, increasing raw_dev->count happens before invoke the
raw_queue_event(), if the raw_queue_event() return error, invoke
raw_release() will not trigger the dev_free() to be called.

[  268.905865][ T5067] raw-gadget.0 gadget.0: failed to queue event
[  268.912053][ T5067] udc dummy_udc.0: failed to start USB Raw Gadget: -12
[  268.918885][ T5067] raw-gadget.0: probe of gadget.0 failed with error -12
[  268.925956][ T5067] UDC core: USB Raw Gadget: couldn't find an available UDC or it's busy
[  268.934657][ T5067] misc raw-gadget: fail, usb_gadget_register_driver returned -16

BUG: memory leak

[<ffffffff8154bf94>] kmalloc_trace+0x24/0x90 mm/slab_common.c:1076
[<ffffffff8347eb55>] kmalloc include/linux/slab.h:582 [inline]
[<ffffffff8347eb55>] kzalloc include/linux/slab.h:703 [inline]
[<ffffffff8347eb55>] dev_new drivers/usb/gadget/legacy/raw_gadget.c:191 [inline]
[<ffffffff8347eb55>] raw_open+0x45/0x110 drivers/usb/gadget/legacy/raw_gadget.c:385
[<ffffffff827d1d09>] misc_open+0x1a9/0x1f0 drivers/char/misc.c:165

[<ffffffff8154bf94>] kmalloc_trace+0x24/0x90 mm/slab_common.c:1076
[<ffffffff8347cd2f>] kmalloc include/linux/slab.h:582 [inline]
[<ffffffff8347cd2f>] raw_ioctl_init+0xdf/0x410 drivers/usb/gadget/legacy/raw_gadget.c:460
[<ffffffff8347dfe9>] raw_ioctl+0x5f9/0x1120 drivers/usb/gadget/legacy/raw_gadget.c:1250
[<ffffffff81685173>] vfs_ioctl fs/ioctl.c:51 [inline]

[<ffffffff8154bf94>] kmalloc_trace+0x24/0x90 mm/slab_common.c:1076
[<ffffffff833ecc6a>] kmalloc include/linux/slab.h:582 [inline]
[<ffffffff833ecc6a>] kzalloc include/linux/slab.h:703 [inline]
[<ffffffff833ecc6a>] dummy_alloc_request+0x5a/0xe0 drivers/usb/gadget/udc/dummy_hcd.c:665
[<ffffffff833e9132>] usb_ep_alloc_request+0x22/0xd0 drivers/usb/gadget/udc/core.c:196
[<ffffffff8347f13d>] gadget_bind+0x6d/0x370 drivers/usb/gadget/legacy/raw_gadget.c:292

This commit therefore invoke kref_get() under the condition that
raw_queue_event() return success.

Reported-by: syzbot+feb045d335c1fdde5bf7@syzkaller.appspotmail.com
Cc: stable <stable@kernel.org>
Closes: https://syzkaller.appspot.com/bug?extid=feb045d335c1fdde5bf7
Signed-off-by: Zqiang <qiang.zhang1211@gmail.com>
Reviewed-by: Andrey Konovalov <andreyknvl@gmail.com>
Tested-by: Andrey Konovalov <andreyknvl@gmail.com>
Link: https://lore.kernel.org/r/20230714074011.20989-1-qiang.zhang1211@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 17:43:23 +02:00
Alan Stern 90bc2af246 USB: gadget: Fix double-free bug in raw_gadget driver
Re-reading a recently merged fix to the raw_gadget driver showed that
it inadvertently introduced a double-free bug in a failure pathway.
If raw_ioctl_init() encounters an error after the driver ID number has
been allocated, it deallocates the ID number before returning.  But
when dev_free() runs later on, it will then try to deallocate the ID
number a second time.

Closely related to this issue is another error in the recent fix: The
ID number is stored in the raw_dev structure before the code checks to
see whether the structure has already been initialized, in which case
the new ID number would overwrite the earlier value.

The solution to both bugs is to keep the new ID number in a local
variable, and store it in the raw_dev structure only after the check
for prior initialization.  No errors can occur after that point, so
the double-free will never happen.

Fixes: f2d8c26068 ("usb: gadget: Fix non-unique driver names in raw-gadget driver")
CC: Andrey Konovalov <andreyknvl@gmail.com>
CC: <stable@vger.kernel.org>
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Link: https://lore.kernel.org/r/YrMrRw5AyIZghN0v@rowland.harvard.edu
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-06-24 13:45:21 +02:00
Alan Stern f2d8c26068 usb: gadget: Fix non-unique driver names in raw-gadget driver
In a report for a separate bug (which has already been fixed by commit
5f0b5f4d50 "usb: gadget: fix race when gadget driver register via
ioctl") in the raw-gadget driver, the syzbot console log included
error messages caused by attempted registration of a new driver with
the same name as an existing driver:

> kobject_add_internal failed for raw-gadget with -EEXIST, don't try to register things with the same name in the same directory.
> UDC core: USB Raw Gadget: driver registration failed: -17
> misc raw-gadget: fail, usb_gadget_register_driver returned -17

These errors arise because raw_gadget.c registers a separate UDC
driver for each of the UDC instances it creates, but these drivers all
have the same name: "raw-gadget".  Until recently this wasn't a
problem, but when the "gadget" bus was added and UDC drivers were
registered on this bus, it became possible for name conflicts to cause
the registrations to fail.  The reason is simply that the bus code in
the driver core uses the driver name as a sysfs directory name (e.g.,
/sys/bus/gadget/drivers/raw-gadget/), and you can't create two
directories with the same pathname.

To fix this problem, the driver names used by raw-gadget are made
distinct by appending a unique ID number: "raw-gadget.N", with a
different value of N for each driver instance.  And to avoid the
proliferation of error handling code in the raw_ioctl_init() routine,
the error return paths are refactored into the common pattern (goto
statements leading to cleanup code at the end of the routine).

Link: https://lore.kernel.org/all/0000000000008c664105dffae2eb@google.com/
Fixes: fc274c1e99 "USB: gadget: Add a new bus for gadgets"
CC: Andrey Konovalov <andreyknvl@gmail.com>
CC: <stable@vger.kernel.org>
Reported-and-tested-by: syzbot+02b16343704b3af1667e@syzkaller.appspotmail.com
Reviewed-by: Andrey Konovalov <andreyknvl@gmail.com>
Acked-by: Hillf Danton <hdanton@sina.com>
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Link: https://lore.kernel.org/r/YqdG32w+3h8c1s7z@rowland.harvard.edu
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-06-21 10:51:09 +02:00
Linus Torvalds 54c2cc7919 USB / Thunderbolt changes for 5.19-rc1
Here is the "big" set of USB and Thunderbolt driver changes for
 5.18-rc1.  For the most part it's been a quiet development cycle for the
 USB core, but there are the usual "hot spots" of development activity.
 
 Included in here are:
 	- Thunderbolt driver updates:
 		- fixes for devices without displayport adapters
 		- lane bonding support and improvements
 		- other minor changes based on device testing
 	- dwc3 gadget driver changes.  It seems this driver will never
 	  be finished given that the IP core is showing up in zillions
 	  of new devices and each implementation decides to do something
 	  different with it...
 	- uvc gadget driver updates as more devices start to use and
 	  rely on this hardware as well
 	- usb_maxpacket() api changes to remove an unneeded and unused
 	  parameter.
 	- usb-serial driver device id updates and small cleanups
 	- typec cleanups and fixes based on device testing
 	- device tree updates for usb properties
 	- lots of other small fixes and driver updates.
 
 All of these have been in linux-next for weeks with no reported
 problems.
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 
 iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCYpnZGw8cZ3JlZ0Brcm9h
 aC5jb20ACgkQMUfUDdst+ymQhwCeLVANsQjBcL4ys4skl+1In17y28gAn3rEZ7rQ
 Yv4uP9zadUqg3Cx0vjgf
 =3s5s
 -----END PGP SIGNATURE-----

Merge tag 'usb-5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

Pull USB / Thunderbolt updates from Greg KH:
 "Here is the "big" set of USB and Thunderbolt driver changes for
  5.18-rc1. For the most part it's been a quiet development cycle for
  the USB core, but there are the usual "hot spots" of development
  activity.

  Included in here are:

   - Thunderbolt driver updates:
       - fixes for devices without displayport adapters
       - lane bonding support and improvements
       - other minor changes based on device testing

   - dwc3 gadget driver changes.

     It seems this driver will never be finished given that the IP core
     is showing up in zillions of new devices and each implementation
     decides to do something different with it...

   - uvc gadget driver updates as more devices start to use and rely on
     this hardware as well

   - usb_maxpacket() api changes to remove an unneeded and unused
     parameter.

   - usb-serial driver device id updates and small cleanups

   - typec cleanups and fixes based on device testing

   - device tree updates for usb properties

   - lots of other small fixes and driver updates.

  All of these have been in linux-next for weeks with no reported
  problems"

* tag 'usb-5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (154 commits)
  USB: new quirk for Dell Gen 2 devices
  usb: dwc3: core: Add error log when core soft reset failed
  usb: dwc3: gadget: Move null pinter check to proper place
  usb: hub: Simplify error and success path in port_over_current_notify
  usb: cdns3: allocate TX FIFO size according to composite EP number
  usb: dwc3: Fix ep0 handling when getting reset while doing control transfer
  usb: Probe EHCI, OHCI controllers asynchronously
  usb: isp1760: Fix out-of-bounds array access
  xhci: Don't defer primary roothub registration if there is only one roothub
  USB: serial: option: add Quectel BG95 modem
  USB: serial: pl2303: fix type detection for odd device
  xhci: Allow host runtime PM as default for Intel Alder Lake N xHCI
  xhci: Remove quirk for over 10 year old evaluation hardware
  xhci: prevent U2 link power state if Intel tier policy prevented U1
  xhci: use generic command timer for stop endpoint commands.
  usb: host: xhci-plat: omit shared hcd if either root hub has no ports
  usb: host: xhci-plat: prepare operation w/o shared hcd
  usb: host: xhci-plat: create shared hcd after having added main hcd
  xhci: prepare for operation w/o shared hcd
  xhci: factor out parts of xhci_gen_setup()
  ...
2022-06-03 11:17:49 -07:00
Schspa Shi 5f0b5f4d50 usb: gadget: fix race when gadget driver register via ioctl
The usb_gadget_register_driver can be called multi time by to
threads via USB_RAW_IOCTL_RUN ioctl syscall, which will lead
to multiple registrations.

Call trace:
  driver_register+0x220/0x3a0 drivers/base/driver.c:171
  usb_gadget_register_driver_owner+0xfb/0x1e0
    drivers/usb/gadget/udc/core.c:1546
  raw_ioctl_run drivers/usb/gadget/legacy/raw_gadget.c:513 [inline]
  raw_ioctl+0x1883/0x2730 drivers/usb/gadget/legacy/raw_gadget.c:1220
  ioctl USB_RAW_IOCTL_RUN

This routine allows two processes to register the same driver instance
via ioctl syscall. which lead to a race condition.

Please refer to the following scenarios.

           T1                                  T2
------------------------------------------------------------------
usb_gadget_register_driver_owner
  driver_register                    driver_register
    driver_find                       driver_find
    bus_add_driver                    bus_add_driver
      priv alloced                     <context switch>
      drv->p = priv;
      <schedule out>
      kobject_init_and_add // refcount = 1;
   //couldn't find an available UDC or it's busy
   <context switch>
                                       priv alloced
                                       drv->priv = priv;
                                       kobject_init_and_add
                                         ---> refcount = 1 <------
                                       // register success
                                       <context switch>
===================== another ioctl/process ======================
                                      driver_register
                                       driver_find
                                        k = kset_find_obj()
                                         ---> refcount = 2 <------
                                        <context out>
   driver_unregister
   // drv->p become T2's priv
   ---> refcount = 1 <------
   <context switch>
                                        kobject_put(k)
                                         ---> refcount = 0 <------
                                        return priv->driver;
                                        --------UAF here----------

There will be UAF in this scenario.

We can fix it by adding a new STATE_DEV_REGISTERING device state to
avoid double register.

Reported-by: syzbot+dc7c3ca638e773db07f6@syzkaller.appspotmail.com
Link: https://lore.kernel.org/all/000000000000e66c2805de55b15a@google.com/
Reviewed-by: Andrey Konovalov <andreyknvl@gmail.com>
Signed-off-by: Schspa Shi <schspa@gmail.com>
Link: https://lore.kernel.org/r/20220508150247.38204-1-schspa@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-05-12 18:34:58 +02:00
Alan Stern af1969a2d7 USB: gadget: Rename usb_gadget_probe_driver()
In preparation for adding a "gadget" bus, this patch renames
usb_gadget_probe_driver() to usb_gadget_register_driver().  The new
name will be more accurate, since gadget drivers will be registered on
the gadget bus and the probing will be done by the driver core, not
the UDC core.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Link: https://lore.kernel.org/r/YmSc29YZvxgT5fEJ@rowland.harvard.edu
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-04-26 14:00:13 +02:00
Wei Ming Chen 0d48aee69c usb: raw-gadget: return -EINVAL if no proper ep address available
If we try to use raw_ioctl_ep_enable() for ep5in on a hardware that
only support from ep1-ep4 for both in and out direction, it will return
-EBUSY originally.

I think it will be more intuitive if we return -EINVAL, because -EBUSY
sounds like ep5in is not available now, but might be available in the
future.

Reviewed-by: Andrey Konovalov <andreyknvl@gmail.com>
Signed-off-by: Wei Ming Chen <jj251510319013@gmail.com>
Link: https://lore.kernel.org/r/20220311082944.4881-1-jj251510319013@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-03-15 15:31:39 +01:00
Julia Lawall beb8518e26 usb: raw-gadget: use kzalloc
Use kzalloc instead of kmalloc + memset.

The semantic patch that makes this change is:
(https://coccinelle.gitlabpages.inria.fr/website/)

//<smpl>
@@
expression res, size, flag;
@@
- res = kmalloc(size, flag);
+ res = kzalloc(size, flag);
  ...
- memset(res, 0, size);
//</smpl>

Signed-off-by: Julia Lawall <Julia.Lawall@inria.fr>

Link: https://lore.kernel.org/r/20220312102705.71413-7-Julia.Lawall@inria.fr
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-03-15 15:24:36 +01:00
Jann Horn 292d2c82b1 usb: raw-gadget: fix handling of dual-direction-capable endpoints
Under dummy_hcd, every available endpoint is *either* IN or OUT capable.
But with some real hardware, there are endpoints that support both IN and
OUT. In particular, the PLX 2380 has four available endpoints that each
support both IN and OUT.

raw-gadget currently gets confused and thinks that any endpoint that is
usable as an IN endpoint can never be used as an OUT endpoint.

Fix it by looking at the direction in the configured endpoint descriptor
instead of looking at the hardware capabilities.

With this change, I can use the PLX 2380 with raw-gadget.

Fixes: f2c2e71764 ("usb: gadget: add raw-gadget interface")
Cc: stable <stable@vger.kernel.org>
Tested-by: Andrey Konovalov <andreyknvl@gmail.com>
Reviewed-by: Andrey Konovalov <andreyknvl@gmail.com>
Signed-off-by: Jann Horn <jannh@google.com>
Link: https://lore.kernel.org/r/20220126205214.2149936-1-jannh@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-01-31 14:22:49 +01:00
Andrey Konovalov 4c1934bda8 usb: raw-gadget: add copyright
Add copyright to drivers/usb/gadget/legacy/raw_gadget.c.

Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
Link: https://lore.kernel.org/r/c8937266c4a5da073ac81cd471b18d869c984dfe.1611429174.git.andreyknvl@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-01-26 18:38:45 +01:00
Zqiang 129aa97345 usb: raw-gadget: fix memory leak in gadget_setup
When fetch 'event' from event queue, after copy its address
space content to user space, the 'event' the memory space
pointed to by the 'event' pointer need be freed.

BUG: memory leak
unreferenced object 0xffff888110622660 (size 32):
  comm "softirq", pid 0, jiffies 4294941981 (age 12.480s)
  hex dump (first 32 bytes):
    02 00 00 00 08 00 00 00 80 06 00 01 00 00 40 00  ..............@.
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  backtrace:
    [<00000000efd29abd>] kmalloc include/linux/slab.h:554 [inline]
    [<00000000efd29abd>] raw_event_queue_add drivers/usb/gadget/legacy/raw_gadget.c:66 [inline]
    [<00000000efd29abd>] raw_queue_event drivers/usb/gadget/legacy/raw_gadget.c:225 [inline]
    [<00000000efd29abd>] gadget_setup+0xf6/0x220 drivers/usb/gadget/legacy/raw_gadget.c:343
    [<00000000952c4a46>] dummy_timer+0xb9f/0x14c0 drivers/usb/gadget/udc/dummy_hcd.c:1899
    [<0000000074ac2c54>] call_timer_fn+0x38/0x200 kernel/time/timer.c:1415
    [<00000000560a3a79>] expire_timers kernel/time/timer.c:1460 [inline]
    [<00000000560a3a79>] __run_timers.part.0+0x319/0x400 kernel/time/timer.c:1757
    [<000000009d9503d0>] __run_timers kernel/time/timer.c:1738 [inline]
    [<000000009d9503d0>] run_timer_softirq+0x3d/0x80 kernel/time/timer.c:1770
    [<000000009df27c89>] __do_softirq+0xcc/0x2c2 kernel/softirq.c:298
    [<000000007a3f1a47>] asm_call_irq_on_stack+0xf/0x20
    [<000000004a62cc2e>] __run_on_irqstack arch/x86/include/asm/irq_stack.h:26 [inline]
    [<000000004a62cc2e>] run_on_irqstack_cond arch/x86/include/asm/irq_stack.h:77 [inline]
    [<000000004a62cc2e>] do_softirq_own_stack+0x32/0x40 arch/x86/kernel/irq_64.c:77
    [<00000000b0086800>] invoke_softirq kernel/softirq.c:393 [inline]
    [<00000000b0086800>] __irq_exit_rcu kernel/softirq.c:423 [inline]
    [<00000000b0086800>] irq_exit_rcu+0x91/0xc0 kernel/softirq.c:435
    [<00000000175f9523>] sysvec_apic_timer_interrupt+0x36/0x80 arch/x86/kernel/apic/apic.c:1091
    [<00000000a348e847>] asm_sysvec_apic_timer_interrupt+0x12/0x20 arch/x86/include/asm/idtentry.h:631
    [<0000000060661100>] native_safe_halt arch/x86/include/asm/irqflags.h:60 [inline]
    [<0000000060661100>] arch_safe_halt arch/x86/include/asm/irqflags.h:103 [inline]
    [<0000000060661100>] acpi_safe_halt drivers/acpi/processor_idle.c:111 [inline]
    [<0000000060661100>] acpi_idle_do_entry+0xc3/0xd0 drivers/acpi/processor_idle.c:517
    [<000000003f413b99>] acpi_idle_enter+0x128/0x1f0 drivers/acpi/processor_idle.c:648
    [<00000000f5e5afb8>] cpuidle_enter_state+0xc9/0x650 drivers/cpuidle/cpuidle.c:237
    [<00000000d50d51fc>] cpuidle_enter+0x29/0x40 drivers/cpuidle/cpuidle.c:351
    [<00000000d674baed>] call_cpuidle kernel/sched/idle.c:132 [inline]
    [<00000000d674baed>] cpuidle_idle_call kernel/sched/idle.c:213 [inline]
    [<00000000d674baed>] do_idle+0x1c8/0x250 kernel/sched/idle.c:273

Reported-by: syzbot+bd38200f53df6259e6bf@syzkaller.appspotmail.com
Signed-off-by: Zqiang <qiang.zhang@windriver.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
2020-10-27 11:34:09 +02:00
Andrey Konovalov da39b5ee40 usb: raw-gadget: fix null-ptr-deref when reenabling endpoints
Currently we preassign gadget endpoints to raw-gadget endpoints during
initialization. Fix resetting this assignment in raw_ioctl_ep_disable(),
otherwise we will get null-ptr-derefs when an endpoint is reenabled.

Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
2020-05-14 12:35:41 +03:00
Andrey Konovalov c61769bd47 usb: raw-gadget: support stalling/halting/wedging endpoints
Raw Gadget is currently unable to stall/halt/wedge gadget endpoints,
which is required for proper emulation of certain USB classes.

This patch adds a few more ioctls:

- USB_RAW_IOCTL_EP0_STALL allows to stall control endpoint #0 when
  there's a pending setup request for it.
- USB_RAW_IOCTL_SET/CLEAR_HALT/WEDGE allow to set/clear halt/wedge status
  on non-control non-isochronous endpoints.

Fixes: f2c2e71764 ("usb: gadget: add raw-gadget interface")
Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
2020-05-14 12:30:18 +03:00
Andrey Konovalov 97df5e5758 usb: raw-gadget: fix gadget endpoint selection
Currently automatic gadget endpoint selection based on required features
doesn't work. Raw Gadget tries iterating over the list of available
endpoints and finding one that has the right direction and transfer type.
Unfortunately selecting arbitrary gadget endpoints (even if they satisfy
feature requirements) doesn't work, as (depending on the UDC driver) they
might have fixed addresses, and one also needs to provide matching
endpoint addresses in the descriptors sent to the host.

The composite framework deals with this by assigning endpoint addresses
in usb_ep_autoconfig() before enumeration starts. This approach won't work
with Raw Gadget as the endpoints are supposed to be enabled after a
set_configuration/set_interface request from the host, so it's too late to
patch the endpoint descriptors that had already been sent to the host.

For Raw Gadget we take another approach. Similarly to GadgetFS, we allow
the user to make the decision as to which gadget endpoints to use.

This patch adds another Raw Gadget ioctl USB_RAW_IOCTL_EPS_INFO that
exposes information about all non-control endpoints that a currently
connected UDC has. This information includes endpoints addresses, as well
as their capabilities and limits to allow the user to choose the most
fitting gadget endpoint.

The USB_RAW_IOCTL_EP_ENABLE ioctl is updated to use the proper endpoint
validation routine usb_gadget_ep_match_desc().

These changes affect the portability of the gadgets that use Raw Gadget
when running on different UDCs. Nevertheless, as long as the user relies
on the information provided by USB_RAW_IOCTL_EPS_INFO to dynamically
choose endpoint addresses, UDC-agnostic gadgets can still be written with
Raw Gadget.

Fixes: f2c2e71764 ("usb: gadget: add raw-gadget interface")
Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
2020-05-14 12:30:17 +03:00
Andrey Konovalov 6e50764420 usb: raw-gadget: fix return value of ep read ioctls
They must return the number of bytes transferred during the data stage.

Fixes: 068fbff4f8 ("usb: raw-gadget: Fix copy_to/from_user() checks")
Fixes: f2c2e71764 ("usb: gadget: add raw-gadget interface")
Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
2020-05-09 11:05:09 +03:00
Andrey Konovalov fdd10499de usb: raw-gadget: fix raw_event_queue_fetch locking
If queue->size check in raw_event_queue_fetch() fails (which normally
shouldn't happen, that check is a fail-safe), the function returns
without reenabling interrupts. This patch fixes that issue, along with
propagating the cause of failure to the function caller.

Fixes: f2c2e71764 ("usb: gadget: add raw-gadget interface")
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
Link: https://lore.kernel.org/r/9f7ce7a1472cfb9447f6c5a494186fa1f2670f6f.1586270396.git.andreyknvl@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2020-04-16 14:52:14 +02:00
Dan Carpenter 068fbff4f8 usb: raw-gadget: Fix copy_to/from_user() checks
The copy_to/from_user() functions return the number of bytes remaining
but we want to return negative error codes.  I changed a couple checks
in raw_ioctl_ep_read() and raw_ioctl_ep0_read() to show that we still
we returning zero on error.

Fixes: f2c2e71764 ("usb: gadget: add raw-gadget interface")
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Reviewed-by: Andrey Konovalov <andreyknvl@google.com>
Tested-by: Andrey Konovalov <andreyknvl@google.com>
Link: https://lore.kernel.org/r/20200406145119.GG68494@mwanda
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2020-04-16 14:52:10 +02:00
Andrey Konovalov f2c2e71764 usb: gadget: add raw-gadget interface
USB Raw Gadget is a kernel module that provides a userspace interface for
the USB Gadget subsystem. Essentially it allows to emulate USB devices
from userspace. Enabled with CONFIG_USB_RAW_GADGET. Raw Gadget is
currently a strictly debugging feature and shouldn't be used in
production.

Raw Gadget is similar to GadgetFS, but provides a more low-level and
direct access to the USB Gadget layer for the userspace. The key
differences are:

1. Every USB request is passed to the userspace to get a response, while
   GadgetFS responds to some USB requests internally based on the provided
   descriptors. However note, that the UDC driver might respond to some
   requests on its own and never forward them to the Gadget layer.

2. GadgetFS performs some sanity checks on the provided USB descriptors,
   while Raw Gadget allows you to provide arbitrary data as responses to
   USB requests.

3. Raw Gadget provides a way to select a UDC device/driver to bind to,
   while GadgetFS currently binds to the first available UDC.

4. Raw Gadget uses predictable endpoint names (handles) across different
   UDCs (as long as UDCs have enough endpoints of each required transfer
   type).

5. Raw Gadget has ioctl-based interface instead of a filesystem-based one.

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
2020-03-15 11:34:48 +02:00