This is the mail archive of the cygwin@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: mmap() and gcc precompiled headers


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/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]