Merge "usb: f_fs: Prevent race & use after free scenario on epfile"

This commit is contained in:
qctecmdr
2022-10-10 00:17:41 -07:00
committed by Gerrit - the friendly Code Review server

View File

@@ -1328,10 +1328,13 @@ ffs_epfile_release(struct inode *inode, struct file *file)
{
struct ffs_epfile *epfile = inode->i_private;
struct ffs_data *ffs = epfile->ffs;
unsigned long flags;
ENTER();
spin_lock_irqsave(&epfile->ffs->eps_lock, flags);
__ffs_epfile_read_buffer_free(epfile);
spin_unlock_irqrestore(&epfile->ffs->eps_lock, flags);
ffs_log("%s: state %d setup_state %d flag %lu opened %u",
epfile->name, epfile->ffs->state, epfile->ffs->setup_state,
epfile->ffs->flags, atomic_read(&epfile->opened));
@@ -1833,11 +1836,13 @@ static void ffs_data_closed(struct ffs_data *ffs)
if (atomic_dec_and_test(&ffs->opened)) {
if (ffs->no_disconnect) {
ffs->state = FFS_DEACTIVATED;
mutex_lock(&ffs->mutex);
if (ffs->epfiles) {
ffs_epfiles_destroy(ffs->epfiles,
ffs->eps_count);
ffs->epfiles = NULL;
}
mutex_unlock(&ffs->mutex);
if (ffs->setup_state == FFS_SETUP_PENDING)
__ffs_ep0_stall(ffs);
} else {
@@ -1909,15 +1914,22 @@ static void ffs_data_clear(struct ffs_data *ffs)
BUG_ON(ffs->gadget);
if (ffs->epfiles)
mutex_lock(&ffs->mutex);
if (ffs->epfiles) {
ffs_epfiles_destroy(ffs->epfiles, ffs->eps_count);
ffs->epfiles = NULL;
}
if (ffs->ffs_eventfd)
eventfd_ctx_put(ffs->ffs_eventfd);
kfree(ffs->raw_descs_data);
ffs->raw_descs_data = NULL;
kfree(ffs->raw_strings);
ffs->raw_strings = NULL;
kfree(ffs->stringtabs);
ffs->stringtabs = NULL;
mutex_unlock(&ffs->mutex);
}
static void ffs_data_reset(struct ffs_data *ffs)
@@ -1929,11 +1941,7 @@ static void ffs_data_reset(struct ffs_data *ffs)
ffs_data_clear(ffs);
ffs->epfiles = NULL;
ffs->raw_descs_data = NULL;
ffs->raw_descs = NULL;
ffs->raw_strings = NULL;
ffs->stringtabs = NULL;
ffs->raw_descs_length = 0;
ffs->fs_descs_count = 0;
@@ -2073,16 +2081,19 @@ static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count)
static void ffs_func_eps_disable(struct ffs_function *func)
{
struct ffs_ep *ep = func->eps;
struct ffs_data *ffs = func->ffs;
struct ffs_epfile *epfile = func->ffs->epfiles;
unsigned count = func->ffs->eps_count;
struct ffs_ep *ep;
struct ffs_epfile *epfile;
unsigned short count;
unsigned long flags;
ffs_log("enter: state %d setup_state %d flag %lu", func->ffs->state,
func->ffs->setup_state, func->ffs->flags);
spin_lock_irqsave(&func->ffs->eps_lock, flags);
count = func->ffs->eps_count;
epfile = func->ffs->epfiles;
ep = func->eps;
while (count--) {
/* pending requests get nuked */
if (likely(ep->ep))