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
...
Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
[dwoo08.lee: cherry-picked from linux-amlogic commit
5dd3ffecd46f to prevent use-after-free when f_fs is unbound before all requests are over]
Signed-off-by: Dongwoo Lee <dwoo08.lee@samsung.com>
Change-Id: Idf2391c53ca0f90fc9484d725304b88fc57fa8a6
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;
else if (io_data->read && ep->status > 0)