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;