Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+12 −4
Original line number Diff line number Diff line
@@ -1277,12 +1277,15 @@ static int srp_map_finish_fmr(struct srp_map_state *state,
	struct ib_pool_fmr *fmr;
	u64 io_addr = 0;

	if (state->fmr.next >= state->fmr.end)
		return -ENOMEM;

	fmr = ib_fmr_pool_map_phys(ch->fmr_pool, state->pages,
				   state->npages, io_addr);
	if (IS_ERR(fmr))
		return PTR_ERR(fmr);

	*state->next_fmr++ = fmr;
	*state->fmr.next++ = fmr;
	state->nmdesc++;

	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,
	struct srp_fr_desc *desc;
	u32 rkey;

	if (state->fr.next >= state->fr.end)
		return -ENOMEM;

	desc = srp_fr_pool_get(ch->fr_pool);
	if (!desc)
		return -ENOMEM;
@@ -1324,7 +1330,7 @@ static int srp_map_finish_fr(struct srp_map_state *state,
				       IB_ACCESS_REMOTE_WRITE);
	wr.wr.fast_reg.rkey = desc->mr->lkey;

	*state->next_fr++ = desc;
	*state->fr.next++ = desc;
	state->nmdesc++;

	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,
	state->desc	= req->indirect_desc;
	state->pages	= req->map_page;
	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;
	} 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;
	}

+8 −2
Original line number Diff line number Diff line
@@ -282,8 +282,14 @@ struct srp_fr_pool {
 */
struct srp_map_state {
	union {
		struct ib_pool_fmr **next_fmr;
		struct srp_fr_desc **next_fr;
		struct {
			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;
	u64		       *pages;