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>
This commit is contained in:
parent
a5d68ba858
commit
5981c245a8
@ -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)
|
|||||||
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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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 @@
|
|||||||
#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 @@
|
|||||||
#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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user