1 From: Chris Leech <christopher.leech@intel.com>
2 Subject: [FcOE] make RSCN parsing more robust
3 References: bnc #459142
5 RSCN parsing needs to verify that the payload length specified in the RSCN ELS
6 message does not exceed the size of the actual frame received.
8 Signed-off-by: Chris Leech <christopher.leech@intel.com>
9 Acked-by: Bernhard Walle <bwalle@suse.de>
12 drivers/scsi/libfc/fc_disc.c | 19 +++++++++++++++----
13 1 files changed, 15 insertions(+), 4 deletions(-)
16 diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c
17 index 0416041..8b609e4 100644
18 --- a/drivers/scsi/libfc/fc_disc.c
19 +++ b/drivers/scsi/libfc/fc_disc.c
20 @@ -173,17 +173,27 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp,
21 FC_DEBUG_DISC("Received an RSCN event on port (%6x)\n",
22 fc_host_port_id(lport->host));
24 + /* make sure the frame contains an RSCN message */
25 rp = fc_frame_payload_get(fp, sizeof(*rp));
27 - if (!rp || rp->rscn_page_len != sizeof(*pp))
31 + /* make sure the page length is as expected (4 bytes) */
32 + if (rp->rscn_page_len != sizeof(*pp))
34 + /* get the RSCN payload length */
35 len = ntohs(rp->rscn_plen);
36 if (len < sizeof(*rp))
38 + /* make sure the frame contains the expected payload */
39 + rp = fc_frame_payload_get(fp, len);
42 + /* payload must be a multiple of the RSCN page size */
44 + if (len % sizeof(*pp))
47 - for (pp = (void *)(rp + 1); len; len -= sizeof(*pp), pp++) {
48 + for (pp = (void *)(rp + 1); len > 0; len -= sizeof(*pp), pp++) {
49 ev_qual = pp->rscn_page_flags >> ELS_RSCN_EV_QUAL_BIT;
50 ev_qual &= ELS_RSCN_EV_QUAL_MASK;
51 fmt = pp->rscn_page_flags >> ELS_RSCN_ADDR_FMT_BIT;
52 @@ -239,6 +249,7 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp,
56 + FC_DEBUG_DISC("Received a bad RSCN frame\n");
58 rjt_data.reason = ELS_RJT_LOGIC;
59 rjt_data.explan = ELS_EXPL_NONE;