Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I have a number of custom allocators that use the same techniques, with some improvements.

When space is cheap: All allocations are two 4k pages The returned pointer is alligned with the end of the buffer to detect overruns. (with a 16byte allignment) The page following the alloc is always denied. The space around the allocation is filled with flag values, and these are checked on free. After free the pages are held in storage for a few thousand following allocations.

The variants of this allocator does things like only doing this for specific ranges of allocation sizes or only after a certain number of allocations.

With this a good number of overruns and use after free bugs have been found.

Mostly used this technique on windows with delphi, on linux i prefer valgrind.



What you describe is implemented in these libraries: libduma (http://duma.sourceforge.net/) and efence (http://linux.die.net/man/3/efence)

They also have buffer underflow protection (either overflow or underflow at a time).

But in 32 bit systems, for applications that heavily use memory, you may run out of address space


Why 2 4k pages? If I'm allocating 1k of memory, what does having an entire extra page get me?


The second 4k is a guard page, to catch buffer overflows. So the heap looks like:

3k empty, 1k data, 4k empty and read/write-protected.

The extra page is needed since you can't set the memory protection flags at a higher granularity.


Ah. It sounded like you were mapping 2 4k pages for the allocation itself, aligning the allocation at the end of that 2-page span, and then mapping the following page and marking it as denied.


I wasn't the original poster, that was just my impression of the scheme. I could have misunderstood, in which case I don't have any alternate theories for what that second page is for :-)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: