From: Alexey Bataev Date: Thu, 4 Feb 2016 04:22:09 +0000 (+0000) Subject: PR23057: fix use-after-free due to local token buffer in ParseCXXAmbiguousParenExpres... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2fa0d3e203ac0ac3db8422a3db3e6e91747e3033;p=clang PR23057: fix use-after-free due to local token buffer in ParseCXXAmbiguousParenExpression, by Dmitry Polukhin Differential Revision: http://reviews.llvm.org/D16572 A test/Parser/cxx-ambig-paren-expr-asan.cpp M lib/Parse/ParseExprCXX.cpp git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@259750 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index 53009caf8c..760c30b812 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -3081,6 +3081,14 @@ Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType, ParseAs = NotCastExpr ? SimpleExpr : CastExpr; } + // Create a fake EOF to mark end of Toks buffer. + Token AttrEnd; + AttrEnd.startToken(); + AttrEnd.setKind(tok::eof); + AttrEnd.setLocation(Tok.getLocation()); + AttrEnd.setEofData(Toks.data()); + Toks.push_back(AttrEnd); + // The current token should go after the cached tokens. Toks.push_back(Tok); // Re-enter the stored parenthesized tokens into the token stream, so we may @@ -3105,6 +3113,10 @@ Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType, Tracker.consumeClose(); ColonProt.restore(); + // Consume EOF marker for Toks buffer. + assert(Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData()); + ConsumeAnyToken(); + if (ParseAs == CompoundLiteral) { ExprType = CompoundLiteral; if (DeclaratorInfo.isInvalidType()) @@ -3141,10 +3153,16 @@ Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType, // Match the ')'. if (Result.isInvalid()) { - SkipUntil(tok::r_paren, StopAtSemi); + while (Tok.isNot(tok::eof)) + ConsumeAnyToken(); + assert(Tok.getEofData() == AttrEnd.getEofData()); + ConsumeAnyToken(); return ExprError(); } Tracker.consumeClose(); + // Consume EOF marker for Toks buffer. + assert(Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData()); + ConsumeAnyToken(); return Result; } diff --git a/test/Parser/cxx-ambig-paren-expr-asan.cpp b/test/Parser/cxx-ambig-paren-expr-asan.cpp new file mode 100644 index 0000000000..ec9d6b9da3 --- /dev/null +++ b/test/Parser/cxx-ambig-paren-expr-asan.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s + +// This syntax error used to cause use-after free due to token local buffer +// in ParseCXXAmbiguousParenExpression. +int H((int()[)]); +// expected-error@-1 {{expected expression}} +// expected-error@-2 {{expected ']'}} +// expected-note@-3 {{to match this '['}} +// expected-error@-4 {{expected ';' after top level declarator}}