Subject: Re: mmap() and gcc precompiled headers
From: Earl Chew <[email-masked]>
To: [email-masked]
Date: Fri, 04 Jul 2003 12:34:13 -0700

Corinna Vinschen wrote:
>> o I think there is a problem with the address arithmetic in the match()
>>   method used by munmap(). Compare the code in list::match (__off64_t
>>   off, DWORD len) with list::match (caddr_t addr, DWORD len,
>>   __off32_t start).
 >
> Uhm, no.

Thanks for the detailed explanation. You're right, it was too late
in the day for me to think straight :-(

Having set me straight about that, here's something else to consider.
I did come across another problem whilst fiddling around trying to
get gcc and cygwin to cooperate.

At one point I managed to have a really small file (couple of kB)
which I attempted to map a really large space (couple of MB). This
failed in a strange way. Consider the code that checks for this:

	  DWORD high;
	  DWORD low = GetFileSize (fh->get_handle (), &high);
	  __off64_t fsiz = ((__off64_t)high << 32) + low;
/*1*/	  fsiz -= gran_off;
	  if (gran_len > fsiz)
/*2*/	    gran_len = fsiz;

Firstly, gran_off was larger than fsiz. The subtraction at /*1*/
doesn't check for overflow, resulting in fsiz becoming negative.
This results in gran_len taking on a very strange value. I suspect
this situation should return with EINVAL or ENXIO.

Secondly, even if the value does not underflow, there is an
interesting side-effect to the assignment made at /*2*/. This
assignment can drastically reduce the value of gran_len.
The caller is not aware that the actual mapping is much smaller
than requested. (Should this fail with EOVERFLOW?)

A later call to munmap() can uses the original addr and len
parameters (since the caller doesn't know about the reduced
gran_len), and munmap() fails because the region described
in the mmapped_areas list is much smaller than [addr, addr+len).

I'm not sure if whether mmap() or munmap() is incorrect in this
regard. Perhaps munmap() is at fault:

     The munmap() function shall remove any mappings for those
     entire pages containing any part of the address space of
     the process starting at addr and continuing for len bytes.
     Further references to these pages shall result in the generation
     of a SIGSEGV signal to the process. If there are no mappings in
     the specified address range, then munmap() has no effect.

Earl

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/