Commit 5981c245 authored by Elena Reshetova's avatar Elena Reshetova Committed by Nicholas Bellinger

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: default avatarElena Reshetova <elena.reshetova@intel.com>
Signed-off-by: default avatarHans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: default avatarKees Cook <keescook@chromium.org>
Signed-off-by: default avatarDavid Windsor <dwindsor@gmail.com>
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
parent a5d68ba8
...@@ -279,7 +279,7 @@ static void iblock_complete_cmd(struct se_cmd *cmd) ...@@ -279,7 +279,7 @@ static void iblock_complete_cmd(struct se_cmd *cmd)
struct iblock_req *ibr = cmd->priv; struct iblock_req *ibr = cmd->priv;
u8 status; u8 status;
if (!atomic_dec_and_test(&ibr->pending)) if (!refcount_dec_and_test(&ibr->pending))
return; return;
if (atomic_read(&ibr->ib_bio_err_cnt)) if (atomic_read(&ibr->ib_bio_err_cnt))
...@@ -487,7 +487,7 @@ iblock_execute_write_same(struct se_cmd *cmd) ...@@ -487,7 +487,7 @@ iblock_execute_write_same(struct se_cmd *cmd)
bio_list_init(&list); bio_list_init(&list);
bio_list_add(&list, bio); bio_list_add(&list, bio);
atomic_set(&ibr->pending, 1); refcount_set(&ibr->pending, 1);
while (sectors) { while (sectors) {
while (bio_add_page(bio, sg_page(sg), sg->length, sg->offset) 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,7 +498,7 @@ iblock_execute_write_same(struct se_cmd *cmd)
if (!bio) if (!bio)
goto fail_put_bios; goto fail_put_bios;
atomic_inc(&ibr->pending); refcount_inc(&ibr->pending);
bio_list_add(&list, bio); bio_list_add(&list, bio);
} }
...@@ -706,7 +706,7 @@ iblock_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, ...@@ -706,7 +706,7 @@ iblock_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
cmd->priv = ibr; cmd->priv = ibr;
if (!sgl_nents) { if (!sgl_nents) {
atomic_set(&ibr->pending, 1); refcount_set(&ibr->pending, 1);
iblock_complete_cmd(cmd); iblock_complete_cmd(cmd);
return 0; return 0;
} }
...@@ -719,7 +719,7 @@ iblock_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, ...@@ -719,7 +719,7 @@ iblock_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
bio_list_init(&list); bio_list_init(&list);
bio_list_add(&list, bio); bio_list_add(&list, bio);
atomic_set(&ibr->pending, 2); refcount_set(&ibr->pending, 2);
bio_cnt = 1; bio_cnt = 1;
for_each_sg(sgl, sg, sgl_nents, i) { 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,7 +740,7 @@ iblock_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
if (!bio) if (!bio)
goto fail_put_bios; goto fail_put_bios;
atomic_inc(&ibr->pending); refcount_inc(&ibr->pending);
bio_list_add(&list, bio); bio_list_add(&list, bio);
bio_cnt++; bio_cnt++;
} }
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#define TARGET_CORE_IBLOCK_H #define TARGET_CORE_IBLOCK_H
#include <linux/atomic.h> #include <linux/atomic.h>
#include <linux/refcount.h>
#include <target/target_core_base.h> #include <target/target_core_base.h>
#define IBLOCK_VERSION "4.0" #define IBLOCK_VERSION "4.0"
...@@ -10,7 +11,7 @@ ...@@ -10,7 +11,7 @@
#define IBLOCK_LBA_SHIFT 9 #define IBLOCK_LBA_SHIFT 9
struct iblock_req { struct iblock_req {
atomic_t pending; refcount_t pending;
atomic_t ib_bio_err_cnt; atomic_t ib_bio_err_cnt;
} ____cacheline_aligned; } ____cacheline_aligned;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment