As per FC-BB-5 rev-2 section 7.8.6.2, malformed FIP frame shall be discarded. Drop Discovery Adv, ELS and CVL's with duplicate critical descriptors.
Signed-off-by: Bhanu Prakash Gollapudi <[email protected]> --- drivers/scsi/fcoe/libfcoe.c | 33 +++++++++++++++++++++++++++++++++ 1 files changed, 33 insertions(+), 0 deletions(-) diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c index 82e9455..7a56634 100644 --- a/drivers/scsi/fcoe/libfcoe.c +++ b/drivers/scsi/fcoe/libfcoe.c @@ -633,6 +633,7 @@ static int fcoe_ctlr_parse_adv(struct fcoe_ctlr *fip, unsigned long t; size_t rlen; size_t dlen; + u32 dupl_desc = 0; memset(fcf, 0, sizeof(*fcf)); fcf->fka_period = msecs_to_jiffies(FCOE_CTLR_DEF_FKA); @@ -649,6 +650,16 @@ static int fcoe_ctlr_parse_adv(struct fcoe_ctlr *fip, dlen = desc->fip_dlen * FIP_BPW; if (dlen < sizeof(*desc) || dlen > rlen) return -EINVAL; + /* Drop Adv if there are duplicate critical descriptors */ + if (desc->fip_dtype < FIP_DT_LIMIT) { + if (dupl_desc & (1 << desc->fip_dtype)) { + LIBFCOE_FIP_DBG(fip, "Duplicate Critical " + "Descriptors in FIP adv\n"); + return -EINVAL; + } else { + dupl_desc |= (1 << desc->fip_dtype); + } + } switch (desc->fip_dtype) { case FIP_DT_PRI: if (dlen != sizeof(struct fip_pri_desc)) @@ -837,6 +848,7 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb) size_t els_len = 0; size_t rlen; size_t dlen; + u32 dupl_desc = 0; fiph = (struct fip_header *)skb->data; sub = fiph->fip_subcode; @@ -852,6 +864,16 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb) dlen = desc->fip_dlen * FIP_BPW; if (dlen < sizeof(*desc) || dlen > rlen) goto drop; + /* Drop ELS if there are duplicate critical descriptors */ + if (desc->fip_dtype < FIP_DT_LIMIT) { + if (dupl_desc & (1 << desc->fip_dtype)) { + LIBFCOE_FIP_DBG(fip, "Duplicate Critical " + "Descriptors in FIP ELS\n"); + goto drop; + } else { + dupl_desc |= (1 << desc->fip_dtype); + } + } switch (desc->fip_dtype) { case FIP_DT_MAC: if (dlen != sizeof(struct fip_mac_desc)) @@ -946,6 +968,7 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip, struct fcoe_fcf *fcf = fip->sel_fcf; struct fc_lport *lport = fip->lp; u32 desc_mask; + u32 dupl_desc = 0; LIBFCOE_FIP_DBG(fip, "Clear Virtual Link received\n"); @@ -963,6 +986,16 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip, dlen = desc->fip_dlen * FIP_BPW; if (dlen > rlen) return; + /* Drop CVL if there are duplicate critical descriptors */ + if (desc->fip_dtype < FIP_DT_LIMIT) { + if (dupl_desc & (1 << desc->fip_dtype)) { + LIBFCOE_FIP_DBG(fip, "Duplicate Critical " + "Descriptors in FIP CVL\n"); + return; + } else { + dupl_desc |= (1 << desc->fip_dtype); + } + } switch (desc->fip_dtype) { case FIP_DT_MAC: mp = (struct fip_mac_desc *)desc; -- 1.7.0.6 _______________________________________________ devel mailing list [email protected] http://www.open-fcoe.org/mailman/listinfo/devel
