Commit 43938613 authored by Elena Reshetova's avatar Elena Reshetova Committed by Greg Kroah-Hartman

drivers, usb: convert ffs_data.ref from atomic_t to refcount_t

refcount_t type and corresponding API should be
used instead of atomic_t when the variable is used as
a reference counter. This allows to avoid accidental
refcounter overflows that might lead to use-after-free
situations.
Signed-off-by: default avatarElena Reshetova <elena.reshetova@intel.com>
Signed-off-by: default avatarHans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: default avatarKees Cook <keescook@chromium.org>
Signed-off-by: default avatarDavid Windsor <dwindsor@gmail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent a25557f2
...@@ -1571,14 +1571,14 @@ static void ffs_data_get(struct ffs_data *ffs) ...@@ -1571,14 +1571,14 @@ static void ffs_data_get(struct ffs_data *ffs)
{ {
ENTER(); ENTER();
atomic_inc(&ffs->ref); refcount_inc(&ffs->ref);
} }
static void ffs_data_opened(struct ffs_data *ffs) static void ffs_data_opened(struct ffs_data *ffs)
{ {
ENTER(); ENTER();
atomic_inc(&ffs->ref); refcount_inc(&ffs->ref);
if (atomic_add_return(1, &ffs->opened) == 1 && if (atomic_add_return(1, &ffs->opened) == 1 &&
ffs->state == FFS_DEACTIVATED) { ffs->state == FFS_DEACTIVATED) {
ffs->state = FFS_CLOSING; ffs->state = FFS_CLOSING;
...@@ -1590,7 +1590,7 @@ static void ffs_data_put(struct ffs_data *ffs) ...@@ -1590,7 +1590,7 @@ static void ffs_data_put(struct ffs_data *ffs)
{ {
ENTER(); ENTER();
if (unlikely(atomic_dec_and_test(&ffs->ref))) { if (unlikely(refcount_dec_and_test(&ffs->ref))) {
pr_info("%s(): freeing\n", __func__); pr_info("%s(): freeing\n", __func__);
ffs_data_clear(ffs); ffs_data_clear(ffs);
BUG_ON(waitqueue_active(&ffs->ev.waitq) || BUG_ON(waitqueue_active(&ffs->ev.waitq) ||
...@@ -1635,7 +1635,7 @@ static struct ffs_data *ffs_data_new(void) ...@@ -1635,7 +1635,7 @@ static struct ffs_data *ffs_data_new(void)
ENTER(); ENTER();
atomic_set(&ffs->ref, 1); refcount_set(&ffs->ref, 1);
atomic_set(&ffs->opened, 0); atomic_set(&ffs->opened, 0);
ffs->state = FFS_READ_DESCRIPTORS; ffs->state = FFS_READ_DESCRIPTORS;
mutex_init(&ffs->mutex); mutex_init(&ffs->mutex);
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/refcount.h>
#ifdef VERBOSE_DEBUG #ifdef VERBOSE_DEBUG
#ifndef pr_vdebug #ifndef pr_vdebug
...@@ -177,7 +178,7 @@ struct ffs_data { ...@@ -177,7 +178,7 @@ struct ffs_data {
struct completion ep0req_completion; /* P: mutex */ struct completion ep0req_completion; /* P: mutex */
/* reference counter */ /* reference counter */
atomic_t ref; refcount_t ref;
/* how many files are opened (EP0 and others) */ /* how many files are opened (EP0 and others) */
atomic_t opened; atomic_t opened;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment