From 930857ce4938f64ce1c31463dbd19b1aa781a5f7 Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Thu, 22 Nov 2018 12:04:36 +0000 Subject: [PATCH] Fix heap-use-after-free in Parser error handling Fixes #2643 --- src/error_handling.cpp | 4 ++-- src/error_handling.hpp | 5 +++-- src/parser.cpp | 5 ++++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/error_handling.cpp b/src/error_handling.cpp index 745f65508..534592ff8 100644 --- a/src/error_handling.cpp +++ b/src/error_handling.cpp @@ -15,8 +15,8 @@ namespace Sass { prefix("Error"), pstate(pstate), traces(traces) { } - InvalidSass::InvalidSass(ParserState pstate, Backtraces traces, std::string msg) - : Base(pstate, msg, traces) + InvalidSass::InvalidSass(ParserState pstate, Backtraces traces, std::string msg, char* owned_src) + : Base(pstate, msg, traces), owned_src(owned_src) { } diff --git a/src/error_handling.hpp b/src/error_handling.hpp index 099f26dcc..d5433bf63 100644 --- a/src/error_handling.hpp +++ b/src/error_handling.hpp @@ -37,8 +37,9 @@ namespace Sass { class InvalidSass : public Base { public: - InvalidSass(ParserState pstate, Backtraces traces, std::string msg); - virtual ~InvalidSass() throw() {}; + InvalidSass(ParserState pstate, Backtraces traces, std::string msg, char* owned_src = nullptr); + virtual ~InvalidSass() throw() { sass_free_memory(owned_src); }; + char *owned_src; }; class InvalidParent : public Base { diff --git a/src/parser.cpp b/src/parser.cpp index f29676500..26fb2c95e 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -3054,8 +3054,11 @@ namespace Sass { { Position p(pos.line ? pos : before_token); ParserState pstate(path, source, p, Offset(0, 0)); + // `pstate.src` may not outlive stack unwind so we must copy it. + char *src_copy = sass_copy_c_string(pstate.src); + pstate.src = src_copy; traces.push_back(Backtrace(pstate)); - throw Exception::InvalidSass(pstate, traces, msg); + throw Exception::InvalidSass(pstate, traces, msg, src_copy); } void Parser::error(std::string msg)