[PATCH 25/29] drivers, usb: convert ffs_data.ref from atomic_t to refcount_t

From: Elena Reshetova
Date: Mon Mar 06 2017 - 09:35:04 EST


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@xxxxxxxxx>
Signed-off-by: Hans Liljestrand <ishkamiel@xxxxxxxxx>
Signed-off-by: Kees Cook <keescook@xxxxxxxxxxxx>
Signed-off-by: David Windsor <dwindsor@xxxxxxxxx>
---
drivers/usb/gadget/function/f_fs.c | 8 ++++----
drivers/usb/gadget/function/u_fs.h | 3 ++-
2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index 87fccf6..3cdeb91 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -1570,14 +1570,14 @@ static void ffs_data_get(struct ffs_data *ffs)
{
ENTER();

- atomic_inc(&ffs->ref);
+ refcount_inc(&ffs->ref);
}

static void ffs_data_opened(struct ffs_data *ffs)
{
ENTER();

- atomic_inc(&ffs->ref);
+ refcount_inc(&ffs->ref);
if (atomic_add_return(1, &ffs->opened) == 1 &&
ffs->state == FFS_DEACTIVATED) {
ffs->state = FFS_CLOSING;
@@ -1589,7 +1589,7 @@ static void ffs_data_put(struct ffs_data *ffs)
{
ENTER();

- if (unlikely(atomic_dec_and_test(&ffs->ref))) {
+ if (unlikely(refcount_dec_and_test(&ffs->ref))) {
pr_info("%s(): freeing\n", __func__);
ffs_data_clear(ffs);
BUG_ON(waitqueue_active(&ffs->ev.waitq) ||
@@ -1634,7 +1634,7 @@ static struct ffs_data *ffs_data_new(void)

ENTER();

- atomic_set(&ffs->ref, 1);
+ refcount_set(&ffs->ref, 1);
atomic_set(&ffs->opened, 0);
ffs->state = FFS_READ_DESCRIPTORS;
mutex_init(&ffs->mutex);
diff --git a/drivers/usb/gadget/function/u_fs.h b/drivers/usb/gadget/function/u_fs.h
index 4b69694..abfca48 100644
--- a/drivers/usb/gadget/function/u_fs.h
+++ b/drivers/usb/gadget/function/u_fs.h
@@ -20,6 +20,7 @@
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/workqueue.h>
+#include <linux/refcount.h>

#ifdef VERBOSE_DEBUG
#ifndef pr_vdebug
@@ -177,7 +178,7 @@ struct ffs_data {
struct completion ep0req_completion; /* P: mutex */

/* reference counter */
- atomic_t ref;
+ refcount_t ref;
/* how many files are opened (EP0 and others) */
atomic_t opened;

--
2.7.4