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

@@ -22,7 +22,9 @@ rgbasm_obj := \
src/asm/output.o \ src/asm/output.o \
src/asm/rpn.o \ src/asm/rpn.o \
src/asm/symbol.o \ src/asm/symbol.o \
src/asm/gameboy/locallex.o src/asm/gameboy/locallex.o \
src/extern/strlcpy.o \
src/extern/strlcat.o
rgblib_obj := \ rgblib_obj := \
src/lib/library.o \ src/lib/library.o \

View File

@@ -9,6 +9,8 @@
#ifndef ASMOTOR_ASM_FSTACK_H #ifndef ASMOTOR_ASM_FSTACK_H
#define ASMOTOR_ASM_FSTACK_H #define ASMOTOR_ASM_FSTACK_H
#include <stdio.h>
#include "asm/asm.h" #include "asm/asm.h"
#include "asm/types.h" #include "asm/types.h"
#include "asm/lexer.h" #include "asm/lexer.h"
@@ -27,14 +29,17 @@ struct sContext {
ULONG nREPTBlockSize; ULONG nREPTBlockSize;
}; };
extern ULONG fstk_RunInclude(char *s); void
fstk_RunInclude(char *);
extern void fstk_RunMacroArg(SLONG s); extern void fstk_RunMacroArg(SLONG s);
extern ULONG fstk_Init(char *s); void
fstk_Init(char *);
extern void fstk_Dump(void); extern void fstk_Dump(void);
extern void fstk_AddIncludePath(char *s); extern void fstk_AddIncludePath(char *s);
extern ULONG fstk_RunMacro(char *s); extern ULONG fstk_RunMacro(char *s);
extern void fstk_RunRept(ULONG count); extern void fstk_RunRept(ULONG count);
extern void fstk_FindFile(char *s); FILE *
fstk_FindFile(char *);
extern int yywrap(void); extern int yywrap(void);

View File

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

View File

@@ -348,7 +348,6 @@ main(int argc, char *argv[])
DefaultOptions = CurrentOptions; DefaultOptions = CurrentOptions;
/* tzMainfile=argv[argn++]; argc-=1; */
tzMainfile = argv[argc - 1]; tzMainfile = argv[argc - 1];
setuplex(); setuplex();
@@ -366,7 +365,7 @@ main(int argc, char *argv[])
nPass = 1; nPass = 1;
nErrors = 0; nErrors = 0;
sym_PrepPass1(); sym_PrepPass1();
if (fstk_Init(tzMainfile)) { fstk_Init(tzMainfile);
if (CurrentOptions.verbose) { if (CurrentOptions.verbose) {
printf("Pass 1...\n"); printf("Pass 1...\n");
} }
@@ -432,9 +431,5 @@ main(int argc, char *argv[])
nErrors); nErrors);
exit(1); exit(1);
} }
} else { return 0;
printf("File '%s' not found\n", tzMainfile);
exit(5);
}
return (0);
} }

View File

@@ -907,9 +907,14 @@ out_BinaryFile(char *s)
{ {
FILE *f; 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); fseek(f, 0, SEEK_END);
@@ -929,8 +934,6 @@ out_BinaryFile(char *s)
nPC += fsize; nPC += fsize;
pPCSymbol->nValue += fsize; pPCSymbol->nValue += fsize;
fclose(f); fclose(f);
} else
fatalerror("Could not open file '%s': %s", s, strerror(errno));
} }
void void
@@ -944,9 +947,14 @@ out_BinaryFileSlice(char *s, SLONG start_pos, SLONG length)
if (length < 0) if (length < 0)
fatalerror("Number of bytes to read must be greater than zero"); 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); fseek(f, 0, SEEK_END);
@@ -974,6 +982,4 @@ out_BinaryFileSlice(char *s, SLONG start_pos, SLONG length)
pPCSymbol->nValue += length; pPCSymbol->nValue += length;
fclose(f); fclose(f);
} else
fatalerror("Could not open file '%s': %s", s, strerror(errno));
} }

View File

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

55
src/extern/strlcat.c vendored Normal file
View File

@@ -0,0 +1,55 @@
/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */
/*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <string.h>
/*
* Appends src to string dst of size siz (unlike strncat, siz is the
* full size of dst, not space left). At most siz-1 characters
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
* If retval >= siz, truncation occurred.
*/
size_t
rgbds_strlcat(char *dst, const char *src, size_t siz)
{
char *d = dst;
const char *s = src;
size_t n = siz;
size_t dlen;
/* Find the end of dst and adjust bytes left but don't go past end */
while (n-- != 0 && *d != '\0')
d++;
dlen = d - dst;
n = siz - dlen;
if (n == 0)
return(dlen + strlen(s));
while (*s != '\0') {
if (n != 1) {
*d++ = *s;
n--;
}
s++;
}
*d = '\0';
return(dlen + (s - src)); /* count does not include NUL */
}

51
src/extern/strlcpy.c vendored Normal file
View File

@@ -0,0 +1,51 @@
/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */
/*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <string.h>
/*
* Copy src to string dst of size siz. At most siz-1 characters
* will be copied. Always NUL terminates (unless siz == 0).
* Returns strlen(src); if retval >= siz, truncation occurred.
*/
size_t
rgbds_strlcpy(char *dst, const char *src, size_t siz)
{
char *d = dst;
const char *s = src;
size_t n = siz;
/* Copy as many bytes as will fit */
if (n != 0) {
while (--n != 0) {
if ((*d++ = *s++) == '\0')
break;
}
}
/* Not enough room in dst, add NUL and traverse rest of src */
if (n == 0) {
if (siz != 0)
*d = '\0'; /* NUL-terminate dst */
while (*s++)
;
}
return(s - src - 1); /* count does not include NUL */
}