summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2018-03-10 21:24:09 -0800
committerOri Bernstein <ori@eigenstate.org>2018-03-10 21:24:09 -0800
commitdda657081b032dc653f669ca85f2c09984f0cb35 (patch)
treefc4059d082cd488d9c6cadf959e0f374d567bcf9
parentdcd6fad70720c2c8baa5e0096f2b14e45e9aa447 (diff)
downloadmc-dda657081b032dc653f669ca85f2c09984f0cb35.tar.gz
Be a bit more paranoid about memory corruption.
Check the tail of slices.
-rw-r--r--lib/std/alloc.myr29
-rw-r--r--lib/std/bytealloc.myr5
2 files changed, 23 insertions, 11 deletions
diff --git a/lib/std/alloc.myr b/lib/std/alloc.myr
index b6f3ee9..15c1f92 100644
--- a/lib/std/alloc.myr
+++ b/lib/std/alloc.myr
@@ -69,7 +69,8 @@ generic slalloc = {len
-> [][:]
;;
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 @@ generic slzalloc = {len
-> [][:]
;;
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 @@ generic slfree = {sl
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 */
diff --git a/lib/std/bytealloc.myr b/lib/std/bytealloc.myr
index 4061d85..3a0d2e3 100644
--- a/lib/std/bytealloc.myr
+++ b/lib/std/bytealloc.myr
@@ -54,6 +54,7 @@ type slab = struct
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 @@ const bytealloc = {sz
/* 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 @@ const mkslab = {bkt
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 @@ const bktfree = {bkt, m
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