aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorElena Reshetova <elena.reshetova@intel.com>2017-03-06 09:21:11 -0500
committerNicholas Bellinger <nab@linux-iscsi.org>2017-05-02 01:20:43 -0400
commit5981c245a890db6a6e16fb6d3838cc9fc9fdf0ff (patch)
treea1aa3f65fa046e1ac40b923e97b8b2f36b347c08
parenta5d68ba85801a78c892a0eb8efb711e293ed314b (diff)
target/iblock: convert iblock_req.pending from atomic_t to refcount_t
refcount_t type and corresponding API should be used instead of atomic_t when the variable is used as a reference counter. This allows to avoid accidental refcounter overflows that might lead to use-after-free situations. Signed-off-by: Elena Reshetova <elena.reshetova@intel.com> Signed-off-by: Hans Liljestrand <ishkamiel@gmail.com> Signed-off-by: Kees Cook <keescook@chromium.org> Signed-off-by: David Windsor <dwindsor@gmail.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r--drivers/target/target_core_iblock.c12
-rw-r--r--drivers/target/target_core_iblock.h3
2 files changed, 8 insertions, 7 deletions
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c
index d316ed537d59..bb069ebe4aa6 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)
279 struct iblock_req *ibr = cmd->priv; 279 struct iblock_req *ibr = cmd->priv;
280 u8 status; 280 u8 status;
281 281
282 if (!atomic_dec_and_test(&ibr->pending)) 282 if (!refcount_dec_and_test(&ibr->pending))
283 return; 283 return;
284 284
285 if (atomic_read(&ibr->ib_bio_err_cnt)) 285 if (atomic_read(&ibr->ib_bio_err_cnt))
@@ -487,7 +487,7 @@ iblock_execute_write_same(struct se_cmd *cmd)
487 bio_list_init(&list); 487 bio_list_init(&list);
488 bio_list_add(&list, bio); 488 bio_list_add(&list, bio);
489 489
490 atomic_set(&ibr->pending, 1); 490 refcount_set(&ibr->pending, 1);
491 491
492 while (sectors) { 492 while (sectors) {
493 while (bio_add_page(bio, sg_page(sg), sg->length, sg->offset) 493 while (bio_add_page(bio, sg_page(sg), sg->length, sg->offset)
@@ -498,7 +498,7 @@ iblock_execute_write_same(struct se_cmd *cmd)
498 if (!bio) 498 if (!bio)
499 goto fail_put_bios; 499 goto fail_put_bios;
500 500
501 atomic_inc(&ibr->pending); 501 refcount_inc(&ibr->pending);
502 bio_list_add(&list, bio); 502 bio_list_add(&list, bio);
503 } 503 }
504 504
@@ -706,7 +706,7 @@ iblock_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
706 cmd->priv = ibr; 706 cmd->priv = ibr;
707 707
708 if (!sgl_nents) { 708 if (!sgl_nents) {
709 atomic_set(&ibr->pending, 1); 709 refcount_set(&ibr->pending, 1);
710 iblock_complete_cmd(cmd); 710 iblock_complete_cmd(cmd);
711 return 0; 711 return 0;
712 } 712 }
@@ -719,7 +719,7 @@ iblock_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
719 bio_list_init(&list); 719 bio_list_init(&list);
720 bio_list_add(&list, bio); 720 bio_list_add(&list, bio);
721 721
722 atomic_set(&ibr->pending, 2); 722 refcount_set(&ibr->pending, 2);
723 bio_cnt = 1; 723 bio_cnt = 1;
724 724
725 for_each_sg(sgl, sg, sgl_nents, i) { 725 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,
740 if (!bio) 740 if (!bio)
741 goto fail_put_bios; 741 goto fail_put_bios;
742 742
743 atomic_inc(&ibr->pending); 743 refcount_inc(&ibr->pending);
744 bio_list_add(&list, bio); 744 bio_list_add(&list, bio);
745 bio_cnt++; 745 bio_cnt++;
746 } 746 }
diff --git a/drivers/target/target_core_iblock.h b/drivers/target/target_core_iblock.h
index 718d3fcd3e7c..f2a5797217d4 100644
--- a/drivers/target/target_core_iblock.h
+++ b/drivers/target/target_core_iblock.h
@@ -2,6 +2,7 @@
2#define TARGET_CORE_IBLOCK_H 2#define TARGET_CORE_IBLOCK_H
3 3
4#include <linux/atomic.h> 4#include <linux/atomic.h>
5#include <linux/refcount.h>
5#include <target/target_core_base.h> 6#include <target/target_core_base.h>
6 7
7#define IBLOCK_VERSION "4.0" 8#define IBLOCK_VERSION "4.0"
@@ -10,7 +11,7 @@
10#define IBLOCK_LBA_SHIFT 9 11#define IBLOCK_LBA_SHIFT 9
11 12
12struct iblock_req { 13struct iblock_req {
13 atomic_t pending; 14 refcount_t pending;
14 atomic_t ib_bio_err_cnt; 15 atomic_t ib_bio_err_cnt;
15} ____cacheline_aligned; 16} ____cacheline_aligned;
16 17