shithub: rgbds

Download patch

ref: 2220f19fa717ee7fd18838f87ead8a1ef5d308fb
parent: 023a3c037f102fcaa5e037b762c33d3537a67472
author: ISSOtm <[email protected]>
date: Sun Apr 12 22:36:07 EDT 2020

Fix use-after-free with `include` in linker scripts

Fixes #510, and further proves that you *really* should not entrust memory
ownership management to humans :P

--- a/include/link/main.h
+++ b/include/link/main.h
@@ -18,7 +18,7 @@
 
 /* Variables related to CLI options */
 extern bool isDmgMode;
-extern char const *linkerScriptName;
+extern char       *linkerScriptName;
 extern char const *mapFileName;
 extern char const *symFileName;
 extern char const *overlayFileName;
--- a/src/link/main.c
+++ b/src/link/main.c
@@ -25,7 +25,7 @@
 #include "version.h"
 
 bool isDmgMode;               /* -d */
-char const *linkerScriptName; /* -l */
+char       *linkerScriptName; /* -l */
 char const *mapFileName;      /* -m */
 char const *symFileName;      /* -n */
 char const *overlayFileName;  /* -O */
--- a/src/link/script.c
+++ b/src/link/script.c
@@ -19,6 +19,7 @@
 #include "extern/err.h"
 
 FILE * linkerScript;
+char *includeFileName;
 
 static uint32_t lineNo;
 
@@ -25,13 +26,13 @@
 static struct {
 	FILE *file;
 	uint32_t lineNo;
-	char const *name;
+	char *name;
 } *fileStack;
 
 static uint32_t fileStackSize;
 static uint32_t fileStackIndex;
 
-static void pushFile(char const *newFileName)
+static void pushFile(char *newFileName)
 {
 	if (fileStackIndex == UINT32_MAX)
 		errx(1, "%s(%u): INCLUDE recursion limit reached",
@@ -66,6 +67,8 @@
 	if (!fileStackIndex)
 		return false;
 
+	free(linkerScriptName);
+
 	fileStackIndex--;
 	linkerScript = fileStack[fileStackIndex].file;
 	lineNo = fileStack[fileStackIndex].lineNo;
@@ -179,7 +182,7 @@
 	return curchar;
 }
 
-static struct LinkerScriptToken const *nextToken(void)
+static struct LinkerScriptToken *nextToken(void)
 {
 	static struct LinkerScriptToken token;
 	int curchar;
@@ -368,7 +371,7 @@
 	}
 
 	for (;;) {
-		struct LinkerScriptToken const *token = nextToken();
+		struct LinkerScriptToken *token = nextToken();
 		enum LinkerScriptTokenType tokType;
 		union LinkerScriptTokenAttr attr;
 		bool hasArg;
@@ -498,6 +501,8 @@
 
 			/* Switch to that file */
 			pushFile(token->attr.string);
+			/* The file stack took ownership of the string */
+			token->attr.string = NULL;
 
 			parserState = PARSER_LINESTART;
 			break;