| From d540476e31b080aa1f903ad20ec0426dd3838be7 Mon Sep 17 00:00:00 2001 |
| From: =?UTF-8?q?Antoine=20Beaupr=C3=A9?= <anarcat@debian.org> |
| 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 a27c1c3b..1b4262ee 100644 |
| --- a/src/singledocparser.cpp |
| +++ b/src/singledocparser.cpp |
| @@ -46,6 +46,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 2b92067c..7046f1e2 100644 |
| --- a/src/singledocparser.h |
| +++ b/src/singledocparser.h |
| @@ -51,6 +51,8 @@ class SingleDocParser : private noncopyable { |
| 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<CollectionStack> m_pCollectionStack; |