[PATCH 1/6] block: convert bio.__bi_cnt from atomic_t to refcount_t

2017-10-20 Thread Elena Reshetova
atomic_t variables are currently used to implement reference
counters with the following properties:
 - counter is initialized to 1 using atomic_set()
 - a resource is freed upon counter reaching zero
 - once counter reaches zero, its further
   increments aren't allowed
 - counter schema uses basic atomic operations
   (set, inc, inc_not_zero, dec_and_test, etc.)

Such atomic variables should be converted to a newly provided
refcount_t type and API that prevents accidental counter overflows
and underflows. This is important since overflows and underflows
can lead to use-after-free situation and be exploitable.

The variable bio.__bi_cnt is used as pure reference counter.
Convert it to refcount_t and fix up the operations.

Suggested-by: Kees Cook <keesc...@chromium.org>
Reviewed-by: David Windsor <dwind...@gmail.com>
Reviewed-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Elena Reshetova <elena.reshet...@intel.com>
---
 block/bio.c   | 6 +++---
 fs/btrfs/volumes.c| 2 +-
 include/linux/bio.h   | 4 ++--
 include/linux/blk_types.h | 3 ++-
 4 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/block/bio.c b/block/bio.c
index 101c2a9..58edc1b 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -279,7 +279,7 @@ void bio_init(struct bio *bio, struct bio_vec *table,
 {
memset(bio, 0, sizeof(*bio));
atomic_set(>__bi_remaining, 1);
-   atomic_set(>__bi_cnt, 1);
+   refcount_set(>__bi_cnt, 1);
 
bio->bi_io_vec = table;
bio->bi_max_vecs = max_vecs;
@@ -557,12 +557,12 @@ void bio_put(struct bio *bio)
if (!bio_flagged(bio, BIO_REFFED))
bio_free(bio);
else {
-   BIO_BUG_ON(!atomic_read(>__bi_cnt));
+   BIO_BUG_ON(!refcount_read(>__bi_cnt));
 
/*
 * last put frees it
 */
-   if (atomic_dec_and_test(>__bi_cnt))
+   if (refcount_dec_and_test(>__bi_cnt))
bio_free(bio);
}
 }
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index b397375..11812ee 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -450,7 +450,7 @@ static noinline void run_scheduled_bios(struct btrfs_device 
*device)
waitqueue_active(_info->async_submit_wait))
wake_up(_info->async_submit_wait);
 
-   BUG_ON(atomic_read(>__bi_cnt) == 0);
+   BUG_ON(refcount_read(>__bi_cnt) == 0);
 
/*
 * if we're doing the sync list, record that our
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 275c91c..0fa4dd2 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -253,7 +253,7 @@ static inline void bio_get(struct bio *bio)
 {
bio->bi_flags |= (1 << BIO_REFFED);
smp_mb__before_atomic();
-   atomic_inc(>__bi_cnt);
+   refcount_inc(>__bi_cnt);
 }
 
 static inline void bio_cnt_set(struct bio *bio, unsigned int count)
@@ -262,7 +262,7 @@ static inline void bio_cnt_set(struct bio *bio, unsigned 
int count)
bio->bi_flags |= (1 << BIO_REFFED);
smp_mb__before_atomic();
}
-   atomic_set(>__bi_cnt, count);
+   refcount_set(>__bi_cnt, count);
 }
 
 static inline bool bio_flagged(struct bio *bio, unsigned int bit)
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index a2d2aa7..1ec370e 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -7,6 +7,7 @@
 
 #include 
 #include 
+#include 
 
 struct bio_set;
 struct bio;
@@ -104,7 +105,7 @@ struct bio {
 
unsigned short  bi_max_vecs;/* max bvl_vecs we can hold */
 
-   atomic_t__bi_cnt;   /* pin count */
+   refcount_t  __bi_cnt;   /* pin count */
 
struct bio_vec  *bi_io_vec; /* the actual vec list */
 
-- 
2.7.4



[PATCH 3/6] block: convert blkcg_gq.refcnt from atomic_t to refcount_t

2017-10-20 Thread Elena Reshetova
atomic_t variables are currently used to implement reference
counters with the following properties:
 - counter is initialized to 1 using atomic_set()
 - a resource is freed upon counter reaching zero
 - once counter reaches zero, its further
   increments aren't allowed
 - counter schema uses basic atomic operations
   (set, inc, inc_not_zero, dec_and_test, etc.)

Such atomic variables should be converted to a newly provided
refcount_t type and API that prevents accidental counter overflows
and underflows. This is important since overflows and underflows
can lead to use-after-free situation and be exploitable.

The variable blkcg_gq.refcnt is used as pure reference counter.
Convert it to refcount_t and fix up the operations.

Suggested-by: Kees Cook <keesc...@chromium.org>
Reviewed-by: David Windsor <dwind...@gmail.com>
Reviewed-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Elena Reshetova <elena.reshet...@intel.com>
---
 block/blk-cgroup.c |  2 +-
 include/linux/blk-cgroup.h | 11 ++-
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index d3f56ba..1e7cedc 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -107,7 +107,7 @@ static struct blkcg_gq *blkg_alloc(struct blkcg *blkcg, 
struct request_queue *q,
blkg->q = q;
INIT_LIST_HEAD(>q_node);
blkg->blkcg = blkcg;
-   atomic_set(>refcnt, 1);
+   refcount_set(>refcnt, 1);
 
/* root blkg uses @q->root_rl, init rl only for !root blkgs */
if (blkcg != _root) {
diff --git a/include/linux/blk-cgroup.h b/include/linux/blk-cgroup.h
index 9d92153..c95d29d 100644
--- a/include/linux/blk-cgroup.h
+++ b/include/linux/blk-cgroup.h
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* percpu_counter batch for blkg_[rw]stats, per-cpu drift doesn't matter */
 #define BLKG_STAT_CPU_BATCH(INT_MAX / 2)
@@ -122,7 +123,7 @@ struct blkcg_gq {
struct request_list rl;
 
/* reference count */
-   atomic_trefcnt;
+   refcount_t  refcnt;
 
/* is this blkg online? protected by both blkcg and q locks */
boolonline;
@@ -354,8 +355,8 @@ static inline int blkg_path(struct blkcg_gq *blkg, char 
*buf, int buflen)
  */
 static inline void blkg_get(struct blkcg_gq *blkg)
 {
-   WARN_ON_ONCE(atomic_read(>refcnt) <= 0);
-   atomic_inc(>refcnt);
+   WARN_ON_ONCE(refcount_read(>refcnt) == 0);
+   refcount_inc(>refcnt);
 }
 
 void __blkg_release_rcu(struct rcu_head *rcu);
@@ -366,8 +367,8 @@ void __blkg_release_rcu(struct rcu_head *rcu);
  */
 static inline void blkg_put(struct blkcg_gq *blkg)
 {
-   WARN_ON_ONCE(atomic_read(>refcnt) <= 0);
-   if (atomic_dec_and_test(>refcnt))
+   WARN_ON_ONCE(refcount_read(>refcnt) == 0);
+   if (refcount_dec_and_test(>refcnt))
call_rcu(>rcu_head, __blkg_release_rcu);
 }
 
-- 
2.7.4



[PATCH 6/6] drivers, block: convert xen_blkif.refcnt from atomic_t to refcount_t

2017-10-20 Thread Elena Reshetova
atomic_t variables are currently used to implement reference
counters with the following properties:
 - counter is initialized to 1 using atomic_set()
 - a resource is freed upon counter reaching zero
 - once counter reaches zero, its further
   increments aren't allowed
 - counter schema uses basic atomic operations
   (set, inc, inc_not_zero, dec_and_test, etc.)

Such atomic variables should be converted to a newly provided
refcount_t type and API that prevents accidental counter overflows
and underflows. This is important since overflows and underflows
can lead to use-after-free situation and be exploitable.

The variable xen_blkif.refcnt is used as pure reference counter.
Convert it to refcount_t and fix up the operations.

Suggested-by: Kees Cook <keesc...@chromium.org>
Reviewed-by: David Windsor <dwind...@gmail.com>
Reviewed-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Elena Reshetova <elena.reshet...@intel.com>
---
 drivers/block/xen-blkback/common.h | 7 ---
 drivers/block/xen-blkback/xenbus.c | 2 +-
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/block/xen-blkback/common.h 
b/drivers/block/xen-blkback/common.h
index ecb35fe..0c3320d 100644
--- a/drivers/block/xen-blkback/common.h
+++ b/drivers/block/xen-blkback/common.h
@@ -35,6 +35,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -319,7 +320,7 @@ struct xen_blkif {
struct xen_vbd  vbd;
/* Back pointer to the backend_info. */
struct backend_info *be;
-   atomic_trefcnt;
+   refcount_t  refcnt;
/* for barrier (drain) requests */
struct completion   drain_complete;
atomic_tdrain;
@@ -372,10 +373,10 @@ struct pending_req {
 (_v)->bdev->bd_part->nr_sects : \
  get_capacity((_v)->bdev->bd_disk))
 
-#define xen_blkif_get(_b) (atomic_inc(&(_b)->refcnt))
+#define xen_blkif_get(_b) (refcount_inc(&(_b)->refcnt))
 #define xen_blkif_put(_b)  \
do {\
-   if (atomic_dec_and_test(&(_b)->refcnt)) \
+   if (refcount_dec_and_test(&(_b)->refcnt))   \
schedule_work(&(_b)->free_work);\
} while (0)
 
diff --git a/drivers/block/xen-blkback/xenbus.c 
b/drivers/block/xen-blkback/xenbus.c
index 21c1be1..5955b61 100644
--- a/drivers/block/xen-blkback/xenbus.c
+++ b/drivers/block/xen-blkback/xenbus.c
@@ -176,7 +176,7 @@ static struct xen_blkif *xen_blkif_alloc(domid_t domid)
return ERR_PTR(-ENOMEM);
 
blkif->domid = domid;
-   atomic_set(>refcnt, 1);
+   refcount_set(>refcnt, 1);
init_completion(>drain_complete);
INIT_WORK(>free_work, xen_blkif_deferred_free);
 
-- 
2.7.4



[PATCH 4/6] block: convert io_context.active_ref from atomic_t to refcount_t

2017-10-20 Thread Elena Reshetova
atomic_t variables are currently used to implement reference
counters with the following properties:
 - counter is initialized to 1 using atomic_set()
 - a resource is freed upon counter reaching zero
 - once counter reaches zero, its further
   increments aren't allowed
 - counter schema uses basic atomic operations
   (set, inc, inc_not_zero, dec_and_test, etc.)

Such atomic variables should be converted to a newly provided
refcount_t type and API that prevents accidental counter overflows
and underflows. This is important since overflows and underflows
can lead to use-after-free situation and be exploitable.

The variable io_context.active_ref is used as pure reference counter.
Convert it to refcount_t and fix up the operations.

Suggested-by: Kees Cook <keesc...@chromium.org>
Reviewed-by: David Windsor <dwind...@gmail.com>
Reviewed-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Elena Reshetova <elena.reshet...@intel.com>
---
 block/bfq-iosched.c   | 2 +-
 block/blk-ioc.c   | 4 ++--
 block/cfq-iosched.c   | 4 ++--
 include/linux/iocontext.h | 7 ---
 4 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
index a4783da..1ec9b22 100644
--- a/block/bfq-iosched.c
+++ b/block/bfq-iosched.c
@@ -4030,7 +4030,7 @@ static void bfq_update_has_short_ttime(struct bfq_data 
*bfqd,
 * bfqq. Otherwise check average think time to
 * decide whether to mark as has_short_ttime
 */
-   if (atomic_read(>icq.ioc->active_ref) == 0 ||
+   if (refcount_read(>icq.ioc->active_ref) == 0 ||
(bfq_sample_valid(bfqq->ttime.ttime_samples) &&
 bfqq->ttime.ttime_mean > bfqd->bfq_slice_idle))
has_short_ttime = false;
diff --git a/block/blk-ioc.c b/block/blk-ioc.c
index 63898d2..69704d2 100644
--- a/block/blk-ioc.c
+++ b/block/blk-ioc.c
@@ -176,7 +176,7 @@ void put_io_context_active(struct io_context *ioc)
unsigned long flags;
struct io_cq *icq;
 
-   if (!atomic_dec_and_test(>active_ref)) {
+   if (!refcount_dec_and_test(>active_ref)) {
put_io_context(ioc);
return;
}
@@ -275,7 +275,7 @@ int create_task_io_context(struct task_struct *task, gfp_t 
gfp_flags, int node)
/* initialize */
atomic_long_set(>refcount, 1);
atomic_set(>nr_tasks, 1);
-   atomic_set(>active_ref, 1);
+   refcount_set(>active_ref, 1);
spin_lock_init(>lock);
INIT_RADIX_TREE(>icq_tree, GFP_ATOMIC | __GFP_HIGH);
INIT_HLIST_HEAD(>icq_list);
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 9f342ef..e6d5d6d 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -2941,7 +2941,7 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd)
 * task has exited, don't wait
 */
cic = cfqd->active_cic;
-   if (!cic || !atomic_read(>icq.ioc->active_ref))
+   if (!cic || !refcount_read(>icq.ioc->active_ref))
return;
 
/*
@@ -3933,7 +3933,7 @@ cfq_update_idle_window(struct cfq_data *cfqd, struct 
cfq_queue *cfqq,
 
if (cfqq->next_rq && req_noidle(cfqq->next_rq))
enable_idle = 0;
-   else if (!atomic_read(>icq.ioc->active_ref) ||
+   else if (!refcount_read(>icq.ioc->active_ref) ||
 !cfqd->cfq_slice_idle ||
 (!cfq_cfqq_deep(cfqq) && CFQQ_SEEKY(cfqq)))
enable_idle = 0;
diff --git a/include/linux/iocontext.h b/include/linux/iocontext.h
index df38db2..a1e28c3 100644
--- a/include/linux/iocontext.h
+++ b/include/linux/iocontext.h
@@ -3,6 +3,7 @@
 
 #include 
 #include 
+#include 
 #include 
 
 enum {
@@ -96,7 +97,7 @@ struct io_cq {
  */
 struct io_context {
atomic_long_t refcount;
-   atomic_t active_ref;
+   refcount_t active_ref;
atomic_t nr_tasks;
 
/* all the fields below are protected by this lock */
@@ -128,9 +129,9 @@ struct io_context {
 static inline void get_io_context_active(struct io_context *ioc)
 {
WARN_ON_ONCE(atomic_long_read(>refcount) <= 0);
-   WARN_ON_ONCE(atomic_read(>active_ref) <= 0);
+   WARN_ON_ONCE(refcount_read(>active_ref) == 0);
atomic_long_inc(>refcount);
-   atomic_inc(>active_ref);
+   refcount_inc(>active_ref);
 }
 
 static inline void ioc_task_link(struct io_context *ioc)
-- 
2.7.4



[PATCH 5/6] block: convert bsg_device.ref_count from atomic_t to refcount_t

2017-10-20 Thread Elena Reshetova
atomic_t variables are currently used to implement reference
counters with the following properties:
 - counter is initialized to 1 using atomic_set()
 - a resource is freed upon counter reaching zero
 - once counter reaches zero, its further
   increments aren't allowed
 - counter schema uses basic atomic operations
   (set, inc, inc_not_zero, dec_and_test, etc.)

Such atomic variables should be converted to a newly provided
refcount_t type and API that prevents accidental counter overflows
and underflows. This is important since overflows and underflows
can lead to use-after-free situation and be exploitable.

The variable bsg_device.ref_count is used as pure reference counter.
Convert it to refcount_t and fix up the operations.

Suggested-by: Kees Cook <keesc...@chromium.org>
Reviewed-by: David Windsor <dwind...@gmail.com>
Reviewed-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Elena Reshetova <elena.reshet...@intel.com>
---
 block/bsg.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/block/bsg.c b/block/bsg.c
index ee1335c..6c98422 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -38,7 +39,7 @@ struct bsg_device {
struct list_head busy_list;
struct list_head done_list;
struct hlist_node dev_list;
-   atomic_t ref_count;
+   refcount_t ref_count;
int queued_cmds;
int done_cmds;
wait_queue_head_t wq_done;
@@ -710,7 +711,7 @@ static int bsg_put_device(struct bsg_device *bd)
 
mutex_lock(_mutex);
 
-   do_free = atomic_dec_and_test(>ref_count);
+   do_free = refcount_dec_and_test(>ref_count);
if (!do_free) {
mutex_unlock(_mutex);
goto out;
@@ -768,7 +769,7 @@ static struct bsg_device *bsg_add_device(struct inode 
*inode,
 
bsg_set_block(bd, file);
 
-   atomic_set(>ref_count, 1);
+   refcount_set(>ref_count, 1);
mutex_lock(_mutex);
hlist_add_head(>dev_list, bsg_dev_idx_hash(iminor(inode)));
 
@@ -788,7 +789,7 @@ static struct bsg_device *__bsg_get_device(int minor, 
struct request_queue *q)
 
hlist_for_each_entry(bd, bsg_dev_idx_hash(minor), dev_list) {
if (bd->queue == q) {
-   atomic_inc(>ref_count);
+   refcount_inc(>ref_count);
goto found;
}
}
-- 
2.7.4



[PATCH 2/6] block: convert blk_queue_tag.refcnt from atomic_t to refcount_t

2017-10-20 Thread Elena Reshetova
atomic_t variables are currently used to implement reference
counters with the following properties:
 - counter is initialized to 1 using atomic_set()
 - a resource is freed upon counter reaching zero
 - once counter reaches zero, its further
   increments aren't allowed
 - counter schema uses basic atomic operations
   (set, inc, inc_not_zero, dec_and_test, etc.)

Such atomic variables should be converted to a newly provided
refcount_t type and API that prevents accidental counter overflows
and underflows. This is important since overflows and underflows
can lead to use-after-free situation and be exploitable.

The variable blk_queue_tag.refcnt is used as pure reference counter.
Convert it to refcount_t and fix up the operations.

Suggested-by: Kees Cook <keesc...@chromium.org>
Reviewed-by: David Windsor <dwind...@gmail.com>
Reviewed-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Elena Reshetova <elena.reshet...@intel.com>
---
 block/blk-tag.c| 8 
 include/linux/blkdev.h | 3 ++-
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/block/blk-tag.c b/block/blk-tag.c
index e1a9c15..a7263e3 100644
--- a/block/blk-tag.c
+++ b/block/blk-tag.c
@@ -35,7 +35,7 @@ EXPORT_SYMBOL(blk_queue_find_tag);
  */
 void blk_free_tags(struct blk_queue_tag *bqt)
 {
-   if (atomic_dec_and_test(>refcnt)) {
+   if (refcount_dec_and_test(>refcnt)) {
BUG_ON(find_first_bit(bqt->tag_map, bqt->max_depth) <
bqt->max_depth);
 
@@ -130,7 +130,7 @@ static struct blk_queue_tag *__blk_queue_init_tags(struct 
request_queue *q,
if (init_tag_map(q, tags, depth))
goto fail;
 
-   atomic_set(>refcnt, 1);
+   refcount_set(>refcnt, 1);
tags->alloc_policy = alloc_policy;
tags->next_tag = 0;
return tags;
@@ -180,7 +180,7 @@ int blk_queue_init_tags(struct request_queue *q, int depth,
queue_flag_set(QUEUE_FLAG_QUEUED, q);
return 0;
} else
-   atomic_inc(>refcnt);
+   refcount_inc(>refcnt);
 
/*
 * assign it, all done
@@ -225,7 +225,7 @@ int blk_queue_resize_tags(struct request_queue *q, int 
new_depth)
 * Currently cannot replace a shared tag map with a new
 * one, so error out if this is the case
 */
-   if (atomic_read(>refcnt) != 1)
+   if (refcount_read(>refcnt) != 1)
return -EBUSY;
 
/*
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 02fa42d..1fefdbb 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -26,6 +26,7 @@
 #include 
 #include 
 #include 
+#include 
 
 struct module;
 struct scsi_ioctl_command;
@@ -295,7 +296,7 @@ struct blk_queue_tag {
unsigned long *tag_map; /* bit map of free/busy tags */
int max_depth;  /* what we will send to device */
int real_max_depth; /* what the array can hold */
-   atomic_t refcnt;/* map can be shared */
+   refcount_t refcnt;  /* map can be shared */
int alloc_policy;   /* tag allocation policy */
int next_tag;   /* next tag */
 };
-- 
2.7.4



[PATCH 0/6] v4 block refcount conversion patches

2017-10-20 Thread Elena Reshetova
Changes in v4:
 - Improved commit messages and signoff info.
 - Rebase on top of linux-next as of yesterday.
 - WARN_ONs are restored since x86 refcount_t does not WARN on zero

Changes in v3:
No changes in patches apart from trivial rebases, but now by
default refcount_t = atomic_t and uses all atomic standard operations
unless CONFIG_REFCOUNT_FULL is enabled. This is a compromize for the
systems that are critical on performance and cannot accept even
slight delay on the refcounter operations.

Changes in v2:
Not needed WARNs are removed since refcount_t warns by itself.
BUG_ONs are left as it is, since refcount_t doesn't bug by default.

This series, for block subsystem, replaces atomic_t reference
counters with the new refcount_t type and API (see include/linux/refcount.h).
By doing this we prevent intentional or accidental
underflows or overflows that can lead to use-after-free vulnerabilities.

The patches are fully independent and can be cherry-picked separately.
If there are no objections to the patches, please merge them via respective 
trees.

Elena Reshetova (6):
  block: convert bio.__bi_cnt from atomic_t to refcount_t
  block: convert blk_queue_tag.refcnt from atomic_t to refcount_t
  block: convert blkcg_gq.refcnt from atomic_t to refcount_t
  block: convert io_context.active_ref from atomic_t to refcount_t
  block: convert bsg_device.ref_count from atomic_t to refcount_t
  drivers, block: convert xen_blkif.refcnt from atomic_t to refcount_t

 block/bfq-iosched.c|  2 +-
 block/bio.c|  6 +++---
 block/blk-cgroup.c |  2 +-
 block/blk-ioc.c|  4 ++--
 block/blk-tag.c|  8 
 block/bsg.c|  9 +
 block/cfq-iosched.c|  4 ++--
 drivers/block/xen-blkback/common.h |  7 ---
 drivers/block/xen-blkback/xenbus.c |  2 +-
 fs/btrfs/volumes.c |  2 +-
 include/linux/bio.h|  4 ++--
 include/linux/blk-cgroup.h | 11 ++-
 include/linux/blk_types.h  |  3 ++-
 include/linux/blkdev.h |  3 ++-
 include/linux/iocontext.h  |  7 ---
 15 files changed, 40 insertions(+), 34 deletions(-)

-- 
2.7.4



[PATCH 3/5] block: convert blkcg_gq.refcnt from atomic_t to refcount_t

2017-06-27 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 block/blk-cgroup.c | 2 +-
 include/linux/blk-cgroup.h | 9 -
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index 0480892..3762908 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -107,7 +107,7 @@ static struct blkcg_gq *blkg_alloc(struct blkcg *blkcg, 
struct request_queue *q,
blkg->q = q;
INIT_LIST_HEAD(>q_node);
blkg->blkcg = blkcg;
-   atomic_set(>refcnt, 1);
+   refcount_set(>refcnt, 1);
 
/* root blkg uses @q->root_rl, init rl only for !root blkgs */
if (blkcg != _root) {
diff --git a/include/linux/blk-cgroup.h b/include/linux/blk-cgroup.h
index 01b62e7..e54f048 100644
--- a/include/linux/blk-cgroup.h
+++ b/include/linux/blk-cgroup.h
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* percpu_counter batch for blkg_[rw]stats, per-cpu drift doesn't matter */
 #define BLKG_STAT_CPU_BATCH(INT_MAX / 2)
@@ -122,7 +123,7 @@ struct blkcg_gq {
struct request_list rl;
 
/* reference count */
-   atomic_trefcnt;
+   refcount_t  refcnt;
 
/* is this blkg online? protected by both blkcg and q locks */
boolonline;
@@ -354,8 +355,7 @@ static inline int blkg_path(struct blkcg_gq *blkg, char 
*buf, int buflen)
  */
 static inline void blkg_get(struct blkcg_gq *blkg)
 {
-   WARN_ON_ONCE(atomic_read(>refcnt) <= 0);
-   atomic_inc(>refcnt);
+   refcount_inc(>refcnt);
 }
 
 void __blkg_release_rcu(struct rcu_head *rcu);
@@ -366,8 +366,7 @@ void __blkg_release_rcu(struct rcu_head *rcu);
  */
 static inline void blkg_put(struct blkcg_gq *blkg)
 {
-   WARN_ON_ONCE(atomic_read(>refcnt) <= 0);
-   if (atomic_dec_and_test(>refcnt))
+   if (refcount_dec_and_test(>refcnt))
call_rcu(>rcu_head, __blkg_release_rcu);
 }
 
-- 
2.7.4



[PATCH 4/5] block: convert io_context.active_ref from atomic_t to refcount_t

2017-06-27 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 block/bfq-iosched.c   | 2 +-
 block/blk-ioc.c   | 4 ++--
 block/cfq-iosched.c   | 4 ++--
 include/linux/iocontext.h | 6 +++---
 4 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
index ed93da2..3a525ab 100644
--- a/block/bfq-iosched.c
+++ b/block/bfq-iosched.c
@@ -3988,7 +3988,7 @@ static void bfq_update_idle_window(struct bfq_data *bfqd,
 
enable_idle = bfq_bfqq_idle_window(bfqq);
 
-   if (atomic_read(>icq.ioc->active_ref) == 0 ||
+   if (refcount_read(>icq.ioc->active_ref) == 0 ||
bfqd->bfq_slice_idle == 0 ||
(bfqd->hw_tag && BFQQ_SEEKY(bfqq) &&
bfqq->wr_coeff == 1))
diff --git a/block/blk-ioc.c b/block/blk-ioc.c
index 63898d2..69704d2 100644
--- a/block/blk-ioc.c
+++ b/block/blk-ioc.c
@@ -176,7 +176,7 @@ void put_io_context_active(struct io_context *ioc)
unsigned long flags;
struct io_cq *icq;
 
-   if (!atomic_dec_and_test(>active_ref)) {
+   if (!refcount_dec_and_test(>active_ref)) {
put_io_context(ioc);
return;
}
@@ -275,7 +275,7 @@ int create_task_io_context(struct task_struct *task, gfp_t 
gfp_flags, int node)
/* initialize */
atomic_long_set(>refcount, 1);
atomic_set(>nr_tasks, 1);
-   atomic_set(>active_ref, 1);
+   refcount_set(>active_ref, 1);
spin_lock_init(>lock);
INIT_RADIX_TREE(>icq_tree, GFP_ATOMIC | __GFP_HIGH);
INIT_HLIST_HEAD(>icq_list);
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index b7e9c7f..07c416a 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -2973,7 +2973,7 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd)
 * task has exited, don't wait
 */
cic = cfqd->active_cic;
-   if (!cic || !atomic_read(>icq.ioc->active_ref))
+   if (!cic || !refcount_read(>icq.ioc->active_ref))
return;
 
/*
@@ -3965,7 +3965,7 @@ cfq_update_idle_window(struct cfq_data *cfqd, struct 
cfq_queue *cfqq,
 
if (cfqq->next_rq && req_noidle(cfqq->next_rq))
enable_idle = 0;
-   else if (!atomic_read(>icq.ioc->active_ref) ||
+   else if (!refcount_read(>icq.ioc->active_ref) ||
 !cfqd->cfq_slice_idle ||
 (!cfq_cfqq_deep(cfqq) && CFQQ_SEEKY(cfqq)))
enable_idle = 0;
diff --git a/include/linux/iocontext.h b/include/linux/iocontext.h
index df38db2..e47b907 100644
--- a/include/linux/iocontext.h
+++ b/include/linux/iocontext.h
@@ -3,6 +3,7 @@
 
 #include 
 #include 
+#include 
 #include 
 
 enum {
@@ -96,7 +97,7 @@ struct io_cq {
  */
 struct io_context {
atomic_long_t refcount;
-   atomic_t active_ref;
+   refcount_t active_ref;
atomic_t nr_tasks;
 
/* all the fields below are protected by this lock */
@@ -128,9 +129,8 @@ struct io_context {
 static inline void get_io_context_active(struct io_context *ioc)
 {
WARN_ON_ONCE(atomic_long_read(>refcount) <= 0);
-   WARN_ON_ONCE(atomic_read(>active_ref) <= 0);
atomic_long_inc(>refcount);
-   atomic_inc(>active_ref);
+   refcount_inc(>active_ref);
 }
 
 static inline void ioc_task_link(struct io_context *ioc)
-- 
2.7.4



[PATCH 5/5] block: convert bsg_device.ref_count from atomic_t to refcount_t

2017-06-27 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 block/bsg.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/block/bsg.c b/block/bsg.c
index 6fd0854..f35e721 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -38,7 +39,7 @@ struct bsg_device {
struct list_head busy_list;
struct list_head done_list;
struct hlist_node dev_list;
-   atomic_t ref_count;
+   refcount_t ref_count;
int queued_cmds;
int done_cmds;
wait_queue_head_t wq_done;
@@ -711,7 +712,7 @@ static int bsg_put_device(struct bsg_device *bd)
 
mutex_lock(_mutex);
 
-   do_free = atomic_dec_and_test(>ref_count);
+   do_free = refcount_dec_and_test(>ref_count);
if (!do_free) {
mutex_unlock(_mutex);
goto out;
@@ -763,7 +764,7 @@ static struct bsg_device *bsg_add_device(struct inode 
*inode,
 
bsg_set_block(bd, file);
 
-   atomic_set(>ref_count, 1);
+   refcount_set(>ref_count, 1);
mutex_lock(_mutex);
hlist_add_head(>dev_list, bsg_dev_idx_hash(iminor(inode)));
 
@@ -783,7 +784,7 @@ static struct bsg_device *__bsg_get_device(int minor, 
struct request_queue *q)
 
hlist_for_each_entry(bd, bsg_dev_idx_hash(minor), dev_list) {
if (bd->queue == q) {
-   atomic_inc(>ref_count);
+   refcount_inc(>ref_count);
goto found;
}
}
-- 
2.7.4



[PATCH 1/5] block: convert bio.__bi_cnt from atomic_t to refcount_t

2017-06-27 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 block/bio.c   | 6 +++---
 fs/btrfs/volumes.c| 2 +-
 include/linux/bio.h   | 4 ++--
 include/linux/blk_types.h | 3 ++-
 4 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/block/bio.c b/block/bio.c
index 888e780..80032f3 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -276,7 +276,7 @@ void bio_init(struct bio *bio, struct bio_vec *table,
 {
memset(bio, 0, sizeof(*bio));
atomic_set(>__bi_remaining, 1);
-   atomic_set(>__bi_cnt, 1);
+   refcount_set(>__bi_cnt, 1);
 
bio->bi_io_vec = table;
bio->bi_max_vecs = max_vecs;
@@ -551,12 +551,12 @@ void bio_put(struct bio *bio)
if (!bio_flagged(bio, BIO_REFFED))
bio_free(bio);
else {
-   BIO_BUG_ON(!atomic_read(>__bi_cnt));
+   BIO_BUG_ON(!refcount_read(>__bi_cnt));
 
/*
 * last put frees it
 */
-   if (atomic_dec_and_test(>__bi_cnt))
+   if (refcount_dec_and_test(>__bi_cnt))
bio_free(bio);
}
 }
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 017b67d..cd8a5d5 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -446,7 +446,7 @@ static noinline void run_scheduled_bios(struct btrfs_device 
*device)
waitqueue_active(_info->async_submit_wait))
wake_up(_info->async_submit_wait);
 
-   BUG_ON(atomic_read(>__bi_cnt) == 0);
+   BUG_ON(refcount_read(>__bi_cnt) == 0);
 
/*
 * if we're doing the sync list, record that our
diff --git a/include/linux/bio.h b/include/linux/bio.h
index d1b04b0..bfd0661 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -229,7 +229,7 @@ static inline void bio_get(struct bio *bio)
 {
bio->bi_flags |= (1 << BIO_REFFED);
smp_mb__before_atomic();
-   atomic_inc(>__bi_cnt);
+   refcount_inc(>__bi_cnt);
 }
 
 static inline void bio_cnt_set(struct bio *bio, unsigned int count)
@@ -238,7 +238,7 @@ static inline void bio_cnt_set(struct bio *bio, unsigned 
int count)
bio->bi_flags |= (1 << BIO_REFFED);
smp_mb__before_atomic();
}
-   atomic_set(>__bi_cnt, count);
+   refcount_set(>__bi_cnt, count);
 }
 
 static inline bool bio_flagged(struct bio *bio, unsigned int bit)
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index 61339bc..f6e5daa 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -7,6 +7,7 @@
 
 #include 
 #include 
+#include 
 
 struct bio_set;
 struct bio;
@@ -81,7 +82,7 @@ struct bio {
 
unsigned short  bi_max_vecs;/* max bvl_vecs we can hold */
 
-   atomic_t__bi_cnt;   /* pin count */
+   refcount_t  __bi_cnt;   /* pin count */
 
struct bio_vec  *bi_io_vec; /* the actual vec list */
 
-- 
2.7.4



[PATCH 2/5] block: convert blk_queue_tag.refcnt from atomic_t to refcount_t

2017-06-27 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 block/blk-tag.c| 8 
 include/linux/blkdev.h | 3 ++-
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/block/blk-tag.c b/block/blk-tag.c
index 07cc329..d83555e 100644
--- a/block/blk-tag.c
+++ b/block/blk-tag.c
@@ -35,7 +35,7 @@ EXPORT_SYMBOL(blk_queue_find_tag);
  */
 void blk_free_tags(struct blk_queue_tag *bqt)
 {
-   if (atomic_dec_and_test(>refcnt)) {
+   if (refcount_dec_and_test(>refcnt)) {
BUG_ON(find_first_bit(bqt->tag_map, bqt->max_depth) <
bqt->max_depth);
 
@@ -130,7 +130,7 @@ static struct blk_queue_tag *__blk_queue_init_tags(struct 
request_queue *q,
if (init_tag_map(q, tags, depth))
goto fail;
 
-   atomic_set(>refcnt, 1);
+   refcount_set(>refcnt, 1);
tags->alloc_policy = alloc_policy;
tags->next_tag = 0;
return tags;
@@ -180,7 +180,7 @@ int blk_queue_init_tags(struct request_queue *q, int depth,
queue_flag_set(QUEUE_FLAG_QUEUED, q);
return 0;
} else
-   atomic_inc(>refcnt);
+   refcount_inc(>refcnt);
 
/*
 * assign it, all done
@@ -225,7 +225,7 @@ int blk_queue_resize_tags(struct request_queue *q, int 
new_depth)
 * Currently cannot replace a shared tag map with a new
 * one, so error out if this is the case
 */
-   if (atomic_read(>refcnt) != 1)
+   if (refcount_read(>refcnt) != 1)
return -EBUSY;
 
/*
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 1ddd36b..3efc8cf 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -26,6 +26,7 @@
 #include 
 #include 
 #include 
+#include 
 
 struct module;
 struct scsi_ioctl_command;
@@ -293,7 +294,7 @@ struct blk_queue_tag {
unsigned long *tag_map; /* bit map of free/busy tags */
int max_depth;  /* what we will send to device */
int real_max_depth; /* what the array can hold */
-   atomic_t refcnt;/* map can be shared */
+   refcount_t refcnt;  /* map can be shared */
int alloc_policy;   /* tag allocation policy */
int next_tag;   /* next tag */
 };
-- 
2.7.4



[PATCH 0/5] v3 block subsystem refcounter conversions

2017-06-27 Thread Elena Reshetova
Changes in v3:
No changes in patches apart from trivial rebases, but now by
default refcount_t = atomic_t and uses all atomic standard operations
unless CONFIG_REFCOUNT_FULL is enabled. This is a compromize for the
systems that are critical on performance and cannot accept even
slight delay on the refcounter operations.

Changes in v2:
Not needed WARNs are removed since refcount_t warns by itself.
BUG_ONs are left as it is, since refcount_t doesn't bug by default.

This series, for block subsystem, replaces atomic_t reference
counters with the new refcount_t type and API (see include/linux/refcount.h).
By doing this we prevent intentional or accidental
underflows or overflows that can lead to use-after-free vulnerabilities.

Elena Reshetova (5):
  block: convert bio.__bi_cnt from atomic_t to refcount_t
  block: convert blk_queue_tag.refcnt from atomic_t to refcount_t
  block: convert blkcg_gq.refcnt from atomic_t to refcount_t
  block: convert io_context.active_ref from atomic_t to refcount_t
  block: convert bsg_device.ref_count from atomic_t to refcount_t

 block/bfq-iosched.c| 2 +-
 block/bio.c| 6 +++---
 block/blk-cgroup.c | 2 +-
 block/blk-ioc.c| 4 ++--
 block/blk-tag.c| 8 
 block/bsg.c| 9 +
 block/cfq-iosched.c| 4 ++--
 fs/btrfs/volumes.c | 2 +-
 include/linux/bio.h| 4 ++--
 include/linux/blk-cgroup.h | 9 -
 include/linux/blk_types.h  | 3 ++-
 include/linux/blkdev.h | 3 ++-
 include/linux/iocontext.h  | 6 +++---
 13 files changed, 32 insertions(+), 30 deletions(-)

-- 
2.7.4



[PATCH 2/5] block: convert blk_queue_tag.refcnt from atomic_t to refcount_t

2017-04-20 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 block/blk-tag.c| 8 
 include/linux/blkdev.h | 3 ++-
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/block/blk-tag.c b/block/blk-tag.c
index 07cc329..d83555e 100644
--- a/block/blk-tag.c
+++ b/block/blk-tag.c
@@ -35,7 +35,7 @@ EXPORT_SYMBOL(blk_queue_find_tag);
  */
 void blk_free_tags(struct blk_queue_tag *bqt)
 {
-   if (atomic_dec_and_test(>refcnt)) {
+   if (refcount_dec_and_test(>refcnt)) {
BUG_ON(find_first_bit(bqt->tag_map, bqt->max_depth) <
bqt->max_depth);
 
@@ -130,7 +130,7 @@ static struct blk_queue_tag *__blk_queue_init_tags(struct 
request_queue *q,
if (init_tag_map(q, tags, depth))
goto fail;
 
-   atomic_set(>refcnt, 1);
+   refcount_set(>refcnt, 1);
tags->alloc_policy = alloc_policy;
tags->next_tag = 0;
return tags;
@@ -180,7 +180,7 @@ int blk_queue_init_tags(struct request_queue *q, int depth,
queue_flag_set(QUEUE_FLAG_QUEUED, q);
return 0;
} else
-   atomic_inc(>refcnt);
+   refcount_inc(>refcnt);
 
/*
 * assign it, all done
@@ -225,7 +225,7 @@ int blk_queue_resize_tags(struct request_queue *q, int 
new_depth)
 * Currently cannot replace a shared tag map with a new
 * one, so error out if this is the case
 */
-   if (atomic_read(>refcnt) != 1)
+   if (refcount_read(>refcnt) != 1)
return -EBUSY;
 
/*
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index aecca0e..95ef11c 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 
 struct module;
 struct scsi_ioctl_command;
@@ -288,7 +289,7 @@ struct blk_queue_tag {
unsigned long *tag_map; /* bit map of free/busy tags */
int max_depth;  /* what we will send to device */
int real_max_depth; /* what the array can hold */
-   atomic_t refcnt;/* map can be shared */
+   refcount_t refcnt;  /* map can be shared */
int alloc_policy;   /* tag allocation policy */
int next_tag;   /* next tag */
 };
-- 
2.7.4



[PATCH 3/5] block: convert blkcg_gq.refcnt from atomic_t to refcount_t

2017-04-20 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 block/blk-cgroup.c | 2 +-
 include/linux/blk-cgroup.h | 9 -
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index 295e98c2..75de844 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -106,7 +106,7 @@ static struct blkcg_gq *blkg_alloc(struct blkcg *blkcg, 
struct request_queue *q,
blkg->q = q;
INIT_LIST_HEAD(>q_node);
blkg->blkcg = blkcg;
-   atomic_set(>refcnt, 1);
+   refcount_set(>refcnt, 1);
 
/* root blkg uses @q->root_rl, init rl only for !root blkgs */
if (blkcg != _root) {
diff --git a/include/linux/blk-cgroup.h b/include/linux/blk-cgroup.h
index 01b62e7..e54f048 100644
--- a/include/linux/blk-cgroup.h
+++ b/include/linux/blk-cgroup.h
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* percpu_counter batch for blkg_[rw]stats, per-cpu drift doesn't matter */
 #define BLKG_STAT_CPU_BATCH(INT_MAX / 2)
@@ -122,7 +123,7 @@ struct blkcg_gq {
struct request_list rl;
 
/* reference count */
-   atomic_trefcnt;
+   refcount_t  refcnt;
 
/* is this blkg online? protected by both blkcg and q locks */
boolonline;
@@ -354,8 +355,7 @@ static inline int blkg_path(struct blkcg_gq *blkg, char 
*buf, int buflen)
  */
 static inline void blkg_get(struct blkcg_gq *blkg)
 {
-   WARN_ON_ONCE(atomic_read(>refcnt) <= 0);
-   atomic_inc(>refcnt);
+   refcount_inc(>refcnt);
 }
 
 void __blkg_release_rcu(struct rcu_head *rcu);
@@ -366,8 +366,7 @@ void __blkg_release_rcu(struct rcu_head *rcu);
  */
 static inline void blkg_put(struct blkcg_gq *blkg)
 {
-   WARN_ON_ONCE(atomic_read(>refcnt) <= 0);
-   if (atomic_dec_and_test(>refcnt))
+   if (refcount_dec_and_test(>refcnt))
call_rcu(>rcu_head, __blkg_release_rcu);
 }
 
-- 
2.7.4



[PATCH 0/5] v2: block subsystem refcounter conversions

2017-04-20 Thread Elena Reshetova
changes in v2:
Not needed WARNs are removed since refcount_t warns by itself.
BUG_ONs are left as it is, since refcount_t doesn't bug by default.

This series, for block subsystem, replaces atomic_t reference
counters with the new refcount_t type and API (see include/linux/refcount.h).
By doing this we prevent intentional or accidental
underflows or overflows that can lead to use-after-free vulnerabilities.


Elena Reshetova (5):
  block: convert bio.__bi_cnt from atomic_t to refcount_t
  block: convert blk_queue_tag.refcnt from atomic_t to refcount_t
  block: convert blkcg_gq.refcnt from atomic_t to refcount_t
  block: convert io_context.active_ref from atomic_t to refcount_t
  block: convert bsg_device.ref_count from atomic_t to refcount_t

 block/bio.c| 6 +++---
 block/blk-cgroup.c | 2 +-
 block/blk-ioc.c| 4 ++--
 block/blk-tag.c| 8 
 block/bsg.c| 9 +
 block/cfq-iosched.c| 4 ++--
 fs/btrfs/volumes.c | 2 +-
 include/linux/bio.h| 4 ++--
 include/linux/blk-cgroup.h | 9 -
 include/linux/blk_types.h  | 3 ++-
 include/linux/blkdev.h | 3 ++-
 include/linux/iocontext.h  | 6 +++---
 12 files changed, 31 insertions(+), 29 deletions(-)

-- 
2.7.4



[PATCH 1/5] block: convert bio.__bi_cnt from atomic_t to refcount_t

2017-04-20 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 block/bio.c   | 6 +++---
 fs/btrfs/volumes.c| 2 +-
 include/linux/bio.h   | 4 ++--
 include/linux/blk_types.h | 3 ++-
 4 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/block/bio.c b/block/bio.c
index 5eec5e0..3dffc17 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -275,7 +275,7 @@ void bio_init(struct bio *bio, struct bio_vec *table,
 {
memset(bio, 0, sizeof(*bio));
atomic_set(>__bi_remaining, 1);
-   atomic_set(>__bi_cnt, 1);
+   refcount_set(>__bi_cnt, 1);
 
bio->bi_io_vec = table;
bio->bi_max_vecs = max_vecs;
@@ -543,12 +543,12 @@ void bio_put(struct bio *bio)
if (!bio_flagged(bio, BIO_REFFED))
bio_free(bio);
else {
-   BIO_BUG_ON(!atomic_read(>__bi_cnt));
+   BIO_BUG_ON(!refcount_read(>__bi_cnt));
 
/*
 * last put frees it
 */
-   if (atomic_dec_and_test(>__bi_cnt))
+   if (refcount_dec_and_test(>__bi_cnt))
bio_free(bio);
}
 }
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 13e55d1..ff1fe9d 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -441,7 +441,7 @@ static noinline void run_scheduled_bios(struct btrfs_device 
*device)
waitqueue_active(_info->async_submit_wait))
wake_up(_info->async_submit_wait);
 
-   BUG_ON(atomic_read(>__bi_cnt) == 0);
+   BUG_ON(refcount_read(>__bi_cnt) == 0);
 
/*
 * if we're doing the sync list, record that our
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 8e52119..44ac678 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -234,7 +234,7 @@ static inline void bio_get(struct bio *bio)
 {
bio->bi_flags |= (1 << BIO_REFFED);
smp_mb__before_atomic();
-   atomic_inc(>__bi_cnt);
+   refcount_inc(>__bi_cnt);
 }
 
 static inline void bio_cnt_set(struct bio *bio, unsigned int count)
@@ -243,7 +243,7 @@ static inline void bio_cnt_set(struct bio *bio, unsigned 
int count)
bio->bi_flags |= (1 << BIO_REFFED);
smp_mb__before_atomic();
}
-   atomic_set(>__bi_cnt, count);
+   refcount_set(>__bi_cnt, count);
 }
 
 static inline bool bio_flagged(struct bio *bio, unsigned int bit)
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index d703acb..c41407f 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -7,6 +7,7 @@
 
 #include 
 #include 
+#include 
 
 struct bio_set;
 struct bio;
@@ -73,7 +74,7 @@ struct bio {
 
unsigned short  bi_max_vecs;/* max bvl_vecs we can hold */
 
-   atomic_t__bi_cnt;   /* pin count */
+   refcount_t  __bi_cnt;   /* pin count */
 
struct bio_vec  *bi_io_vec; /* the actual vec list */
 
-- 
2.7.4



[PATCH 4/5] block: convert io_context.active_ref from atomic_t to refcount_t

2017-04-20 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 block/blk-ioc.c   | 4 ++--
 block/cfq-iosched.c   | 4 ++--
 include/linux/iocontext.h | 6 +++---
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/block/blk-ioc.c b/block/blk-ioc.c
index b12f9c8..130dc23 100644
--- a/block/blk-ioc.c
+++ b/block/blk-ioc.c
@@ -173,7 +173,7 @@ void put_io_context_active(struct io_context *ioc)
unsigned long flags;
struct io_cq *icq;
 
-   if (!atomic_dec_and_test(>active_ref)) {
+   if (!refcount_dec_and_test(>active_ref)) {
put_io_context(ioc);
return;
}
@@ -256,7 +256,7 @@ int create_task_io_context(struct task_struct *task, gfp_t 
gfp_flags, int node)
/* initialize */
atomic_long_set(>refcount, 1);
atomic_set(>nr_tasks, 1);
-   atomic_set(>active_ref, 1);
+   refcount_set(>active_ref, 1);
spin_lock_init(>lock);
INIT_RADIX_TREE(>icq_tree, GFP_ATOMIC | __GFP_HIGH);
INIT_HLIST_HEAD(>icq_list);
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 9212627..2871bb9 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -2959,7 +2959,7 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd)
 * task has exited, don't wait
 */
cic = cfqd->active_cic;
-   if (!cic || !atomic_read(>icq.ioc->active_ref))
+   if (!cic || !refcount_read(>icq.ioc->active_ref))
return;
 
/*
@@ -3959,7 +3959,7 @@ cfq_update_idle_window(struct cfq_data *cfqd, struct 
cfq_queue *cfqq,
 
if (cfqq->next_rq && req_noidle(cfqq->next_rq))
enable_idle = 0;
-   else if (!atomic_read(>icq.ioc->active_ref) ||
+   else if (!refcount_read(>icq.ioc->active_ref) ||
 !cfqd->cfq_slice_idle ||
 (!cfq_cfqq_deep(cfqq) && CFQQ_SEEKY(cfqq)))
enable_idle = 0;
diff --git a/include/linux/iocontext.h b/include/linux/iocontext.h
index df38db2..e47b907 100644
--- a/include/linux/iocontext.h
+++ b/include/linux/iocontext.h
@@ -3,6 +3,7 @@
 
 #include 
 #include 
+#include 
 #include 
 
 enum {
@@ -96,7 +97,7 @@ struct io_cq {
  */
 struct io_context {
atomic_long_t refcount;
-   atomic_t active_ref;
+   refcount_t active_ref;
atomic_t nr_tasks;
 
/* all the fields below are protected by this lock */
@@ -128,9 +129,8 @@ struct io_context {
 static inline void get_io_context_active(struct io_context *ioc)
 {
WARN_ON_ONCE(atomic_long_read(>refcount) <= 0);
-   WARN_ON_ONCE(atomic_read(>active_ref) <= 0);
atomic_long_inc(>refcount);
-   atomic_inc(>active_ref);
+   refcount_inc(>active_ref);
 }
 
 static inline void ioc_task_link(struct io_context *ioc)
-- 
2.7.4



[PATCH 5/5] block: convert bsg_device.ref_count from atomic_t to refcount_t

2017-04-20 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 block/bsg.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/block/bsg.c b/block/bsg.c
index 74835db..6d0ceb9 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -38,7 +39,7 @@ struct bsg_device {
struct list_head busy_list;
struct list_head done_list;
struct hlist_node dev_list;
-   atomic_t ref_count;
+   refcount_t ref_count;
int queued_cmds;
int done_cmds;
wait_queue_head_t wq_done;
@@ -711,7 +712,7 @@ static int bsg_put_device(struct bsg_device *bd)
 
mutex_lock(_mutex);
 
-   do_free = atomic_dec_and_test(>ref_count);
+   do_free = refcount_dec_and_test(>ref_count);
if (!do_free) {
mutex_unlock(_mutex);
goto out;
@@ -763,7 +764,7 @@ static struct bsg_device *bsg_add_device(struct inode 
*inode,
 
bsg_set_block(bd, file);
 
-   atomic_set(>ref_count, 1);
+   refcount_set(>ref_count, 1);
mutex_lock(_mutex);
hlist_add_head(>dev_list, bsg_dev_idx_hash(iminor(inode)));
 
@@ -783,7 +784,7 @@ static struct bsg_device *__bsg_get_device(int minor, 
struct request_queue *q)
 
hlist_for_each_entry(bd, bsg_dev_idx_hash(minor), dev_list) {
if (bd->queue == q) {
-   atomic_inc(>ref_count);
+   refcount_inc(>ref_count);
goto found;
}
}
-- 
2.7.4



[PATCH] drivers, scsi: convert iscsi_task.refcount from atomic_t to refcount_t

2017-03-09 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
Acked-by: Chris Leech <cle...@redhat.com>
---
 drivers/scsi/libiscsi.c| 8 
 drivers/scsi/qedi/qedi_iscsi.c | 2 +-
 include/scsi/libiscsi.h| 3 ++-
 3 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 834d121..7eb1d2c 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -516,13 +516,13 @@ static void iscsi_free_task(struct iscsi_task *task)
 
 void __iscsi_get_task(struct iscsi_task *task)
 {
-   atomic_inc(>refcount);
+   refcount_inc(>refcount);
 }
 EXPORT_SYMBOL_GPL(__iscsi_get_task);
 
 void __iscsi_put_task(struct iscsi_task *task)
 {
-   if (atomic_dec_and_test(>refcount))
+   if (refcount_dec_and_test(>refcount))
iscsi_free_task(task);
 }
 EXPORT_SYMBOL_GPL(__iscsi_put_task);
@@ -744,7 +744,7 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct 
iscsi_hdr *hdr,
 * released by the lld when it has transmitted the task for
 * pdus we do not expect a response for.
 */
-   atomic_set(>refcount, 1);
+   refcount_set(>refcount, 1);
task->conn = conn;
task->sc = NULL;
INIT_LIST_HEAD(>running);
@@ -1616,7 +1616,7 @@ static inline struct iscsi_task *iscsi_alloc_task(struct 
iscsi_conn *conn,
sc->SCp.phase = conn->session->age;
sc->SCp.ptr = (char *) task;
 
-   atomic_set(>refcount, 1);
+   refcount_set(>refcount, 1);
task->state = ISCSI_TASK_PENDING;
task->conn = conn;
task->sc = sc;
diff --git a/drivers/scsi/qedi/qedi_iscsi.c b/drivers/scsi/qedi/qedi_iscsi.c
index b9f79d3..3895bd5 100644
--- a/drivers/scsi/qedi/qedi_iscsi.c
+++ b/drivers/scsi/qedi/qedi_iscsi.c
@@ -1372,7 +1372,7 @@ static void qedi_cleanup_task(struct iscsi_task *task)
 {
if (!task->sc || task->state == ISCSI_TASK_PENDING) {
QEDI_INFO(NULL, QEDI_LOG_IO, "Returning ref_cnt=%d\n",
- atomic_read(>refcount));
+ refcount_read(>refcount));
return;
}
 
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index b0e275d..24d74b5 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -139,7 +140,7 @@ struct iscsi_task {
 
/* state set/tested under session->lock */
int state;
-   atomic_trefcount;
+   refcount_t  refcount;
struct list_headrunning;/* running cmd list */
void*dd_data;   /* driver/transport data */
 };
-- 
2.7.4



[PATCH] drivers, scsi: convert fc_fcp_pkt.ref_cnt from atomic_t to refcount_t

2017-03-08 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
Acked-by: Johannes Thumshirn <j...@kernel.org>
---
 drivers/scsi/libfc/fc_fcp.c | 6 +++---
 include/scsi/libfc.h| 3 ++-
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index 0e67621..a808e8e 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -154,7 +154,7 @@ static struct fc_fcp_pkt *fc_fcp_pkt_alloc(struct fc_lport 
*lport, gfp_t gfp)
memset(fsp, 0, sizeof(*fsp));
fsp->lp = lport;
fsp->xfer_ddp = FC_XID_UNKNOWN;
-   atomic_set(>ref_cnt, 1);
+   refcount_set(>ref_cnt, 1);
init_timer(>timer);
fsp->timer.data = (unsigned long)fsp;
INIT_LIST_HEAD(>list);
@@ -175,7 +175,7 @@ static struct fc_fcp_pkt *fc_fcp_pkt_alloc(struct fc_lport 
*lport, gfp_t gfp)
  */
 static void fc_fcp_pkt_release(struct fc_fcp_pkt *fsp)
 {
-   if (atomic_dec_and_test(>ref_cnt)) {
+   if (refcount_dec_and_test(>ref_cnt)) {
struct fc_fcp_internal *si = fc_get_scsi_internal(fsp->lp);
 
mempool_free(fsp, si->scsi_pkt_pool);
@@ -188,7 +188,7 @@ static void fc_fcp_pkt_release(struct fc_fcp_pkt *fsp)
  */
 static void fc_fcp_pkt_hold(struct fc_fcp_pkt *fsp)
 {
-   atomic_inc(>ref_cnt);
+   refcount_inc(>ref_cnt);
 }
 
 /**
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index da5033d..2109844 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -321,7 +322,7 @@ struct fc_seq_els_data {
  */
 struct fc_fcp_pkt {
spinlock_tscsi_pkt_lock;
-   atomic_t  ref_cnt;
+   refcount_tref_cnt;
 
/* SCSI command and data transfer information */
u32   data_len;
-- 
2.7.4



[PATCH 03/29] drivers, char: convert vma_data.refcnt from atomic_t to refcount_t

2017-03-06 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 drivers/char/mspec.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/char/mspec.c b/drivers/char/mspec.c
index a9c2fa3..7b75669 100644
--- a/drivers/char/mspec.c
+++ b/drivers/char/mspec.c
@@ -43,6 +43,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -89,7 +90,7 @@ static int is_sn2;
  * protect in fork case where multiple tasks share the vma_data.
  */
 struct vma_data {
-   atomic_t refcnt;/* Number of vmas sharing the data. */
+   refcount_t refcnt;  /* Number of vmas sharing the data. */
spinlock_t lock;/* Serialize access to this structure. */
int count;  /* Number of pages allocated. */
enum mspec_page_type type; /* Type of pages allocated. */
@@ -144,7 +145,7 @@ mspec_open(struct vm_area_struct *vma)
struct vma_data *vdata;
 
vdata = vma->vm_private_data;
-   atomic_inc(>refcnt);
+   refcount_inc(>refcnt);
 }
 
 /*
@@ -162,7 +163,7 @@ mspec_close(struct vm_area_struct *vma)
 
vdata = vma->vm_private_data;
 
-   if (!atomic_dec_and_test(>refcnt))
+   if (!refcount_dec_and_test(>refcnt))
return;
 
last_index = (vdata->vm_end - vdata->vm_start) >> PAGE_SHIFT;
@@ -274,7 +275,7 @@ mspec_mmap(struct file *file, struct vm_area_struct *vma,
vdata->vm_end = vma->vm_end;
vdata->type = type;
spin_lock_init(>lock);
-   atomic_set(>refcnt, 1);
+   refcount_set(>refcnt, 1);
vma->vm_private_data = vdata;
 
vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;
-- 
2.7.4



[PATCH 21/29] drivers, s390: convert fc_fcp_pkt.ref_cnt from atomic_t to refcount_t

2017-03-06 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 drivers/scsi/libfc/fc_fcp.c | 6 +++---
 include/scsi/libfc.h| 3 ++-
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index 0e67621..a808e8e 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -154,7 +154,7 @@ static struct fc_fcp_pkt *fc_fcp_pkt_alloc(struct fc_lport 
*lport, gfp_t gfp)
memset(fsp, 0, sizeof(*fsp));
fsp->lp = lport;
fsp->xfer_ddp = FC_XID_UNKNOWN;
-   atomic_set(>ref_cnt, 1);
+   refcount_set(>ref_cnt, 1);
init_timer(>timer);
fsp->timer.data = (unsigned long)fsp;
INIT_LIST_HEAD(>list);
@@ -175,7 +175,7 @@ static struct fc_fcp_pkt *fc_fcp_pkt_alloc(struct fc_lport 
*lport, gfp_t gfp)
  */
 static void fc_fcp_pkt_release(struct fc_fcp_pkt *fsp)
 {
-   if (atomic_dec_and_test(>ref_cnt)) {
+   if (refcount_dec_and_test(>ref_cnt)) {
struct fc_fcp_internal *si = fc_get_scsi_internal(fsp->lp);
 
mempool_free(fsp, si->scsi_pkt_pool);
@@ -188,7 +188,7 @@ static void fc_fcp_pkt_release(struct fc_fcp_pkt *fsp)
  */
 static void fc_fcp_pkt_hold(struct fc_fcp_pkt *fsp)
 {
-   atomic_inc(>ref_cnt);
+   refcount_inc(>ref_cnt);
 }
 
 /**
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index da5033d..2109844 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -321,7 +322,7 @@ struct fc_seq_els_data {
  */
 struct fc_fcp_pkt {
spinlock_tscsi_pkt_lock;
-   atomic_t  ref_cnt;
+   refcount_tref_cnt;
 
/* SCSI command and data transfer information */
u32   data_len;
-- 
2.7.4



[PATCH 20/29] drivers, s390: convert qeth_reply.refcnt from atomic_t to refcount_t

2017-03-06 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 drivers/s390/net/qeth_core.h  | 3 ++-
 drivers/s390/net/qeth_core_main.c | 8 +++-
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index e7addea..e2c81d21 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -641,7 +642,7 @@ struct qeth_reply {
int rc;
void *param;
struct qeth_card *card;
-   atomic_t refcnt;
+   refcount_t refcnt;
 };
 
 
diff --git a/drivers/s390/net/qeth_core_main.c 
b/drivers/s390/net/qeth_core_main.c
index 315d8a2..a2bf13f 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -555,7 +555,7 @@ static struct qeth_reply *qeth_alloc_reply(struct qeth_card 
*card)
 
reply = kzalloc(sizeof(struct qeth_reply), GFP_ATOMIC);
if (reply) {
-   atomic_set(>refcnt, 1);
+   refcount_set(>refcnt, 1);
atomic_set(>received, 0);
reply->card = card;
}
@@ -564,14 +564,12 @@ static struct qeth_reply *qeth_alloc_reply(struct 
qeth_card *card)
 
 static void qeth_get_reply(struct qeth_reply *reply)
 {
-   WARN_ON(atomic_read(>refcnt) <= 0);
-   atomic_inc(>refcnt);
+   refcount_inc(>refcnt);
 }
 
 static void qeth_put_reply(struct qeth_reply *reply)
 {
-   WARN_ON(atomic_read(>refcnt) <= 0);
-   if (atomic_dec_and_test(>refcnt))
+   if (refcount_dec_and_test(>refcnt))
kfree(reply);
 }
 
-- 
2.7.4



[PATCH 18/29] drivers, s390: convert urdev.ref_count from atomic_t to refcount_t

2017-03-06 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 drivers/s390/char/vmur.c | 8 
 drivers/s390/char/vmur.h | 4 +++-
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c
index 04aceb6..ced8151 100644
--- a/drivers/s390/char/vmur.c
+++ b/drivers/s390/char/vmur.c
@@ -110,7 +110,7 @@ static struct urdev *urdev_alloc(struct ccw_device *cdev)
mutex_init(>io_mutex);
init_waitqueue_head(>wait);
spin_lock_init(>open_lock);
-   atomic_set(>ref_count,  1);
+   refcount_set(>ref_count,  1);
urd->cdev = cdev;
get_device(>dev);
return urd;
@@ -126,7 +126,7 @@ static void urdev_free(struct urdev *urd)
 
 static void urdev_get(struct urdev *urd)
 {
-   atomic_inc(>ref_count);
+   refcount_inc(>ref_count);
 }
 
 static struct urdev *urdev_get_from_cdev(struct ccw_device *cdev)
@@ -159,7 +159,7 @@ static struct urdev *urdev_get_from_devno(u16 devno)
 
 static void urdev_put(struct urdev *urd)
 {
-   if (atomic_dec_and_test(>ref_count))
+   if (refcount_dec_and_test(>ref_count))
urdev_free(urd);
 }
 
@@ -946,7 +946,7 @@ static int ur_set_offline_force(struct ccw_device *cdev, 
int force)
rc = -EBUSY;
goto fail_urdev_put;
}
-   if (!force && (atomic_read(>ref_count) > 2)) {
+   if (!force && (refcount_read(>ref_count) > 2)) {
/* There is still a user of urd (e.g. ur_open) */
TRACE("ur_set_offline: BUSY\n");
rc = -EBUSY;
diff --git a/drivers/s390/char/vmur.h b/drivers/s390/char/vmur.h
index fa320ad..35ea9d1 100644
--- a/drivers/s390/char/vmur.h
+++ b/drivers/s390/char/vmur.h
@@ -11,6 +11,8 @@
 #ifndef _VMUR_H_
 #define _VMUR_H_
 
+#include 
+
 #define DEV_CLASS_UR_I 0x20 /* diag210 unit record input device class */
 #define DEV_CLASS_UR_O 0x10 /* diag210 unit record output device class */
 /*
@@ -69,7 +71,7 @@ struct urdev {
size_t reclen;  /* Record length for *write* CCWs */
int class;  /* VM device class */
int io_request_rc;  /* return code from I/O request */
-   atomic_t ref_count; /* reference counter */
+   refcount_t ref_count;   /* reference counter */
wait_queue_head_t wait; /* wait queue to serialize open */
int open_flag;  /* "urdev is open" flag */
spinlock_t open_lock;   /* serialize critical sections */
-- 
2.7.4



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

2017-03-06 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 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(>ref);
+   refcount_inc(>ref);
 }
 
 static void ffs_data_opened(struct ffs_data *ffs)
 {
ENTER();
 
-   atomic_inc(>ref);
+   refcount_inc(>ref);
if (atomic_add_return(1, >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(>ref))) {
+   if (unlikely(refcount_dec_and_test(>ref))) {
pr_info("%s(): freeing\n", __func__);
ffs_data_clear(ffs);
BUG_ON(waitqueue_active(>ev.waitq) ||
@@ -1634,7 +1634,7 @@ static struct ffs_data *ffs_data_new(void)
 
ENTER();
 
-   atomic_set(>ref, 1);
+   refcount_set(>ref, 1);
atomic_set(>opened, 0);
ffs->state = FFS_READ_DESCRIPTORS;
mutex_init(>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 
 #include 
 #include 
+#include 
 
 #ifdef VERBOSE_DEBUG
 #ifndef pr_vdebug
@@ -177,7 +178,7 @@ struct ffs_data {
struct completion   ep0req_completion;  /* P: mutex */
 
/* reference counter */
-   atomic_tref;
+   refcount_t  ref;
/* how many files are opened (EP0 and others) */
atomic_topened;
 
-- 
2.7.4



[PATCH 29/29] drivers, xen: convert grant_map.users from atomic_t to refcount_t

2017-03-06 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 drivers/xen/gntdev.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
index 2ef2b61..b183cb2 100644
--- a/drivers/xen/gntdev.c
+++ b/drivers/xen/gntdev.c
@@ -35,6 +35,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -85,7 +86,7 @@ struct grant_map {
int index;
int count;
int flags;
-   atomic_t users;
+   refcount_t users;
struct unmap_notify notify;
struct ioctl_gntdev_grant_ref *grants;
struct gnttab_map_grant_ref   *map_ops;
@@ -165,7 +166,7 @@ static struct grant_map *gntdev_alloc_map(struct 
gntdev_priv *priv, int count)
 
add->index = 0;
add->count = count;
-   atomic_set(>users, 1);
+   refcount_set(>users, 1);
 
return add;
 
@@ -211,7 +212,7 @@ static void gntdev_put_map(struct gntdev_priv *priv, struct 
grant_map *map)
if (!map)
return;
 
-   if (!atomic_dec_and_test(>users))
+   if (!refcount_dec_and_test(>users))
return;
 
atomic_sub(map->count, _mapped);
@@ -399,7 +400,7 @@ static void gntdev_vma_open(struct vm_area_struct *vma)
struct grant_map *map = vma->vm_private_data;
 
pr_debug("gntdev_vma_open %p\n", vma);
-   atomic_inc(>users);
+   refcount_inc(>users);
 }
 
 static void gntdev_vma_close(struct vm_area_struct *vma)
@@ -1003,7 +1004,7 @@ static int gntdev_mmap(struct file *flip, struct 
vm_area_struct *vma)
goto unlock_out;
}
 
-   atomic_inc(>users);
+   refcount_inc(>users);
 
vma->vm_ops = _vmops;
 
-- 
2.7.4



[PATCH 27/29] drivers, usb: convert ep_data.count from atomic_t to refcount_t

2017-03-06 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 drivers/usb/gadget/legacy/inode.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/gadget/legacy/inode.c 
b/drivers/usb/gadget/legacy/inode.c
index 81d76f3..d21a5f8 100644
--- a/drivers/usb/gadget/legacy/inode.c
+++ b/drivers/usb/gadget/legacy/inode.c
@@ -191,7 +191,7 @@ enum ep_state {
 struct ep_data {
struct mutexlock;
enum ep_state   state;
-   atomic_tcount;
+   refcount_t  count;
struct dev_data *dev;
/* must hold dev->lock before accessing ep or req */
struct usb_ep   *ep;
@@ -206,12 +206,12 @@ struct ep_data {
 
 static inline void get_ep (struct ep_data *data)
 {
-   atomic_inc (>count);
+   refcount_inc (>count);
 }
 
 static void put_ep (struct ep_data *data)
 {
-   if (likely (!atomic_dec_and_test (>count)))
+   if (likely (!refcount_dec_and_test (>count)))
return;
put_dev (data->dev);
/* needs no more cleanup */
@@ -1562,7 +1562,7 @@ static int activate_ep_files (struct dev_data *dev)
init_waitqueue_head (>wait);
 
strncpy (data->name, ep->name, sizeof (data->name) - 1);
-   atomic_set (>count, 1);
+   refcount_set (>count, 1);
data->dev = dev;
get_dev (dev);
 
-- 
2.7.4



[PATCH 01/29] drivers, block: convert xen_blkif.refcnt from atomic_t to refcount_t

2017-03-06 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 drivers/block/xen-blkback/common.h | 7 ---
 drivers/block/xen-blkback/xenbus.c | 2 +-
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/block/xen-blkback/common.h 
b/drivers/block/xen-blkback/common.h
index dea61f6..2ccfd62 100644
--- a/drivers/block/xen-blkback/common.h
+++ b/drivers/block/xen-blkback/common.h
@@ -35,6 +35,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -333,7 +334,7 @@ struct xen_blkif {
struct xen_vbd  vbd;
/* Back pointer to the backend_info. */
struct backend_info *be;
-   atomic_trefcnt;
+   refcount_t  refcnt;
/* for barrier (drain) requests */
struct completion   drain_complete;
atomic_tdrain;
@@ -386,10 +387,10 @@ struct pending_req {
 (_v)->bdev->bd_part->nr_sects : \
  get_capacity((_v)->bdev->bd_disk))
 
-#define xen_blkif_get(_b) (atomic_inc(&(_b)->refcnt))
+#define xen_blkif_get(_b) (refcount_inc(&(_b)->refcnt))
 #define xen_blkif_put(_b)  \
do {\
-   if (atomic_dec_and_test(&(_b)->refcnt)) \
+   if (refcount_dec_and_test(&(_b)->refcnt))   \
schedule_work(&(_b)->free_work);\
} while (0)
 
diff --git a/drivers/block/xen-blkback/xenbus.c 
b/drivers/block/xen-blkback/xenbus.c
index 8fe61b5..9f89be3 100644
--- a/drivers/block/xen-blkback/xenbus.c
+++ b/drivers/block/xen-blkback/xenbus.c
@@ -176,7 +176,7 @@ static struct xen_blkif *xen_blkif_alloc(domid_t domid)
return ERR_PTR(-ENOMEM);
 
blkif->domid = domid;
-   atomic_set(>refcnt, 1);
+   refcount_set(>refcnt, 1);
init_completion(>drain_complete);
INIT_WORK(>free_work, xen_blkif_deferred_free);
 
-- 
2.7.4



[PATCH 09/29] drivers, md: convert table_device.count from atomic_t to refcount_t

2017-03-06 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 drivers/md/dm.c | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 9f37d7f..cba91c3 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define DM_MSG_PREFIX "core"
 
@@ -96,7 +97,7 @@ struct dm_md_mempools {
 
 struct table_device {
struct list_head list;
-   atomic_t count;
+   refcount_t count;
struct dm_dev dm_dev;
 };
 
@@ -680,10 +681,11 @@ int dm_get_table_device(struct mapped_device *md, dev_t 
dev, fmode_t mode,
 
format_dev_t(td->dm_dev.name, dev);
 
-   atomic_set(>count, 0);
+   refcount_set(>count, 1);
list_add(>list, >table_devices);
+   } else {
+   refcount_inc(>count);
}
-   atomic_inc(>count);
mutex_unlock(>table_devices_lock);
 
*result = >dm_dev;
@@ -696,7 +698,7 @@ void dm_put_table_device(struct mapped_device *md, struct 
dm_dev *d)
struct table_device *td = container_of(d, struct table_device, dm_dev);
 
mutex_lock(>table_devices_lock);
-   if (atomic_dec_and_test(>count)) {
+   if (refcount_dec_and_test(>count)) {
close_table_device(td, md);
list_del(>list);
kfree(td);
@@ -713,7 +715,7 @@ static void free_table_devices(struct list_head *devices)
struct table_device *td = list_entry(tmp, struct table_device, 
list);
 
DMWARN("dm_destroy: %s still exists with %d references",
-  td->dm_dev.name, atomic_read(>count));
+  td->dm_dev.name, refcount_read(>count));
kfree(td);
}
 }
-- 
2.7.4



[PATCH 15/29] drivers, media: convert vb2_dma_sg_buf.refcount from atomic_t to refcount_t

2017-03-06 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 drivers/media/v4l2-core/videobuf2-dma-sg.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c 
b/drivers/media/v4l2-core/videobuf2-dma-sg.c
index ecff8f4..29fde1a 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-sg.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c
@@ -12,6 +12,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -46,7 +47,7 @@ struct vb2_dma_sg_buf {
struct sg_table *dma_sgt;
size_t  size;
unsigned intnum_pages;
-   atomic_trefcount;
+   refcount_t  refcount;
struct vb2_vmarea_handler   handler;
 
struct dma_buf_attachment   *db_attach;
@@ -150,7 +151,7 @@ static void *vb2_dma_sg_alloc(struct device *dev, unsigned 
long dma_attrs,
buf->handler.put = vb2_dma_sg_put;
buf->handler.arg = buf;
 
-   atomic_inc(>refcount);
+   refcount_set(>refcount, 1);
 
dprintk(1, "%s: Allocated buffer of %d pages\n",
__func__, buf->num_pages);
@@ -176,7 +177,7 @@ static void vb2_dma_sg_put(void *buf_priv)
struct sg_table *sgt = >sg_table;
int i = buf->num_pages;
 
-   if (atomic_dec_and_test(>refcount)) {
+   if (refcount_dec_and_test(>refcount)) {
dprintk(1, "%s: Freeing buffer of %d pages\n", __func__,
buf->num_pages);
dma_unmap_sg_attrs(buf->dev, sgt->sgl, sgt->orig_nents,
@@ -320,7 +321,7 @@ static unsigned int vb2_dma_sg_num_users(void *buf_priv)
 {
struct vb2_dma_sg_buf *buf = buf_priv;
 
-   return atomic_read(>refcount);
+   return refcount_read(>refcount);
 }
 
 static int vb2_dma_sg_mmap(void *buf_priv, struct vm_area_struct *vma)
@@ -530,7 +531,7 @@ static struct dma_buf *vb2_dma_sg_get_dmabuf(void 
*buf_priv, unsigned long flags
return NULL;
 
/* dmabuf keeps reference to vb2 buffer */
-   atomic_inc(>refcount);
+   refcount_inc(>refcount);
 
return dbuf;
 }
-- 
2.7.4



[PATCH 19/29] drivers, s390: convert lcs_reply.refcnt from atomic_t to refcount_t

2017-03-06 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 drivers/s390/net/lcs.c | 8 +++-
 drivers/s390/net/lcs.h | 3 ++-
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index 211b31d..18dc787 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -774,15 +774,13 @@ lcs_get_lancmd(struct lcs_card *card, int count)
 static void
 lcs_get_reply(struct lcs_reply *reply)
 {
-   WARN_ON(atomic_read(>refcnt) <= 0);
-   atomic_inc(>refcnt);
+   refcount_inc(>refcnt);
 }
 
 static void
 lcs_put_reply(struct lcs_reply *reply)
 {
-WARN_ON(atomic_read(>refcnt) <= 0);
-if (atomic_dec_and_test(>refcnt)) {
+if (refcount_dec_and_test(>refcnt)) {
kfree(reply);
}
 
@@ -798,7 +796,7 @@ lcs_alloc_reply(struct lcs_cmd *cmd)
reply = kzalloc(sizeof(struct lcs_reply), GFP_ATOMIC);
if (!reply)
return NULL;
-   atomic_set(>refcnt,1);
+   refcount_set(>refcnt,1);
reply->sequence_no = cmd->sequence_no;
reply->received = 0;
reply->rc = 0;
diff --git a/drivers/s390/net/lcs.h b/drivers/s390/net/lcs.h
index 150fcb4..3802f4f 100644
--- a/drivers/s390/net/lcs.h
+++ b/drivers/s390/net/lcs.h
@@ -4,6 +4,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #define LCS_DBF_TEXT(level, name, text) \
@@ -270,7 +271,7 @@ struct lcs_buffer {
 struct lcs_reply {
struct list_head list;
__u16 sequence_no;
-   atomic_t refcnt;
+   refcount_t refcnt;
/* Callback for completion notification. */
void (*callback)(struct lcs_card *, struct lcs_cmd *);
wait_queue_head_t wait_q;
-- 
2.7.4



[PATCH 17/29] drivers, pci: convert hv_pci_dev.refs from atomic_t to refcount_t

2017-03-06 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 drivers/pci/host/pci-hyperv.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c
index cd114c6..870deed 100644
--- a/drivers/pci/host/pci-hyperv.c
+++ b/drivers/pci/host/pci-hyperv.c
@@ -56,6 +56,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 /*
@@ -421,7 +422,7 @@ enum hv_pcidev_ref_reason {
 struct hv_pci_dev {
/* List protected by pci_rescan_remove_lock */
struct list_head list_entry;
-   atomic_t refs;
+   refcount_t refs;
enum hv_pcichild_state state;
struct pci_function_description desc;
bool reported_missing;
@@ -1254,13 +1255,13 @@ static void q_resource_requirements(void *context, 
struct pci_response *resp,
 static void get_pcichild(struct hv_pci_dev *hpdev,
enum hv_pcidev_ref_reason reason)
 {
-   atomic_inc(>refs);
+   refcount_inc(>refs);
 }
 
 static void put_pcichild(struct hv_pci_dev *hpdev,
enum hv_pcidev_ref_reason reason)
 {
-   if (atomic_dec_and_test(>refs))
+   if (refcount_dec_and_test(>refs))
kfree(hpdev);
 }
 
@@ -1314,7 +1315,7 @@ static struct hv_pci_dev *new_pcichild_device(struct 
hv_pcibus_device *hbus,
wait_for_completion(_pkt.host_event);
 
hpdev->desc = *desc;
-   get_pcichild(hpdev, hv_pcidev_ref_initial);
+   refcount_set(>refs, 1);
get_pcichild(hpdev, hv_pcidev_ref_childlist);
spin_lock_irqsave(>device_list_lock, flags);
list_add_tail(>list_entry, >children);
-- 
2.7.4



[PATCH 07/29] drivers, md: convert dm_dev_internal.count from atomic_t to refcount_t

2017-03-06 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 drivers/md/dm-table.c | 6 +++---
 drivers/md/dm.h   | 3 ++-
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 3ad16d9..d2e2741 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -416,15 +416,15 @@ int dm_get_device(struct dm_target *ti, const char *path, 
fmode_t mode,
return r;
}
 
-   atomic_set(>count, 0);
+   refcount_set(>count, 1);
list_add(>list, >devices);
 
} else if (dd->dm_dev->mode != (mode | dd->dm_dev->mode)) {
r = upgrade_mode(dd, mode, t->md);
if (r)
return r;
+   refcount_inc(>count);
}
-   atomic_inc(>count);
 
*result = dd->dm_dev;
return 0;
@@ -478,7 +478,7 @@ void dm_put_device(struct dm_target *ti, struct dm_dev *d)
   dm_device_name(ti->table->md), d->name);
return;
}
-   if (atomic_dec_and_test(>count)) {
+   if (refcount_dec_and_test(>count)) {
dm_put_table_device(ti->table->md, d);
list_del(>list);
kfree(dd);
diff --git a/drivers/md/dm.h b/drivers/md/dm.h
index f298b01..63b8142 100644
--- a/drivers/md/dm.h
+++ b/drivers/md/dm.h
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "dm-stats.h"
 
@@ -38,7 +39,7 @@
  */
 struct dm_dev_internal {
struct list_head list;
-   atomic_t count;
+   refcount_t count;
struct dm_dev *dm_dev;
 };
 
-- 
2.7.4



[PATCH 23/29] drivers: convert vme_user_vma_priv.refcnt from atomic_t to refcount_t

2017-03-06 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 drivers/staging/vme/devices/vme_user.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/vme/devices/vme_user.c 
b/drivers/staging/vme/devices/vme_user.c
index 69e9a770..a3d4610 100644
--- a/drivers/staging/vme/devices/vme_user.c
+++ b/drivers/staging/vme/devices/vme_user.c
@@ -17,7 +17,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -118,7 +118,7 @@ static const int type[VME_DEVS] = { MASTER_MINOR,   
MASTER_MINOR,
 
 struct vme_user_vma_priv {
unsigned int minor;
-   atomic_t refcnt;
+   refcount_t refcnt;
 };
 
 static ssize_t resource_to_user(int minor, char __user *buf, size_t count,
@@ -430,7 +430,7 @@ static void vme_user_vm_open(struct vm_area_struct *vma)
 {
struct vme_user_vma_priv *vma_priv = vma->vm_private_data;
 
-   atomic_inc(_priv->refcnt);
+   refcount_inc(_priv->refcnt);
 }
 
 static void vme_user_vm_close(struct vm_area_struct *vma)
@@ -438,7 +438,7 @@ static void vme_user_vm_close(struct vm_area_struct *vma)
struct vme_user_vma_priv *vma_priv = vma->vm_private_data;
unsigned int minor = vma_priv->minor;
 
-   if (!atomic_dec_and_test(_priv->refcnt))
+   if (!refcount_dec_and_test(_priv->refcnt))
return;
 
mutex_lock([minor].mutex);
@@ -473,7 +473,7 @@ static int vme_user_master_mmap(unsigned int minor, struct 
vm_area_struct *vma)
}
 
vma_priv->minor = minor;
-   atomic_set(_priv->refcnt, 1);
+   refcount_set(_priv->refcnt, 1);
vma->vm_ops = _user_vm_ops;
vma->vm_private_data = vma_priv;
 
-- 
2.7.4



[PATCH 13/29] drivers, media: convert vb2_vmarea_handler.refcount from atomic_t to refcount_t

2017-03-06 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 drivers/media/v4l2-core/videobuf2-memops.c | 6 +++---
 include/media/videobuf2-memops.h   | 3 ++-
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-memops.c 
b/drivers/media/v4l2-core/videobuf2-memops.c
index 1cd322e..4bb8424 100644
--- a/drivers/media/v4l2-core/videobuf2-memops.c
+++ b/drivers/media/v4l2-core/videobuf2-memops.c
@@ -96,10 +96,10 @@ static void vb2_common_vm_open(struct vm_area_struct *vma)
struct vb2_vmarea_handler *h = vma->vm_private_data;
 
pr_debug("%s: %p, refcount: %d, vma: %08lx-%08lx\n",
-  __func__, h, atomic_read(h->refcount), vma->vm_start,
+  __func__, h, refcount_read(h->refcount), vma->vm_start,
   vma->vm_end);
 
-   atomic_inc(h->refcount);
+   refcount_inc(h->refcount);
 }
 
 /**
@@ -114,7 +114,7 @@ static void vb2_common_vm_close(struct vm_area_struct *vma)
struct vb2_vmarea_handler *h = vma->vm_private_data;
 
pr_debug("%s: %p, refcount: %d, vma: %08lx-%08lx\n",
-  __func__, h, atomic_read(h->refcount), vma->vm_start,
+  __func__, h, refcount_read(h->refcount), vma->vm_start,
   vma->vm_end);
 
h->put(h->arg);
diff --git a/include/media/videobuf2-memops.h b/include/media/videobuf2-memops.h
index 36565c7a..a6ed091 100644
--- a/include/media/videobuf2-memops.h
+++ b/include/media/videobuf2-memops.h
@@ -16,6 +16,7 @@
 
 #include 
 #include 
+#include 
 
 /**
  * struct vb2_vmarea_handler - common vma refcount tracking handler
@@ -25,7 +26,7 @@
  * @arg:   argument for @put callback
  */
 struct vb2_vmarea_handler {
-   atomic_t*refcount;
+   refcount_t  *refcount;
void(*put)(void *arg);
void*arg;
 };
-- 
2.7.4



[PATCH 16/29] drivers, media: convert vb2_vmalloc_buf.refcount from atomic_t to refcount_t

2017-03-06 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 drivers/media/v4l2-core/videobuf2-vmalloc.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-vmalloc.c 
b/drivers/media/v4l2-core/videobuf2-vmalloc.c
index 3f77814..f83253a 100644
--- a/drivers/media/v4l2-core/videobuf2-vmalloc.c
+++ b/drivers/media/v4l2-core/videobuf2-vmalloc.c
@@ -13,6 +13,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -26,7 +27,7 @@ struct vb2_vmalloc_buf {
struct frame_vector *vec;
enum dma_data_direction dma_dir;
unsigned long   size;
-   atomic_trefcount;
+   refcount_t  refcount;
struct vb2_vmarea_handler   handler;
struct dma_buf  *dbuf;
 };
@@ -56,7 +57,7 @@ static void *vb2_vmalloc_alloc(struct device *dev, unsigned 
long attrs,
return ERR_PTR(-ENOMEM);
}
 
-   atomic_inc(>refcount);
+   refcount_set(>refcount, 1);
return buf;
 }
 
@@ -64,7 +65,7 @@ static void vb2_vmalloc_put(void *buf_priv)
 {
struct vb2_vmalloc_buf *buf = buf_priv;
 
-   if (atomic_dec_and_test(>refcount)) {
+   if (refcount_dec_and_test(>refcount)) {
vfree(buf->vaddr);
kfree(buf);
}
@@ -161,7 +162,7 @@ static void *vb2_vmalloc_vaddr(void *buf_priv)
 static unsigned int vb2_vmalloc_num_users(void *buf_priv)
 {
struct vb2_vmalloc_buf *buf = buf_priv;
-   return atomic_read(>refcount);
+   return refcount_read(>refcount);
 }
 
 static int vb2_vmalloc_mmap(void *buf_priv, struct vm_area_struct *vma)
@@ -368,7 +369,7 @@ static struct dma_buf *vb2_vmalloc_get_dmabuf(void 
*buf_priv, unsigned long flag
return NULL;
 
/* dmabuf keeps reference to vb2 buffer */
-   atomic_inc(>refcount);
+   refcount_inc(>refcount);
 
return dbuf;
 }
-- 
2.7.4



[PATCH 14/29] drivers, media: convert vb2_dc_buf.refcount from atomic_t to refcount_t

2017-03-06 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index fb6a177..d29a07f 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -12,6 +12,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -34,7 +35,7 @@ struct vb2_dc_buf {
 
/* MMAP related */
struct vb2_vmarea_handler   handler;
-   atomic_trefcount;
+   refcount_t  refcount;
struct sg_table *sgt_base;
 
/* DMABUF related */
@@ -86,7 +87,7 @@ static unsigned int vb2_dc_num_users(void *buf_priv)
 {
struct vb2_dc_buf *buf = buf_priv;
 
-   return atomic_read(>refcount);
+   return refcount_read(>refcount);
 }
 
 static void vb2_dc_prepare(void *buf_priv)
@@ -122,7 +123,7 @@ static void vb2_dc_put(void *buf_priv)
 {
struct vb2_dc_buf *buf = buf_priv;
 
-   if (!atomic_dec_and_test(>refcount))
+   if (!refcount_dec_and_test(>refcount))
return;
 
if (buf->sgt_base) {
@@ -170,7 +171,7 @@ static void *vb2_dc_alloc(struct device *dev, unsigned long 
attrs,
buf->handler.put = vb2_dc_put;
buf->handler.arg = buf;
 
-   atomic_inc(>refcount);
+   refcount_set(>refcount, 1);
 
return buf;
 }
@@ -407,7 +408,7 @@ static struct dma_buf *vb2_dc_get_dmabuf(void *buf_priv, 
unsigned long flags)
return NULL;
 
/* dmabuf keeps reference to vb2 buffer */
-   atomic_inc(>refcount);
+   refcount_inc(>refcount);
 
return dbuf;
 }
-- 
2.7.4



[PATCH 28/29] drivers: convert sbd_duart.map_guard from atomic_t to refcount_t

2017-03-06 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 drivers/tty/serial/sb1250-duart.c | 18 +++---
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/drivers/tty/serial/sb1250-duart.c 
b/drivers/tty/serial/sb1250-duart.c
index 771f361..041625c 100644
--- a/drivers/tty/serial/sb1250-duart.c
+++ b/drivers/tty/serial/sb1250-duart.c
@@ -41,7 +41,7 @@
 #include 
 #include 
 
-#include 
+#include 
 #include 
 #include 
 
@@ -103,7 +103,7 @@ struct sbd_port {
 struct sbd_duart {
struct sbd_port sport[2];
unsigned long   mapctrl;
-   atomic_tmap_guard;
+   refcount_t  map_guard;
 };
 
 #define to_sport(uport) container_of(uport, struct sbd_port, port)
@@ -654,15 +654,13 @@ static void sbd_release_port(struct uart_port *uport)
 {
struct sbd_port *sport = to_sport(uport);
struct sbd_duart *duart = sport->duart;
-   int map_guard;
 
iounmap(sport->memctrl);
sport->memctrl = NULL;
iounmap(uport->membase);
uport->membase = NULL;
 
-   map_guard = atomic_add_return(-1, >map_guard);
-   if (!map_guard)
+   if(refcount_dec_and_test(>map_guard))
release_mem_region(duart->mapctrl, DUART_CHANREG_SPACING);
release_mem_region(uport->mapbase, DUART_CHANREG_SPACING);
 }
@@ -698,7 +696,6 @@ static int sbd_request_port(struct uart_port *uport)
 {
const char *err = KERN_ERR "sbd: Unable to reserve MMIO resource\n";
struct sbd_duart *duart = to_sport(uport)->duart;
-   int map_guard;
int ret = 0;
 
if (!request_mem_region(uport->mapbase, DUART_CHANREG_SPACING,
@@ -706,11 +703,11 @@ static int sbd_request_port(struct uart_port *uport)
printk(err);
return -EBUSY;
}
-   map_guard = atomic_add_return(1, >map_guard);
-   if (map_guard == 1) {
+   refcount_inc(>map_guard);
+   if (refcount_read(>map_guard) == 1) {
if (!request_mem_region(duart->mapctrl, DUART_CHANREG_SPACING,
"sb1250-duart")) {
-   atomic_add(-1, >map_guard);
+   refcount_dec(>map_guard);
printk(err);
ret = -EBUSY;
}
@@ -718,8 +715,7 @@ static int sbd_request_port(struct uart_port *uport)
if (!ret) {
ret = sbd_map_port(uport);
if (ret) {
-   map_guard = atomic_add_return(-1, >map_guard);
-   if (!map_guard)
+   if (refcount_dec_and_test(>map_guard))
release_mem_region(duart->mapctrl,
   DUART_CHANREG_SPACING);
}
-- 
2.7.4



[PATCH 22/29] drivers, scsi: convert iscsi_task.refcount from atomic_t to refcount_t

2017-03-06 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 drivers/scsi/libiscsi.c| 8 
 drivers/scsi/qedi/qedi_iscsi.c | 2 +-
 include/scsi/libiscsi.h| 3 ++-
 3 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 834d121..7eb1d2c 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -516,13 +516,13 @@ static void iscsi_free_task(struct iscsi_task *task)
 
 void __iscsi_get_task(struct iscsi_task *task)
 {
-   atomic_inc(>refcount);
+   refcount_inc(>refcount);
 }
 EXPORT_SYMBOL_GPL(__iscsi_get_task);
 
 void __iscsi_put_task(struct iscsi_task *task)
 {
-   if (atomic_dec_and_test(>refcount))
+   if (refcount_dec_and_test(>refcount))
iscsi_free_task(task);
 }
 EXPORT_SYMBOL_GPL(__iscsi_put_task);
@@ -744,7 +744,7 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct 
iscsi_hdr *hdr,
 * released by the lld when it has transmitted the task for
 * pdus we do not expect a response for.
 */
-   atomic_set(>refcount, 1);
+   refcount_set(>refcount, 1);
task->conn = conn;
task->sc = NULL;
INIT_LIST_HEAD(>running);
@@ -1616,7 +1616,7 @@ static inline struct iscsi_task *iscsi_alloc_task(struct 
iscsi_conn *conn,
sc->SCp.phase = conn->session->age;
sc->SCp.ptr = (char *) task;
 
-   atomic_set(>refcount, 1);
+   refcount_set(>refcount, 1);
task->state = ISCSI_TASK_PENDING;
task->conn = conn;
task->sc = sc;
diff --git a/drivers/scsi/qedi/qedi_iscsi.c b/drivers/scsi/qedi/qedi_iscsi.c
index b9f79d3..3895bd5 100644
--- a/drivers/scsi/qedi/qedi_iscsi.c
+++ b/drivers/scsi/qedi/qedi_iscsi.c
@@ -1372,7 +1372,7 @@ static void qedi_cleanup_task(struct iscsi_task *task)
 {
if (!task->sc || task->state == ISCSI_TASK_PENDING) {
QEDI_INFO(NULL, QEDI_LOG_IO, "Returning ref_cnt=%d\n",
- atomic_read(>refcount));
+ refcount_read(>refcount));
return;
}
 
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index b0e275d..24d74b5 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -139,7 +140,7 @@ struct iscsi_task {
 
/* state set/tested under session->lock */
int state;
-   atomic_trefcount;
+   refcount_t  refcount;
struct list_headrunning;/* running cmd list */
void*dd_data;   /* driver/transport data */
 };
-- 
2.7.4



[PATCH 04/29] drivers, connector: convert cn_callback_entry.refcnt from atomic_t to refcount_t

2017-03-06 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 drivers/connector/cn_queue.c  | 4 ++--
 drivers/connector/connector.c | 2 +-
 include/linux/connector.h | 4 ++--
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/connector/cn_queue.c b/drivers/connector/cn_queue.c
index 1f8bf05..9c54fdf 100644
--- a/drivers/connector/cn_queue.c
+++ b/drivers/connector/cn_queue.c
@@ -45,7 +45,7 @@ cn_queue_alloc_callback_entry(struct cn_queue_dev *dev, const 
char *name,
return NULL;
}
 
-   atomic_set(>refcnt, 1);
+   refcount_set(>refcnt, 1);
 
atomic_inc(>refcnt);
cbq->pdev = dev;
@@ -58,7 +58,7 @@ cn_queue_alloc_callback_entry(struct cn_queue_dev *dev, const 
char *name,
 
 void cn_queue_release_callback(struct cn_callback_entry *cbq)
 {
-   if (!atomic_dec_and_test(>refcnt))
+   if (!refcount_dec_and_test(>refcnt))
return;
 
atomic_dec(>pdev->refcnt);
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index 25693b0..8615594b 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -157,7 +157,7 @@ static int cn_call_callback(struct sk_buff *skb)
spin_lock_bh(>cbdev->queue_lock);
list_for_each_entry(i, >cbdev->queue_list, callback_entry) {
if (cn_cb_equal(>id.id, >id)) {
-   atomic_inc(>refcnt);
+   refcount_inc(>refcnt);
cbq = i;
break;
}
diff --git a/include/linux/connector.h b/include/linux/connector.h
index f8fe863..032102b 100644
--- a/include/linux/connector.h
+++ b/include/linux/connector.h
@@ -22,7 +22,7 @@
 #define __CONNECTOR_H
 
 
-#include 
+#include 
 
 #include 
 #include 
@@ -49,7 +49,7 @@ struct cn_callback_id {
 
 struct cn_callback_entry {
struct list_head callback_entry;
-   atomic_t refcnt;
+   refcount_t refcnt;
struct cn_queue_dev *pdev;
 
struct cn_callback_id id;
-- 
2.7.4



[PATCH 05/29] drivers, md, bcache: convert cached_dev.count from atomic_t to refcount_t

2017-03-06 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 drivers/md/bcache/bcache.h| 7 ---
 drivers/md/bcache/super.c | 6 +++---
 drivers/md/bcache/writeback.h | 2 +-
 3 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h
index c3ea03c..de2be28 100644
--- a/drivers/md/bcache/bcache.h
+++ b/drivers/md/bcache/bcache.h
@@ -184,6 +184,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -299,7 +300,7 @@ struct cached_dev {
struct semaphoresb_write_mutex;
 
/* Refcount on the cache set. Always nonzero when we're caching. */
-   atomic_tcount;
+   refcount_t  count;
struct work_struct  detach;
 
/*
@@ -805,13 +806,13 @@ do {  
\
 
 static inline void cached_dev_put(struct cached_dev *dc)
 {
-   if (atomic_dec_and_test(>count))
+   if (refcount_dec_and_test(>count))
schedule_work(>detach);
 }
 
 static inline bool cached_dev_get(struct cached_dev *dc)
 {
-   if (!atomic_inc_not_zero(>count))
+   if (!refcount_inc_not_zero(>count))
return false;
 
/* Paired with the mb in cached_dev_attach */
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index 85e3f21..cc36ce4 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -891,7 +891,7 @@ static void cached_dev_detach_finish(struct work_struct *w)
closure_init_stack();
 
BUG_ON(!test_bit(BCACHE_DEV_DETACHING, >disk.flags));
-   BUG_ON(atomic_read(>count));
+   BUG_ON(refcount_read(>count));
 
mutex_lock(_register_lock);
 
@@ -1018,7 +1018,7 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct 
cache_set *c)
 * dc->c must be set before dc->count != 0 - paired with the mb in
 * cached_dev_get()
 */
-   atomic_set(>count, 1);
+   refcount_set(>count, 1);
 
/* Block writeback thread, but spawn it */
down_write(>writeback_lock);
@@ -1030,7 +1030,7 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct 
cache_set *c)
if (BDEV_STATE(>sb) == BDEV_STATE_DIRTY) {
bch_sectors_dirty_init(dc);
atomic_set(>has_dirty, 1);
-   atomic_inc(>count);
+   refcount_inc(>count);
bch_writeback_queue(dc);
}
 
diff --git a/drivers/md/bcache/writeback.h b/drivers/md/bcache/writeback.h
index 629bd1a..5bac1b0 100644
--- a/drivers/md/bcache/writeback.h
+++ b/drivers/md/bcache/writeback.h
@@ -70,7 +70,7 @@ static inline void bch_writeback_add(struct cached_dev *dc)
 {
if (!atomic_read(>has_dirty) &&
!atomic_xchg(>has_dirty, 1)) {
-   atomic_inc(>count);
+   refcount_inc(>count);
 
if (BDEV_STATE(>sb) != BDEV_STATE_DIRTY) {
SET_BDEV_STATE(>sb, BDEV_STATE_DIRTY);
-- 
2.7.4



[PATCH 06/29] drivers, md: convert dm_cache_metadata.ref_count from atomic_t to refcount_t

2017-03-06 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 drivers/md/dm-cache-metadata.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/md/dm-cache-metadata.c b/drivers/md/dm-cache-metadata.c
index e4c2c1a..6d26e71 100644
--- a/drivers/md/dm-cache-metadata.c
+++ b/drivers/md/dm-cache-metadata.c
@@ -13,6 +13,7 @@
 #include "persistent-data/dm-transaction-manager.h"
 
 #include 
+#include 
 
 /**/
 
@@ -102,7 +103,7 @@ struct cache_disk_superblock {
 } __packed;
 
 struct dm_cache_metadata {
-   atomic_t ref_count;
+   refcount_t ref_count;
struct list_head list;
 
unsigned version;
@@ -756,7 +757,7 @@ static struct dm_cache_metadata *metadata_open(struct 
block_device *bdev,
}
 
cmd->version = metadata_version;
-   atomic_set(>ref_count, 1);
+   refcount_set(>ref_count, 1);
init_rwsem(>root_lock);
cmd->bdev = bdev;
cmd->data_block_size = data_block_size;
@@ -794,7 +795,7 @@ static struct dm_cache_metadata *lookup(struct block_device 
*bdev)
 
list_for_each_entry(cmd, , list)
if (cmd->bdev == bdev) {
-   atomic_inc(>ref_count);
+   refcount_inc(>ref_count);
return cmd;
}
 
@@ -865,7 +866,7 @@ struct dm_cache_metadata *dm_cache_metadata_open(struct 
block_device *bdev,
 
 void dm_cache_metadata_close(struct dm_cache_metadata *cmd)
 {
-   if (atomic_dec_and_test(>ref_count)) {
+   if (refcount_dec_and_test(>ref_count)) {
mutex_lock(_lock);
list_del(>list);
mutex_unlock(_lock);
-- 
2.7.4



[PATCH 24/29] drivers: convert iblock_req.pending from atomic_t to refcount_t

2017-03-06 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 drivers/target/target_core_iblock.c | 12 ++--
 drivers/target/target_core_iblock.h |  3 ++-
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/target/target_core_iblock.c 
b/drivers/target/target_core_iblock.c
index d316ed5..bb069eb 100644
--- a/drivers/target/target_core_iblock.c
+++ b/drivers/target/target_core_iblock.c
@@ -279,7 +279,7 @@ static void iblock_complete_cmd(struct se_cmd *cmd)
struct iblock_req *ibr = cmd->priv;
u8 status;
 
-   if (!atomic_dec_and_test(>pending))
+   if (!refcount_dec_and_test(>pending))
return;
 
if (atomic_read(>ib_bio_err_cnt))
@@ -487,7 +487,7 @@ iblock_execute_write_same(struct se_cmd *cmd)
bio_list_init();
bio_list_add(, bio);
 
-   atomic_set(>pending, 1);
+   refcount_set(>pending, 1);
 
while (sectors) {
while (bio_add_page(bio, sg_page(sg), sg->length, sg->offset)
@@ -498,7 +498,7 @@ iblock_execute_write_same(struct se_cmd *cmd)
if (!bio)
goto fail_put_bios;
 
-   atomic_inc(>pending);
+   refcount_inc(>pending);
bio_list_add(, bio);
}
 
@@ -706,7 +706,7 @@ iblock_execute_rw(struct se_cmd *cmd, struct scatterlist 
*sgl, u32 sgl_nents,
cmd->priv = ibr;
 
if (!sgl_nents) {
-   atomic_set(>pending, 1);
+   refcount_set(>pending, 1);
iblock_complete_cmd(cmd);
return 0;
}
@@ -719,7 +719,7 @@ iblock_execute_rw(struct se_cmd *cmd, struct scatterlist 
*sgl, u32 sgl_nents,
bio_list_init();
bio_list_add(, bio);
 
-   atomic_set(>pending, 2);
+   refcount_set(>pending, 2);
bio_cnt = 1;
 
for_each_sg(sgl, sg, sgl_nents, i) {
@@ -740,7 +740,7 @@ iblock_execute_rw(struct se_cmd *cmd, struct scatterlist 
*sgl, u32 sgl_nents,
if (!bio)
goto fail_put_bios;
 
-   atomic_inc(>pending);
+   refcount_inc(>pending);
bio_list_add(, bio);
bio_cnt++;
}
diff --git a/drivers/target/target_core_iblock.h 
b/drivers/target/target_core_iblock.h
index 718d3fc..f2a5797 100644
--- a/drivers/target/target_core_iblock.h
+++ b/drivers/target/target_core_iblock.h
@@ -2,6 +2,7 @@
 #define TARGET_CORE_IBLOCK_H
 
 #include 
+#include 
 #include 
 
 #define IBLOCK_VERSION "4.0"
@@ -10,7 +11,7 @@
 #define IBLOCK_LBA_SHIFT   9
 
 struct iblock_req {
-   atomic_t pending;
+   refcount_t pending;
atomic_t ib_bio_err_cnt;
 } cacheline_aligned;
 
-- 
2.7.4



[PATCH 11/29] drivers, media: convert cx88_core.refcount from atomic_t to refcount_t

2017-03-06 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 drivers/media/pci/cx88/cx88-cards.c | 2 +-
 drivers/media/pci/cx88/cx88-core.c  | 4 ++--
 drivers/media/pci/cx88/cx88.h   | 3 ++-
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/media/pci/cx88/cx88-cards.c 
b/drivers/media/pci/cx88/cx88-cards.c
index cdfbde2..7fc5f5f 100644
--- a/drivers/media/pci/cx88/cx88-cards.c
+++ b/drivers/media/pci/cx88/cx88-cards.c
@@ -3670,7 +3670,7 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, 
int nr)
if (!core)
return NULL;
 
-   atomic_inc(>refcount);
+   refcount_set(>refcount, 1);
core->pci_bus  = pci->bus->number;
core->pci_slot = PCI_SLOT(pci->devfn);
core->pci_irqmask = PCI_INT_RISC_RD_BERRINT | PCI_INT_RISC_WR_BERRINT |
diff --git a/drivers/media/pci/cx88/cx88-core.c 
b/drivers/media/pci/cx88/cx88-core.c
index 973a9cd4..8bfa5b7 100644
--- a/drivers/media/pci/cx88/cx88-core.c
+++ b/drivers/media/pci/cx88/cx88-core.c
@@ -1052,7 +1052,7 @@ struct cx88_core *cx88_core_get(struct pci_dev *pci)
mutex_unlock();
return NULL;
}
-   atomic_inc(>refcount);
+   refcount_inc(>refcount);
mutex_unlock();
return core;
}
@@ -1073,7 +1073,7 @@ void cx88_core_put(struct cx88_core *core, struct pci_dev 
*pci)
release_mem_region(pci_resource_start(pci, 0),
   pci_resource_len(pci, 0));
 
-   if (!atomic_dec_and_test(>refcount))
+   if (!refcount_dec_and_test(>refcount))
return;
 
mutex_lock();
diff --git a/drivers/media/pci/cx88/cx88.h b/drivers/media/pci/cx88/cx88.h
index 115414c..16c1313 100644
--- a/drivers/media/pci/cx88/cx88.h
+++ b/drivers/media/pci/cx88/cx88.h
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -339,7 +340,7 @@ struct cx8802_dev;
 
 struct cx88_core {
struct list_head   devlist;
-   atomic_t   refcount;
+   refcount_t   refcount;
 
/* board name */
intnr;
-- 
2.7.4



[PATCH 12/29] drivers, media: convert s2255_dev.num_channels from atomic_t to refcount_t

2017-03-06 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 drivers/media/usb/s2255/s2255drv.c | 21 +++--
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/media/usb/s2255/s2255drv.c 
b/drivers/media/usb/s2255/s2255drv.c
index a9d4484..2b4b009 100644
--- a/drivers/media/usb/s2255/s2255drv.c
+++ b/drivers/media/usb/s2255/s2255drv.c
@@ -36,6 +36,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -256,7 +257,7 @@ struct s2255_vc {
 struct s2255_dev {
struct s2255_vc vc[MAX_CHANNELS];
struct v4l2_device  v4l2_dev;
-   atomic_tnum_channels;
+   refcount_tnum_channels;
int frames;
struct mutexlock;   /* channels[].vdev.lock */
struct mutexcmdlock; /* protects cmdbuf */
@@ -1581,11 +1582,11 @@ static void s2255_video_device_release(struct 
video_device *vdev)
container_of(vdev, struct s2255_vc, vdev);
 
dprintk(dev, 4, "%s, chnls: %d\n", __func__,
-   atomic_read(>num_channels));
+   refcount_read(>num_channels));
 
v4l2_ctrl_handler_free(>hdl);
 
-   if (atomic_dec_and_test(>num_channels))
+   if (refcount_dec_and_test(>num_channels))
s2255_destroy(dev);
return;
 }
@@ -1688,7 +1689,7 @@ static int s2255_probe_v4l(struct s2255_dev *dev)
"failed to register video device!\n");
break;
}
-   atomic_inc(>num_channels);
+   refcount_set(>num_channels, 1);
v4l2_info(>v4l2_dev, "V4L2 device registered as %s\n",
  video_device_node_name(>vdev));
 
@@ -1696,11 +1697,11 @@ static int s2255_probe_v4l(struct s2255_dev *dev)
pr_info("Sensoray 2255 V4L driver Revision: %s\n",
S2255_VERSION);
/* if no channels registered, return error and probe will fail*/
-   if (atomic_read(>num_channels) == 0) {
+   if (refcount_read(>num_channels) == 0) {
v4l2_device_unregister(>v4l2_dev);
return ret;
}
-   if (atomic_read(>num_channels) != MAX_CHANNELS)
+   if (refcount_read(>num_channels) != MAX_CHANNELS)
pr_warn("s2255: Not all channels available.\n");
return 0;
 }
@@ -2248,7 +2249,7 @@ static int s2255_probe(struct usb_interface *interface,
goto errorFWDATA1;
}
 
-   atomic_set(>num_channels, 0);
+   refcount_set(>num_channels, 0);
dev->pid = id->idProduct;
dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL);
if (!dev->fw_data)
@@ -2368,12 +2369,12 @@ static void s2255_disconnect(struct usb_interface 
*interface)
 {
struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface));
int i;
-   int channels = atomic_read(>num_channels);
+   int channels = refcount_read(>num_channels);
mutex_lock(>lock);
v4l2_device_disconnect(>v4l2_dev);
mutex_unlock(>lock);
/*see comments in the uvc_driver.c usb disconnect function */
-   atomic_inc(>num_channels);
+   refcount_inc(>num_channels);
/* unregister each video device. */
for (i = 0; i < channels; i++)
video_unregister_device(>vc[i].vdev);
@@ -2386,7 +2387,7 @@ static void s2255_disconnect(struct usb_interface 
*interface)
dev->vc[i].vidstatus_ready = 1;
wake_up(>vc[i].wait_vidstatus);
}
-   if (atomic_dec_and_test(>num_channels))
+   if (refcount_dec_and_test(>num_channels))
s2255_destroy(dev);
dev_info(>dev, "%s\n", __func__);
 }
-- 
2.7.4



[PATCH 00/29] drivers, mics refcount conversions

2017-03-06 Thread Elena Reshetova
This series, for various different drivers, replaces atomic_t reference
counters with the new refcount_t type and API (see include/linux/refcount.h).
By doing this we prevent intentional or accidental
underflows or overflows that can led to use-after-free vulnerabilities.

The below patches are fully independent and can be cherry-picked separately*.
Since we convert all kernel subsystems in the same fashion, resulting
in about 300 patches, we have to group them for sending at least in some
fashion to be manageable. Please excuse the long cc list.

*with the exception of the media/vb2-related patches that depend on
vb2_vmarea_handler.refcount conversions.

Not run-time tested beyond booting and using kernel with refcount conversions
for my daily work.

If there are no objections to these patches,
I think they can go via Greg's drivers tree, as he suggested before.

Elena Reshetova (29):
  drivers, block: convert xen_blkif.refcnt from atomic_t to refcount_t
  drivers, firewire: convert fw_node.ref_count from atomic_t to
refcount_t
  drivers, char: convert vma_data.refcnt from atomic_t to refcount_t
  drivers, connector: convert cn_callback_entry.refcnt from atomic_t to
refcount_t
  drivers, md, bcache: convert cached_dev.count from atomic_t to
refcount_t
  drivers, md: convert dm_cache_metadata.ref_count from atomic_t to
refcount_t
  drivers, md: convert dm_dev_internal.count from atomic_t to refcount_t
  drivers, md: convert mddev.active from atomic_t to refcount_t
  drivers, md: convert table_device.count from atomic_t to refcount_t
  drivers, md: convert stripe_head.count from atomic_t to refcount_t
  drivers, media: convert cx88_core.refcount from atomic_t to refcount_t
  drivers, media: convert s2255_dev.num_channels from atomic_t to
refcount_t
  drivers, media: convert vb2_vmarea_handler.refcount from atomic_t to
refcount_t
  drivers, media: convert vb2_dc_buf.refcount from atomic_t to
refcount_t
  drivers, media: convert vb2_dma_sg_buf.refcount from atomic_t to
refcount_t
  drivers, media: convert vb2_vmalloc_buf.refcount from atomic_t to
refcount_t
  drivers, pci: convert hv_pci_dev.refs from atomic_t to refcount_t
  drivers, s390: convert urdev.ref_count from atomic_t to refcount_t
  drivers, s390: convert lcs_reply.refcnt from atomic_t to refcount_t
  drivers, s390: convert qeth_reply.refcnt from atomic_t to refcount_t
  drivers, s390: convert fc_fcp_pkt.ref_cnt from atomic_t to refcount_t
  drivers, scsi: convert iscsi_task.refcount from atomic_t to refcount_t
  drivers: convert vme_user_vma_priv.refcnt from atomic_t to refcount_t
  drivers: convert iblock_req.pending from atomic_t to refcount_t
  drivers, usb: convert ffs_data.ref from atomic_t to refcount_t
  drivers, usb: convert dev_data.count from atomic_t to refcount_t
  drivers, usb: convert ep_data.count from atomic_t to refcount_t
  drivers: convert sbd_duart.map_guard from atomic_t to refcount_t
  drivers, xen: convert grant_map.users from atomic_t to refcount_t

 drivers/block/xen-blkback/common.h |  7 +--
 drivers/block/xen-blkback/xenbus.c |  2 +-
 drivers/char/mspec.c   |  9 ++--
 drivers/connector/cn_queue.c   |  4 +-
 drivers/connector/connector.c  |  2 +-
 drivers/firewire/core-topology.c   |  2 +-
 drivers/firewire/core.h|  8 ++--
 drivers/md/bcache/bcache.h |  7 +--
 drivers/md/bcache/super.c  |  6 +--
 drivers/md/bcache/writeback.h  |  2 +-
 drivers/md/dm-cache-metadata.c |  9 ++--
 drivers/md/dm-table.c  |  6 +--
 drivers/md/dm.c| 12 +++--
 drivers/md/dm.h|  3 +-
 drivers/md/md.c|  6 +--
 drivers/md/md.h|  3 +-
 drivers/md/raid5-cache.c   |  8 ++--
 drivers/md/raid5.c | 66 +-
 drivers/md/raid5.h |  3 +-
 drivers/media/pci/cx88/cx88-cards.c|  2 +-
 drivers/media/pci/cx88/cx88-core.c |  4 +-
 drivers/media/pci/cx88/cx88.h  |  3 +-
 drivers/media/usb/s2255/s2255drv.c | 21 
 drivers/media/v4l2-core/videobuf2-dma-contig.c | 11 +++--
 drivers/media/v4l2-core/videobuf2-dma-sg.c | 11 +++--
 drivers/media/v4l2-core/videobuf2-memops.c |  6 +--
 drivers/media/v4l2-core/videobuf2-vmalloc.c| 11 +++--
 drivers/pci/host/pci-hyperv.c  |  9 ++--
 drivers/s390/char/vmur.c   |  8 ++--
 drivers/s390/char/vmur.h   |  4 +-
 drivers/s390/net/lcs.c |  8 ++--
 drivers/s390/net/lcs.h |  3 +-
 drivers/s390/net/qeth_core.h   |  3 +-
 drivers/s390/net/qeth_core_main.c  |  8 ++--
 drivers

[PATCH 10/29] drivers, md: convert stripe_head.count from atomic_t to refcount_t

2017-03-06 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 drivers/md/raid5-cache.c |  8 +++---
 drivers/md/raid5.c   | 66 
 drivers/md/raid5.h   |  3 ++-
 3 files changed, 39 insertions(+), 38 deletions(-)

diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
index 3f307be..6c05e12 100644
--- a/drivers/md/raid5-cache.c
+++ b/drivers/md/raid5-cache.c
@@ -979,7 +979,7 @@ int r5l_write_stripe(struct r5l_log *log, struct 
stripe_head *sh)
 * don't delay.
 */
clear_bit(STRIPE_DELAYED, >state);
-   atomic_inc(>count);
+   refcount_inc(>count);
 
mutex_lock(>io_mutex);
/* meta + data */
@@ -1321,7 +1321,7 @@ static void r5c_flush_stripe(struct r5conf *conf, struct 
stripe_head *sh)
assert_spin_locked(>device_lock);
 
list_del_init(>lru);
-   atomic_inc(>count);
+   refcount_inc(>count);
 
set_bit(STRIPE_HANDLE, >state);
atomic_inc(>active_stripes);
@@ -1424,7 +1424,7 @@ static void r5c_do_reclaim(struct r5conf *conf)
 */
if (!list_empty(>lru) &&
!test_bit(STRIPE_HANDLE, >state) &&
-   atomic_read(>count) == 0) {
+   refcount_read(>count) == 0) {
r5c_flush_stripe(conf, sh);
if (count++ >= R5C_RECLAIM_STRIPE_GROUP)
break;
@@ -2650,7 +2650,7 @@ r5c_cache_data(struct r5l_log *log, struct stripe_head 
*sh,
 * don't delay.
 */
clear_bit(STRIPE_DELAYED, >state);
-   atomic_inc(>count);
+   refcount_inc(>count);
 
mutex_lock(>io_mutex);
/* meta + data */
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 2ce23b0..30c96a8 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -296,7 +296,7 @@ static void do_release_stripe(struct r5conf *conf, struct 
stripe_head *sh,
 static void __release_stripe(struct r5conf *conf, struct stripe_head *sh,
 struct list_head *temp_inactive_list)
 {
-   if (atomic_dec_and_test(>count))
+   if (refcount_dec_and_test(>count))
do_release_stripe(conf, sh, temp_inactive_list);
 }
 
@@ -388,7 +388,7 @@ void raid5_release_stripe(struct stripe_head *sh)
 
/* Avoid release_list until the last reference.
 */
-   if (atomic_add_unless(>count, -1, 1))
+   if (refcount_dec_not_one(>count))
return;
 
if (unlikely(!conf->mddev->thread) ||
@@ -401,7 +401,7 @@ void raid5_release_stripe(struct stripe_head *sh)
 slow_path:
local_irq_save(flags);
/* we are ok here if STRIPE_ON_RELEASE_LIST is set or not */
-   if (atomic_dec_and_lock(>count, >device_lock)) {
+   if (refcount_dec_and_lock(>count, >device_lock)) {
INIT_LIST_HEAD();
hash = sh->hash_lock_index;
do_release_stripe(conf, sh, );
@@ -491,7 +491,7 @@ static void init_stripe(struct stripe_head *sh, sector_t 
sector, int previous)
struct r5conf *conf = sh->raid_conf;
int i, seq;
 
-   BUG_ON(atomic_read(>count) != 0);
+   BUG_ON(refcount_read(>count) != 0);
BUG_ON(test_bit(STRIPE_HANDLE, >state));
BUG_ON(stripe_operations_active(sh));
BUG_ON(sh->batch_head);
@@ -668,11 +668,11 @@ raid5_get_active_stripe(struct r5conf *conf, sector_t 
sector,
  >cache_state);
} else {
init_stripe(sh, sector, previous);
-   atomic_inc(>count);
+   refcount_inc(>count);
}
-   } else if (!atomic_inc_not_zero(>count)) {
+   } else if (!refcount_inc_not_zero(>count)) {
spin_lock(>device_lock);
-   if (!atomic_read(>count)) {
+   if (!refcount_read(>count)) {
if (!test_bit(STRIPE_HANDLE, >state))
atomic_inc(>active_stripes);
BUG_ON(list_empty(>lru) &&
@@ -688,7 +688,7 @@ raid5_get_active_stripe(struct r5conf *conf, sector_t 
sector,
sh->group = NULL;
 

[PATCH 08/29] drivers, md: convert mddev.active from atomic_t to refcount_t

2017-03-06 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 drivers/md/md.c | 6 +++---
 drivers/md/md.h | 3 ++-
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 985374f..94c8ebf 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -449,7 +449,7 @@ EXPORT_SYMBOL(md_unplug);
 
 static inline struct mddev *mddev_get(struct mddev *mddev)
 {
-   atomic_inc(>active);
+   refcount_inc(>active);
return mddev;
 }
 
@@ -459,7 +459,7 @@ static void mddev_put(struct mddev *mddev)
 {
struct bio_set *bs = NULL;
 
-   if (!atomic_dec_and_lock(>active, _mddevs_lock))
+   if (!refcount_dec_and_lock(>active, _mddevs_lock))
return;
if (!mddev->raid_disks && list_empty(>disks) &&
mddev->ctime == 0 && !mddev->hold_active) {
@@ -495,7 +495,7 @@ void mddev_init(struct mddev *mddev)
INIT_LIST_HEAD(>all_mddevs);
setup_timer(>safemode_timer, md_safemode_timeout,
(unsigned long) mddev);
-   atomic_set(>active, 1);
+   refcount_set(>active, 1);
atomic_set(>openers, 0);
atomic_set(>active_io, 0);
spin_lock_init(>lock);
diff --git a/drivers/md/md.h b/drivers/md/md.h
index b8859cb..4811663 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -360,7 +361,7 @@ struct mddev {
 */
struct mutexopen_mutex;
struct mutexreconfig_mutex;
-   atomic_tactive; /* general refcount */
+   refcount_t  active; /* general refcount */
atomic_topeners;/* number of active 
opens */
 
int changed;/* True if we might 
need to
-- 
2.7.4



[PATCH 02/29] drivers, firewire: convert fw_node.ref_count from atomic_t to refcount_t

2017-03-06 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 drivers/firewire/core-topology.c | 2 +-
 drivers/firewire/core.h  | 8 
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/firewire/core-topology.c b/drivers/firewire/core-topology.c
index 0de8350..939d259 100644
--- a/drivers/firewire/core-topology.c
+++ b/drivers/firewire/core-topology.c
@@ -124,7 +124,7 @@ static struct fw_node *fw_node_create(u32 sid, int 
port_count, int color)
node->initiated_reset = SELF_ID_PHY_INITIATOR(sid);
node->port_count = port_count;
 
-   atomic_set(>ref_count, 1);
+   refcount_set(>ref_count, 1);
INIT_LIST_HEAD(>link);
 
return node;
diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h
index e1480ff6..c07962e 100644
--- a/drivers/firewire/core.h
+++ b/drivers/firewire/core.h
@@ -12,7 +12,7 @@
 #include 
 #include 
 
-#include 
+#include 
 
 struct device;
 struct fw_card;
@@ -184,7 +184,7 @@ struct fw_node {
 * local node to this node. */
u8 max_depth:4; /* Maximum depth to any leaf node */
u8 max_hops:4;  /* Max hops in this sub tree */
-   atomic_t ref_count;
+   refcount_t ref_count;
 
/* For serializing node topology into a list. */
struct list_head link;
@@ -197,14 +197,14 @@ struct fw_node {
 
 static inline struct fw_node *fw_node_get(struct fw_node *node)
 {
-   atomic_inc(>ref_count);
+   refcount_inc(>ref_count);
 
return node;
 }
 
 static inline void fw_node_put(struct fw_node *node)
 {
-   if (atomic_dec_and_test(>ref_count))
+   if (refcount_dec_and_test(>ref_count))
kfree(node);
 }
 
-- 
2.7.4



[PATCH 26/29] drivers, usb: convert dev_data.count from atomic_t to refcount_t

2017-03-06 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 drivers/usb/gadget/legacy/inode.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/gadget/legacy/inode.c 
b/drivers/usb/gadget/legacy/inode.c
index 79a2d8f..81d76f3 100644
--- a/drivers/usb/gadget/legacy/inode.c
+++ b/drivers/usb/gadget/legacy/inode.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -114,7 +115,7 @@ enum ep0_state {
 
 struct dev_data {
spinlock_t  lock;
-   atomic_tcount;
+   refcount_t  count;
enum ep0_state  state;  /* P: lock */
struct usb_gadgetfs_event   event [N_EVENT];
unsignedev_next;
@@ -150,12 +151,12 @@ struct dev_data {
 
 static inline void get_dev (struct dev_data *data)
 {
-   atomic_inc (>count);
+   refcount_inc (>count);
 }
 
 static void put_dev (struct dev_data *data)
 {
-   if (likely (!atomic_dec_and_test (>count)))
+   if (likely (!refcount_dec_and_test (>count)))
return;
/* needs no more cleanup */
BUG_ON (waitqueue_active (>wait));
@@ -170,7 +171,7 @@ static struct dev_data *dev_new (void)
if (!dev)
return NULL;
dev->state = STATE_DEV_DISABLED;
-   atomic_set (>count, 1);
+   refcount_set (>count, 1);
spin_lock_init (>lock);
INIT_LIST_HEAD (>epfiles);
init_waitqueue_head (>wait);
-- 
2.7.4



[PATCH 0/5] block subsystem refcounter conversions

2017-02-20 Thread Elena Reshetova
Now when new refcount_t type and API are finally merged
(see include/linux/refcount.h), the following
patches convert various refcounters in the block susystem from atomic_t
to refcount_t. By doing this we prevent intentional or accidental
underflows or overflows that can led to use-after-free vulnerabilities.

The below patches are fully independent and can be cherry-picked separately.
Since we convert all kernel subsystems in the same fashion, resulting
in about 300 patches, we have to group them for sending at least in some
fashion to be manageable. Please excuse the long cc list.

Elena Reshetova (5):
  block: convert bio.__bi_cnt from atomic_t to refcount_t
  block: convert blk_queue_tag.refcnt from atomic_t to refcount_t
  block: convert blkcg_gq.refcnt from atomic_t to refcount_t
  block: convert io_context.active_ref from atomic_t to refcount_t
  block: convert bsg_device.ref_count from atomic_t to refcount_t

 block/bio.c|  6 +++---
 block/blk-cgroup.c |  2 +-
 block/blk-ioc.c|  4 ++--
 block/blk-tag.c|  8 
 block/bsg.c|  9 +
 block/cfq-iosched.c|  4 ++--
 fs/btrfs/volumes.c |  2 +-
 include/linux/bio.h|  4 ++--
 include/linux/blk-cgroup.h | 11 ++-
 include/linux/blk_types.h  |  3 ++-
 include/linux/blkdev.h |  3 ++-
 include/linux/iocontext.h  |  7 ---
 12 files changed, 34 insertions(+), 29 deletions(-)

-- 
2.7.4



[PATCH 2/5] block: convert blk_queue_tag.refcnt from atomic_t to refcount_t

2017-02-20 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 block/blk-tag.c| 8 
 include/linux/blkdev.h | 3 ++-
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/block/blk-tag.c b/block/blk-tag.c
index 07cc329..d83555e 100644
--- a/block/blk-tag.c
+++ b/block/blk-tag.c
@@ -35,7 +35,7 @@ EXPORT_SYMBOL(blk_queue_find_tag);
  */
 void blk_free_tags(struct blk_queue_tag *bqt)
 {
-   if (atomic_dec_and_test(>refcnt)) {
+   if (refcount_dec_and_test(>refcnt)) {
BUG_ON(find_first_bit(bqt->tag_map, bqt->max_depth) <
bqt->max_depth);
 
@@ -130,7 +130,7 @@ static struct blk_queue_tag *__blk_queue_init_tags(struct 
request_queue *q,
if (init_tag_map(q, tags, depth))
goto fail;
 
-   atomic_set(>refcnt, 1);
+   refcount_set(>refcnt, 1);
tags->alloc_policy = alloc_policy;
tags->next_tag = 0;
return tags;
@@ -180,7 +180,7 @@ int blk_queue_init_tags(struct request_queue *q, int depth,
queue_flag_set(QUEUE_FLAG_QUEUED, q);
return 0;
} else
-   atomic_inc(>refcnt);
+   refcount_inc(>refcnt);
 
/*
 * assign it, all done
@@ -225,7 +225,7 @@ int blk_queue_resize_tags(struct request_queue *q, int 
new_depth)
 * Currently cannot replace a shared tag map with a new
 * one, so error out if this is the case
 */
-   if (atomic_read(>refcnt) != 1)
+   if (refcount_read(>refcnt) != 1)
return -EBUSY;
 
/*
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index aecca0e..95ef11c 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 
 struct module;
 struct scsi_ioctl_command;
@@ -288,7 +289,7 @@ struct blk_queue_tag {
unsigned long *tag_map; /* bit map of free/busy tags */
int max_depth;  /* what we will send to device */
int real_max_depth; /* what the array can hold */
-   atomic_t refcnt;/* map can be shared */
+   refcount_t refcnt;  /* map can be shared */
int alloc_policy;   /* tag allocation policy */
int next_tag;   /* next tag */
 };
-- 
2.7.4



[PATCH 1/5] block: convert bio.__bi_cnt from atomic_t to refcount_t

2017-02-20 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 block/bio.c   | 6 +++---
 fs/btrfs/volumes.c| 2 +-
 include/linux/bio.h   | 4 ++--
 include/linux/blk_types.h | 3 ++-
 4 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/block/bio.c b/block/bio.c
index 5eec5e0..3dffc17 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -275,7 +275,7 @@ void bio_init(struct bio *bio, struct bio_vec *table,
 {
memset(bio, 0, sizeof(*bio));
atomic_set(>__bi_remaining, 1);
-   atomic_set(>__bi_cnt, 1);
+   refcount_set(>__bi_cnt, 1);
 
bio->bi_io_vec = table;
bio->bi_max_vecs = max_vecs;
@@ -543,12 +543,12 @@ void bio_put(struct bio *bio)
if (!bio_flagged(bio, BIO_REFFED))
bio_free(bio);
else {
-   BIO_BUG_ON(!atomic_read(>__bi_cnt));
+   BIO_BUG_ON(!refcount_read(>__bi_cnt));
 
/*
 * last put frees it
 */
-   if (atomic_dec_and_test(>__bi_cnt))
+   if (refcount_dec_and_test(>__bi_cnt))
bio_free(bio);
}
 }
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 13e55d1..ff1fe9d 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -441,7 +441,7 @@ static noinline void run_scheduled_bios(struct btrfs_device 
*device)
waitqueue_active(_info->async_submit_wait))
wake_up(_info->async_submit_wait);
 
-   BUG_ON(atomic_read(>__bi_cnt) == 0);
+   BUG_ON(refcount_read(>__bi_cnt) == 0);
 
/*
 * if we're doing the sync list, record that our
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 8e52119..44ac678 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -234,7 +234,7 @@ static inline void bio_get(struct bio *bio)
 {
bio->bi_flags |= (1 << BIO_REFFED);
smp_mb__before_atomic();
-   atomic_inc(>__bi_cnt);
+   refcount_inc(>__bi_cnt);
 }
 
 static inline void bio_cnt_set(struct bio *bio, unsigned int count)
@@ -243,7 +243,7 @@ static inline void bio_cnt_set(struct bio *bio, unsigned 
int count)
bio->bi_flags |= (1 << BIO_REFFED);
smp_mb__before_atomic();
}
-   atomic_set(>__bi_cnt, count);
+   refcount_set(>__bi_cnt, count);
 }
 
 static inline bool bio_flagged(struct bio *bio, unsigned int bit)
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index d703acb..c41407f 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -7,6 +7,7 @@
 
 #include 
 #include 
+#include 
 
 struct bio_set;
 struct bio;
@@ -73,7 +74,7 @@ struct bio {
 
unsigned short  bi_max_vecs;/* max bvl_vecs we can hold */
 
-   atomic_t__bi_cnt;   /* pin count */
+   refcount_t  __bi_cnt;   /* pin count */
 
struct bio_vec  *bi_io_vec; /* the actual vec list */
 
-- 
2.7.4



[PATCH 3/5] block: convert blkcg_gq.refcnt from atomic_t to refcount_t

2017-02-20 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 block/blk-cgroup.c |  2 +-
 include/linux/blk-cgroup.h | 11 ++-
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index 295e98c2..75de844 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -106,7 +106,7 @@ static struct blkcg_gq *blkg_alloc(struct blkcg *blkcg, 
struct request_queue *q,
blkg->q = q;
INIT_LIST_HEAD(>q_node);
blkg->blkcg = blkcg;
-   atomic_set(>refcnt, 1);
+   refcount_set(>refcnt, 1);
 
/* root blkg uses @q->root_rl, init rl only for !root blkgs */
if (blkcg != _root) {
diff --git a/include/linux/blk-cgroup.h b/include/linux/blk-cgroup.h
index 01b62e7..0d3efa9 100644
--- a/include/linux/blk-cgroup.h
+++ b/include/linux/blk-cgroup.h
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* percpu_counter batch for blkg_[rw]stats, per-cpu drift doesn't matter */
 #define BLKG_STAT_CPU_BATCH(INT_MAX / 2)
@@ -122,7 +123,7 @@ struct blkcg_gq {
struct request_list rl;
 
/* reference count */
-   atomic_trefcnt;
+   refcount_t  refcnt;
 
/* is this blkg online? protected by both blkcg and q locks */
boolonline;
@@ -354,8 +355,8 @@ static inline int blkg_path(struct blkcg_gq *blkg, char 
*buf, int buflen)
  */
 static inline void blkg_get(struct blkcg_gq *blkg)
 {
-   WARN_ON_ONCE(atomic_read(>refcnt) <= 0);
-   atomic_inc(>refcnt);
+   WARN_ON_ONCE(refcount_read(>refcnt) == 0);
+   refcount_inc(>refcnt);
 }
 
 void __blkg_release_rcu(struct rcu_head *rcu);
@@ -366,8 +367,8 @@ void __blkg_release_rcu(struct rcu_head *rcu);
  */
 static inline void blkg_put(struct blkcg_gq *blkg)
 {
-   WARN_ON_ONCE(atomic_read(>refcnt) <= 0);
-   if (atomic_dec_and_test(>refcnt))
+   WARN_ON_ONCE(refcount_read(>refcnt) == 0);
+   if (refcount_dec_and_test(>refcnt))
call_rcu(>rcu_head, __blkg_release_rcu);
 }
 
-- 
2.7.4



[PATCH 5/5] block: convert bsg_device.ref_count from atomic_t to refcount_t

2017-02-20 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 block/bsg.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/block/bsg.c b/block/bsg.c
index 74835db..6d0ceb9 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -38,7 +39,7 @@ struct bsg_device {
struct list_head busy_list;
struct list_head done_list;
struct hlist_node dev_list;
-   atomic_t ref_count;
+   refcount_t ref_count;
int queued_cmds;
int done_cmds;
wait_queue_head_t wq_done;
@@ -711,7 +712,7 @@ static int bsg_put_device(struct bsg_device *bd)
 
mutex_lock(_mutex);
 
-   do_free = atomic_dec_and_test(>ref_count);
+   do_free = refcount_dec_and_test(>ref_count);
if (!do_free) {
mutex_unlock(_mutex);
goto out;
@@ -763,7 +764,7 @@ static struct bsg_device *bsg_add_device(struct inode 
*inode,
 
bsg_set_block(bd, file);
 
-   atomic_set(>ref_count, 1);
+   refcount_set(>ref_count, 1);
mutex_lock(_mutex);
hlist_add_head(>dev_list, bsg_dev_idx_hash(iminor(inode)));
 
@@ -783,7 +784,7 @@ static struct bsg_device *__bsg_get_device(int minor, 
struct request_queue *q)
 
hlist_for_each_entry(bd, bsg_dev_idx_hash(minor), dev_list) {
if (bd->queue == q) {
-   atomic_inc(>ref_count);
+   refcount_inc(>ref_count);
goto found;
}
}
-- 
2.7.4



[PATCH 4/5] block: convert io_context.active_ref from atomic_t to refcount_t

2017-02-20 Thread Elena Reshetova
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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 block/blk-ioc.c   | 4 ++--
 block/cfq-iosched.c   | 4 ++--
 include/linux/iocontext.h | 7 ---
 3 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/block/blk-ioc.c b/block/blk-ioc.c
index b12f9c8..130dc23 100644
--- a/block/blk-ioc.c
+++ b/block/blk-ioc.c
@@ -173,7 +173,7 @@ void put_io_context_active(struct io_context *ioc)
unsigned long flags;
struct io_cq *icq;
 
-   if (!atomic_dec_and_test(>active_ref)) {
+   if (!refcount_dec_and_test(>active_ref)) {
put_io_context(ioc);
return;
}
@@ -256,7 +256,7 @@ int create_task_io_context(struct task_struct *task, gfp_t 
gfp_flags, int node)
/* initialize */
atomic_long_set(>refcount, 1);
atomic_set(>nr_tasks, 1);
-   atomic_set(>active_ref, 1);
+   refcount_set(>active_ref, 1);
spin_lock_init(>lock);
INIT_RADIX_TREE(>icq_tree, GFP_ATOMIC | __GFP_HIGH);
INIT_HLIST_HEAD(>icq_list);
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 9212627..2871bb9 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -2959,7 +2959,7 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd)
 * task has exited, don't wait
 */
cic = cfqd->active_cic;
-   if (!cic || !atomic_read(>icq.ioc->active_ref))
+   if (!cic || !refcount_read(>icq.ioc->active_ref))
return;
 
/*
@@ -3959,7 +3959,7 @@ cfq_update_idle_window(struct cfq_data *cfqd, struct 
cfq_queue *cfqq,
 
if (cfqq->next_rq && req_noidle(cfqq->next_rq))
enable_idle = 0;
-   else if (!atomic_read(>icq.ioc->active_ref) ||
+   else if (!refcount_read(>icq.ioc->active_ref) ||
 !cfqd->cfq_slice_idle ||
 (!cfq_cfqq_deep(cfqq) && CFQQ_SEEKY(cfqq)))
enable_idle = 0;
diff --git a/include/linux/iocontext.h b/include/linux/iocontext.h
index df38db2..a1e28c3 100644
--- a/include/linux/iocontext.h
+++ b/include/linux/iocontext.h
@@ -3,6 +3,7 @@
 
 #include 
 #include 
+#include 
 #include 
 
 enum {
@@ -96,7 +97,7 @@ struct io_cq {
  */
 struct io_context {
atomic_long_t refcount;
-   atomic_t active_ref;
+   refcount_t active_ref;
atomic_t nr_tasks;
 
/* all the fields below are protected by this lock */
@@ -128,9 +129,9 @@ struct io_context {
 static inline void get_io_context_active(struct io_context *ioc)
 {
WARN_ON_ONCE(atomic_long_read(>refcount) <= 0);
-   WARN_ON_ONCE(atomic_read(>active_ref) <= 0);
+   WARN_ON_ONCE(refcount_read(>active_ref) == 0);
atomic_long_inc(>refcount);
-   atomic_inc(>active_ref);
+   refcount_inc(>active_ref);
 }
 
 static inline void ioc_task_link(struct io_context *ioc)
-- 
2.7.4