* [9front] 5e: add support for memory constraint checking
@ 2023-09-10 1:46 ori
0 siblings, 0 replies; only message in thread
From: ori @ 2023-09-10 1:46 UTC (permalink / raw)
To: 9front
similar to valgrind, '5e -c' is growing support for finding
use-after-free, out of bounds reads, and other similar bugs.
It works by maintaing a bitmap with 2 bits for each byte
in the program segments: one for whether the bit has been
written to (initialized), and one for whether the bit has
been allocated with malloc, realloc, or a raw sbrk.
So far, it seems to be working, though there are still
a few unresolved issues:
- It doesn't know about the APE allocator, which
means that it will report uninitialized memory
for nearly all APE programs.
- It doesn't know about how much stack a function
uses, so it will flag it as initialized even
after a function returns
- It has not been tested heavily, especially not
on concurrent code.
And almost certainly a few others. But so far, it's been
quite useful, and I'd be happy to expand it to make it
more useful.
To use it, simply do something like:
cd /sys/src/cmd && objtype=arm mk 5.ls
5e -c 5.ls
And the emulated program will either work as normal (but
slower), or will die.
diff 41a932f370cee1423827e0c0175ba457d3cacd82 uncommitted
--- a/sys/src/cmd/5e/5e.c
+++ b/sys/src/cmd/5e/5e.c
@@ -6,6 +6,12 @@
int vfp = 1;
int nflag, pflag, bflag;
+int check;
+u32int mallocaddr;
+u32int freeaddr;
+u32int reallocaddr;
+u32int setmalloctagaddr;
+u32int setrealloctagaddr;
Ref nproc;
void
@@ -85,17 +91,22 @@
static void
dotext(int argc, char **argv)
{
- char *file;
-
+ char *file, **p, *path[] = {"/bin", ".", nil};
+
if(**argv == '/' || **argv == '.' || **argv == '#') {
if(loadtext(*argv, argc, argv) < 0)
sysfatal("loadtext: %r");
return;
}
- file = smprint("/bin/%s", *argv);
- if(loadtext(file, argc, argv) < 0)
- sysfatal("loadtext: %r");
- free(file);
+ for(p = path; *p; p++){
+ file = smprint("%s/%s", *p, *argv);
+ if(loadtext(file, argc, argv) >= 0){
+ free(file);
+ return;
+ }
+ free(file);
+ }
+ sysfatal("loadtext: %r");
}
void
@@ -107,6 +118,7 @@
case 'b': bflag++; break;
case 'f': vfp = 1; break;
case 'F': vfp = 0; break;
+ case 'c': check++; break;
default: usage();
} ARGEND;
if(argc < 1)
@@ -118,7 +130,7 @@
atexit(cleanup);
if(!nflag)
adjustns();
- if(pflag)
+ if(pflag || check)
initfs("armproc", "/proc");
initproc();
dotext(argc, argv);
--- a/sys/src/cmd/5e/arm.c
+++ b/sys/src/cmd/5e/arm.c
@@ -19,6 +19,35 @@
fH = 1<<5,
};
+u32int mallocaddr;
+u32int freeaddr;
+u32int reallocaddr;
+u32int sbrkaddr;
+u32int setmalloctagaddr;
+u32int setrealloctagaddr;
+
+static u32int
+arg(int n)
+{
+ /* no locking necessary, since we're on the stack */
+ if(n == 0)
+ return P->R[0];
+ else
+ return *(u32int*) vaddrnol(P->R[13] + 4 + 4 * n, 4, ARD);
+}
+
+static u32int
+asize(int n)
+{
+ /* keep in sync with Bhdr in pool.c */
+ u32int a;
+
+ a = *(u32int*) vaddrnol(P->R[13] + 4 + 4 * n, 4, ARD);
+ if(a == 0)
+ return ~0;
+ return *(ulong*) vaddrnol(a-4, 4, 0);
+}
+
void
invalid(u32int instr)
{
@@ -117,27 +146,32 @@
if(instr & fW)
invalid(instr);
addr = P->R[15] + 4;
- }
- else
+ }else
addr = *Rn;
if(instr & fP)
addr += offset;
if((instr & fB) == 0)
addr = evenaddr(addr, 3);
- targ = vaddr(addr, (instr & fB) == 0 ? 4 : 1, &seg);
switch(instr & (fB | fL)) {
case 0:
+ targ = vaddr(addr, 4, AWR, &seg);
*(u32int*) targ = *Rd;
break;
case fB:
+ targ = vaddr(addr, 1, AWR, &seg);
*(u8int*) targ = *Rd;
break;
case fL:
+ targ = vaddr(addr, 4, ARD, &seg);
*Rd = *(u32int*) targ;
break;
case fB | fL:
+ targ = vaddr(addr, 1, ARD, &seg);
*Rd = *(u8int*) targ;
break;
+ default:
+ targ = nil;
+ abort();
}
if(Rd == P->R + 15 && !(instr & fL)) {
if(instr & fB)
@@ -169,7 +203,7 @@
addr = *Rn;
if((instr & fB) == 0)
addr = evenaddr(addr, 3);
- targ = (u32int *) vaddr(addr & ~3, 4, &seg);
+ targ = (u32int *) vaddr(addr & ~3, 4, ARD|AWR, &seg);
do {
old = *targ;
new = *Rm;
@@ -196,16 +230,23 @@
if(type) {
res2 = (u64int)a - b + *carry - 1;
res1 = res2;
- if(((a ^ b) & (1<<31)) && !((b ^ res1) & (1<<31))) *overflow = 1;
- else *overflow = 0;
- if(res2 & 0x100000000LL) *carry = 0;
- else *carry = 1;
+ if(((a ^ b) & (1<<31)) && !((b ^ res1) & (1<<31)))
+ *overflow = 1;
+ else
+ *overflow = 0;
+ if(res2 & 0x100000000LL)
+ *carry = 0;
+ else
+ *carry = 1;
} else {
res2 = (u64int)a + b + *carry;
res1 = res2;
- if(!((a ^ b) & (1<<31)) && ((b ^ res1) & (1<<31))) *overflow = 1;
- else *overflow = 0;
- if(res2 & 0x100000000LL) *carry = 1;
+ if(!((a ^ b) & (1<<31)) && ((b ^ res1) & (1<<31)))
+ *overflow = 1;
+ else
+ *overflow = 0;
+ if(res2 & 0x100000000LL)
+ *carry = 1;
else *carry = 0;
}
return res1;
@@ -276,14 +317,44 @@
branch(u32int instr)
{
long offset;
+ u32int npc;
offset = instr & ((1<<24) - 1);
if(offset & (1<<23))
offset |= ~((1 << 24) - 1);
offset *= 4;
- if(instr & fLi)
+ npc = P->R[15] + offset + 4;
+ if(instr & fLi){
P->R[14] = P->R[15];
- P->R[15] += offset + 4;
+ if(check && P->hookpc == 0){
+ if(npc == mallocaddr){
+ P->hookarg[0] = arg(1); /* size */
+ P->hookfn = hookmalloc;
+ P->hookpc = P->R[15];
+ }else if(npc == reallocaddr){
+ P->hookarg[0] = arg(1); /* old */
+ P->hookarg[1] = asize(1); /* oldsz */
+ P->hookarg[2] = arg(2); /* newsz */
+ P->hookfn = hookrealloc;
+ P->hookpc = P->R[15];
+ }else if(npc == freeaddr){
+ P->hookarg[0] = arg(1);
+ P->hookarg[1] = asize(1);
+ P->hookfn = hookfree;
+ P->hookpc = P->R[15];
+ }else if(npc == sbrkaddr){
+ P->hookarg[0] = arg(0);
+ P->hookarg[1] = asize(1);
+ P->hookfn = hookfree;
+ P->hookpc = P->R[15];
+ }else if(npc == setmalloctagaddr){
+ P->hookpc = P->R[15];
+ }else if(npc == setrealloctagaddr){
+ P->hookpc = P->R[15];
+ }
+ }
+ }
+ P->R[15] = npc;
}
static void
@@ -313,11 +384,21 @@
if(instr & fH)
target = evenaddr(target, 1);
switch(instr & (fSg | fH | fL)) {
- case fSg: *(u8int*) vaddr(target, 1, &seg) = *Rd; break;
- case fSg | fL: *Rd = (long) *(char*) vaddr(target, 1, &seg); break;
- case fH: case fSg | fH: *(u16int*) vaddr(target, 2, &seg) = *Rd; break;
- case fH | fL: *Rd = *(u16int*) vaddr(target, 2, &seg); break;
- case fH | fL | fSg: *Rd = (long) *(short*) vaddr(target, 2, &seg); break;
+ case fSg:
+ *(u8int*) vaddr(target, 1, AWR, &seg) = *Rd;
+ break;
+ case fSg | fL:
+ *Rd = (long) *(char*) vaddr(target, 1, ARD, &seg);
+ break;
+ case fH: case fSg | fH:
+ *(u16int*) vaddr(target, 2, AWR, &seg) = *Rd;
+ break;
+ case fH | fL:
+ *Rd = *(u16int*) vaddr(target, 2, ARD, &seg);
+ break;
+ case fH | fL | fSg:
+ *Rd = (long) *(short*) vaddr(target, 2, ARD, &seg);
+ break;
}
segunlock(seg);
if(!(instr & fP))
@@ -346,9 +427,9 @@
if(instr & fP)
targ += 4;
if(instr & fL)
- P->R[i] = *(u32int*) vaddr(targ, 4, &seg);
+ P->R[i] = *(u32int*) vaddr(targ, 4, ARD, &seg);
else
- *(u32int*) vaddr(targ, 4, &seg) = P->R[i];
+ *(u32int*) vaddr(targ, 4, AWR, &seg) = P->R[i];
segunlock(seg);
if(!(instr & fP))
targ += 4;
@@ -360,9 +441,9 @@
if(instr & fP)
targ -= 4;
if(instr & fL)
- P->R[i] = *(u32int*) vaddr(targ, 4, &seg);
+ P->R[i] = *(u32int*) vaddr(targ, 4, ARD, &seg);
else
- *(u32int*) vaddr(targ, 4, &seg) = P->R[i];
+ *(u32int*) vaddr(targ, 4, AWR, &seg) = P->R[i];
segunlock(seg);
if(!(instr & fP))
targ -= 4;
@@ -406,7 +487,8 @@
Rs = P->R + ((instr >> 8) & 15);
RdL = P->R + ((instr >> 12) & 15);
RdH = P->R + ((instr >> 16) & 15);
- if(RdL == RdH || RdH == Rm || RdL == Rm || Rm == P->R + 15 || Rs == P->R + 15 || RdL == P->R + 15 || RdH == P->R + 15)
+ if(RdL == RdH || RdH == Rm || RdL == Rm || Rm == P->R + 15
+ || Rs == P->R + 15 || RdL == P->R + 15 || RdH == P->R + 15)
invalid(instr);
if(instr & (1<<22))
res = ((vlong)*(int*)Rs) * *(int*)Rm;
@@ -441,7 +523,7 @@
invalid(instr);
addr = evenaddr(*Rn, 3);
if(instr & fS) {
- targ = vaddr(addr, 4, &seg);
+ targ = vaddr(addr, 4, ARD, &seg);
*Rd = *targ;
P->lladdr = addr;
P->llval = *Rd;
@@ -450,7 +532,7 @@
Rm = P->R + (instr & 15);
if(Rm == P->R + 15)
invalid(instr);
- targ = vaddr(addr, 4, &seg);
+ targ = vaddr(addr, 4, ARD|AWR, &seg);
/*
* this is not quite correct as we will succeed even
@@ -486,19 +568,17 @@
u32int instr;
Segment *seg;
- instr = *(u32int*) vaddr(P->R[15], 4, &seg);
+ instr = *(u32int*) vaddr(P->R[15], 4, 0, &seg);
segunlock(seg);
if(fulltrace) {
print("%d ", P->pid);
- if(havesymbols) {
- Symbol s;
- char buf[512];
-
- if(findsym(P->R[15], CTEXT, &s) >= 0)
- print("%s ", s.name);
- if(fileline(buf, 512, P->R[15]) >= 0)
- print("%s ", buf);
- }
+ Symbol s;
+ char buf[512];
+
+ if(findsym(P->R[15], CTEXT, &s) >= 0)
+ print("%s ", s.name);
+ if(fileline(buf, 512, P->R[15]) >= 0)
+ print("%s ", buf);
print("%.8ux %.8ux %c%c%c%c\n", P->R[15], instr,
(P->CPSR & flZ) ? 'Z' : ' ',
(P->CPSR & flC) ? 'C' : ' ',
@@ -505,6 +585,12 @@
(P->CPSR & flN) ? 'N' : ' ',
(P->CPSR & flV) ? 'V' : ' '
);
+ }
+ if(P->R[15] == P->hookpc){
+ if(P->hookfn)
+ P->hookfn(P->hookarg);
+ P->hookpc = 0;
+ P->hookfn = nil;
}
P->R[15] += 4;
switch(instr >> 28) {
--- a/sys/src/cmd/5e/dat.h
+++ b/sys/src/cmd/5e/dat.h
@@ -24,6 +24,16 @@
SEGSTACK,
};
+enum {
+ ARD = 1<<0,
+ AWR = 1<<1,
+};
+
+enum {
+ MARKALLOC = 1<<0,
+ MARKINIT = 1<<1,
+};
+
struct Process {
Process *prev, *next; /* linked list (for fs) */
int pid;
@@ -50,6 +60,10 @@
jmp_buf notejmp;
char notes[ERRMAX][NNOTE];
long notein, noteout;
+
+ u32int hookpc;
+ u32int hookarg[3];
+ void (*hookfn)(u32int*);
};
int vfp;
@@ -60,6 +74,15 @@
extern Ref nproc;
extern Process plist;
extern Lock plistlock;
+extern int check;
+extern u32int mallocaddr;
+extern u32int freeaddr;
+extern u32int reallocaddr;
+extern u32int sbrkaddr;
+extern u32int setmalloctagaddr;
+extern u32int setrealloctagaddr;
+extern uvlong okrange[];
+extern int nokrange;
enum {
SEGFLLOCK = 1,
@@ -71,6 +94,7 @@
RWLock rw; /* lock for SEGFLLOCK segments */
u32int start, size;
void *data;
+ uchar *shadow;
Ref *dref;
};
@@ -82,6 +106,5 @@
};
#define fulltrace 0
-#define havesymbols 0
#define ultraverbose 0
#define systrace 0
--- a/sys/src/cmd/5e/fns.h
+++ b/sys/src/cmd/5e/fns.h
@@ -4,8 +4,8 @@
void initproc(void);
int loadtext(char *, int, char **);
Segment *newseg(u32int, u32int, int);
-void *vaddr(u32int, u32int, Segment **);
-void *vaddrnol(u32int, u32int);
+void *vaddr(u32int, u32int, int, Segment **);
+void *vaddrnol(u32int, u32int, int);
void step(void);
void syscall(void);
void cherrstr(char *, ...);
@@ -31,6 +31,7 @@
void donote(char *, ulong);
void addnote(char *);
void dump(void);
+void dumpmap(Segment *, u32int, u32int, char *, ...);
void resetfpa(void);
void invalid(u32int);
u32int evenaddr(u32int,u32int);
@@ -42,3 +43,10 @@
void vfprmtransfer(u32int);
void vfpoperation(u32int);
void inittos(void);
+void initmem(void);
+void checkaccess(Segment*, u32int, u32int, int);
+void markvalid(Segment*, u32int, u32int, int);
+void markinvalid(Segment*, u32int, u32int, int);
+void hookmalloc(u32int*);
+void hookrealloc(u32int*);
+void hookfree(u32int*);
--- a/sys/src/cmd/5e/fpa.c
+++ b/sys/src/cmd/5e/fpa.c
@@ -44,13 +44,13 @@
addr = *Rn;
if(instr & fP)
addr += off;
- targ = vaddr(addr, 8, &seg);
+ targ = vaddr(addr, 8, 0, &seg);
switch(instr & (fT0 | fT1 | fL)) {
- case 0: *(float *) targ = *Fd; break;
- case fL: *Fd = *(float *) targ; break;
- case fT0: *(double *) targ = *Fd; break;
- case fT0 | fL: *Fd = *(double *) targ; break;
- default: invalid(instr);
+ case 0: *(float *) targ = *Fd; break;
+ case fL: *Fd = *(float *) targ; break;
+ case fT0: *(double *) targ = *Fd; break;
+ case fT0 | fL: *Fd = *(double *) targ; break;
+ default: invalid(instr);
}
segunlock(seg);
if(!(instr & fP))
--- a/sys/src/cmd/5e/mkfile
+++ b/sys/src/cmd/5e/mkfile
@@ -1,7 +1,7 @@
</$objtype/mkfile
TARG=5e
-OFILES=5e.$O seg.$O proc.$O util.$O arm.$O sys.$O fs.$O fpa.$O vfp.$O
+OFILES=5e.$O seg.$O proc.$O util.$O arm.$O sys.$O fs.$O fpa.$O vfp.$O chk.$O
HFILES=dat.h fns.h
BIN=/$objtype/bin
--- a/sys/src/cmd/5e/proc.c
+++ b/sys/src/cmd/5e/proc.c
@@ -120,17 +120,17 @@
P->R[1] = mach->utop - 4;
P->R[13] = sp;
- *(ulong *) vaddrnol(sp, 4) = argc;
+ *(ulong *) vaddrnol(sp, 4, AWR) = argc;
sp += 4;
ap = sp + (argc + 1) * 4;
for(i = 0; i < argc; i++) {
- *(ulong *) vaddrnol(sp, 4) = ap;
+ *(ulong *) vaddrnol(sp, 4, AWR) = ap;
sp += 4;
len = strlen(argv[i]) + 1;
- memcpy(vaddrnol(ap, len), argv[i], len);
+ memcpy(vaddrnol(ap, len, AWR), argv[i], len);
ap += len;
}
- *(ulong *) vaddrnol(sp, 4) = 0;
+ *(ulong *) vaddrnol(sp, 4, AWR) = 0;
inittos();
}
@@ -140,7 +140,7 @@
ulong tos;
tos = (mach->utop & ~7) - sizeof(Tos) * 2;
- ((Tos *) vaddrnol(tos, sizeof(Tos)))->pid = P->pid;
+ ((Tos *) vaddrnol(tos, sizeof(Tos), AWR))->pid = P->pid;
}
static int
@@ -195,12 +195,50 @@
return -1;
}
+u32int
+hookaddr(char *name)
+{
+ Symbol s;
+
+ if(lookup(name, nil, &s) == -1)
+ return -1;
+ return s.value;
+}
+
int
+getokrange(char *name, uvlong *bounds)
+{
+ uvlong addr;
+
+ if((addr = hookaddr(name)) == -1)
+ return 0;
+ if(fnbound(addr, bounds) == 0)
+ return 0;
+ return 2;
+}
+
+static void
+inithooks(void)
+{
+ mallocaddr = hookaddr("poolalloc");
+ reallocaddr = hookaddr("poolrealloc");
+ freeaddr = hookaddr("poolfree");
+ setmalloctagaddr = hookaddr("setmalloctag");
+ setrealloctagaddr = hookaddr("setrealloctag");
+ nokrange += getokrange("memmove", &okrange[nokrange]);
+ nokrange += getokrange("memcpy", &okrange[nokrange]);
+ nokrange += getokrange("memset", &okrange[nokrange]);
+ nokrange += getokrange("strchr", &okrange[nokrange]);
+ nokrange += getokrange("strcmp", &okrange[nokrange]);
+ nokrange += getokrange("strcpy", &okrange[nokrange]);
+}
+
+int
loadtext(char *file, int argc, char **argv)
{
int fd;
Fhdr fp;
- Segment *text, *data, *bss;
+ Segment *text, *data, *bss, *stk;
char buf[2];
fd = open(file, OREAD);
@@ -220,7 +258,13 @@
text = newseg(fp.txtaddr - fp.hdrsz, fp.txtsz + fp.hdrsz, SEGTEXT);
data = newseg(fp.dataddr, fp.datsz, SEGDATA);
bss = newseg(fp.dataddr + fp.datsz, fp.bsssz, SEGBSS);
- newseg((mach->utop & ~7) - STACKSIZE, STACKSIZE, SEGSTACK);
+ stk = newseg((mach->utop & ~7) - STACKSIZE, STACKSIZE, SEGSTACK);
+ if(check){
+ markvalid(text, 0, fp.txtsz+fp.hdrsz, MARKALLOC|MARKINIT);
+ markvalid(data, 0, fp.datsz, MARKALLOC|MARKINIT);
+ markvalid(bss, 0, fp.bsssz, MARKALLOC|MARKINIT);
+ markvalid(stk, 0, stk->size, MARKALLOC);
+ }
seek(fd, fp.txtoff - fp.hdrsz, 0);
if(readn(fd, text->data, fp.txtsz + fp.hdrsz) < fp.txtsz + fp.hdrsz)
sysfatal("%r");
@@ -229,8 +273,10 @@
sysfatal("%r");
memset(bss->data, 0, bss->size);
P->R[15] = fp.entry;
- if(havesymbols && syminit(fd, &fp) < 0)
+ if(syminit(fd, &fp) < 0)
fprint(2, "initializing symbol table: %r\n");
+ if(check)
+ inithooks();
close(fd);
fdclear(P->fd);
initstack(argc, argv);
@@ -380,7 +426,7 @@
clrex();
uregp = P->R[13] - 18 * 4;
- ureg = vaddrnol(uregp, 18 * 4);
+ ureg = vaddrnol(uregp, 18 * 4, 0);
memcpy(ureg, P->R, 15 * 4);
ureg[15] = type;
ureg[16] = P->CPSR;
@@ -387,10 +433,10 @@
ureg[17] = P->R[15];
P->R[13] = uregp;
msgp = P->R[13] -= ERRMAX;
- msgb = vaddrnol(msgp, ERRMAX);
+ msgb = vaddrnol(msgp, ERRMAX, 0);
strncpy(msgb, msg, ERRMAX);
P->R[13] -= 3 * 4;
- sp = vaddrnol(P->R[13], 3 * 4);
+ sp = vaddrnol(P->R[13], 3 * 4, 0);
sp[0] = 0;
sp[2] = msgp;
P->R[0] = uregp;
@@ -411,7 +457,7 @@
sysfatal("unhandled noted argument %d", rc);
}
P->innote = 0;
- ureg = vaddrnol(uregp, 18 * 4); /* just to be sure */
+ ureg = vaddrnol(uregp, 18 * 4, 0); /* just to be sure */
memcpy(P->R, ureg, 15 * 4);
P->CPSR = ureg[16];
P->R[15] = ureg[17];
--- a/sys/src/cmd/5e/seg.c
+++ b/sys/src/cmd/5e/seg.c
@@ -17,6 +17,8 @@
memset(s->dref, 0, sizeof(Ref));
incref(s->dref);
s->data = s->dref + 1;
+ if(check)
+ s->shadow = emallocz((size+3)/4);
if(idx == SEGBSS)
s->flags = SEGFLLOCK;
P->S[idx] = s;
@@ -40,9 +42,11 @@
}
void *
-vaddr(u32int addr, u32int len, Segment **seg)
+vaddr(u32int addr, u32int len, int op, Segment **seg)
{
Segment **ss, *s;
+ u32int off;
+ int bits;
for(ss = P->S; ss < P->S + SEGNUM; ss++) {
if(*ss == nil)
@@ -54,20 +58,28 @@
if(s->flags & SEGFLLOCK)
rlock(&s->rw);
*seg = s;
- return (char *)s->data + (addr - s->start);
+ off = (addr - s->start);
+ if(check && op != 0){
+ bits = MARKALLOC;
+ if(op & ARD) bits |= MARKINIT;
+ checkaccess(s, off, len, bits);
+ if(op & AWR) markvalid(s, off, len, MARKINIT);
+ }
+ return (char *)s->data + off;
}
}
+ abort();
suicide("fault %.8ux (%d) @ %.8ux", addr, len, P->R[15]);
return nil;
}
void *
-vaddrnol(u32int addr, u32int len)
+vaddrnol(u32int addr, u32int len, int op)
{
Segment *seg;
void *ret;
- ret = vaddr(addr, len, &seg);
+ ret = vaddr(addr, len, op, &seg);
segunlock(seg);
return ret;
}
@@ -86,7 +98,7 @@
void *targ, *ret;
Segment *seg;
- targ = vaddr(addr, len > 0 ? len : 0, &seg);
+ targ = vaddr(addr, len > 0 ? len : 0, 0, &seg);
if((seg->flags & SEGFLLOCK) == 0) {
*copied = 0;
return targ;
@@ -107,7 +119,7 @@
void *targ, *v;
Segment *seg;
- targ = vaddr(addr, len, &seg);
+ targ = vaddr(addr, len, 0, &seg);
if((seg->flags & SEGFLLOCK) == 0) {
*buffered = 0;
return targ;
@@ -129,7 +141,7 @@
free(data);
return;
}
- targ = vaddr(addr, len, &seg);
+ targ = vaddr(addr, len, 0, &seg);
memmove(targ, data, len);
segunlock(seg);
free(data);
--- a/sys/src/cmd/5e/sys.c
+++ b/sys/src/cmd/5e/sys.c
@@ -9,7 +9,7 @@
arg(int n)
{
/* no locking necessary, since we're on the stack */
- return *(u32int*) vaddrnol(P->R[13] + 4 + 4 * n, 4);
+ return *(u32int*) vaddrnol(P->R[13] + 4 + 4 * n, 4, ARD);
}
static u64int
@@ -87,6 +87,7 @@
u32int fd, size, buf;
u64int off;
void *targ;
+ Segment *seg;
fd = arg(0);
buf = arg(1);
@@ -98,6 +99,12 @@
P->R[0] = noteerr(pread(fd, targ, size, off), size);
if(buffered)
copyback(buf, P->R[0], targ);
+ if(check && (s32int)P->R[0] > 0){
+ vaddr(buf, 0, 0, &seg);
+ checkaccess(seg, buf-seg->start, P->R[0], MARKALLOC);
+ markvalid(seg, buf-seg->start, P->R[0], MARKINIT);
+ segunlock(seg);
+ }
}
static void
@@ -127,7 +134,7 @@
vlong n, *ret;
Segment *seg;
- ret = vaddr(arg(0), 8, &seg);
+ ret = vaddr(arg(0), 8, 0, &seg);
fd = arg(1);
n = argv(2);
type = arg(4);
@@ -163,6 +170,7 @@
char *namet;
void *edirt;
int copied, buffered;
+ Segment *seg;
name = arg(0);
namet = copyifnec(name, -1, &copied);
@@ -176,6 +184,12 @@
free(namet);
if(buffered)
copyback(edir, P->R[0], edirt);
+ if(check && (s32int)P->R[0] > 0){
+ vaddr(edir, 0, 0, &seg);
+ checkaccess(seg, edir-seg->start, P->R[0], MARKALLOC);
+ markvalid(seg, edir-seg->start, P->R[0], MARKINIT);
+ segunlock(seg);
+ }
}
static void
@@ -184,6 +198,7 @@
u32int fd, edir, nedir;
void *edirt;
int buffered;
+ Segment *seg;
fd = arg(0);
edir = arg(1);
@@ -194,6 +209,12 @@
P->R[0] = noteerr(fstat(fd, edirt, nedir), nedir);
if(buffered)
copyback(edir, P->R[0], edirt);
+ if(check && (s32int)P->R[0] > 0){
+ vaddr(edir, 0, 0, &seg);
+ checkaccess(seg, edir-seg->start, P->R[0], MARKALLOC);
+ markvalid(seg, edir-seg->start, P->R[0], MARKINIT);
+ segunlock(seg);
+ }
}
static void
@@ -242,7 +263,7 @@
if(arg(0) == 0)
exits(nil);
else
- exits(vaddrnol(arg(0), 0));
+ exits(vaddrnol(arg(0), 0, ARD));
}
static void
@@ -249,6 +270,7 @@
sysbrk(void)
{
ulong v;
+ vlong o, n;
Segment *s;
v = arg(0);
@@ -260,13 +282,22 @@
if(v < P->S[SEGBSS]->start)
sysfatal("bss length < 0, wtf?");
s = P->S[SEGBSS];
+ n = v - s->start;
+ o = s->size;
wlock(&s->rw);
- s->dref = realloc(s->dref, v - s->start + sizeof(Ref));
+ s->dref = realloc(s->dref, n + sizeof(Ref));
if(s->dref == nil)
sysfatal("error reallocating");
s->data = s->dref + 1;
- if(s->size < v - s->start)
- memset((char*)s->data + s->size, 0, v - s->start - s->size);
+ if(o < n)
+ memset((char*)s->data + o, 0, n - o);
+ if(s->shadow != nil){
+ s->shadow = realloc(s->shadow, (n+3)/4);
+ if(s->shadow == nil)
+ sysfatal("error reallocating");
+ if(n - o > 0)
+ memset(s->shadow + (o+3)/4, 0, (n - o + 3)/4);
+ }
s->size = v - s->start;
P->R[0] = 0;
wunlock(&s->rw);
@@ -382,6 +413,10 @@
incref(t->dref);
t->data = t->dref + 1;
memcpy(t->data, s->data, s->size);
+ if(t->shadow != nil){
+ t->shadow = emalloc((s->size+7)/8);
+ memcpy(t->shadow, s->shadow, (s->size+7)/8);
+ }
p->S[i] = t;
} else {
incref(s->dref);
@@ -420,9 +455,9 @@
name = arg(0);
argv = arg(1);
- namet = strdup(vaddr(name, 0, &seg1));
+ namet = strdup(vaddr(name, 0, ARD, &seg1));
segunlock(seg1);
- argvt = vaddr(argv, 0, &seg1);
+ argvt = vaddr(argv, 0, ARD, &seg1);
if(systrace)
fprint(2, "exec(%#ux=\"%s\", %#ux)\n", name, namet, argv);
for(argc = 0; argvt[argc]; argc++)
@@ -429,7 +464,7 @@
;
argvv = emalloc(sizeof(char *) * argc);
for(i = 0; i < argc; i++) {
- argvv[i] = strdup(vaddr(argvt[i], 0, &seg2));
+ argvv[i] = strdup(vaddr(argvt[i], 0, ARD, &seg2));
segunlock(seg2);
}
segunlock(seg1);
@@ -627,7 +662,7 @@
block = arg(1);
if(systrace)
fprint(2, "semacquire(%#ux, %ud)\n", addr, block);
- addrt = vaddrnol(addr, 4);
+ addrt = vaddrnol(addr, 4, ARD|AWR);
P->R[0] = noteerr(semacquire(addrt, block), 0);
}
@@ -642,7 +677,7 @@
count = arg(1);
if(systrace)
fprint(2, "semrelease(%#ux, %ud)\n", addr, count);
- addrt = vaddr(addr, 4, &seg);
+ addrt = vaddr(addr, 4, ARD|AWR, &seg);
P->R[0] = noteerr(semrelease(addrt, count), 0);
segunlock(seg);
}
--- a/sys/src/cmd/5e/vfp.c
+++ b/sys/src/cmd/5e/vfp.c
@@ -45,7 +45,7 @@
void
vfprmtransfer(u32int instr)
{
- int n, d, off, sz;
+ int m, n, d, off, sz;
void* ea;
Segment *seg;
@@ -55,8 +55,9 @@
sz = instr & (1<<8);
if((instr & (1<<23)) == 0)
off = -off;
- ea = vaddr(evenaddr(P->R[n] + off, 3), sz ? 8 : 4, &seg);
- switch((instr>>20)&0x3){
+ m = (instr>>20)&0x3;
+ ea = vaddr(evenaddr(P->R[n] + off, 3), sz ? 8 : 4, m?ARD:AWR, &seg);
+ switch(m){
case 0:
if(sz)
*(double*)ea = P->F[d];
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2023-09-10 1:48 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-09-10 1:46 [9front] 5e: add support for memory constraint checking ori
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).