summaryrefslogtreecommitdiff
path: root/print-bgp.c
diff options
context:
space:
mode:
authorDenis Ovsienko <denis@ovsienko.info>2018-09-06 21:26:21 +0100
committerFrancois-Xavier Le Bail <devel.fx.lebail@orange.fr>2019-10-28 20:10:56 +0100
commit756d0a1356a49efbd1a9f461f478913cb8163b23 (patch)
tree9b629716cc195ac001e069cd979b798ff4f48534 /print-bgp.c
parent8d32220a44bfd218758f8e9ca615ab73eefa0ca8 (diff)
downloadtcpdump-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.c19
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;