ref: dcb8c6966155f556ff186dd21d3fdac610d2baba
parent: cc6b70f1d56a105a2affcf4113eb4b529f1c5baa
author: ISSOtm <eldredhabert0@gmail.com>
date: Sat May 1 08:24:33 EDT 2021
Fix UAF in lexer capture Fixes #689
--- a/src/asm/lexer.c
+++ b/src/asm/lexer.c
@@ -2426,6 +2426,7 @@
static char *startCapture(void)
{
+ assert(!lexerState->capturing);
lexerState->capturing = true;
lexerState->captureSize = 0;
lexerState->disableMacroArgs = true;
@@ -2435,8 +2436,9 @@
return &lexerState->ptr[lexerState->offset];
} else {
lexerState->captureCapacity = 128; /* The initial size will be twice that */
+ assert(lexerState->captureBuf == NULL);
reallocCaptureBuf();
- return lexerState->captureBuf;
+ return NULL; // Indicate to retrieve the capture buffer when done capturing
}
}
@@ -2443,8 +2445,8 @@
bool lexer_CaptureRept(struct CaptureBody *capture)
{
capture->lineNo = lexer_GetLineNo();
+ capture->body = startCapture();
- char *captureStart = startCapture();
size_t depth = 0;
int c = EOF;
@@ -2496,7 +2498,10 @@
}
finish:
- capture->body = captureStart;
+ // This being NULL means we're capturing from the capture buf, which is `realloc`'d during
+ // the whole capture process, and so MUST be retrieved at the end
+ if (!capture->body)
+ capture->body = lexerState->captureBuf;
capture->size = lexerState->captureSize;
lexerState->capturing = false;
lexerState->captureBuf = NULL;
@@ -2511,8 +2516,8 @@
bool lexer_CaptureMacroBody(struct CaptureBody *capture)
{
capture->lineNo = lexer_GetLineNo();
+ capture->body = startCapture();
- char *captureStart = startCapture();
int c = EOF;
/* If the file is `mmap`ed, we need not to unmap it to keep access to the macro */
@@ -2558,7 +2563,10 @@
}
finish:
- capture->body = captureStart;
+ // This being NULL means we're capturing from the capture buf, which is `realloc`'d during
+ // the whole capture process, and so MUST be retrieved at the end
+ if (!capture->body)
+ capture->body = lexerState->captureBuf;
capture->size = lexerState->captureSize;
lexerState->capturing = false;
lexerState->captureBuf = NULL;