ref: 9d471caaae56a734728c3b19755adfe26f6c4f4c
parent: 33636932054f74c7a922a9713a9229d6d5fc7f38
author: cinap_lenrek <[email protected]>
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;
}