shithub: riscv

Download patch

ref: e24bfa4941679fafc7578f542acc08acd18fff99
parent: 3f87ffea44150d233b11a38b1ca3673207fe206e
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Apr 19 18:59:21 EDT 2020

?a: catch symb[NSYMB] buffer overflow in lexer, cleanup, assume thechar is a rune

--- a/sys/src/cmd/1a/lex.c
+++ b/sys/src/cmd/1a/lex.c
@@ -38,7 +38,7 @@
 		break;
 	} ARGEND
 	if(*argv == 0) {
-		print("usage: %ca [-options] file.s\n", thechar);
+		print("usage: %Ca [-options] file.s\n", thechar);
 		errorexit();
 	}
 	if(argc > 1 && systemtype(Windows)){
@@ -92,10 +92,10 @@
 int
 assemble(char *file)
 {
-	char ofile[100], incfile[20], *p;
+	char *ofile, *p;
 	int i, of;
 
-	strcpy(ofile, file);
+	ofile = strdup(file);
 	p = utfrrune(ofile, pathchar());
 	if(p) {
 		include[0] = ofile;
@@ -103,16 +103,13 @@
 	} else
 		p = ofile;
 	if(outfile == 0) {
-		outfile = p;
-		if(outfile){
+		if(p){
+			outfile = p;
 			p = utfrrune(outfile, '.');
 			if(p)
 				if(p[1] == 's' && p[2] == 0)
 					p[0] = 0;
-			p = utfrune(outfile, 0);
-			p[0] = '.';
-			p[1] = thechar;
-			p[2] = 0;
+			outfile = smprint("%s.%C", outfile, thechar);
 		} else
 			outfile = "/dev/null";
 	}
@@ -120,15 +117,13 @@
 	if(p) {
 		setinclude(p);
 	} else {
-		if(systemtype(Plan9)) {
-			sprint(incfile,"/%s/include", thestring);
-			setinclude(strdup(incfile));
-		}
+		if(systemtype(Plan9))
+			setinclude(smprint("/%s/include", thestring));
 	}
 
 	of = mycreat(outfile, 0664);
 	if(of < 0) {
-		yyerror("%ca: cannot create %s", thechar, outfile);
+		yyerror("%Ca: cannot create %s", thechar, outfile);
 		errorexit();
 	}
 	Binit(&obuf, of, OWRITE);
--- a/sys/src/cmd/2a/lex.c
+++ b/sys/src/cmd/2a/lex.c
@@ -38,7 +38,7 @@
 		break;
 	} ARGEND
 	if(*argv == 0) {
-		print("usage: %ca [-options] file.s\n", thechar);
+		print("usage: %Ca [-options] file.s\n", thechar);
 		errorexit();
 	}
 	if(argc > 1 && systemtype(Windows)){
@@ -92,10 +92,10 @@
 int
 assemble(char *file)
 {
-	char ofile[100], incfile[20], *p;
+	char *ofile, *p;
 	int i, of;
 
-	strcpy(ofile, file);
+	ofile = strdup(file);
 	p = utfrrune(ofile, pathchar());
 	if(p) {
 		include[0] = ofile;
@@ -103,16 +103,13 @@
 	} else
 		p = ofile;
 	if(outfile == 0) {
-		outfile = p;
-		if(outfile){
+		if(p){
+			outfile = p;
 			p = utfrrune(outfile, '.');
 			if(p)
 				if(p[1] == 's' && p[2] == 0)
 					p[0] = 0;
-			p = utfrune(outfile, 0);
-			p[0] = '.';
-			p[1] = thechar;
-			p[2] = 0;
+			outfile = smprint("%s.%C", outfile, thechar);
 		} else
 			outfile = "/dev/null";
 	}
@@ -120,15 +117,13 @@
 	if(p) {
 		setinclude(p);
 	} else {
-		if(systemtype(Plan9)) {
-			sprint(incfile,"/%s/include", thestring);
-			setinclude(strdup(incfile));
-		}
+		if(systemtype(Plan9))
+			setinclude(smprint("/%s/include", thestring));
 	}
 
 	of = mycreat(outfile, 0664);
 	if(of < 0) {
-		yyerror("%ca: cannot create %s", thechar, outfile);
+		yyerror("%Ca: cannot create %s", thechar, outfile);
 		errorexit();
 	}
 	Binit(&obuf, of, OWRITE);
--- a/sys/src/cmd/5a/lex.c
+++ b/sys/src/cmd/5a/lex.c
@@ -42,7 +42,7 @@
 		break;
 	} ARGEND
 	if(*argv == 0) {
-		print("usage: %ca [-options] file.s\n", thechar);
+		print("usage: %Ca [-options] file.s\n", thechar);
 		errorexit();
 	}
 	if(argc > 1 && systemtype(Windows)){
@@ -96,10 +96,10 @@
 int
 assemble(char *file)
 {
-	char ofile[100], incfile[20], *p;
+	char *ofile, *p;
 	int i, of;
 
-	strcpy(ofile, file);
+	ofile = strdup(file);
 	p = utfrrune(ofile, pathchar());
 	if(p) {
 		include[0] = ofile;
@@ -107,16 +107,13 @@
 	} else
 		p = ofile;
 	if(outfile == 0) {
-		outfile = p;
-		if(outfile){
+		if(p){
+			outfile = p;
 			p = utfrrune(outfile, '.');
 			if(p)
 				if(p[1] == 's' && p[2] == 0)
 					p[0] = 0;
-			p = utfrune(outfile, 0);
-			p[0] = '.';
-			p[1] = thechar;
-			p[2] = 0;
+			outfile = smprint("%s.%C", outfile, thechar);
 		} else
 			outfile = "/dev/null";
 	}
@@ -124,15 +121,13 @@
 	if(p) {
 		setinclude(p);
 	} else {
-		if(systemtype(Plan9)) {
-			sprint(incfile,"/%s/include", thestring);
-			setinclude(strdup(incfile));
-		}
+		if(systemtype(Plan9))
+			setinclude(smprint("/%s/include", thestring));
 	}
 
 	of = mycreat(outfile, 0664);
 	if(of < 0) {
-		yyerror("%ca: cannot create %s", thechar, outfile);
+		yyerror("%Ca: cannot create %s", thechar, outfile);
 		errorexit();
 	}
 	Binit(&obuf, of, OWRITE);
--- a/sys/src/cmd/6a/lex.c
+++ b/sys/src/cmd/6a/lex.c
@@ -38,7 +38,7 @@
 		break;
 	} ARGEND
 	if(*argv == 0) {
-		print("usage: %ca [-options] file.s\n", thechar);
+		print("usage: %Ca [-options] file.s\n", thechar);
 		errorexit();
 	}
 	if(argc > 1 && systemtype(Windows)){
@@ -92,10 +92,10 @@
 int
 assemble(char *file)
 {
-	char ofile[100], incfile[20], *p;
+	char *ofile, *p;
 	int i, of;
 
-	strcpy(ofile, file);
+	ofile = strdup(file);
 	p = utfrrune(ofile, pathchar());
 	if(p) {
 		include[0] = ofile;
@@ -103,16 +103,13 @@
 	} else
 		p = ofile;
 	if(outfile == 0) {
-		outfile = p;
-		if(outfile){
+		if(p){
+			outfile = p;
 			p = utfrrune(outfile, '.');
 			if(p)
 				if(p[1] == 's' && p[2] == 0)
 					p[0] = 0;
-			p = utfrune(outfile, 0);
-			p[0] = '.';
-			p[1] = thechar;
-			p[2] = 0;
+			outfile = smprint("%s.%C", outfile, thechar);
 		} else
 			outfile = "/dev/null";
 	}
@@ -120,15 +117,13 @@
 	if(p) {
 		setinclude(p);
 	} else {
-		if(systemtype(Plan9)) {
-			sprint(incfile,"/%s/include", thestring);
-			setinclude(strdup(incfile));
-		}
+		if(systemtype(Plan9))
+			setinclude(smprint("/%s/include", thestring));
 	}
 
 	of = mycreat(outfile, 0664);
 	if(of < 0) {
-		yyerror("%ca: cannot create %s", thechar, outfile);
+		yyerror("%Ca: cannot create %s", thechar, outfile);
 		errorexit();
 	}
 	Binit(&obuf, of, OWRITE);
--- a/sys/src/cmd/7a/lex.c
+++ b/sys/src/cmd/7a/lex.c
@@ -38,7 +38,7 @@
 		break;
 	} ARGEND
 	if(*argv == 0) {
-		print("usage: %ca [-options] file.s\n", thechar);
+		print("usage: %Ca [-options] file.s\n", thechar);
 		errorexit();
 	}
 	if(argc > 1 && systemtype(Windows)){
@@ -92,10 +92,10 @@
 int
 assemble(char *file)
 {
-	char ofile[100], incfile[20], *p;
+	char *ofile, *p;
 	int i, of;
 
-	strcpy(ofile, file);
+	ofile = strdup(file);
 	p = utfrrune(ofile, pathchar());
 	if(p) {
 		include[0] = ofile;
@@ -103,16 +103,13 @@
 	} else
 		p = ofile;
 	if(outfile == 0) {
-		outfile = p;
-		if(outfile){
+		if(p){
+			outfile = p;
 			p = utfrrune(outfile, '.');
 			if(p)
 				if(p[1] == 's' && p[2] == 0)
 					p[0] = 0;
-			p = utfrune(outfile, 0);
-			p[0] = '.';
-			p[1] = thechar;
-			p[2] = 0;
+			outfile = smprint("%s.%C", outfile, thechar);
 		} else
 			outfile = "/dev/null";
 	}
@@ -120,15 +117,13 @@
 	if(p) {
 		setinclude(p);
 	} else {
-		if(systemtype(Plan9)) {
-			sprint(incfile,"/%s/include", thestring);
-			setinclude(strdup(incfile));
-		}
+		if(systemtype(Plan9))
+			setinclude(smprint("/%s/include", thestring));
 	}
 
 	of = mycreat(outfile, 0664);
 	if(of < 0) {
-		yyerror("%ca: cannot create %s", thechar, outfile);
+		yyerror("%Ca: cannot create %s", thechar, outfile);
 		errorexit();
 	}
 	Binit(&obuf, of, OWRITE);
--- a/sys/src/cmd/8a/lex.c
+++ b/sys/src/cmd/8a/lex.c
@@ -38,7 +38,7 @@
 		break;
 	} ARGEND
 	if(*argv == 0) {
-		print("usage: %ca [-options] file.s\n", thechar);
+		print("usage: %Ca [-options] file.s\n", thechar);
 		errorexit();
 	}
 	if(argc > 1 && systemtype(Windows)){
@@ -92,10 +92,10 @@
 int
 assemble(char *file)
 {
-	char ofile[100], incfile[20], *p;
+	char *ofile, *p;
 	int i, of;
 
-	strcpy(ofile, file);
+	ofile = strdup(file);
 	p = utfrrune(ofile, pathchar());
 	if(p) {
 		include[0] = ofile;
@@ -103,16 +103,13 @@
 	} else
 		p = ofile;
 	if(outfile == 0) {
-		outfile = p;
-		if(outfile){
+		if(p){
+			outfile = p;
 			p = utfrrune(outfile, '.');
 			if(p)
 				if(p[1] == 's' && p[2] == 0)
 					p[0] = 0;
-			p = utfrune(outfile, 0);
-			p[0] = '.';
-			p[1] = thechar;
-			p[2] = 0;
+			outfile = smprint("%s.%C", outfile, thechar);
 		} else
 			outfile = "/dev/null";
 	}
@@ -120,15 +117,13 @@
 	if(p) {
 		setinclude(p);
 	} else {
-		if(systemtype(Plan9)) {
-			sprint(incfile,"/%s/include", thestring);
-			setinclude(strdup(incfile));
-		}
+		if(systemtype(Plan9))
+			setinclude(smprint("/%s/include", thestring));
 	}
 
 	of = mycreat(outfile, 0664);
 	if(of < 0) {
-		yyerror("%ca: cannot create %s", thechar, outfile);
+		yyerror("%Ca: cannot create %s", thechar, outfile);
 		errorexit();
 	}
 	Binit(&obuf, of, OWRITE);
--- a/sys/src/cmd/cc/lexbody
+++ b/sys/src/cmd/cc/lexbody
@@ -111,7 +111,7 @@
 	if(f < 0)
 		i->f = open(s, 0);
 	if(i->f < 0) {
-		yyerror("%ca: %r: %s", thechar, s);
+		yyerror("%Ca: %r: %s", thechar, s);
 		errorexit();
 	}
 	fi.c = 0;
@@ -121,8 +121,11 @@
 Sym*
 slookup(char *s)
 {
-
-	strcpy(symb, s);
+	strncpy(symb, s, NSYMB);
+	if(symb[NSYMB-1] != '\0'){
+		yyerror("symbol too long: %s", s);
+		errorexit();
+	}
 	return lookup();
 }
 
@@ -130,15 +133,17 @@
 lookup(void)
 {
 	Sym *s;
-	long h;
+	ulong h;
 	char *p;
-	int c, l;
+	int c, n;
 
 	h = 0;
-	for(p=symb; c = *p; p++)
-		h = h+h+h + c;
-	l = (p - symb) + 1;
-	if(h < 0)
+	for(p=symb; *p;) {
+		h = h * 3;
+		h += *p++;
+	}
+	n = (p - symb) + 1;
+	if((long)h < 0)
 		h = ~h;
 	h %= NHASH;
 	c = symb[0];
@@ -145,16 +150,17 @@
 	for(s = hash[h]; s != S; s = s->link) {
 		if(s->name[0] != c)
 			continue;
-		if(memcmp(s->name, symb, l) == 0)
+		if(strcmp(s->name, symb) == 0)
 			return s;
 	}
 	s = alloc(sizeof(*s));
-	s->name = alloc(l);
-	memmove(s->name, symb, l);
+	s->name = alloc(n);
+	memmove(s->name, symb, n);
 
 	s->link = hash[h];
 	hash[h] = s;
 	syminit(s);
+
 	return s;
 }
 
@@ -220,6 +226,8 @@
 		cp = symb;
 
 	aloop:
+		if(cp >= &symb[NSYMB-1])
+			goto toolong;
 		*cp++ = c;
 		c = GETC();
 		if(isalpha(c) || isdigit(c) || c == '_' || c == '$')
@@ -295,6 +303,8 @@
 		for(;;) {
 			if(!isdigit(c))
 				break;
+			if(cp >= &symb[NSYMB-1])
+				goto toolong;
 			*cp++ = c;
 			c = GETC();
 		}
@@ -316,6 +326,8 @@
 
 	casedot:
 		for(;;) {
+			if(cp >= &symb[NSYMB-1])
+				goto toolong;
 			*cp++ = c;
 			c = GETC();
 			if(!isdigit(c))
@@ -326,13 +338,19 @@
 		goto caseout;
 
 	casee:
+		if(cp >= &symb[NSYMB-1])
+			goto toolong;
 		*cp++ = 'e';
 		c = GETC();
 		if(c == '+' || c == '-') {
+			if(cp >= &symb[NSYMB-1])
+				goto toolong;
 			*cp++ = c;
 			c = GETC();
 		}
 		while(isdigit(c)) {
+			if(cp >= &symb[NSYMB-1])
+				goto toolong;
 			*cp++ = c;
 			c = GETC();
 		}
@@ -409,6 +427,10 @@
 	}
 	peekc = c1;
 	return c;
+toolong:
+	yyerror("token too long: %.*s...", utfnlen(symb, cp-symb), symb);
+	errorexit();
+	return -1;
 }
 
 int
--- a/sys/src/cmd/ka/lex.c
+++ b/sys/src/cmd/ka/lex.c
@@ -38,7 +38,7 @@
 		break;
 	} ARGEND
 	if(*argv == 0) {
-		print("usage: %ca [-options] file.s\n", thechar);
+		print("usage: %Ca [-options] file.s\n", thechar);
 		errorexit();
 	}
 	if(argc > 1 && systemtype(Windows)){
@@ -92,10 +92,10 @@
 int
 assemble(char *file)
 {
-	char ofile[100], incfile[20], *p;
+	char *ofile, *p;
 	int i, of;
 
-	strcpy(ofile, file);
+	ofile = strdup(file);
 	p = utfrrune(ofile, pathchar());
 	if(p) {
 		include[0] = ofile;
@@ -103,16 +103,13 @@
 	} else
 		p = ofile;
 	if(outfile == 0) {
-		outfile = p;
-		if(outfile){
+		if(p){
+			outfile = p;
 			p = utfrrune(outfile, '.');
 			if(p)
 				if(p[1] == 's' && p[2] == 0)
 					p[0] = 0;
-			p = utfrune(outfile, 0);
-			p[0] = '.';
-			p[1] = thechar;
-			p[2] = 0;
+			outfile = smprint("%s.%C", outfile, thechar);
 		} else
 			outfile = "/dev/null";
 	}
@@ -120,15 +117,13 @@
 	if(p) {
 		setinclude(p);
 	} else {
-		if(systemtype(Plan9)) {
-			sprint(incfile,"/%s/include", thestring);
-			setinclude(strdup(incfile));
-		}
+		if(systemtype(Plan9))
+			setinclude(smprint("/%s/include", thestring));
 	}
 
 	of = mycreat(outfile, 0664);
 	if(of < 0) {
-		yyerror("%ca: cannot create %s", thechar, outfile);
+		yyerror("%Ca: cannot create %s", thechar, outfile);
 		errorexit();
 	}
 	Binit(&obuf, of, OWRITE);
--- a/sys/src/cmd/qa/lex.c
+++ b/sys/src/cmd/qa/lex.c
@@ -38,7 +38,7 @@
 		break;
 	} ARGEND
 	if(*argv == 0) {
-		print("usage: %ca [-options] file.s\n", thechar);
+		print("usage: %Ca [-options] file.s\n", thechar);
 		errorexit();
 	}
 	if(argc > 1 && systemtype(Windows)){
@@ -92,38 +92,38 @@
 int
 assemble(char *file)
 {
-	char ofile[100], incfile[20], *p;
+	char *ofile, *p;
 	int i, of;
 
-	strcpy(ofile, file);
-	if(p = strrchr(ofile, pathchar())) {
+	ofile = strdup(file);
+	p = utfrrune(ofile, pathchar());
+	if(p) {
 		include[0] = ofile;
 		*p++ = 0;
 	} else
 		p = ofile;
 	if(outfile == 0) {
-		outfile = p;
-		if(p = strrchr(outfile, '.'))
-			if(p[1] == 's' && p[2] == 0)
-				p[0] = 0;
-		p = strrchr(outfile, 0);
-		p[0] = '.';
-		p[1] = thechar;
-		p[2] = 0;
+		if(p){
+			outfile = p;
+			p = utfrrune(outfile, '.');
+			if(p)
+				if(p[1] == 's' && p[2] == 0)
+					p[0] = 0;
+			outfile = smprint("%s.%C", outfile, thechar);
+		} else
+			outfile = "/dev/null";
 	}
 	p = getenv("INCLUDE");
 	if(p) {
 		setinclude(p);
 	} else {
-		if(systemtype(Plan9)) {
-			sprint(incfile,"/%s/include", thestring);
-			setinclude(strdup(incfile));
-		}
+		if(systemtype(Plan9))
+			setinclude(smprint("/%s/include", thestring));
 	}
 
 	of = mycreat(outfile, 0664);
 	if(of < 0) {
-		yyerror("%ca: cannot create %s", thechar, outfile);
+		yyerror("%Ca: cannot create %s", thechar, outfile);
 		errorexit();
 	}
 	Binit(&obuf, of, OWRITE);
--- a/sys/src/cmd/va/lex.c
+++ b/sys/src/cmd/va/lex.c
@@ -42,7 +42,7 @@
 		break;
 	} ARGEND
 	if(*argv == 0) {
-		print("usage: %ca [-options] file.s\n", thechar);
+		print("usage: %Ca [-options] file.s\n", thechar);
 		errorexit();
 	}
 	if(argc > 1 && systemtype(Windows)){
@@ -96,10 +96,10 @@
 int
 assemble(char *file)
 {
-	char ofile[100], incfile[20], *p;
+	char *ofile, *p;
 	int i, of;
 
-	strcpy(ofile, file);
+	ofile = strdup(file);
 	p = utfrrune(ofile, pathchar());
 	if(p) {
 		include[0] = ofile;
@@ -107,16 +107,13 @@
 	} else
 		p = ofile;
 	if(outfile == 0) {
-		outfile = p;
-		if(outfile){
+		if(p){
+			outfile = p;
 			p = utfrrune(outfile, '.');
 			if(p)
 				if(p[1] == 's' && p[2] == 0)
 					p[0] = 0;
-			p = utfrune(outfile, 0);
-			p[0] = '.';
-			p[1] = thechar;
-			p[2] = 0;
+			outfile = smprint("%s.%C", outfile, thechar);
 		} else
 			outfile = "/dev/null";
 	}
@@ -124,15 +121,13 @@
 	if(p) {
 		setinclude(p);
 	} else {
-		if(systemtype(Plan9)) {
-			sprint(incfile,"/%s/include", thestring);
-			setinclude(strdup(incfile));
-		}
+		if(systemtype(Plan9))
+			setinclude(smprint("/%s/include", thestring));
 	}
 
 	of = mycreat(outfile, 0664);
 	if(of < 0) {
-		yyerror("%ca: cannot create %s", thechar, outfile);
+		yyerror("%Ca: cannot create %s", thechar, outfile);
 		errorexit();
 	}
 	Binit(&obuf, of, OWRITE);