shithub: riscv

Download patch

ref: 9d471caaae56a734728c3b19755adfe26f6c4f4c
parent: 33636932054f74c7a922a9713a9229d6d5fc7f38
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Thu Nov 22 07:44:15 EST 2018

snap: check for overflows, cleanup error handling

--- a/sys/src/cmd/snap/read.c
+++ b/sys/src/cmd/snap/read.c
@@ -3,14 +3,6 @@
 #include <bio.h>
 #include "snap.h"
 
-void
-panic(char *s)
-{
-	fprint(2, "%s\n", s);
-	abort();
-	exits(s);
-}
-
 static Proc*
 findpid(Proc *plist, long pid)
 {
@@ -30,11 +22,11 @@
 
 	plist = findpid(plist, pid);
 	if(plist == nil)
-		panic("can't find referenced pid");
+		sysfatal("can't find referenced pid");
 
 	if(type == 't') {
 		if(off%Pagesize)
-			panic("bad text offset alignment");
+			sysfatal("bad text offset alignment");
 		s = plist->text;
 		if(off >= s->len)
 			return nil;
@@ -53,7 +45,7 @@
 
 	off -= s->offset;
 	if(off%Pagesize)
-		panic("bad mem offset alignment");
+		sysfatal("bad mem offset alignment");
 
 	return s->pg[off/Pagesize];
 }
@@ -116,15 +108,17 @@
 {
 	Data *d;
 	char str[32];
-	long len;
+	ulong len;
 
 	if(Bread(b, str, 12) != 12)
-		panic("can't read data hdr\n");
-
-	len = atoi(str);
+		sysfatal("can't read data hdr: %r");
+	str[12] = 0;
+	len = strtoul(str, 0, 0);
+	if(len + sizeof(*d) < sizeof(*d))
+		sysfatal("data len too large");
 	d = emalloc(sizeof(*d) + len);
-	if(Bread(b, d->data, len) != len)
-		panic("can't read data body\n");
+	if(len && Bread(b, d->data, len) != len)
+		sysfatal("can't read data body");
 	d->len = len;
 	return d;
 }
@@ -140,12 +134,12 @@
 	ulong pid;
 	uvlong off;
 	char buf[Pagesize];
-	static char zero[Pagesize];
+	extern char zeros[];
 
 	s = emalloc(sizeof *s);
 	if(Breaduvlong(b, &s->offset) < 0
 	|| Breaduvlong(b, &s->len) < 0)
-		panic("error reading segment");
+		sysfatal("error reading segment: %r");
 
 	npg = (s->len + Pagesize-1)/Pagesize;
 	s->npg = npg;
@@ -164,7 +158,7 @@
 
 		switch(t = Bgetc(b)) {
 		case 'z':
-			pp[i] = datapage(zero, len);
+			pp[i] = datapage(zeros, len);
 			if(debug)
 				fprint(2, "0x%.8llux all zeros\n", s->offset+(uvlong)i*Pagesize);
 			break;
@@ -172,10 +166,10 @@
 		case 't':
 			if(Breadulong(b, &pid) < 0 
 			|| Breaduvlong(b, &off) < 0)
-				panic("error reading segment x");
+				sysfatal("error reading segment x: %r");
 			pp[i] = findpage(plist, pid, t, off);
 			if(pp[i] == nil)
-				panic("bad page reference in snapshot");
+				sysfatal("bad page reference in snapshot");
 			if(debug)
 				fprint(2, "0x%.8llux same as %s pid %lud 0x%.8llux\n",
 					s->offset+(uvlong)i*Pagesize, t=='m'?"mem":"text", pid, off);
@@ -189,7 +183,7 @@
 			break;
 		default:
 			fprint(2, "bad type char %#.2ux\n", t);
-			panic("error reading segment");
+			sysfatal("error reading segment");
 		}
 	}
 	return s;
@@ -205,9 +199,9 @@
 	int i, n;
 
 	if((q = Brdline(b, '\n')) == nil)
-		panic("error reading snapshot file");
+		sysfatal("error reading snapshot file");
 	if(strncmp(q, "process snapshot", strlen("process snapshot")) != 0)
-		panic("bad snapshot file format");
+		sysfatal("bad snapshot file format");
 
 	plist = nil;
 	while(q = Brdline(b, '\n')) {
@@ -232,8 +226,11 @@
 			continue;
 		if(strcmp(q, "mem") == 0) {
 			if(Bread(b, buf, 12) != 12) 
-				panic("can't read memory section");
+				sysfatal("can't read memory section: %r");
+			buf[12] = 0;
 			n = atoi(buf);
+			if(n <= 0 || n > 16)
+				sysfatal("bad segment count: %d", n);
 			p->nseg = n;
 			p->seg = emalloc(n*sizeof(*p->seg));
 			for(i=0; i<n; i++)
@@ -241,7 +238,7 @@
 		} else if(strcmp(q, "text") == 0)
 			readseg(&p->text, b, plist);
 		else
-			panic("unknown section");
+			sysfatal("unknown section");
 	}
 	return plist;
 }
--- a/sys/src/cmd/snap/snap.c
+++ b/sys/src/cmd/snap/snap.c
@@ -33,15 +33,11 @@
 		usage();
 
 	/* get kernel compilation time */
-	if((d = dirstat("#/")) == nil) {
-		fprint(2, "cannot stat #/ ???\n");
-		exits("stat");
-	}
+	if((d = dirstat("#/")) == nil)
+		sysfatal("cannot stat #/: %r");
 
-	if((b = Bopen(ofile, OWRITE)) == nil) {
-		fprint(2, "cannot write to \"%s\"\n", ofile);
-		exits("Bopen");
-	}
+	if((b = Bopen(ofile, OWRITE)) == nil)
+		sysfatal("cannot write to \"%s\": %r", ofile);
 
 	if((user = getuser()) == nil)
 		user = "gre";
--- a/sys/src/cmd/snap/snapfs.c
+++ b/sys/src/cmd/snap/snapfs.c
@@ -154,16 +154,11 @@
 	if(argc != 1)
 		usage();
 
-	b = Bopen(argv[0], OREAD);
-	if(b == nil) {
-		fprint(2, "cannot open \"%s\": %r\n", argv[0]);
-		exits("Bopen");
-	}
+	if((b = Bopen(argv[0], OREAD)) == nil)
+		sysfatal("cannot open \"%s\": %r", argv[0]);
 
-	if((plist = readsnap(b)) == nil) {
-		fprint(2, "readsnap fails\n");
-		exits("readsnap");
-	}
+	if((plist = readsnap(b)) == nil)
+		sysfatal("readsnap fails");
 
 	tree = alloctree(nil, nil, DMDIR|0555, nil);
 	fs.tree = tree;
--- a/sys/src/cmd/snap/take.c
+++ b/sys/src/cmd/snap/take.c
@@ -20,6 +20,7 @@
 	return sum;
 }
 
+char zeros[Pagesize];
 static ulong npage;
 static Page *pgtab[1<<10];
 
@@ -27,31 +28,15 @@
 datapage(char *p, long len)
 {
 	Page *pg;
-	char *q, *ep;
-	long	sum;
-	int iszero;
+	ulong sum;
 
-	if(len > Pagesize) {
-		fprint(2, "datapage cannot handle pages > %d\n", Pagesize);
-		exits("datapage");
-	}
+	if(len > Pagesize)
+		sysfatal("datapage cannot handle pages > %d", Pagesize);
 
 	sum = sumr(0, p, len) & (nelem(pgtab)-1);
-	if(sum == 0) {
-		iszero = 1;
-		for(q=p, ep=p+len; q<ep; q++)
-			if(*q != 0) {
-				iszero = 0;
-				break;
-			}
-	} else
-		iszero = 0;
-
-	for(pg = pgtab[sum]; pg; pg=pg->link)
+	for(pg = pgtab[sum]; pg != nil; pg=pg->link)
 		if(pg->len == len && memcmp(pg->data, p, len) == 0)
-			break;
-	if(pg)
-		return pg;
+			return pg;
 
 	pg = emalloc(sizeof(*pg)+len);
 	pg->data = (char*)&pg[1];
@@ -58,12 +43,12 @@
 	pg->type = 0;
 	pg->len = len;
 	memmove(pg->data, p, len);
-	pg->link = pgtab[sum];
-	pgtab[sum] = pg;
-	if(iszero) {
+	if(sum == 0 && memcmp(zeros, p, len) == 0) {
 		pg->type = 'z';
 		pg->written = 1;
 	}
+	pg->link = pgtab[sum];
+	pgtab[sum] = pg;
 
 	++npage;
 	return pg;
@@ -148,7 +133,7 @@
 	char *q;
 	Fhdr f;
 	Reglist *r;
-	long textoff;
+	vlong textoff;
 	int i;
 	Data *dreg;
 
@@ -160,7 +145,9 @@
 	if(textoff == -1)
 		return 0;
 
-	seek(fd, textoff, 0);
+	if(seek(fd, textoff, 0) < 0)
+		return 0;
+
 	if(crackhdr(fd, &f) == 0)
 		return 0;
 
--- a/sys/src/cmd/snap/util.c
+++ b/sys/src/cmd/snap/util.c
@@ -8,10 +8,8 @@
 {
 	void *v;
 	v = malloc(n);
-	if(v == nil){
-		fprint(2, "out of memory\n");
-		exits("memory");
-	}
+	if(v == nil)
+		sysfatal("out of memory");
 	memset(v, 0, n);
 	return v;
 }
@@ -20,10 +18,8 @@
 erealloc(void *v, ulong n)
 {
 	v = realloc(v, n);
-	if(v == nil) {
-		fprint(2, "out of memory\n");
-		exits("memory");
-	}
+	if(v == nil && n != 0)
+		sysfatal("out of memory");
 	return v;
 }
 
@@ -31,9 +27,7 @@
 estrdup(char *s)
 {
 	s = strdup(s);
-	if(s == nil) {
-		fprint(2, "out of memory\n");
-		exits("memory");
-	}
+	if(s == nil)
+		sysfatal("out of memory");
 	return s;
 }