target/iblock: convert iblock_req.pending from atomic_t to refcount_t
authorElena Reshetova <elena.reshetova@intel.com>
Mon, 6 Mar 2017 14:21:11 +0000 (16:21 +0200)
committerNicholas Bellinger <nab@linux-iscsi.org>
Tue, 2 May 2017 05:20:43 +0000 (22:20 -0700)
refcount_t type and corresponding API should be
used instead of atomic_t when the variable is used as
a reference counter. This allows to avoid accidental
refcounter overflows that might lead to use-after-free
situations.

Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
Signed-off-by: Hans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: David Windsor <dwindsor@gmail.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
drivers/target/target_core_iblock.c
drivers/target/target_core_iblock.h

index d316ed537d59132a3fde2dfd11eba3194d899bec..bb069ebe4aa6c1abcce203c7133a446493abc7eb 100644 (file)
@@ -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(&ibr->pending))
+       if (!refcount_dec_and_test(&ibr->pending))
                return;
 
        if (atomic_read(&ibr->ib_bio_err_cnt))
@@ -487,7 +487,7 @@ iblock_execute_write_same(struct se_cmd *cmd)
        bio_list_init(&list);
        bio_list_add(&list, bio);
 
-       atomic_set(&ibr->pending, 1);
+       refcount_set(&ibr->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(&ibr->pending);
+                       refcount_inc(&ibr->pending);
                        bio_list_add(&list, 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(&ibr->pending, 1);
+               refcount_set(&ibr->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(&list);
        bio_list_add(&list, bio);
 
-       atomic_set(&ibr->pending, 2);
+       refcount_set(&ibr->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(&ibr->pending);
+                       refcount_inc(&ibr->pending);
                        bio_list_add(&list, bio);
                        bio_cnt++;
                }
index 718d3fcd3e7cd8d8cacd7057ff85119a836725ca..f2a5797217d43e233a5cb1229f7e5977e0a564b8 100644 (file)
@@ -2,6 +2,7 @@
 #define TARGET_CORE_IBLOCK_H
 
 #include <linux/atomic.h>
+#include <linux/refcount.h>
 #include <target/target_core_base.h>
 
 #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;