shithub: rgbds

Download patch

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;