diff options
author | Filip Varga <fivarga@cisco.com> | 2018-10-22 12:36:58 +0200 |
---|---|---|
committer | Damjan Marion <dmarion@me.com> | 2018-10-22 11:52:44 +0000 |
commit | 115a3ac59a16f9dcfee92eaecc79cd1fa3320e29 (patch) | |
tree | 8d3a0c5fa52c10a45a6697b1219676a877a5552f /src/plugins/cdp/cdp_input.c | |
parent | 31555a3475a37195938378217a635b3451e449de (diff) |
VPP-1420 CDP check memory bounds fix
Change-Id: I7951ffd050acb618dd20b86ae5946e1228ff5d79
Signed-off-by: Filip Varga <fivarga@cisco.com>
Diffstat (limited to 'src/plugins/cdp/cdp_input.c')
-rw-r--r-- | src/plugins/cdp/cdp_input.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/src/plugins/cdp/cdp_input.c b/src/plugins/cdp/cdp_input.c index bce8eebe7b0..66ae97142c5 100644 --- a/src/plugins/cdp/cdp_input.c +++ b/src/plugins/cdp/cdp_input.c @@ -250,7 +250,7 @@ process_cdp_hdr (cdp_main_t * cm, cdp_neighbor_t * n, cdp_hdr_t * h) static int cdp_packet_scan (cdp_main_t * cm, cdp_neighbor_t * n) { - u8 *cur = n->last_rx_pkt; + u8 *end, *cur = n->last_rx_pkt; cdp_hdr_t *h; cdp_tlv_t *tlv; cdp_error_t e = CDP_ERROR_NONE; @@ -269,13 +269,24 @@ cdp_packet_scan (cdp_main_t * cm, cdp_neighbor_t * n) if (e) return e; + // there are no tlvs + if (vec_len (n->last_rx_pkt) <= 0) + return CDP_ERROR_BAD_TLV; + cur = (u8 *) (h + 1); + end = n->last_rx_pkt + vec_len (n->last_rx_pkt) - 1; - while (cur < n->last_rx_pkt + vec_len (n->last_rx_pkt) - 1) + // look ahead 4 bytes (u16 tlv->t + u16 tlv->l) + while (cur + 3 <= end) { tlv = (cdp_tlv_t *) cur; tlv->t = ntohs (tlv->t); tlv->l = ntohs (tlv->l); + + /* tlv length includes t, l and v */ + cur += tlv->l; + if ((cur - 1) > end) + return CDP_ERROR_BAD_TLV; /* * Only process known TLVs. In practice, certain * devices send tlv->t = 0xFF, perhaps as an EOF of sorts. @@ -288,10 +299,12 @@ cdp_packet_scan (cdp_main_t * cm, cdp_neighbor_t * n) if (e) return e; } - /* tlv length includes (t, l) */ - cur += tlv->l; } + // did not process all tlvs or none tlv processed + if ((cur - 1) != end) + return CDP_ERROR_BAD_TLV; + return CDP_ERROR_NONE; } |