Commit f731ed62 authored by Bart Van Assche's avatar Bart Van Assche Committed by Doug Ledford

IB/srp: Add memory descriptor array pointer range checking

Although most paths through which a request is submitted check
block layer parameters like the max_segments limit, these are
not checked when an SG_IO or direct I/O request is submitted.
Hence add a range check for the memory descriptor array pointer.
Signed-off-by: default avatarBart Van Assche <bart.vanassche@sandisk.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent 7e85c919
...@@ -1277,12 +1277,15 @@ static int srp_map_finish_fmr(struct srp_map_state *state, ...@@ -1277,12 +1277,15 @@ static int srp_map_finish_fmr(struct srp_map_state *state,
struct ib_pool_fmr *fmr; struct ib_pool_fmr *fmr;
u64 io_addr = 0; u64 io_addr = 0;
if (state->fmr.next >= state->fmr.end)
return -ENOMEM;
fmr = ib_fmr_pool_map_phys(ch->fmr_pool, state->pages, fmr = ib_fmr_pool_map_phys(ch->fmr_pool, state->pages,
state->npages, io_addr); state->npages, io_addr);
if (IS_ERR(fmr)) if (IS_ERR(fmr))
return PTR_ERR(fmr); return PTR_ERR(fmr);
*state->next_fmr++ = fmr; *state->fmr.next++ = fmr;
state->nmdesc++; state->nmdesc++;
srp_map_desc(state, state->base_dma_addr & ~dev->mr_page_mask, srp_map_desc(state, state->base_dma_addr & ~dev->mr_page_mask,
...@@ -1301,6 +1304,9 @@ static int srp_map_finish_fr(struct srp_map_state *state, ...@@ -1301,6 +1304,9 @@ static int srp_map_finish_fr(struct srp_map_state *state,
struct srp_fr_desc *desc; struct srp_fr_desc *desc;
u32 rkey; u32 rkey;
if (state->fr.next >= state->fr.end)
return -ENOMEM;
desc = srp_fr_pool_get(ch->fr_pool); desc = srp_fr_pool_get(ch->fr_pool);
if (!desc) if (!desc)
return -ENOMEM; return -ENOMEM;
...@@ -1324,7 +1330,7 @@ static int srp_map_finish_fr(struct srp_map_state *state, ...@@ -1324,7 +1330,7 @@ static int srp_map_finish_fr(struct srp_map_state *state,
IB_ACCESS_REMOTE_WRITE); IB_ACCESS_REMOTE_WRITE);
wr.wr.fast_reg.rkey = desc->mr->lkey; wr.wr.fast_reg.rkey = desc->mr->lkey;
*state->next_fr++ = desc; *state->fr.next++ = desc;
state->nmdesc++; state->nmdesc++;
srp_map_desc(state, state->base_dma_addr, state->dma_len, srp_map_desc(state, state->base_dma_addr, state->dma_len,
...@@ -1450,10 +1456,12 @@ static int srp_map_sg(struct srp_map_state *state, struct srp_rdma_ch *ch, ...@@ -1450,10 +1456,12 @@ static int srp_map_sg(struct srp_map_state *state, struct srp_rdma_ch *ch,
state->desc = req->indirect_desc; state->desc = req->indirect_desc;
state->pages = req->map_page; state->pages = req->map_page;
if (dev->use_fast_reg) { if (dev->use_fast_reg) {
state->next_fr = req->fr_list; state->fr.next = req->fr_list;
state->fr.end = req->fr_list + target->cmd_sg_cnt;
use_mr = !!ch->fr_pool; use_mr = !!ch->fr_pool;
} else { } else {
state->next_fmr = req->fmr_list; state->fmr.next = req->fmr_list;
state->fmr.end = req->fmr_list + target->cmd_sg_cnt;
use_mr = !!ch->fmr_pool; use_mr = !!ch->fmr_pool;
} }
......
...@@ -282,8 +282,14 @@ struct srp_fr_pool { ...@@ -282,8 +282,14 @@ struct srp_fr_pool {
*/ */
struct srp_map_state { struct srp_map_state {
union { union {
struct ib_pool_fmr **next_fmr; struct {
struct srp_fr_desc **next_fr; struct ib_pool_fmr **next;
struct ib_pool_fmr **end;
} fmr;
struct {
struct srp_fr_desc **next;
struct srp_fr_desc **end;
} fr;
}; };
struct srp_direct_buf *desc; struct srp_direct_buf *desc;
u64 *pages; u64 *pages;
......
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