Skip to content

Commit a3c3c0a

Browse files
Justin Teemartinkpetersen
Justin Tee
authored andcommitted
scsi: lpfc: Validate ELS LS_ACC completion payload
A WCQE success completion status does not guarantee valid LS_ACC receipt for ELS commands. So, introduce a small helper routine that validates ELS LS_ACC frames in ELS cmpl routines. Signed-off-by: Justin Tee <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 12e896c commit a3c3c0a

File tree

1 file changed

+23
-0
lines changed

1 file changed

+23
-0
lines changed

drivers/scsi/lpfc/lpfc_els.c

+23
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,15 @@ lpfc_els_chk_latt(struct lpfc_vport *vport)
131131
return 1;
132132
}
133133

134+
static bool lpfc_is_els_acc_rsp(struct lpfc_dmabuf *buf)
135+
{
136+
struct fc_els_ls_acc *rsp = buf->virt;
137+
138+
if (rsp && rsp->la_cmd == ELS_LS_ACC)
139+
return true;
140+
return false;
141+
}
142+
134143
/**
135144
* lpfc_prep_els_iocb - Allocate and prepare a lpfc iocb data structure
136145
* @vport: pointer to a host virtual N_Port data structure.
@@ -1107,6 +1116,8 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
11071116
prsp = list_get_first(&pcmd->list, struct lpfc_dmabuf, list);
11081117
if (!prsp)
11091118
goto out;
1119+
if (!lpfc_is_els_acc_rsp(prsp))
1120+
goto out;
11101121
sp = prsp->virt + sizeof(uint32_t);
11111122

11121123
/* FLOGI completes successfully */
@@ -2119,6 +2130,10 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
21192130
/* Good status, call state machine */
21202131
prsp = list_entry(cmdiocb->cmd_dmabuf->list.next,
21212132
struct lpfc_dmabuf, list);
2133+
if (!prsp)
2134+
goto out;
2135+
if (!lpfc_is_els_acc_rsp(prsp))
2136+
goto out;
21222137
ndlp = lpfc_plogi_confirm_nport(phba, prsp->virt, ndlp);
21232138

21242139
sp = (struct serv_parm *)((u8 *)prsp->virt +
@@ -3445,6 +3460,8 @@ lpfc_cmpl_els_disc_cmd(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
34453460
prdf = (struct lpfc_els_rdf_rsp *)prsp->virt;
34463461
if (!prdf)
34473462
goto out;
3463+
if (!lpfc_is_els_acc_rsp(prsp))
3464+
goto out;
34483465

34493466
for (i = 0; i < ELS_RDF_REG_TAG_CNT &&
34503467
i < be32_to_cpu(prdf->reg_d1.reg_desc.count); i++)
@@ -4043,6 +4060,9 @@ lpfc_cmpl_els_edc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
40434060
edc_rsp->acc_hdr.la_cmd,
40444061
be32_to_cpu(edc_rsp->desc_list_len));
40454062

4063+
if (!lpfc_is_els_acc_rsp(prsp))
4064+
goto out;
4065+
40464066
/*
40474067
* Payload length in bytes is the response descriptor list
40484068
* length minus the 12 bytes of Link Service Request
@@ -11339,6 +11359,9 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1133911359
prsp = list_get_first(&pcmd->list, struct lpfc_dmabuf, list);
1134011360
if (!prsp)
1134111361
goto out;
11362+
if (!lpfc_is_els_acc_rsp(prsp))
11363+
goto out;
11364+
1134211365
sp = prsp->virt + sizeof(uint32_t);
1134311366
fabric_param_changed = lpfc_check_clean_addr_bit(vport, sp);
1134411367
memcpy(&vport->fabric_portname, &sp->portName,

0 commit comments

Comments
 (0)