[GHC] #10435: catastrophic exception-handling disablement on Windows Server 2008 R2

GHC ghc-devs at haskell.org
Mon Jun 29 15:05:27 UTC 2015


#10435: catastrophic exception-handling disablement on Windows Server 2008 R2
-------------------------------------+-------------------------------------
        Reporter:  malcolmw          |                   Owner:  simonmar
            Type:  bug               |                  Status:  new
        Priority:  normal            |               Milestone:
       Component:  Runtime System    |                 Version:  7.10.1
      Resolution:                    |                Keywords:  windows,
Operating System:  Windows           |  exceptions
 Type of failure:  Runtime crash     |            Architecture:  x86
      Blocked By:                    |               Test Case:
 Related Tickets:                    |                Blocking:
                                     |  Differential Revisions:
-------------------------------------+-------------------------------------

Comment (by Phyx-):

 So this crash happens because of `SEHOP`, on the Windows client versions
 (Vista+) it is '''off''' by default (Windows 8 has it on for Microsoft
 processes) but on Windows server 2008 SEHOP is '''on''' by default.

 `SEHOP` is a `SEH` exploit mitigation technique which among others checks
 that the `SEH` registration records ends with the default handler in
 `ntdll`. http://blogs.technet.com/b/srd/archive/2009/02/02/preventing-the-
 exploitation-of-seh-overwrites-with-sehop.aspx and https://www.exploit-
 db.com/docs/15379.pdf for how it works.

 This same error can be gotten on windows 7 (or 8) by opting in to `SEHOP`
 manually http://blogs.technet.com/b/srd/archive/2009/11/20/sehop-per-
 process-opt-in-support-in-windows-7.aspx . This can be done globally or
 per process.

 `MingW-w64` and `MSVC++` don't seem to have this problem, they both
 preserve the exception chain properly.

 But `GHC i686` seems to be using `Mingw` which has a different `crtmain`.
 But looking at it I can't figure out why it's going wrong,
 http://sourceforge.net/p/mingw/mingw-org-
 wsl/ci/21762bb4a1bd0c88c38eead03f59e8d994349e83/tree/src/libcrt/crt/crt1.c#l212

 unless `SetUnhandledExceptionFilter` clears the exception chain. But
 that's doubtful (and calling it from `Mingw-w64 g++` didn't reproduce the
 error).

 This is looking like it's a bug in `libcrt` *somewhere* though I am not
 entirely sure, but there's nothing in GHC's `rts` that's manually
 modifying the exception chain (as far as I know).

 So on the short term, what can you do?

 I can think of two options:

 1) compile the code to x86_64
 2) opt your binary out of `SEHOP` on Windows 2008 R2

 Second one is the easiest.

 For GHC, we should either find out what's causing the issue and report it
 upwards (but Mingw hasn't been maintained since 2012 on first glance) or
 switch to MingW-w64 for both x86 and x64_86 since they seem to do it right
 http://sourceforge.net/p/mingw-w64/mingw-w64/ci/8a67ab4541226a80b3ec2047347890d915126de1/tree/mingw-w64-headers/crt/excpt.h#l102

 A bit more detail on what's happening:


 {{{
 BUGCHECK_STR:  APPLICATION_FAULT_APPLICATION_FAULT_SEHOP

 PRIMARY_PROBLEM_CLASS:  APPLICATION_FAULT_SEHOP

 DEFAULT_BUCKET_ID:  APPLICATION_FAULT_SEHOP

 LAST_CONTROL_TRANSFER:  from 74059339 to 74efb727

 STACK_TEXT:
 00cedd78 74059339 e06d7363 00000001 00000003
 KERNELBASE!RaiseException+0x58
 00ceddb8 741e106a 00ceddd4 741e2280 026021b4
 msvcr120!_CxxThrowException+0x5b
 00ceddf0 004015b6 741e2104 00000000 00000000 Exception_cpp!foo+0x6a
 WARNING: Stack unwind information not available. Following frames may be
 wrong.
 00cedef0 76f9cbaf 00000000 00cee1a4 00000000 TestExceptions+0x15b6
 74aba010 80000018 00000000 00000000 00000000
 ntdll!LdrpResCompareResourceNames+0x1dc
 74aba034 00000000 00010000 00000409 00000048 0x80000018
 }}}

 When `RaiseException` is called it tried to walk the exception chain.

 On load, the exception chain is:

 {{{
 00cefb08: ntdll!_except_handler4+0 (77b274a0)
   CRT scope  0, filter: ntdll!LdrpDoDebuggerBreak+2e (77b43bf0)
                 func:   ntdll!LdrpDoDebuggerBreak+32 (77b43bf4)
 00cefca8: ntdll!_except_handler4+0 (77b274a0)
   CRT scope  0, func:   ntdll!LdrpInitializeProcess+16d4 (77b18e85)
 00cefcf8: ntdll!_except_handler4+0 (77b274a0)
   CRT scope  0, filter: ntdll!_LdrpInitialize+42ace (77b2d4a4)
                 func:   ntdll!_LdrpInitialize+42ae1 (77b2d4b7)
 }}}

 But when the exception happens something's off:

 {{{
 0:000> gh
 ModLoad: 75470000 75497000   C:\WINDOWS\SysWOW64\IMM32.DLL
 ModLoad: 759b0000 75ac2000   C:\WINDOWS\SysWOW64\MSCTF.dll
 (2171c.203c4): C++ EH exception - code e06d7363 (first chance)
 (2171c.203c4): C++ EH exception - code e06d7363 (!!! second chance !!!)
 eax=00cedd10 ebx=004e6670 ecx=00000003 edx=00000000 esi=62602200
 edi=00ceddc4
 eip=75b04598 esp=00cedd10 ebp=00cedd68 iopl=0         nv up ei pl nz ac po
 nc
 cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b
 efl=00000212
 KERNELBASE!RaiseException+0x48:
 75b04598 8b4c2454        mov     ecx,dword ptr [esp+54h]
 ss:002b:00cedd64=8a43e393

 0:000> !exchain
 00ceddd4: *** ERROR: Symbol file could not be found.  Defaulted to export
 symbols for H:\Exception.cpp.dll -
 Exception_cpp!foo+ae0 (62601ae0)
 00cefe88: 00000000
 Invalid exception stack at 02603bc4
 }}}

 Without SEHOP the invalid stack is ignored, with SEHOP that fault
 `(NTSTATUS) 0xe06d7363` is thrown and you get the crash you reported.

 For the record, the `mingw-w64` compilers return:

 {{{
 00eafdd4: msvcrt!_except_handler4+0 (773c7220)
   CRT scope  0, func:   msvcrt!doexit+110 (773b3bcc)
 00eaffcc: ntdll!_except_handler4+0 (77b274a0)
   CRT scope  0, filter: ntdll!__RtlUserThreadStart+54386 (77b3f076)
                 func:   ntdll!__RtlUserThreadStart+543cd (77b3f0bd)
 00eaffe4: ntdll!FinalExceptionHandlerPad50+0 (77ad0241)

 }}}

 Which also correctly ends in `FinalExceptionHandler`.

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10435#comment:11>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list