From 9d471caaae56a734728c3b19755adfe26f6c4f4c Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Thu, 22 Nov 2018 12:44:15 +0100 Subject: [PATCH] snap: check for overflows, cleanup error handling --- sys/src/cmd/snap/read.c | 51 ++++++++++++++++++--------------------- sys/src/cmd/snap/snap.c | 12 +++------ sys/src/cmd/snap/snapfs.c | 13 +++------- sys/src/cmd/snap/take.c | 39 ++++++++++-------------------- sys/src/cmd/snap/util.c | 18 +++++--------- 5 files changed, 51 insertions(+), 82 deletions(-) diff --git a/sys/src/cmd/snap/read.c b/sys/src/cmd/snap/read.c index f1e552cbe..035deebf1 100644 --- a/sys/src/cmd/snap/read.c +++ b/sys/src/cmd/snap/read.c @@ -3,14 +3,6 @@ #include #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 @@ findpage(Proc *plist, long pid, int type, uvlong off) 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 @@ findpage(Proc *plist, long pid, int type, uvlong off) 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 @@ readdata(Biobuf *b) { 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 @@ readseg(Seg **ps, Biobuf *b, Proc *plist) 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 @@ readseg(Seg **ps, Biobuf *b, Proc *plist) 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 @@ readseg(Seg **ps, Biobuf *b, Proc *plist) 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 @@ readseg(Seg **ps, Biobuf *b, Proc *plist) break; default: fprint(2, "bad type char %#.2ux\n", t); - panic("error reading segment"); + sysfatal("error reading segment"); } } return s; @@ -205,9 +199,9 @@ readsnap(Biobuf *b) 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 @@ readsnap(Biobuf *b) 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; itext, b, plist); else - panic("unknown section"); + sysfatal("unknown section"); } return plist; } diff --git a/sys/src/cmd/snap/snap.c b/sys/src/cmd/snap/snap.c index 16912be34..a64d688aa 100644 --- a/sys/src/cmd/snap/snap.c +++ b/sys/src/cmd/snap/snap.c @@ -33,15 +33,11 @@ main(int argc, char **argv) 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"; diff --git a/sys/src/cmd/snap/snapfs.c b/sys/src/cmd/snap/snapfs.c index d27305ae5..6b695f572 100644 --- a/sys/src/cmd/snap/snapfs.c +++ b/sys/src/cmd/snap/snapfs.c @@ -154,16 +154,11 @@ main(int argc, char **argv) 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; diff --git a/sys/src/cmd/snap/take.c b/sys/src/cmd/snap/take.c index 3ef884fd8..64a454fbf 100644 --- a/sys/src/cmd/snap/take.c +++ b/sys/src/cmd/snap/take.c @@ -20,6 +20,7 @@ sumr(ulong sum, void *buf, int n) return sum; } +char zeros[Pagesize]; static ulong npage; static Page *pgtab[1<<10]; @@ -27,43 +28,27 @@ Page* 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; qlink) + 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]; 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 @@ stackptr(Proc *proc, int fd) char *q; Fhdr f; Reglist *r; - long textoff; + vlong textoff; int i; Data *dreg; @@ -160,7 +145,9 @@ stackptr(Proc *proc, int fd) if(textoff == -1) return 0; - seek(fd, textoff, 0); + if(seek(fd, textoff, 0) < 0) + return 0; + if(crackhdr(fd, &f) == 0) return 0; diff --git a/sys/src/cmd/snap/util.c b/sys/src/cmd/snap/util.c index bfca991ed..bbde6293c 100644 --- a/sys/src/cmd/snap/util.c +++ b/sys/src/cmd/snap/util.c @@ -8,10 +8,8 @@ emalloc(ulong n) { 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 @@ void* 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 @@ char* 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; }