Subject: Re: Permission denied with makeinfo from texinfo-4.0
From: "J. David Bryan" <[email-masked]>
To: Cygnus Win32 List <[email-masked]>
Date: Sun, 2 Apr 2000 17:22:08 -0400

On 2 Apr 2000, at 15:58, Mumit Khan wrote:

> Here's what David Korn says when it showed up in UWIN as well:
> 
>   Yet some more bizarre undocumented win32 behavior.  If you call the 
>   Win32 ReadFile() function with size greater than 32K, and you are 
>   at the end of file, it does not return successfully with 0 bytes as 
>   you would expect, but fails with ERROR_NOACCESS.

I observed the problem with makeinfo with a read of a little over 10K.  A 
32K buffer size may always fail, but it's not necessary to cause failure.

I confess that I haven't tried to trace the actual ReadFile code, but it 
appears to check the accessibility of the entire buffer using the length 
specified in the call before actually determining the number of bytes left 
to read.  If the buffer accessibility check fails, ERROR_NOACCESS is 
returned.

The particular case in makeinfo is that after reading a full buffer's worth 
of file data, it tries to read a *second* full buffer's worth of data with 
the buffer pointer pointing at the *end* of the original buffer (i.e., to 
unallocated space).  ReadFile checks the validity of this area, and if the 
unallocated space crosses a page boundary into a protected page, the 
ERROR_NOACCESS fault occurs.

I checked this by tracing the makeinfo code with gdb, and if I altered the 
second call on the fly to specify a size that kept the unallocated space 
wholly within the page containing the original buffer, ReadFile correctly 
returned 0.  If I increased the call length by one, such that the 
unallocated buffer space extended into the next page by a single byte, 
ERROR_NOACCESS was returned.

One can argue whether specifying an invalid buffer to ReadFile should or 
should not fail if there are no more bytes left to read.  Either way, there 
is clearly a bug in makeinfo -- if the file is extended between the stat 
call that is used to allocate the buffer, and the read call that fills it, 
the routine will scribble on unallocated space.

                                      -- Dave Bryan

--
Want to unsubscribe from this list?
Send a message to [email-masked]