1

The gflags was configured to only have "Enable heap tail checking" enabled. The PageHeap was not enabled.

c:\Program Files (x86)\Windows Kits\10\Debuggers\x64>gflags /i test.exe
Current Registry Settings for test.exe executable are: 00000010
    htc - Enable heap tail checking

In the program below, a 4 bytes integer was allocated off the heap which was using 16 bytes alignment. So the rest of 12 bytes are filled with marker bytes.

int main()
{
    int *p = new int{};

    for (size_t i = 0; i < 16; ++i)
    {
        ((char*)p)[i] = '0';
        cout << ((char*)p)[i] << endl;
    }
    delete p;
    cout << "After delete\n";
    return 0;
}

And per MSFT, this is pretty straightforward.

This flag adds a short pattern to the end of each allocation. The Windows heap manager detects the pattern when the block is freed and, if the block was modified, the heap manager breaks into the debugger.

However, this was not happening. The buffer overrun was not captured and the process finished successfully.

Memory layout before the loop, starting from the address of the allocated integer. The rest 12 bytes were filled w/ specific byte patterns ab ab .. which is correct.

enter image description here

This is after the loop was executed. The 12 bytes pattern was overrun. enter image description here

This is after the memory block was released. enter image description here

There was no exception, no debugger kick-in. And the message after delete was also printed successfully. enter image description here

Note: If I enabled the PageHeap at the same time, this same tail buffer overrun problem (I'm sure it didn't overrun into the next page protected by PageHeap of course) was then captured.

Is this a bug in heap manager? I think "Enable heap tail checking" and PageHeap are two independent features.

Eric Z
  • 14,327
  • 7
  • 45
  • 69
  • What happens if you also enable heap free checking? – dxiv Aug 06 '20 at 03:19
  • Tried w/ heap free checking + tail checking (with HeapPage disabled). Not working. Heap free checking shouldn't matter here since the program doesn't write the buffer AFTER the buffer is freed. – Eric Z Aug 06 '20 at 04:29
  • Right, I was only wondering if maybe "*detects the pattern when the block is freed*" meant more. – dxiv Aug 06 '20 at 05:04

0 Answers0