DosRead returns too much data for small read counts

David Graser
Posts: 21
Joined: Thu Apr 19, 2007 19:01

DosRead returns too much data for small read counts

Postby David Graser » Wed Mar 26, 2008 20:44

We encountered this problem with NTFS while developing FM/2. Steven posted it the the eComstation bugtracker, but I thought I would post it here also.
---------------------------------

Under some conditions DosRead returns more data than requested. Under the right conditions this will cause buffer overflows and crashes. This was discovered for counts on the order of 4 bytes.

This occurs for both 2.010 and 2.017.

Steven Levine
steve53 at earthlink.net

We can provide a working testcase executable if need. We are still tweaking the testcase code to determine if there's a pattern to the failure.

The testcase code is basically.

int main(int argc, // i: Argument count
char **argv) // i: Argument list
{
APIRET apiret = 0;
PSZ pszFileName;
BYTE abBuffer[4096];
ULONG cToRead;
ULONG cRead;
UINT argndx;
HFILE handle;
ULONG action;
UINT ndx;
UINT errs;
# define FILL_CHAR 0x55

for (argndx = 1; argndx < argc; argndx++) {
pszFileName = argv[argndx];
cToRead = 4;
printf("Trying to read %lu bytes from %s\n",
cToRead, pszFileName);

apiret = DosOpen(pszFileName,
&handle,
&action,
0,
0,
OPEN_ACTION_FAIL_IF_NEW |
OPEN_ACTION_OPEN_IF_EXISTS,
OPEN_FLAGS_FAIL_ON_ERROR |
OPEN_FLAGS_NOINHERIT |
OPEN_FLAGS_RANDOMSEQUENTIAL |
OPEN_SHARE_DENYNONE |
OPEN_ACCESS_READONLY, 0);
if (apiret != NO_ERROR) {
printf("DosOpen %s failed with error %lu\n",
pszFileName, apiret);
continue;
}
memset(abBuffer, FILL_CHAR, sizeof(abBuffer));
apiret = DosRead(handle, abBuffer, cToRead, &cRead);
if (apiret != NO_ERROR) {
printf("DosRead %s of %l bytes failed with error %lu\n",
pszFileName, cToRead, apiret);
DosClose(handle);
continue;
}
if (cRead != cToRead) {
printf("DosRead request for %lu bytes returned %lu bytes\n",
cToRead, cRead);
}
errs = 0;
for (ndx = 4; ndx < sizeof(abBuffer) && errs < 5; ndx++) {
// Report just 1st 5 errors
if (abBuffer[ndx] != FILL_CHAR) {
printf("DosRead corrupted buffer at offset %lu with %x\n",
ndx, abBuffer[ndx]);
if (++errs >= 5)
break;
}
} // for
DosClose(handle);
if (!errs)
printf("OK\n");
} // for
} // main

When the error occurs, the typical output is

[u:\fm2_workspace]testme c:\windows\web\printers\ipp_adsi.inc
Trying to read 4 bytes from c:\windows\web\printers\ipp_adsi.inc
DosRead request for 4 bytes returned 520 bytes

Return to “Совместимость с Windows / Compatibility with Windows”

Who is online

Users browsing this forum: No registered users and 1 guest

cron