diff options
author | Denis Ovsienko <denis@ovsienko.info> | 2018-09-06 21:26:21 +0100 |
---|---|---|
committer | Francois-Xavier Le Bail <devel.fx.lebail@orange.fr> | 2019-10-28 20:10:56 +0100 |
commit | 756d0a1356a49efbd1a9f461f478913cb8163b23 (patch) | |
tree | 9b629716cc195ac001e069cd979b798ff4f48534 /print-bgp.c | |
parent | 8d32220a44bfd218758f8e9ca615ab73eefa0ca8 (diff) | |
download | tcpdump-756d0a1356a49efbd1a9f461f478913cb8163b23.tar.gz |
BGP: prevent stack exhaustion
Enforce a limit on how many times bgp_attr_print() can recurse.
This change fixes CVE-2018-16300.
This fixes a stack exhaustion discovered by Include Security working
under the Mozilla SOS program in 2018 by means of code audit.
Cherry picked from af2cf04a9394c1a56227c2289ae8da262828294a
in 4.9 branch.
Diffstat (limited to 'print-bgp.c')
-rw-r--r-- | print-bgp.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/print-bgp.c b/print-bgp.c index 841e496b..36903d22 100644 --- a/print-bgp.c +++ b/print-bgp.c @@ -1826,7 +1826,8 @@ trunc: /* we rely on the caller to recognize -2 return value */ static int bgp_attr_print(netdissect_options *ndo, - uint8_t atype, const u_char *pptr, u_int len) + uint8_t atype, const u_char *pptr, u_int len, + const unsigned attr_set_level) { u_int i; uint16_t af; @@ -2405,8 +2406,18 @@ bgp_attr_print(netdissect_options *ndo, tptr += len; break; } - /* FIXME check for recursion */ - if (!bgp_attr_print(ndo, atype, tptr, alen)) + /* + * The protocol encoding per se allows ATTR_SET to be nested + * as many times as the message can accommodate. This printer + * used to be able to recurse into ATTR_SET contents until the + * stack exhaustion, but now there is a limit on that (if live + * protocol exchange goes that many levels deep, something is + * probably wrong anyway). Feel free to refine this value if + * you can find the spec with respective normative text. + */ + if (attr_set_level == 10) + ND_PRINT("(too many nested levels, not recursing)"); + else if (!bgp_attr_print(ndo, atype, tptr, alen, attr_set_level + 1)) return 0; tptr += alen; len -= alen; @@ -2797,7 +2808,7 @@ bgp_update_print(netdissect_options *ndo, } if (length < alen) goto trunc; - if (!bgp_attr_print(ndo, atype, p, alen)) + if (!bgp_attr_print(ndo, atype, p, alen, 0)) goto trunc; p += alen; len -= alen; |