Code in a bug
int main() { void *ptr = 0; int overrun = 1; ptr = malloc(overrun); while(overrun++) { if(!ptr) while(1) Sleep(500); *((char*)ptr + (overrun+1)) = 'a'; printf("\n%d\n",overrun); } return 0; }
From project menu of visual studio 2010 made sure the build is "Release" and "x64" (machine is x64)
Enable FULL PAGE HEAP
gflags /p /enable test.exe /full
Make windbg default debugger
E:\installed\Debugging Tools for Windows (x64)>windbg -I
Run the code as separate exe from
cmd
without debuggerOutput:
2 3 4 5 6 7 8 9 10 11 12 13 14
after which windbg is seen catching the corruption. And I thought full page heap is suppose to catch corruptions instantly.
Any comments as to why full page heap sucks?

- 317,000
- 35
- 244
- 286
-
3anybody ? or should I ask at "heapoverrun.com" get it XD – Nov 09 '12 at 18:22
2 Answers
Since heap allocations are required to be aligned, an overrun that does not cross an alignment boundary cannot be caught at the time the overrun occurs because memory protection is page-granular, not byte-granular. This is a hardware limitation. The overrun will be detected when you free the memory and the tail bytes are checked for tampering.
(By the way, saying that something sucks makes it less likely the person you accused of sucking is going to bother to help you with your problem. Just a tip.)

- 44,448
- 11
- 96
- 135
-
If you use `/unaligned` then you're telling the heap to abandon its alignment requirement. If you do that, then you can be byte-granular on the end, but it also breaks the heap contract. (For example, code that uses SSE may crash due to misalignment.) If you can live with that rule breakage, then go nuts. – Raymond Chen Nov 09 '12 at 20:57
-
1omg, u mean SSE instruction caller will blindly use memory pointers without checking alignment requirement ? – Nov 09 '12 at 21:03
-
1malloc from CRT heap (windows) does not grantee any alignment, SSE statement was thus false – Nov 09 '12 at 21:05
-
so summary there is no "heap contract" malloc returns any alignment. if you wanna detect any byte of overrun or underrun use the above gflags, the answer brought to you by not Raymond – Nov 09 '12 at 21:08
-
3Pageheap affects the `HeapAllocate` function, and `HeapAllocate` does have alignment requirements beyond those of `malloc`. – Raymond Chen Nov 09 '12 at 23:10
-
block tail checking on free doesn't seem to work either here. https://stackoverflow.com/questions/63275787/why-gflags-enable-heap-tail-checking-is-not-working-alone-on-windows – Eric Z Aug 06 '20 at 03:14
To expand on Raymond's response. If you look in the debugger at the original pointer returned via malloc you will see that it is 16 bytes from the end of the page. This is because the HeapAlloc alignment requirement on x64 is 16-bytes. So it placed the 1 byte you asked for as close as it could to the end of the page. Once you walk off the end of the page you fault.

- 3,935
- 1
- 17
- 15