From e951e9fb0bba2565ef1deb48e50af072e116389a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antoine=20Beaupr=C3=A9?= Date: Tue, 25 Apr 2017 20:10:20 -0400 Subject: [PATCH] fix stack overflow in HandleNode() (CVE-2017-5950) simply set a hardcoded recursion limit to 2000 (inspired by Python's) to avoid infinitely recursing into arbitrary data structures assert() the depth. unsure if this is the right approach, but given that HandleNode() is "void", I am not sure how else to return an error. the problem with this approach of course is that it will still crash the caller, unless they have proper exception handling in place. Closes: #459 --- src/singledocparser.cpp | 2 ++ src/singledocparser.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/singledocparser.cpp b/src/singledocparser.cpp index 47e9e04..293ba76 100644 --- a/src/singledocparser.cpp +++ b/src/singledocparser.cpp @@ -47,6 +47,8 @@ void SingleDocParser::HandleDocument(EventHandler& eventHandler) { } void SingleDocParser::HandleNode(EventHandler& eventHandler) { + assert(depth < depth_limit); + depth++; // an empty node *is* a possibility if (m_scanner.empty()) { eventHandler.OnNull(m_scanner.mark(), NullAnchor); diff --git a/src/singledocparser.h b/src/singledocparser.h index c8cfca9..47f9b94 100644 --- a/src/singledocparser.h +++ b/src/singledocparser.h @@ -55,6 +55,8 @@ class SingleDocParser { anchor_t LookupAnchor(const Mark& mark, const std::string& name) const; private: + int depth = 0; + int depth_limit = 2000; Scanner& m_scanner; const Directives& m_directives; std::unique_ptr m_pCollectionStack;