If usb has stall, then there can be remaining submitted io and
unbinding f_fs with the remaining io, there is use-after-free.
Fix the use-after-free by checking endpoint after wait.
This fixes following kasan warning:
BUG: KASAN: use-after-free in ffs_epfile_io+0x654/0xb58
Read of size 4 at addr
ffffffc0a44e65dc by task mtp-responder/5117
...
[<
ffffff900a037794>] ffs_epfile_io+0x654/0xb58
[<
ffffff900a03818c>] ffs_epfile_read_iter+0x1ac/0x3e0
...
Allocated by task 3869:
...
__kmalloc+0x234/0x760
_ffs_func_bind+0x264/0x7c8
ffs_func_bind+0xe8/0x650
usb_add_function+0x13c/0x378
...
Freed by task 3869:
...
kfree+0xa4/0x750
ffs_func_unbind+0x150/0x248
purge_configs_funcs+0x1a0/0x310
...
Change-Id: I2bb9b07d93b1ac42432caaa2c2176d987b36b140
Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
spin_unlock_irq(&epfile->ffs->eps_lock);
- if (unlikely(wait_for_completion_interruptible(&done))) {
+ if (unlikely(wait_for_completion_interruptible(&done)) &&
+ epfile->ep) {
/*
* To avoid race condition with ffs_epfile_io_complete,
* dequeue the request first then check
interrupted = ep->status < 0;
}
+ if (epfile->ep != ep) {
+ /* In the meantime, endpoint got disabled or changed. */
+ ret = -ESHUTDOWN;
+ goto error_mutex;
+ }
+
if (interrupted)
ret = -EINTR;