Mail Archives: cygwin/2009/07/16/15:56:19
On Jul 16 17:47, Dave Korn wrote:
> Corinna Vinschen wrote:
>
> > And that's what I get in the Perl testcase:
> >
> > (gdb) x/xw 0x7efdd000
> > 0x7efdd000: 0x0088ce68
> > (gdb) x/2xw 0x0088ce68
> > 0x88ce68: 0x0088400c 0x6103ce20 <-- Cygwin exception handler
> > (gdb) x/2xw 0x0088400c
> > 0x88400c: 0x00000000 0x00000001 <-- Huh?
> >
> > This looks wrong, doesn't it? The question is now, how and why does
> > that happen?
>
> > Where's the 0x00000000 pointer coming from on 2008? Is it possible that
> > the OS overwrote the entry because it appears to be an address in Perl's
> > stack, so it's a potential security theat?
>
> The addresses are in the wrong order; SEH registration records should
> always nest in the same way as stack call frames, i.e. unwinding toward
> ascending memory addresses, but the second record is at a lower address than
> the first, so the chain has been mangled somehow. Perhaps that breaks an
> integrity check in the kernel? Where actually is $esp at the time; is the
> bogus one in an already-released frame below $esp?
Seems so. $esp is 0x88c8c0.
> You might want to try again with a watchpoint:
>
> watch *(unsigned int*)0x88ce68
>
> ... and see how and where that head entry gets set up and whether it
> subsequently gets overwritten somehow.
That was really helpful, Dave. Thank you!
Here's the result:
(gdb) br pthread_attr_init
Breakpoint 2 at 0x610f42dc: file /home/corinna/src/cygwin/vanilla/winsup/cygwin/thread.cc, line 1909.
(gdb) watch *(unsigned int*)0x88ce68
Hardware watchpoint 3: *(unsigned int *) 8965736
(gdb) c
Continuing.
Hardware watchpoint 3: *(unsigned int *) 8965736
Old value = 8978372
New value = 8929292
_cygtls::init_exception_handler (this=0x88ce64,
eh=0x6103ce20 <_cygtls::handle_exceptions(_EXCEPTION_RECORD*, _exception_lis
t*, _CONTEXT*, void*)>)
at /home/corinna/src/cygwin/vanilla/winsup/cygwin/cygtls.cc:244
244 _except_list = ⪙
Current language: auto; currently c++
(gdb) p/x 8978372
$1 = 0x88ffc4
(gdb) p/x 8929292
$2 = 0x88400c
(gdb) p $esp
$3 = (void *) 0x883e78
(gdb) bt
#0 _cygtls::init_exception_handler (this=0x88ce64,
eh=0x6103ce20 <_cygtls::handle_exceptions(_EXCEPTION_RECORD*, _exception_lis
t*, _CONTEXT*, void*)>)
at /home/corinna/src/cygwin/vanilla/winsup/cygwin/cygtls.cc:244
#1 0x61033ff5 in dll_dllcrt0_1 (x=0x883edc)
at /home/corinna/src/cygwin/vanilla/winsup/cygwin/dll_init.cc:321
#2 0x6103414f in dll_dllcrt0 (h=0x6eb70000, p=0x6eb79070)
at /home/corinna/src/cygwin/vanilla/winsup/cygwin/dll_init.cc:302
#3 0x6eb77acf in _cygwin_dll_entry AT 12 ()
from /usr/lib/perl5/5.10/i686-cygwin/auto/threads/threads.dll
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
So this exception handler is installed as part of the Perl threads DLL
initialization. But appanrelty the address is not valid anymore when
leaving the DLL initialization.
For testing I disabled the
_my_tls.init_exception_handler (_cygtls::handle_exceptions);
call in dll_init.cc:dll_dllcrt0_1() and re-ran the Perl testcase.
Now it runs fine:
$ perl ./perlthread.pl
Testing threads...
I'm a thread!
Testing done
Is it possible that we have to remove the exception handler before
dll_dllcrt0_1 returns?
Corinna
--
Corinna Vinschen Please, send mails regarding Cygwin to
Cygwin Project Co-Leader cygwin AT cygwin DOT com
Red Hat
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
- Raw text -