linux/drivers/usb/gadget/function
John Stultz 54f64d5c98 usb: f_fs: Avoid crash due to out-of-scope stack ptr access
Since the 5.0 merge window opened, I've been seeing frequent
crashes on suspend and reboot with the trace:

[   36.911170] Unable to handle kernel paging request at virtual address ffffff801153d660
[   36.912769] Unable to handle kernel paging request at virtual address ffffff800004b564
...
[   36.950666] Call trace:
[   36.950670]  queued_spin_lock_slowpath+0x1cc/0x2c8
[   36.950681]  _raw_spin_lock_irqsave+0x64/0x78
[   36.950692]  complete+0x28/0x70
[   36.950703]  ffs_epfile_io_complete+0x3c/0x50
[   36.950713]  usb_gadget_giveback_request+0x34/0x108
[   36.950721]  dwc3_gadget_giveback+0x50/0x68
[   36.950723]  dwc3_thread_interrupt+0x358/0x1488
[   36.950731]  irq_thread_fn+0x30/0x88
[   36.950734]  irq_thread+0x114/0x1b0
[   36.950739]  kthread+0x104/0x130
[   36.950747]  ret_from_fork+0x10/0x1c

I isolated this down to in ffs_epfile_io():
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/usb/gadget/function/f_fs.c#n1065

Where the completion done is setup on the stack:
  DECLARE_COMPLETION_ONSTACK(done);

Then later we setup a request and queue it, and wait for it:
  if (unlikely(wait_for_completion_interruptible(&done))) {
    /*
    * To avoid race condition with ffs_epfile_io_complete,
    * dequeue the request first then check
    * status. usb_ep_dequeue API should guarantee no race
    * condition with req->complete callback.
    */
    usb_ep_dequeue(ep->ep, req);
    interrupted = ep->status < 0;
  }

The problem is, that we end up being interrupted, dequeue the
request, and exit.

But then the irq triggers and we try calling complete() on the
context pointer which points to now random stack space, which
results in the panic.

Alan Stern pointed out there is a bug here, in that the snippet
above "assumes that usb_ep_dequeue() waits until the request has
been completed." And that:

    wait_for_completion(&done);

Is needed right after the usb_ep_dequeue().

Thus this patch implements that change. With it I no longer see
the crashes on suspend or reboot.

This issue seems to have been uncovered by behavioral changes in
the dwc3 driver in commit fec9095bde ("usb: dwc3: gadget:
remove wait_end_transfer").

Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Felipe Balbi <balbi@kernel.org>
Cc: Zeng Tao <prime.zeng@hisilicon.com>
Cc: Jack Pham <jackp@codeaurora.org>
Cc: Thinh Nguyen <thinh.nguyen@synopsys.com>
Cc: Chen Yu <chenyu56@huawei.com>
Cc: Jerry Zhang <zhangjerry@google.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Vincent Pelletier <plr.vincent@gmail.com>
Cc: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Linux USB List <linux-usb@vger.kernel.org>
Suggested-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
2019-02-11 11:11:29 +02:00
..
Makefile License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
f_acm.c A couple of configfs cleanups: 2017-11-14 14:44:04 -08:00
f_ecm.c usb: gadget: f_ecm: fix host mac address for multiple instances 2018-05-15 10:17:18 +03:00
f_eem.c net: drivers/net: Remove unnecessary skb_copy_expand OOM messages 2018-03-15 14:28:03 -04:00
f_fs.c usb: f_fs: Avoid crash due to out-of-scope stack ptr access 2019-02-11 11:11:29 +02:00
f_hid.c Remove 'type' argument from access_ok() function 2019-01-03 18:57:57 -08:00
f_loopback.c A couple of configfs cleanups: 2017-11-14 14:44:04 -08:00
f_mass_storage.c Merge branch 'siginfo-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace 2018-10-24 11:22:39 +01:00
f_mass_storage.h usb: gadget: storage: Remove reference counting 2018-07-26 13:55:39 +03:00
f_midi.c - Introduce arithmetic overflow test helper functions (Rasmus) 2018-06-06 17:27:14 -07:00
f_ncm.c usb/gadget/NCM: Replace tasklet with softirq hrtimer 2018-01-16 09:51:23 +01:00
f_obex.c A couple of configfs cleanups: 2017-11-14 14:44:04 -08:00
f_phonet.c usb: gadget: f_phonet: fix pn_net_xmit()'s return type 2018-05-21 10:36:14 +03:00
f_printer.c usb: gadget: function: printer: avoid wrong list handling in printer_write() 2018-05-24 18:14:28 +02:00
f_rndis.c A couple of configfs cleanups: 2017-11-14 14:44:04 -08:00
f_serial.c A couple of configfs cleanups: 2017-11-14 14:44:04 -08:00
f_sourcesink.c usb: gadget: Potential NULL dereference on allocation error 2019-01-14 10:29:55 +02:00
f_subset.c A couple of configfs cleanups: 2017-11-14 14:44:04 -08:00
f_tcm.c scsi: target: replace fabric_ops.name with fabric_alias 2018-11-28 18:50:59 -05:00
f_uac1.c usb: gadget: function: sync f_uac1 ac header baInterfaceNr 2019-02-07 13:14:51 +02:00
f_uac1_legacy.c usb: Remove Blackfin references in USB support 2018-03-26 15:57:16 +02:00
f_uac2.c usb: gadget: f_uac2: disable IN/OUT ep if unused 2018-10-02 10:45:36 +03:00
f_uvc.c usb: gadget: uvc: Remove uvc_set_trace_param() function 2018-09-25 18:48:07 +03:00
f_uvc.h usb: gadget: uvc: Minimize #include in headers 2018-07-26 13:33:44 +03:00
g_zero.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ndis.h
rndis.c USB: rndis: Fix for handling garbled messages 2018-05-15 10:24:28 +03:00
rndis.h USB: gadget: function: Remove redundant license text 2017-11-07 15:45:02 +01:00
storage_common.c USB: gadget: function: Remove redundant license text 2017-11-07 15:45:02 +01:00
storage_common.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
tcm.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
u_audio.c usb: gadget: u_audio: protect stream runtime fields with stream spinlock 2018-07-17 10:12:51 +03:00
u_audio.h USB: gadget: function: Remove redundant license text 2017-11-07 15:45:02 +01:00
u_ecm.h USB: gadget: function: Remove redundant license text 2017-11-07 15:45:02 +01:00
u_eem.h USB: gadget: function: Remove redundant license text 2017-11-07 15:45:02 +01:00
u_ether.c net: dev: Add extack argument to dev_set_mac_address() 2018-12-13 18:41:38 -08:00
u_ether.h USB: gadget: function: Remove redundant license text 2017-11-07 15:45:02 +01:00
u_ether_configfs.h USB: gadget: function: Remove redundant license text 2017-11-07 15:45:02 +01:00
u_fs.h USB: gadget: function: Remove redundant license text 2017-11-07 15:45:02 +01:00
u_gether.h USB: gadget: function: Remove redundant license text 2017-11-07 15:45:02 +01:00
u_hid.h USB: gadget: function: Remove redundant license text 2017-11-07 15:45:02 +01:00
u_midi.h USB: gadget: function: Remove redundant license text 2017-11-07 15:45:02 +01:00
u_ncm.h USB: gadget: function: Remove redundant license text 2017-11-07 15:45:02 +01:00
u_phonet.h USB: gadget: function: Remove redundant license text 2017-11-07 15:45:02 +01:00
u_printer.h USB: gadget: function: Remove redundant license text 2017-11-07 15:45:02 +01:00
u_rndis.h USB: gadget: function: Remove redundant license text 2017-11-07 15:45:02 +01:00
u_serial.c usb: gadget: u_serial: process RX in workqueue instead of tasklet 2019-01-28 12:51:30 +02:00
u_serial.h USB: gadget: function: Remove redundant license text 2017-11-07 15:45:02 +01:00
u_tcm.h USB: gadget: function: Remove redundant license text 2017-11-07 15:45:02 +01:00
u_uac1.h USB: gadget: function: Remove redundant license text 2017-11-07 15:45:02 +01:00
u_uac1_legacy.c usb: Remove Blackfin references in USB support 2018-03-26 15:57:16 +02:00
u_uac1_legacy.h usb: Remove Blackfin references in USB support 2018-03-26 15:57:16 +02:00
u_uac2.h USB: gadget: function: Remove redundant license text 2017-11-07 15:45:02 +01:00
u_uvc.h usb: gadget: uvc: configfs: Add interface number attributes 2018-09-24 18:54:26 +03:00
uvc.h usb: gadget: uvc: add uvcg_warn macro 2019-01-28 12:51:30 +02:00
uvc_configfs.c usb: gadget: Remove dead branch code 2019-01-28 12:51:29 +02:00
uvc_configfs.h USB: gadget: function: Remove redundant license text 2017-11-07 15:45:02 +01:00
uvc_queue.c usb: gadget: uvc: constify vb2_ops structure 2018-11-26 09:06:32 +02:00
uvc_queue.h usb: gadget: uvc: Minimize #include in headers 2018-07-26 13:33:44 +03:00
uvc_v4l2.c usb: gadget: uvc: Replace plain printk() with dev_*() 2018-09-25 18:41:00 +03:00
uvc_v4l2.h USB: gadget: function: Remove redundant license text 2017-11-07 15:45:02 +01:00
uvc_video.c usb: gadget: uvc: Replace plain printk() with dev_*() 2018-09-25 18:41:00 +03:00
uvc_video.h usb: gadget: uvc: Replace plain printk() with dev_*() 2018-09-25 18:41:00 +03:00