rgbasm: Fix TOCTOU and reduce buffering.

This commit is contained in:
Anthony J. Bentley
2014-09-24 00:23:40 -06:00
parent 056109652d
commit 45b6872e2a
8 changed files with 282 additions and 156 deletions

View File

@@ -5,10 +5,19 @@
*
*/
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef STRL_IN_LIBC
#define strlcpy rgbds_strlcpy
#define strlcat rgbds_strlcat
size_t strlcpy(char *, const char *, size_t);
size_t strlcat(char *, const char *, size_t);
#endif
#include "asm/symbol.h"
#include "asm/fstack.h"
#include "asm/types.h"
@@ -195,28 +204,33 @@ fstk_AddIncludePath(char *s)
strcpy(IncludePaths[NextIncPath++], s);
}
void
fstk_FindFile(char *s)
FILE *
fstk_FindFile(char *fname)
{
char t[_MAX_PATH + 1];
SLONG i = -1;
char path[PATH_MAX];
int i;
FILE *f;
strcpy(t, s);
if ((f = fopen(fname, "rb")) != NULL || errno != ENOENT) {
return f;
}
while (i < NextIncPath) {
FILE *f;
if ((f = fopen(t, "rb")) != NULL) {
fclose(f);
strcpy(s, t);
return;
for (i = 0; i < NextIncPath; ++i) {
if (strlcpy(path, IncludePaths[i], sizeof path) >=
sizeof path) {
continue;
}
i += 1;
if (i < NextIncPath) {
strcpy(t, IncludePaths[i]);
strcat(t, s);
if (strlcat(path, fname, sizeof path) >= sizeof path) {
continue;
}
if ((f = fopen(path, "rb")) != NULL || errno != ENOENT) {
return f;
}
}
errno = ENOENT;
return NULL;
}
/*
* RGBAsm - FSTACK.C (FileStack routines)
@@ -225,33 +239,32 @@ fstk_FindFile(char *s)
*
*/
ULONG
void
fstk_RunInclude(char *tzFileName)
{
FILE *f;
//printf("INCLUDE: %s\n", s);
f = fstk_FindFile(tzFileName);
fstk_FindFile(tzFileName);
//printf("INCLUDING: %s\n", tzFileName);
if (f == NULL) {
fprintf(stderr, "Unable to open included file '%s': ",
tzFileName);
perror(NULL);
exit(1);
}
if ((f = fopen(tzFileName, "r")) != NULL) {
pushcontext();
nLineNo = 1;
nCurrentStatus = STAT_isInclude;
strcpy(tzCurrentFileName, tzFileName);
pCurrentFile = f;
CurrentFlexHandle = yy_create_buffer(pCurrentFile);
yy_switch_to_buffer(CurrentFlexHandle);
pushcontext();
nLineNo = 1;
nCurrentStatus = STAT_isInclude;
strcpy(tzCurrentFileName, tzFileName);
pCurrentFile = f;
CurrentFlexHandle = yy_create_buffer(pCurrentFile);
yy_switch_to_buffer(CurrentFlexHandle);
//Dirty hack to give the INCLUDE directive a linefeed
//Dirty hack to give the INCLUDE directive a linefeed
yyunput('\n');
nLineNo -= 1;
return (1);
} else
return (0);
yyunput('\n');
nLineNo -= 1;
}
/*
* RGBAsm - FSTACK.C (FileStack routines)
@@ -360,7 +373,7 @@ fstk_RunRept(ULONG count)
*
*/
ULONG
void
fstk_Init(char *s)
{
char tzFileName[_MAX_PATH + 1];
@@ -368,17 +381,19 @@ fstk_Init(char *s)
sym_AddString("__FILE__", s);
strcpy(tzFileName, s);
fstk_FindFile(tzFileName);
pFileStack = NULL;
if ((pCurrentFile = fopen(tzFileName, "r")) != NULL) {
nMacroCount = 0;
nCurrentStatus = STAT_isInclude;
strcpy(tzCurrentFileName, tzFileName);
CurrentFlexHandle = yy_create_buffer(pCurrentFile);
yy_switch_to_buffer(CurrentFlexHandle);
nLineNo = 1;
return (1);
} else
return (0);
pCurrentFile = fopen(tzFileName, "rb");
if (pCurrentFile == NULL) {
fprintf(stderr, "Unable to open file '%s': ",
tzFileName);
perror(NULL);
exit(1);
}
nMacroCount = 0;
nCurrentStatus = STAT_isInclude;
strcpy(tzCurrentFileName, tzFileName);
CurrentFlexHandle = yy_create_buffer(pCurrentFile);
yy_switch_to_buffer(CurrentFlexHandle);
nLineNo = 1;
}

View File

@@ -348,7 +348,6 @@ main(int argc, char *argv[])
DefaultOptions = CurrentOptions;
/* tzMainfile=argv[argn++]; argc-=1; */
tzMainfile = argv[argc - 1];
setuplex();
@@ -366,75 +365,71 @@ main(int argc, char *argv[])
nPass = 1;
nErrors = 0;
sym_PrepPass1();
if (fstk_Init(tzMainfile)) {
if (CurrentOptions.verbose) {
printf("Pass 1...\n");
}
fstk_Init(tzMainfile);
if (CurrentOptions.verbose) {
printf("Pass 1...\n");
}
yy_set_state(LEX_STATE_NORMAL);
opt_SetCurrentOptions(&DefaultOptions);
yy_set_state(LEX_STATE_NORMAL);
opt_SetCurrentOptions(&DefaultOptions);
if (yyparse() == 0 && nErrors == 0) {
if (nIFDepth == 0) {
nTotalLines = 0;
nLineNo = 1;
nIFDepth = 0;
nPC = 0;
nPass = 2;
nErrors = 0;
sym_PrepPass2();
out_PrepPass2();
fstk_Init(tzMainfile);
yy_set_state(LEX_STATE_NORMAL);
opt_SetCurrentOptions(&DefaultOptions);
if (yyparse() == 0 && nErrors == 0) {
if (nIFDepth == 0) {
nTotalLines = 0;
nLineNo = 1;
nIFDepth = 0;
nPC = 0;
nPass = 2;
nErrors = 0;
sym_PrepPass2();
out_PrepPass2();
fstk_Init(tzMainfile);
yy_set_state(LEX_STATE_NORMAL);
opt_SetCurrentOptions(&DefaultOptions);
if (CurrentOptions.verbose) {
printf("Pass 2...\n");
}
if (yyparse() == 0 && nErrors == 0) {
double timespent;
nEndClock = clock();
timespent =
((double) (nEndClock - nStartClock))
/ (double) CLOCKS_PER_SEC;
if (CurrentOptions.verbose) {
printf("Pass 2...\n");
}
if (yyparse() == 0 && nErrors == 0) {
double timespent;
nEndClock = clock();
timespent =
((double) (nEndClock - nStartClock))
/ (double) CLOCKS_PER_SEC;
if (CurrentOptions.verbose) {
printf
("Success! %ld lines in %d.%02d seconds ",
nTotalLines, (int) timespent,
((int) (timespent * 100.0)) % 100);
if (timespent == 0)
printf
("(INFINITY lines/minute)\n");
else
printf("(%d lines/minute)\n",
(int) (60 / timespent *
nTotalLines));
}
out_WriteObject();
} else {
printf
("Assembly aborted in pass 2 (%ld errors)!\n",
nErrors);
//sym_PrintSymbolTable();
exit(5);
("Success! %ld lines in %d.%02d seconds ",
nTotalLines, (int) timespent,
((int) (timespent * 100.0)) % 100);
if (timespent == 0)
printf
("(INFINITY lines/minute)\n");
else
printf("(%d lines/minute)\n",
(int) (60 / timespent *
nTotalLines));
}
out_WriteObject();
} else {
fprintf(stderr,
"Unterminated IF construct (%ld levels)!\n",
nIFDepth);
exit(1);
printf
("Assembly aborted in pass 2 (%ld errors)!\n",
nErrors);
//sym_PrintSymbolTable();
exit(5);
}
} else {
fprintf(stderr,
"Assembly aborted in pass 1 (%ld errors)!\n",
nErrors);
"Unterminated IF construct (%ld levels)!\n",
nIFDepth);
exit(1);
}
} else {
printf("File '%s' not found\n", tzMainfile);
exit(5);
fprintf(stderr,
"Assembly aborted in pass 1 (%ld errors)!\n",
nErrors);
exit(1);
}
return (0);
return 0;
}

View File

@@ -907,30 +907,33 @@ out_BinaryFile(char *s)
{
FILE *f;
fstk_FindFile(s);
f = fstk_FindFile(s);
if (f == NULL) {
fprintf(stderr, "Unable to open incbin file '%s': ",
s);
perror(NULL);
exit(1);
}
if ((f = fopen(s, "rb")) != NULL) {
SLONG fsize;
SLONG fsize;
fseek(f, 0, SEEK_END);
fsize = ftell(f);
fseek(f, 0, SEEK_SET);
fseek(f, 0, SEEK_END);
fsize = ftell(f);
fseek(f, 0, SEEK_SET);
checkcodesection(fsize);
checkcodesection(fsize);
if (nPass == 2) {
SLONG dest = nPC;
SLONG todo = fsize;
if (nPass == 2) {
SLONG dest = nPC;
SLONG todo = fsize;
while (todo--)
pCurrentSection->tData[dest++] = fgetc(f);
}
pCurrentSection->nPC += fsize;
nPC += fsize;
pPCSymbol->nValue += fsize;
fclose(f);
} else
fatalerror("Could not open file '%s': %s", s, strerror(errno));
while (todo--)
pCurrentSection->tData[dest++] = fgetc(f);
}
pCurrentSection->nPC += fsize;
nPC += fsize;
pPCSymbol->nValue += fsize;
fclose(f);
}
void
@@ -944,36 +947,39 @@ out_BinaryFileSlice(char *s, SLONG start_pos, SLONG length)
if (length < 0)
fatalerror("Number of bytes to read must be greater than zero");
fstk_FindFile(s);
f = fstk_FindFile(s);
if (f == NULL) {
fprintf(stderr, "Unable to open included file '%s': ",
s);
perror(NULL);
exit(1);
}
if ((f = fopen(s, "rb")) != NULL) {
SLONG fsize;
SLONG fsize;
fseek(f, 0, SEEK_END);
fsize = ftell(f);
fseek(f, 0, SEEK_END);
fsize = ftell(f);
if (start_pos >= fsize)
fatalerror("Specified start position is greater than length of file");
if (start_pos >= fsize)
fatalerror("Specified start position is greater than length of file");
if ((start_pos + length) > fsize)
fatalerror("Specified range in INCBIN is out of bounds");
if ((start_pos + length) > fsize)
fatalerror("Specified range in INCBIN is out of bounds");
fseek(f, start_pos, SEEK_SET);
fseek(f, start_pos, SEEK_SET);
checkcodesection(length);
checkcodesection(length);
if (nPass == 2) {
SLONG dest = nPC;
SLONG todo = length;
if (nPass == 2) {
SLONG dest = nPC;
SLONG todo = length;
while (todo--)
pCurrentSection->tData[dest++] = fgetc(f);
}
pCurrentSection->nPC += length;
nPC += length;
pPCSymbol->nValue += length;
while (todo--)
pCurrentSection->tData[dest++] = fgetc(f);
}
pCurrentSection->nPC += length;
nPC += length;
pPCSymbol->nValue += length;
fclose(f);
} else
fatalerror("Could not open file '%s': %s", s, strerror(errno));
fclose(f);
}

View File

@@ -265,10 +265,7 @@ set : T_LABEL T_POP_SET const
include : T_POP_INCLUDE string
{
if( !fstk_RunInclude($2) )
{
yyerror("Could not open file '%s' : %s\n", $2, strerror(errno));
}
fstk_RunInclude($2);
}
;