> It would also be interesting to try out a more aggressive form of > freeunmap for 64-bit where the allocations are purged with MADV_FREE > and then the virtual memory is kept out of circulation with a similar > FIFO queue approach. Could potentially do it by default when malloc > hints are enabled, so it wouldn't need a new option exposed (but it > would change the MADV_FREE option into something that enhances security > at the expense of more VM fragmentation rather than a performance vs. > memory trade-off so that may not make much sense after all). > > It's the same issue as the junk validation feature where there's a need > for a reliable delay to get the most out of the feature. Randomization > does help, but it's not as good as knowing that virtual memory doesn't > go back into circulation until some configured amount of allocator > throughput has occurred.
Kept out of circulation? It sounds like it would be incredibly expensive data-structure wise for the kernel to even attempt such a gaurantee.. On a 64-bit VA / 48-bit PA system, the address space should be large enough that this does not occur commonly due to mmap ASLR; or at least, when it does occur, the reuse cannot be predicted usably. So what is the purpose of your proposal? Is it to opportunistically find bugs? Or to resist attack in UAF situations by "gauranteeing" the memory is unallocated at time of reuse? #include <sys/types.h> #include <sys/mman.h> #include <stdio.h> main() { int max = 100000; while (max--) { void *p = mmap(NULL, 4096, PROT_READ, MAP_ANON, -1, 0); munmap(p, 4096); printf("%p\n", p); } } ./test | sort | uniq -c | sort -n | awk '{print $1}' | sort | uniq -c 90880 1 (addresses only used once) 4314 2 123 3 3 4 1 111 (I wonder what this subtle bias is due to) These are independent allocations of course, but maybe we can get a trend out of this. Except in really large memory programs, I suspect a UAF would find the memory unallocation, as long as free() has pushed it out via munmap(). (Curiously, your other proposal is about the part of the cache which is not munmap()'d...) Add in the subtle effects of guarding we also do, and it seems we are in good shape. Maybe you are on a system with where mmap ASLR isn't as good? The OpenBSD one isn't perfect, because we are trying to maintain a small amount of page-table locality (so that N-level page tables don't have to be walked fully from root for every access that misses in the TLB). The result above feels "good enough" to make reliable UAF attack after free()->munmap() very difficult. Am I missing something which would justify what seems like a huge cost?