]> The Tcpdump Group git mirrors - tcpdump/commitdiff
(for 4.9.3) CVE-2018-16300/BGP: prevent stack exhaustion
authorDenis Ovsienko <[email protected]>
Thu, 6 Sep 2018 20:26:21 +0000 (21:26 +0100)
committerFrancois-Xavier Le Bail <[email protected]>
Tue, 27 Aug 2019 09:20:43 +0000 (11:20 +0200)
Enforce a limit on how many times bgp_attr_print() can recurse.

This fixes a stack exhaustion discovered by Include Security working
under the Mozilla SOS program in 2018 by means of code audit.

print-bgp.c

index e9b4c2bd9c8d18cb26b838715651ee768e7e757d..7db3c6bb0f93931a2cdddae9ff55cdf544dac2f5 100644 (file)
@@ -1361,7 +1361,7 @@ trunc:
 
 static int
 bgp_attr_print(netdissect_options *ndo,
-               u_int atype, const u_char *pptr, u_int len)
+               u_int atype, const u_char *pptr, u_int len, const unsigned attr_set_level)
 {
        int i;
        uint16_t af;
@@ -2284,8 +2284,16 @@ bgp_attr_print(netdissect_options *ndo,
                             ND_PRINT((ndo, "+%x", aflags & 0xf));
                         ND_PRINT((ndo, "]: "));
                     }
-                    /* 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((ndo, "(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;
@@ -2592,7 +2600,7 @@ bgp_update_print(netdissect_options *ndo,
                                goto trunc;
                        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;