The following test case will cause GP fault when run using the PSDK x64
compiler. The x86 library seems to handle this case just fine. The issue is
having a string without a null terminator that aligns itself onto the very
end of an allocates region such that strncpy() will run right off the end
looking for the terminating '\0'. This problem persists in Vista x64 RC2.

The test case does not verify that the next page is unallocated and you
could be unlucky and have the test case work if that were to happen.

I have not tried this with VS2005 x64 library.

The workaround is to use memcpy() since I know the exact length of the string.

#include <windows.h>
#include <stdio.h>

void main(void)
{
char *buffer;
char *ptr;
int len = 8;
char Str[30];
SYSTEM_INFO info;
register int ii;

// Figure out the page size
GetSystemInfo(&info);

// Allocate a chunk of memory
// Exactly one page in length
buffer = VirtualAlloc(0, info.dwPageSize, MEM_COMMIT, PAGE_READWRITE);

// Get a pointer to the last 8 bytes
ptr = buffer + info.dwPageSize - len;
for (ii=0;ii<len;ii++)
{
ptr[ii] = 'a' + ii;
}

// pass that to strncpy();
strncpy(Str, ptr, len);
Str[len] = '\0';
}

Re: Bug in x64 strncpy() in PSDK msvcrt.dll by Tim

Tim
Thu Oct 26 00:25:04 CDT 2006

Alan Brown <AlanBrown@discussions.microsoft.com> wrote:
>
>The following test case will cause GP fault when run using the PSDK x64
>compiler. The x86 library seems to handle this case just fine. The issue is
>having a string without a null terminator that aligns itself onto the very
>end of an allocates region such that strncpy() will run right off the end
>looking for the terminating '\0'. This problem persists in Vista x64 RC2.

It absolutely is a bug. I just disassembled the one from x64\libcmt.lib,
and the code (at qword_loop_entrance) prefetches the next src qword BEFORE
it checks whether the count has been satisfied. The x86 code does it in
the other order.

>The test case does not verify that the next page is unallocated and you
>could be unlucky and have the test case work if that were to happen.
>
>I have not tried this with VS2005 x64 library.

Remember that msvcrt.dll is not part of either the PlatformSDK or VS2005.
It is part of the operating system. What I disassembled was actually from
libcmt.lib.
--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.