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: Elena Reshetova <elena.reshetova@intel.com> Signed-off-by: Hans Liljestrand <ishkamiel@gmail.com> Signed-off-by: Kees Cook <keescook@chromium.org> Signed-off-by: David Windsor <dwindsor@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
a25557f247
commit
43938613c6
|
@ -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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
|
|
||||||
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 @@
|
||||||
#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 {
|
||||||
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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue