IIS: ReadFileChunk allocates only 1 byte but reads m_dwPageSize (latent overflow)
Summary
In iis/mymodule.cpp, ReadFileChunk allocates its I/O scratch buffer with VirtualAlloc(NULL, 1, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE) but then reads m_dwPageSize bytes into it via ReadFile.
pIoBuffer = (BYTE *)VirtualAlloc(NULL, 1, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
// ...
if (!ReadFile(..., pIoBuffer, m_dwPageSize, ...))This only "works" by accident: VirtualAlloc's allocation size is rounded up to a full page (the system page size, obtained as sysInfo.dwPageSize → m_dwPageSize, mymodule.cpp:1274), and the returned address is page-aligned. So requesting 1 byte effectively commits one page, which happens to be exactly m_dwPageSize bytes — and ReadFile writes exactly that many.
Why it is a latent bug
- The code relies on an implicit, undocumented assumption that
m_dwPageSizeequals the system page size. If that ever differs (large-page configuration, or the value being mis-tuned larger),ReadFilewrites past the committed region → access violation. VirtualAlloc(..., 1, ...)is misleading and fragile; the real buffer size is invisible at the call site.
Suggested fix
Allocate the real size explicitly:
pIoBuffer = (BYTE *)VirtualAlloc(NULL, m_dwPageSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);The page-aligned address still satisfies the file I/O alignment requirements already used in the function, and the committed size now matches the ReadFile length. The existing VirtualFree(pIoBuffer, 0, MEM_RELEASE) cleanup is unaffected (it releases the whole region regardless of size).
Source: owasp-modsecurity/ModSecurity