This is the mail archive of the cygwin-developers 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: Address space clobbers during fork() (was Re: Extending /proc/*/maps)


On Apr 19 14:16, Ryan Johnson wrote:
> On 19/04/2011 12:01 PM, Corinna Vinschen wrote:
> >On Apr 19 11:38, Ryan Johnson wrote:
> >>BTW, /cygdrive/c/Windows/System32/locale.nls seems to be the reason
> >>that even statically linked dlls don't always load in the same place
> >>twice in a row.
> >How so?  And then, when is it loaded?  I assume that this file is
> >fetched as soon as the GetLocaleInfo function is called.  What OS
> >are you using?  If it's Vista or later, there's a chance that the
> >LocaleNameToLCID function is the culprit as well.  But the real
> >problem is, how can that be worked around?  For the locale stuff
> >we need these functions.
> (subject changed to reflect what we're actually discussing)
> 
> I'm using Win7-x64.
> 
> When locale.nls gets mapped in, Windows doesn't always put it in the
> same place. As a result, fork() can run into all the usual problems
> with DLL base addresses, except it can bite even statically-linked
> dlls.
> [...]
> Recall that cygfoo.dll and cygbar.dll both want to load at 00660000.
> The latter always gets the coveted base address because it always
> loads first (last in link order? luck?). In the parent, locale.nls
> maps to 002B0000, while cygfoo.dll loads at 00320000. The child, on
> the other hand, puts cygfoo.dll at 002B0000, and maps locale.nls to
> 00380000. That latter address is reserved for some sort of anonymous
> memory in the parent (most likely a thread stack,*** since there are
> some guarded pages at 003B9000 and it's not a heap). My best guess
> is that this stack lives at 00410000 in the child, which is free
> space in the parent.

Unfortunately there's no way set the thread stack address manually.
If we want to have that under control we would have to create a thread,
then create a new stack and free the original one.  That's kind of
tricky.  Or slow.

> The other main difference is the lack of shared memory in the child
> and completely different heaps. I assume the former is because
> cygwin hasn't finished initializing yet, and will not be a problem.
> I don't know whether the latter matters wrt fork() semantics, but it
> certainly is another potential source of address space clobbers.
> It's also rather odd that the child has 3-4 heaps when its parent
> has only 1-2.

Maybe that's some of the anti-hijacking measures in Windows.  ASLR?

> I actually hadn't noticed that thread stack before making the diff,
> so at this point it's a toss-up which of the thread or locale.nls
> got there first and messed up the other. Does Windows tend to map
> files at the same address every time, or just executable images it
> hopes to share as-is between processes? Without knowing that it's
> hard to say what happened.

I assume it will map the file to the same address if there's nothing
else already in the way.  This should make virtual memory handling
easier.  OTOH locale.nls is just a data file, so Win32 shouldn't care
at all where it's located.

> Regardless of file mapping behavior, though, I don't see right off
> how to make this problem go away.

Just an idea:  What if we map locale.nls to some fixed address ourselves
before any NLS function is called?  Somewhere early in dll_crt0_1.
If the file is already mapped, there should be no reason for the OS to
map it again at some other address.


Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat


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