snap: check for overflows, cleanup error handling
This commit is contained in:
parent
3363693205
commit
9d471caaae
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue