From 695ef95fd7d5d8e48e2406092a2f52c8c9c784f3 Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Wed, 25 Nov 2015 17:14:35 +0000 Subject: [PATCH] bgpd: Check capability falls on right multiple of size, where possible. * bgp_open.c: (cap_modsizes) Table of multiple a capability's data size should fall on, if applicable. (bgp_capability_parse) Check the header lengthcap_modsizes should fall on. Inspiration from Cumulus bgpd-capability-cleanup.patch patch, with a slightly different approach. Acked-by: Donald Sharp (cherry picked from commit 4078f2eb7a3a94ddb30cfd8b76b054e790aab524) --- bgpd/bgp_open.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c index 06cf8a17b..8d2491b96 100644 --- a/bgpd/bgp_open.c +++ b/bgpd/bgp_open.c @@ -713,6 +713,23 @@ static const size_t cap_minsizes[] = [CAPABILITY_CODE_FQDN] = CAPABILITY_CODE_MIN_FQDN_LEN, }; +/* value the capability must be a multiple of. + * 0-data capabilities won't be checked against this. + * Other capabilities whose data doesn't fall on convenient boundaries for this + * table should be set to 1. + */ +static const size_t cap_modsizes[] = +{ + [CAPABILITY_CODE_MP] = 4, + [CAPABILITY_CODE_REFRESH] = 1, + [CAPABILITY_CODE_ORF] = 1, + [CAPABILITY_CODE_RESTART] = 1, + [CAPABILITY_CODE_AS4] = 4, + [CAPABILITY_CODE_DYNAMIC] = 1, + [CAPABILITY_CODE_REFRESH_OLD] = 1, + [CAPABILITY_CODE_ORF_OLD] = 1, +}; + /** * Parse given capability. * XXX: This is reading into a stream, but not using stream API @@ -790,6 +807,19 @@ bgp_capability_parse (struct peer *peer, size_t length, int *mp_capability, bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_MALFORMED_ATTR); return -1; } + if (caphdr.length + && caphdr.length % cap_modsizes[caphdr.code] != 0) + { + zlog_info ("%s %s Capability length error: got %u," + " expected a multiple of %u", + peer->host, + LOOKUP (capcode_str, caphdr.code), + caphdr.length, + (unsigned) cap_modsizes[caphdr.code]); + bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR, + BGP_NOTIFY_OPEN_UNSPECIFIC); + return -1; + } /* we deliberately ignore unknown codes, see below */ default: break; -- 2.39.2