usb: f_fs: Avoid use-after-free of ffs_data
Consider a case, where ffs_func_unbind was called twice due to some reason and the opts->refcnt becomes NULL causing functionfs_unbind to happen. This will free the ffs_data structure but later in the function it is being used to add ffs_event which can lead to UAF scenario. Avoid this by returning early from ffs_func_unbind function. While we are at it, let's say ffs_epfile_io (which will be called from ffs_epfile_read_iter) is called after functionfs_unbind happened then there is a possibility the driver may end up using already freed ffs_data. Fix it by initializing the variable after the FFS_ACTIVE check. Change-Id: Ic04857f95a6756d2d177bfbc382a11ffd651ef62 Signed-off-by: Pratham Pratap <prathampratap@codeaurora.org>
This commit is contained in:
parent
120c562bdf
commit
2df1806a2b
1 changed files with 8 additions and 4 deletions
|
@ -940,7 +940,7 @@ static ssize_t __ffs_epfile_read_data(struct ffs_epfile *epfile,
|
|||
static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
|
||||
{
|
||||
struct ffs_epfile *epfile = file->private_data;
|
||||
struct ffs_data *ffs = epfile->ffs;
|
||||
struct ffs_data *ffs;
|
||||
struct usb_request *req;
|
||||
struct ffs_ep *ep;
|
||||
char *data = NULL;
|
||||
|
@ -948,12 +948,13 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
|
|||
int halt;
|
||||
size_t extra_buf_alloc = 0;
|
||||
|
||||
ffs_log("enter: %s", epfile->name);
|
||||
|
||||
/* Are we still active? */
|
||||
if (WARN_ON(epfile->ffs->state != FFS_ACTIVE))
|
||||
return -ENODEV;
|
||||
|
||||
ffs = epfile->ffs;
|
||||
ffs_log("enter: %s", epfile->name);
|
||||
|
||||
/* Wait for endpoint to be enabled */
|
||||
ep = epfile->ep;
|
||||
if (!ep) {
|
||||
|
@ -3775,8 +3776,11 @@ static void ffs_func_unbind(struct usb_configuration *c,
|
|||
ffs->func = NULL;
|
||||
}
|
||||
|
||||
if (!--opts->refcnt)
|
||||
if (!--opts->refcnt) {
|
||||
ffs_event_add(ffs, FUNCTIONFS_UNBIND);
|
||||
functionfs_unbind(ffs);
|
||||
return;
|
||||
}
|
||||
|
||||
/* cleanup after autoconfig */
|
||||
spin_lock_irqsave(&func->ffs->eps_lock, flags);
|
||||
|
|
Loading…
Add table
Reference in a new issue