Is there a way to tell kernels “I’m done with this addr space, don’t recycle it and fault me if I access it, but don’t actually keep the page around”? Maybe madvise+mprotect?
It would make for cheap use-after-free detection at the cost of eventually running out of address space.
Conversation
Replying to
I haven't tested it, but I think: mmap(addr, length, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0)
1
5
Exactly. It might be slightly cheaper to madvise with MADV_DONTNEED then mprotect to PROT_NONE, but less portable. MAP_FIXED is the right way.
1
6
Since it's at page granularity, though, you'll run out of memory rather quick with 's idea, since all small allocations would have to be rounded up to whole pages. Or you'd have to give up being able to detect UAF for small allocations.
1
1
I think it's significantly cheaper to use mmap with MAP_FIXED. 2 system calls and mprotect still grabs mmap_sem write lock and MADV_DONTNEED grabs the read lock. End result is also actually slightly different. It would only be cheaper if you used MADV_FREE for lazy free.
1
1
And really, if you are never going to use it again, MADV_DONTNEED is better than MADV_FREE. You are going to pay the cost of dropping and zeroing the pages anyway, and you don't take advantage of not needing to fault them in again when reusing before memory pressure wipes it out.
1
This Tweet was deleted by the Tweet author. Learn more
In github.com/GrapheneOS/har, the large allocation quarantine does this, and eventually reuses the address space. Slabs also get purged / protected and quarantined if they become free and the slab cache is full. Still detects UAF for small allocations without that though.
I don't really think of the slab quarantine as a valuable feature since it doesn't happen reliably. The way it actually works for small allocations is the small allocation quarantine. They're zeroed on free and it can check for the zeroing on allocation when reusing the memory.
1
These 3 quarantines (small allocations in slabs, slabs - when pushed out of cache, large) are a bit like ASan using a FIFO queue but it also borrows the random swap with a slot in an array approach used by OpenBSD malloc for small allocations, to make reuse unpredictable.
1
Show replies



