[PATCH] D95112: X86: Fix use-after-realloc in X86AsmParser::ParseIntelExpression
Duncan P. N. Exon Smith via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 20 19:04:00 PST 2021
dexonsmith created this revision.
dexonsmith added a reviewer: dblaikie.
Herald added subscribers: ributzka, pengfei, hiraditya.
dexonsmith requested review of this revision.
Herald added a project: LLVM.
`X86AsmParser::ParseIntelExpression` has a while loop. In the body,
calls to MCAsmLexer::UnLex can force a reallocation in the MCAsmLexer's
`CurToken` SmallVector, invalidating saved references to
`MCAsmLexer::getTok()`.
`const MCAsmToken &Tok` is such a saved reference, and this moves it
from outside the while loop to inside the body, fixing a
use-after-realloc.
`Tok` will still be reused across calls to `Lex()`, each of which
effectively destroys and constructs the pointed-to token. I'm a bit
skeptical of this usage pattern, but it seems broadly used in the
X86AsmParser (and others) so I'm leaving it alone (for now).
Somehow this bug was exposed by https://reviews.llvm.org/D94811,
resulting in test failures in dot-operator related tests in
llvm/test/tools/llvm-ml. I suspect the exposure path is related to
optimizer changes from splitting up the grow operation, but I haven't
dug all the way in. Regardless, there are already tests in tree that
cover this; they might fail consistently if we added ASan
instrumentation to SmallVector.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D95112
Files:
llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
Index: llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
===================================================================
--- llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -1842,15 +1842,17 @@
bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
MCAsmParser &Parser = getParser();
- const AsmToken &Tok = Parser.getTok();
StringRef ErrMsg;
AsmToken::TokenKind PrevTK = AsmToken::Error;
bool Done = false;
while (!Done) {
+ // Get a fresh reference on each loop iteration in case the previous
+ // iteration moved the token storage during UnLex().
+ const AsmToken &Tok = Parser.getTok();
+
bool UpdateLocLex = true;
AsmToken::TokenKind TK = getLexer().getKind();
-
switch (TK) {
default:
if ((Done = SM.isValidEndState()))
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D95112.318089.patch
Type: text/x-patch
Size: 863 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210121/3d3ebb5a/attachment.bin>
More information about the llvm-commits
mailing list