shithub: mc

Download patch

ref: dda657081b032dc653f669ca85f2c09984f0cb35
parent: dcd6fad70720c2c8baa5e0096f2b14e45e9aa447
author: Ori Bernstein <ori@eigenstate.org>
date: Sat Mar 10 16:24:09 EST 2018

Be a bit more paranoid about memory corruption.

	Check the tail of slices.

--- a/lib/std/alloc.myr
+++ b/lib/std/alloc.myr
@@ -69,7 +69,8 @@
 		-> [][:]
 	;;
 	sz = len*sizeof(@a) + align(sizeof(slheader), Align)
-	p = bytealloc(sz)
+	sz = allocsz(sz)
+	p = bytealloc(sz + sizeof(size))
 	p = inithdr(p, sz)
 	-> (p : @a#)[0:len]
 }
@@ -81,34 +82,43 @@
 		-> [][:]
 	;;
 	sz = len*sizeof(@a) + align(sizeof(slheader), Align)
-	p = zbytealloc(sz)
+	sz = allocsz(sz)
+	p = zbytealloc(sz + sizeof(size))
 	p = inithdr(p, sz)
 	-> (p : @a#)[0:len]
 }
 
 const inithdr = {p, sz
-	var phdr, prest
+	var phdr, pdat, pend
 
 	phdr = (p : slheader#)
-	phdr.cap = allocsz(sz) - align(sizeof(slheader), Align)
+	phdr.cap = sz - align(sizeof(slheader), Align)
+
+	/* add start/end magics */
 	phdr.magic = (0xdeadbeefbadf00d : size)
+	pdat = (p : size) + align(sizeof(slheader), Align)
+	pend = ((pdat : size) + sz - align(sizeof(slheader), Align) : size#)
+	pend# = 0xfee1deadfee1dead
 
-	prest = (p : size) + align(sizeof(slheader), Align)
-	-> (prest : byte#)
+	-> (pdat : byte#)
 }
 
 const checkhdr = {p
-	var phdr, addr
+	var phdr, pend, addr
 
 	addr = (p : size)
 	addr -= align(sizeof(slheader), Align)
+
+	/* check start/end magics */
 	phdr = (addr : slheader#)
 	iassert(phdr.magic == (0xdeadbeefbadf00d : size), "corrupt memory\n")
+	pend = ((p : size) + phdr.cap : size#)
+	iassert(pend# == 0xfee1deadfee1dead, "corrupt memory")
 }
 
 /* Frees a slice */
 generic slfree	 = {sl
-	var head
+	var head, sz
 
 	if (sl : byte#) == Zsliceptr
 		-> void
@@ -117,7 +127,8 @@
 	checkhdr((sl : byte#))
 	head = ((sl : byte#) : size)
 	head -= align(sizeof(slheader), Align)
-	bytefree((head : byte#), slcap((sl : byte#)))
+	sz = slcap((sl : byte#)) + align(sizeof(slheader), Align)
+	bytefree((head : byte#), sz + sizeof(size))
 }
 
 /* Grows a slice */
--- a/lib/std/bytealloc.myr
+++ b/lib/std/bytealloc.myr
@@ -54,6 +54,7 @@
 	prev	: slab#	/* the prev slab on the chain */
 	freehd	: chunk#	/* the nodes we're allocating */
 	nfree	: size	/* the number of free nodes */
+	magic	: size	/* ensure we didn't index into the void */
 ;;
 
 /* NB: must be smaller than sizeof(slab) */
@@ -144,12 +145,10 @@
 /* frees a blob that is 'sz' bytes long. */
 const bytefree = {p, sz
 	var bkt
-	var v
 
 	if p == (0 : byte#)
 		-> void
 	;;
-	v = ((p : size) + sz : uint32#)#
 	if trace
 		lock(memlck)
 		tracefree(p, sz)
@@ -298,6 +297,7 @@
 	s.nfree = bkt.nper
 	s.next = Zslab
 	s.prev = Zslab
+	s.magic = 0xfee1baff1ed
 	/* skip past the slab header */
 	off = align(sizeof(slab), Align)
 	bnext = nextchunk((s : chunk#), off)
@@ -352,6 +352,7 @@
 	var s, c
 
 	s = (mtrunc(m, Slabsz) : slab#)
+	iassert(s.magic == 0xfee1baff1ed, "bad free")
 	c = (m : chunk#)
 	if s.nfree == 0
 		if bkt.slabs != Zslab