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
This commit is contained in:
ISSOtm
2020-04-13 02:36:07 +02:00
parent 023a3c037f
commit 2220f19fa7
3 changed files with 11 additions and 6 deletions

View File

@@ -18,7 +18,7 @@
/* Variables related to CLI options */ /* Variables related to CLI options */
extern bool isDmgMode; extern bool isDmgMode;
extern char const *linkerScriptName; extern char *linkerScriptName;
extern char const *mapFileName; extern char const *mapFileName;
extern char const *symFileName; extern char const *symFileName;
extern char const *overlayFileName; extern char const *overlayFileName;

View File

@@ -25,7 +25,7 @@
#include "version.h" #include "version.h"
bool isDmgMode; /* -d */ bool isDmgMode; /* -d */
char const *linkerScriptName; /* -l */ char *linkerScriptName; /* -l */
char const *mapFileName; /* -m */ char const *mapFileName; /* -m */
char const *symFileName; /* -n */ char const *symFileName; /* -n */
char const *overlayFileName; /* -O */ char const *overlayFileName; /* -O */

View File

@@ -19,19 +19,20 @@
#include "extern/err.h" #include "extern/err.h"
FILE * linkerScript; FILE * linkerScript;
char *includeFileName;
static uint32_t lineNo; static uint32_t lineNo;
static struct { static struct {
FILE *file; FILE *file;
uint32_t lineNo; uint32_t lineNo;
char const *name; char *name;
} *fileStack; } *fileStack;
static uint32_t fileStackSize; static uint32_t fileStackSize;
static uint32_t fileStackIndex; static uint32_t fileStackIndex;
static void pushFile(char const *newFileName) static void pushFile(char *newFileName)
{ {
if (fileStackIndex == UINT32_MAX) if (fileStackIndex == UINT32_MAX)
errx(1, "%s(%u): INCLUDE recursion limit reached", errx(1, "%s(%u): INCLUDE recursion limit reached",
@@ -66,6 +67,8 @@ static bool popFile(void)
if (!fileStackIndex) if (!fileStackIndex)
return false; return false;
free(linkerScriptName);
fileStackIndex--; fileStackIndex--;
linkerScript = fileStack[fileStackIndex].file; linkerScript = fileStack[fileStackIndex].file;
lineNo = fileStack[fileStackIndex].lineNo; lineNo = fileStack[fileStackIndex].lineNo;
@@ -179,7 +182,7 @@ static int readChar(FILE *file)
return curchar; return curchar;
} }
static struct LinkerScriptToken const *nextToken(void) static struct LinkerScriptToken *nextToken(void)
{ {
static struct LinkerScriptToken token; static struct LinkerScriptToken token;
int curchar; int curchar;
@@ -368,7 +371,7 @@ struct SectionPlacement *script_NextSection(void)
} }
for (;;) { for (;;) {
struct LinkerScriptToken const *token = nextToken(); struct LinkerScriptToken *token = nextToken();
enum LinkerScriptTokenType tokType; enum LinkerScriptTokenType tokType;
union LinkerScriptTokenAttr attr; union LinkerScriptTokenAttr attr;
bool hasArg; bool hasArg;
@@ -498,6 +501,8 @@ struct SectionPlacement *script_NextSection(void)
/* Switch to that file */ /* Switch to that file */
pushFile(token->attr.string); pushFile(token->attr.string);
/* The file stack took ownership of the string */
token->attr.string = NULL;
parserState = PARSER_LINESTART; parserState = PARSER_LINESTART;
break; break;