shithub: 5v

Download patch

ref: 390f5e1938e255599ad1d87a83185b6e57e4b0b8
parent: 26dd49399614ec9544f66aa95809af437247322e
author: Ori Bernstein <[email protected]>
date: Sat Sep 9 20:57:43 EDT 2023

chk: whitelist some pc ranges for ok-but-sketchy asm functions

--- a/5e.c
+++ b/5e.c
@@ -7,7 +7,11 @@
 int vfp = 1;
 int nflag, pflag, bflag;
 int check;
-u32int mallocaddr, freeaddr, reallocaddr, vtraceaddr;
+u32int mallocaddr;
+u32int freeaddr;
+u32int reallocaddr;
+u32int setmalloctagaddr;
+u32int setrealloctagaddr;
 Ref nproc;
 
 void
@@ -132,8 +136,7 @@
 	dotext(argc, argv);
 	atnotify(notehandler, 1);
 	for(;;) {
-extern int vtrace;
-		if(ultraverbose || vtrace)
+		if(ultraverbose)
 			dump();
 		step();
 		while((P->notein - P->noteout) % NNOTE) {
--- a/arm.c
+++ b/arm.c
@@ -19,14 +19,11 @@
 	fH = 1<<5,
 };
 
-int vtrace;
-
 u32int mallocaddr;
 u32int freeaddr;
 u32int reallocaddr;
 u32int setmalloctagaddr;
 u32int setrealloctagaddr;
-u32int vtraceaddr;
 
 static u32int
 arg(int n)
@@ -348,8 +345,6 @@
 				P->hookpc = P->R[15];
 			}else if(npc == setrealloctagaddr){
 				P->hookpc = P->R[15];
-			}else if(npc == vtraceaddr){
-				vtrace = arg(0);
 			}
 		}
 	}
--- a/chk.c
+++ b/chk.c
@@ -6,6 +6,10 @@
 #include "dat.h"
 #include "fns.h"
 
+
+uvlong	okrange[32];
+int	nokrange;
+
 void
 dumpmap(Segment *seg, u32int off, u32int len, char *fmt, ...)
 {
@@ -22,7 +26,6 @@
 		print("not tracing\n");
 		return;
 	}
-print("off: %d, len: %d\n", off, len);
 	for(i = off/8; i <= (off+len+7)/8; i++){
 		if(i >= off/8 && i+40 < off/8)
 			c = '*';
@@ -43,6 +46,20 @@
 	return *(u32int*) vaddrnol(P->R[13] + 4 + 4 * n, 4, ARD);
 }
 
+static int
+okfunc(u32int pc)
+{
+	uvlong *p;
+	int i;
+
+	for(i = 0, p = okrange; i < nokrange; i += 2, p += 2)
+{print("check %#llux <= %#x <= %#llux\n", p[0], pc, p[1]);
+		if(p[0] <= pc && pc <= p[1])
+			return 1;
+}
+	return 0;
+}
+
 void
 checkaccess(Segment *seg, u32int off, u32int len, int chk)
 {
@@ -63,8 +80,8 @@
 		exits("bad access");
 	}
 	for(; off != end; off++){
-		bits = seg->shadow[off>>2] >> 2*(off&3);
-		if((bits&3) != chk){
+		bits = seg->shadow[off>>2] >> (2*(off&3));
+		if((bits&chk) != chk && !okfunc(P->R[15]-4)){
 			if(chk&MARKALLOC)
 				print("%d: access outside alloc: %#x at PC %#x\n",
 					P->pid, seg->start+off, P->R[15] - 4);
@@ -85,6 +102,7 @@
 	end = off+len;
 	if(end > seg->size)
 		end = seg->size;
+//print("valid: %#x..%#x\n", seg->start+off, seg->start+end);
 	for(; off != end; off++)
 		seg->shadow[off>>2] |= chk<<(2*(off&3));
 }
@@ -97,6 +115,7 @@
 	end = off+len;
 	if(end > seg->size)
 		end = seg->size;
+//print("invalid: %#x..%#x\n", seg->start+off, seg->start+end);
 	for(; off != end; off++)
 		seg->shadow[off>>2] &= ~(chk<<(2*(off&3)));
 }
--- a/dat.h
+++ b/dat.h
@@ -80,7 +80,8 @@
 extern u32int reallocaddr;
 extern u32int setmalloctagaddr;
 extern u32int setrealloctagaddr;
-extern u32int vtraceaddr;
+extern uvlong okrange[];
+extern int nokrange;
 
 enum {
 	SEGFLLOCK = 1,
--- a/proc.c
+++ b/proc.c
@@ -205,6 +205,18 @@
 	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)
 {
@@ -213,7 +225,12 @@
 	freeaddr = hookaddr("poolfree");
 	setmalloctagaddr = hookaddr("setmalloctag");
 	setrealloctagaddr = hookaddr("setrealloctag");
-	vtraceaddr = hookaddr("vtrace");
+	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
@@ -246,7 +263,7 @@
 		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|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)
@@ -400,7 +417,6 @@
 void
 donote(char *msg, ulong type)
 {
-extern int vtrace;
 	int rc;
 	u32int *ureg, *sp, uregp, msgp;
 	char *msgb;
@@ -429,7 +445,7 @@
 	switch(rc = setjmp(P->notejmp) - 1) {
 	case -1:
 		for(;;) {
-			if(ultraverbose || vtrace)
+			if(ultraverbose)
 				dump();
 			step();
 		}