diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2020-04-19 23:37:05 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2020-04-19 23:37:05 +0200 |
commit | 0d59a2358a2a1f93fb28cd7f47f8420fbf06a9af (patch) | |
tree | cd6870a2b7489a68492908fdece342653193e3e9 /sys/src/cmd/cc | |
parent | e24bfa4941679fafc7578f542acc08acd18fff99 (diff) |
?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.
Diffstat (limited to 'sys/src/cmd/cc')
-rw-r--r-- | sys/src/cmd/cc/lex.c | 2 | ||||
-rw-r--r-- | sys/src/cmd/cc/lexbody | 2 | ||||
-rw-r--r-- | sys/src/cmd/cc/macbody | 45 |
3 files changed, 31 insertions, 18 deletions
diff --git a/sys/src/cmd/cc/lex.c b/sys/src/cmd/cc/lex.c index 5419f26bf..0fac0c95b 100644 --- a/sys/src/cmd/cc/lex.c +++ b/sys/src/cmd/cc/lex.c @@ -760,7 +760,7 @@ talph: if(s->macro) { newio(); cp = ionext->b; - macexpand(s, cp); + macexpand(s, cp, sizeof(ionext->b)); pushio(); ionext->link = iostack; iostack = ionext; diff --git a/sys/src/cmd/cc/lexbody b/sys/src/cmd/cc/lexbody index 2b3134296..2dcb9696e 100644 --- a/sys/src/cmd/cc/lexbody +++ b/sys/src/cmd/cc/lexbody @@ -238,7 +238,7 @@ l1: if(s->macro) { newio(); cp = ionext->b; - macexpand(s, cp); + macexpand(s, cp, sizeof(ionext->b)); pushio(); ionext->link = iostack; iostack = ionext; diff --git a/sys/src/cmd/cc/macbody b/sys/src/cmd/cc/macbody index 0a921cbb8..ba2fc4882 100644 --- a/sys/src/cmd/cc/macbody +++ b/sys/src/cmd/cc/macbody @@ -128,7 +128,11 @@ dodefine(char *cp) char *p; 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, '='); if(p) { *p++ = 0; @@ -376,15 +380,14 @@ bad: } void -macexpand(Sym *s, char *b) +macexpand(Sym *s, char *b, int blen) { char buf[2000]; 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) { - strcpy(b, s->macro+1); + strncpy(b, s->macro+1, blen); if(debug['m']) print("#expand %s %s\n", s->name, ob); return; @@ -493,8 +496,12 @@ macexpand(Sym *s, char *b) *b = 0; return; } + ob = b; + eb = b + blen-1; cp = s->macro+1; for(;;) { + if(b >= eb) + goto toobig; c = *cp++; if(c == '\n') c = ' '; @@ -514,8 +521,11 @@ macexpand(Sym *s, char *b) c -= 'a'; if(c < 0 || c >= n) continue; - strcpy(b, arg[c]); - b += strlen(arg[c]); + l = strlen(arg[c]); + if(b+l > eb) + goto toobig; + memmove(b, arg[c], l); + b += l; } *b = 0; if(debug['m']) @@ -551,6 +561,10 @@ macinc(void) break; if(c == '\n') goto bad; + if(hp >= &str[STRINGSZ-1]){ + yyerror("name too long for #include"); + break; + } *hp++ = c; } *hp = 0; @@ -558,29 +572,28 @@ macinc(void) c = getcom(); if(c != '\n') goto bad; - f = -1; + c = 0; for(i=0; i<ninclude; i++) { if(i == 0 && c0 == '>') continue; - strcpy(symb, include[i]); - strcat(symb, "/"); - if(strcmp(symb, "./") == 0) - symb[0] = 0; - strcat(symb, str); + c = snprint(symb, NSYMB, "%s/%s", include[i], str)+1; + if(strncmp(symb, "./", 2) == 0){ + c -= 2; + memmove(symb, symb+2, c); + } f = open(symb, 0); if(f >= 0) break; } if(f < 0) - strcpy(symb, str); - c = strlen(symb) + 1; + c = snprint(symb, NSYMB, "%s", str)+1; while(c & 3) c++; while(nhunk < c) gethunk(); hp = hunk; - memcpy(hunk, symb, c); + memmove(hunk, symb, c); nhunk -= c; hunk += c; newio(); |