From 0d59a2358a2a1f93fb28cd7f47f8420fbf06a9af Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Sun, 19 Apr 2020 23:37:05 +0200 Subject: [PATCH] ?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. --- sys/src/cmd/1a/a.h | 2 +- sys/src/cmd/2a/a.h | 2 +- sys/src/cmd/5a/a.h | 2 +- sys/src/cmd/6a/a.h | 2 +- sys/src/cmd/7a/a.h | 2 +- sys/src/cmd/8a/a.h | 2 +- sys/src/cmd/cc/lex.c | 2 +- sys/src/cmd/cc/lexbody | 2 +- sys/src/cmd/cc/macbody | 45 +++++++++++++++++++++++++++--------------- sys/src/cmd/ka/a.h | 2 +- sys/src/cmd/qa/a.h | 2 +- sys/src/cmd/va/a.h | 2 +- 12 files changed, 40 insertions(+), 27 deletions(-) diff --git a/sys/src/cmd/1a/a.h b/sys/src/cmd/1a/a.h index f0e2443a2..ff8f11ca3 100644 --- a/sys/src/cmd/1a/a.h +++ b/sys/src/cmd/1a/a.h @@ -156,7 +156,7 @@ Sym* getsym(void); void domacro(void); void macund(void); void macdef(void); -void macexpand(Sym*, char*); +void macexpand(Sym*, char*, int); void macinc(void); void macprag(void); void maclin(void); diff --git a/sys/src/cmd/2a/a.h b/sys/src/cmd/2a/a.h index 798b2a1d7..65549baf9 100644 --- a/sys/src/cmd/2a/a.h +++ b/sys/src/cmd/2a/a.h @@ -157,7 +157,7 @@ Sym* getsym(void); void domacro(void); void macund(void); void macdef(void); -void macexpand(Sym*, char*); +void macexpand(Sym*, char*, int); void macinc(void); void macprag(void); void maclin(void); diff --git a/sys/src/cmd/5a/a.h b/sys/src/cmd/5a/a.h index 0e07a1e10..8bafbee64 100644 --- a/sys/src/cmd/5a/a.h +++ b/sys/src/cmd/5a/a.h @@ -137,7 +137,7 @@ Sym* getsym(void); void domacro(void); void macund(void); void macdef(void); -void macexpand(Sym*, char*); +void macexpand(Sym*, char*, int); void macinc(void); void maclin(void); void macprag(void); diff --git a/sys/src/cmd/6a/a.h b/sys/src/cmd/6a/a.h index 709059056..08c23ee0d 100644 --- a/sys/src/cmd/6a/a.h +++ b/sys/src/cmd/6a/a.h @@ -151,7 +151,7 @@ Sym* getsym(void); void domacro(void); void macund(void); void macdef(void); -void macexpand(Sym*, char*); +void macexpand(Sym*, char*, int); void macinc(void); void macprag(void); void maclin(void); diff --git a/sys/src/cmd/7a/a.h b/sys/src/cmd/7a/a.h index 306a3a285..f60e7dac1 100644 --- a/sys/src/cmd/7a/a.h +++ b/sys/src/cmd/7a/a.h @@ -143,7 +143,7 @@ Sym* getsym(void); void domacro(void); void macund(void); void macdef(void); -void macexpand(Sym*, char*); +void macexpand(Sym*, char*, int); void macinc(void); void maclin(void); void macprag(void); diff --git a/sys/src/cmd/8a/a.h b/sys/src/cmd/8a/a.h index 868031d80..0bd5cbaf2 100644 --- a/sys/src/cmd/8a/a.h +++ b/sys/src/cmd/8a/a.h @@ -152,7 +152,7 @@ Sym* getsym(void); void domacro(void); void macund(void); void macdef(void); -void macexpand(Sym*, char*); +void macexpand(Sym*, char*, int); void macinc(void); void macprag(void); void maclin(void); 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') 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(); diff --git a/sys/src/cmd/ka/a.h b/sys/src/cmd/ka/a.h index 5c15ceb14..cbac168d7 100644 --- a/sys/src/cmd/ka/a.h +++ b/sys/src/cmd/ka/a.h @@ -136,7 +136,7 @@ Sym* getsym(void); void domacro(void); void macund(void); void macdef(void); -void macexpand(Sym*, char*); +void macexpand(Sym*, char*, int); void macinc(void); void macprag(void); void maclin(void); diff --git a/sys/src/cmd/qa/a.h b/sys/src/cmd/qa/a.h index d2a231557..24c3a1766 100644 --- a/sys/src/cmd/qa/a.h +++ b/sys/src/cmd/qa/a.h @@ -138,7 +138,7 @@ Sym* getsym(void); void domacro(void); void macund(void); void macdef(void); -void macexpand(Sym*, char*); +void macexpand(Sym*, char*, int); void macinc(void); void macprag(void); void maclin(void); diff --git a/sys/src/cmd/va/a.h b/sys/src/cmd/va/a.h index 4aef20de4..63bec8038 100644 --- a/sys/src/cmd/va/a.h +++ b/sys/src/cmd/va/a.h @@ -136,7 +136,7 @@ Sym* getsym(void); void domacro(void); void macund(void); void macdef(void); -void macexpand(Sym*, char*); +void macexpand(Sym*, char*, int); void macinc(void); void maclin(void); void macprag(void);