snap: check for overflows, cleanup error handling

This commit is contained in:
cinap_lenrek 2018-11-22 12:44:15 +01:00
parent 3363693205
commit 9d471caaae
5 changed files with 51 additions and 82 deletions

View file

@ -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 @@ 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; i<n; i++)
@ -241,7 +238,7 @@ readsnap(Biobuf *b)
} else if(strcmp(q, "text") == 0)
readseg(&p->text, b, plist);
else
panic("unknown section");
sysfatal("unknown section");
}
return plist;
}

View file

@ -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";

View file

@ -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;

View file

@ -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; 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];
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;

View file

@ -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;
}