Conversation

I'd strongly recommend measuring the size of the address space and reserving a huge portion as a massive PROT_NONE mapping rather than using hints though. mmap hints aren't respected everywhere and you can end up with other mappings getting in the way and screwing up the hints.
2
3
Basically, make a massive PROT_NONE mapping and then you allocate with mprotect to PROT_READ|PROT_WRITE and free by using MAP_FIXED mmap to replace a section with a new fresh PROT_NONE region. It prevents anything else from getting that via mmap outside of your own mmap usage.
2
9
Here's the output of /proc/1/maps showing the address space of an arbitrary process (init) on GrapheneOS which uses hardened_malloc: gist.githubusercontent.com/thestinger/28c Android adds support for setting labels on anonymous mappings and hardened_malloc does that in a debug build.
Shows how it reserves all address space it ever needs for all metadata (entirely out-of-line) and slab allocations (<= 128k by default) with a dedicated region for each size class. Can also see 1 active large allocation (which get random guards) and 1 freed one (quarantined).
1
Can also see the guard slabs it leaves between each slab for the slab allocation region. Since init hasn't used most size classes, the inactive size class regions are still labelled as slab region gaps since it starts out that way and has reserved random gaps between regions.