?a, cc: fix buffer overflows in built-in preprocessor (macbody)

add a buffer size argument to macexpand() and check for
overflow.

check for overflow when parsing #include directives.
This commit is contained in:
cinap_lenrek 2020-04-19 23:37:05 +02:00
parent e24bfa4941
commit 0d59a2358a
12 changed files with 40 additions and 27 deletions

View file

@ -156,7 +156,7 @@ Sym* getsym(void);
void domacro(void); void domacro(void);
void macund(void); void macund(void);
void macdef(void); void macdef(void);
void macexpand(Sym*, char*); void macexpand(Sym*, char*, int);
void macinc(void); void macinc(void);
void macprag(void); void macprag(void);
void maclin(void); void maclin(void);

View file

@ -157,7 +157,7 @@ Sym* getsym(void);
void domacro(void); void domacro(void);
void macund(void); void macund(void);
void macdef(void); void macdef(void);
void macexpand(Sym*, char*); void macexpand(Sym*, char*, int);
void macinc(void); void macinc(void);
void macprag(void); void macprag(void);
void maclin(void); void maclin(void);

View file

@ -137,7 +137,7 @@ Sym* getsym(void);
void domacro(void); void domacro(void);
void macund(void); void macund(void);
void macdef(void); void macdef(void);
void macexpand(Sym*, char*); void macexpand(Sym*, char*, int);
void macinc(void); void macinc(void);
void maclin(void); void maclin(void);
void macprag(void); void macprag(void);

View file

@ -151,7 +151,7 @@ Sym* getsym(void);
void domacro(void); void domacro(void);
void macund(void); void macund(void);
void macdef(void); void macdef(void);
void macexpand(Sym*, char*); void macexpand(Sym*, char*, int);
void macinc(void); void macinc(void);
void macprag(void); void macprag(void);
void maclin(void); void maclin(void);

View file

@ -143,7 +143,7 @@ Sym* getsym(void);
void domacro(void); void domacro(void);
void macund(void); void macund(void);
void macdef(void); void macdef(void);
void macexpand(Sym*, char*); void macexpand(Sym*, char*, int);
void macinc(void); void macinc(void);
void maclin(void); void maclin(void);
void macprag(void); void macprag(void);

View file

@ -152,7 +152,7 @@ Sym* getsym(void);
void domacro(void); void domacro(void);
void macund(void); void macund(void);
void macdef(void); void macdef(void);
void macexpand(Sym*, char*); void macexpand(Sym*, char*, int);
void macinc(void); void macinc(void);
void macprag(void); void macprag(void);
void maclin(void); void maclin(void);

View file

@ -760,7 +760,7 @@ talph:
if(s->macro) { if(s->macro) {
newio(); newio();
cp = ionext->b; cp = ionext->b;
macexpand(s, cp); macexpand(s, cp, sizeof(ionext->b));
pushio(); pushio();
ionext->link = iostack; ionext->link = iostack;
iostack = ionext; iostack = ionext;

View file

@ -238,7 +238,7 @@ l1:
if(s->macro) { if(s->macro) {
newio(); newio();
cp = ionext->b; cp = ionext->b;
macexpand(s, cp); macexpand(s, cp, sizeof(ionext->b));
pushio(); pushio();
ionext->link = iostack; ionext->link = iostack;
iostack = ionext; iostack = ionext;

View file

@ -128,7 +128,11 @@ dodefine(char *cp)
char *p; char *p;
long l; long l;
strcpy(symb, cp); strncpy(symb, cp, NSYMB);
if(symb[NSYMB-1] != '\0'){
yyerror("macro too long: %s", cp);
symb[NSYMB-1] = 0;
}
p = strchr(symb, '='); p = strchr(symb, '=');
if(p) { if(p) {
*p++ = 0; *p++ = 0;
@ -376,15 +380,14 @@ bad:
} }
void void
macexpand(Sym *s, char *b) macexpand(Sym *s, char *b, int blen)
{ {
char buf[2000]; char buf[2000];
int n, l, c, nargs; int n, l, c, nargs;
char *arg[NARG], *cp, *ob, *ecp, dots; char *arg[NARG], *cp, *ob, *eb, *ecp, dots;
ob = b;
if(*s->macro == 0) { if(*s->macro == 0) {
strcpy(b, s->macro+1); strncpy(b, s->macro+1, blen);
if(debug['m']) if(debug['m'])
print("#expand %s %s\n", s->name, ob); print("#expand %s %s\n", s->name, ob);
return; return;
@ -493,8 +496,12 @@ macexpand(Sym *s, char *b)
*b = 0; *b = 0;
return; return;
} }
ob = b;
eb = b + blen-1;
cp = s->macro+1; cp = s->macro+1;
for(;;) { for(;;) {
if(b >= eb)
goto toobig;
c = *cp++; c = *cp++;
if(c == '\n') if(c == '\n')
c = ' '; c = ' ';
@ -514,8 +521,11 @@ macexpand(Sym *s, char *b)
c -= 'a'; c -= 'a';
if(c < 0 || c >= n) if(c < 0 || c >= n)
continue; continue;
strcpy(b, arg[c]); l = strlen(arg[c]);
b += strlen(arg[c]); if(b+l > eb)
goto toobig;
memmove(b, arg[c], l);
b += l;
} }
*b = 0; *b = 0;
if(debug['m']) if(debug['m'])
@ -551,6 +561,10 @@ macinc(void)
break; break;
if(c == '\n') if(c == '\n')
goto bad; goto bad;
if(hp >= &str[STRINGSZ-1]){
yyerror("name too long for #include");
break;
}
*hp++ = c; *hp++ = c;
} }
*hp = 0; *hp = 0;
@ -558,29 +572,28 @@ macinc(void)
c = getcom(); c = getcom();
if(c != '\n') if(c != '\n')
goto bad; goto bad;
f = -1; f = -1;
c = 0;
for(i=0; i<ninclude; i++) { for(i=0; i<ninclude; i++) {
if(i == 0 && c0 == '>') if(i == 0 && c0 == '>')
continue; continue;
strcpy(symb, include[i]); c = snprint(symb, NSYMB, "%s/%s", include[i], str)+1;
strcat(symb, "/"); if(strncmp(symb, "./", 2) == 0){
if(strcmp(symb, "./") == 0) c -= 2;
symb[0] = 0; memmove(symb, symb+2, c);
strcat(symb, str); }
f = open(symb, 0); f = open(symb, 0);
if(f >= 0) if(f >= 0)
break; break;
} }
if(f < 0) if(f < 0)
strcpy(symb, str); c = snprint(symb, NSYMB, "%s", str)+1;
c = strlen(symb) + 1;
while(c & 3) while(c & 3)
c++; c++;
while(nhunk < c) while(nhunk < c)
gethunk(); gethunk();
hp = hunk; hp = hunk;
memcpy(hunk, symb, c); memmove(hunk, symb, c);
nhunk -= c; nhunk -= c;
hunk += c; hunk += c;
newio(); newio();

View file

@ -136,7 +136,7 @@ Sym* getsym(void);
void domacro(void); void domacro(void);
void macund(void); void macund(void);
void macdef(void); void macdef(void);
void macexpand(Sym*, char*); void macexpand(Sym*, char*, int);
void macinc(void); void macinc(void);
void macprag(void); void macprag(void);
void maclin(void); void maclin(void);

View file

@ -138,7 +138,7 @@ Sym* getsym(void);
void domacro(void); void domacro(void);
void macund(void); void macund(void);
void macdef(void); void macdef(void);
void macexpand(Sym*, char*); void macexpand(Sym*, char*, int);
void macinc(void); void macinc(void);
void macprag(void); void macprag(void);
void maclin(void); void maclin(void);

View file

@ -136,7 +136,7 @@ Sym* getsym(void);
void domacro(void); void domacro(void);
void macund(void); void macund(void);
void macdef(void); void macdef(void);
void macexpand(Sym*, char*); void macexpand(Sym*, char*, int);
void macinc(void); void macinc(void);
void maclin(void); void maclin(void);
void macprag(void); void macprag(void);