[Boost-bugs] [Boost C++ Libraries] #12592: Wrongly aligned bottom stack address

Subject: [Boost-bugs] [Boost C++ Libraries] #12592: Wrongly aligned bottom stack address
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2016-11-07 17:55:20


#12592: Wrongly aligned bottom stack address
-----------------------------------------------------+---------------------
 Reporter: Christian Maaser <runningwithscythes@…> | Owner: olli
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: context
  Version: Boost 1.62.0 | Severity: Problem
 Keywords: |
-----------------------------------------------------+---------------------
 I'm facing an incompatibility of Boost context based coroutines with the
 compiler generated function {{{__chkstk()}}} (on Windows using MSVC2015),
 where apparently the bottom stack address is not aligned correctly to page
 boundaries.

 My application uses Qt within a Boost coroutine (v2) and unfortunately
 runs out of stack space, which is a different issue and out of scope of
 this problem here. However, symptoms are that deep within the call stack
 some QT function implicitly calls the compiler generated function
 {{{__chkstk()}}} and crashes with a memory access violation. The
 function's code looks like this:

 {{{
 void QQmlNotifier::emitNotify(QQmlNotifierEndpoint *endpoint, void **a)
 {
 ; auto generated code at the beginning of the function
 00000000730D9C20 48 89 54 24 10 mov qword ptr [rsp+10h],rdx
 00000000730D9C25 48 89 4C 24 08 mov qword ptr [rsp+8],rcx
 ; This QT function needs 0x1878 bytes on the stack, which is more than one
 page of memory,
 ; thus call __chkstk to make sure that all pages are mapped to actual
 memory
 00000000730D9C2A B8 78 18 00 00 mov eax,1878h
 00000000730D9C2F E8 39 CE B6 FF call __chkstk (072C46A6Dh)

 Qt5Qmld.dll!__chkstk():
 __chkstk:
 ; simply jump to actual function below
 0000000072C46A6D E9 0E 23 58 00 jmp __chkstk (0731C8D80h)

 ; do some stuff...
 00000000731C8D80 48 83 EC 10 sub rsp,10h
 00000000731C8D84 4C 89 14 24 mov qword ptr [rsp],r10
 00000000731C8D88 4C 89 5C 24 08 mov qword ptr [rsp+8],r11
 00000000731C8D8D 4D 33 DB xor r11,r11
 00000000731C8D90 4C 8D 54 24 18 lea r10,[rsp+18h]
 00000000731C8D95 4C 2B D0 sub r10,rax
 00000000731C8D98 4D 0F 42 D3 cmovb r10,r11
 ; At this point r11 gets the bottom address of context stack assigned
 00000000731C8D9C 65 4C 8B 1C 25 10 00 00 00 mov r11,qword ptr
 gs:[10h]

 ; check if the actually allocated size of stack is big enough
 00000000731C8DA5 4D 3B D3 cmp r10,r11
 ; if this is false and if we don't jump to cs20, trouble begins
 00000000731C8DA8 F2 73 17 bnd jae cs20 (0731C8DC2h)
 00000000731C8DAB 66 41 81 E2 00 F0 and r10w,0F000h
 cs10:
 ; walk down the stack in 4096 byte steps
 00000000731C8DB1 4D 8D 9B 00 F0 FF FF lea r11,[r11-1000h]

 ; trigger guard page (by writing a value) to allow dynamic resize of stack
 or mapping of additional pages
 00000000731C8DB8 41 C6 03 00 mov byte ptr [r11],0

 ; r10 and r11 will never be equal because the value of r11 is not aligned
 to 0x1000.
 00000000731C8DBC 4D 3B D3 cmp r10,r11
 00000000731C8DBF F2 75 EF bnd jne cs10 (0731C8DB1h)

 cs20:
 ; irrelevant end of function
 00000000731C8DC2 4C 8B 14 24 mov r10,qword ptr [rsp]
 00000000731C8DC6 4C 8B 5C 24 08 mov r11,qword ptr [rsp+8]
 00000000731C8DCB 48 83 C4 10 add rsp,10h
 00000000731C8DCF F2 C3 bnd ret
 }}}

 The value of r11 in above code is the same as is assigned in
 boost_1_62_0\libs\context\src\asm\make_x86_64_ms_pe_masm.asm during
 context creation:

 {{{
 ; ...
 ; save bottom address of context stack as 'limit'
 00007FF7C0A05A8C 48 89 48 10 mov qword ptr [rax+10h],rcx
 ; ... (see source file for full code)
 }}}

 When using QT without the surrounding coroutine/context and walking into
 {{{__chkstk}}}, the bottom stack limit (r11) is always a value aligned to
 0x1000. Due to the fact that context does not align this value to 0x1000
 the loop above writes random zeros into the applications stack address
 space until an access violation/seg fault occurs, destroying vital data on
 its way down and possibly interfering with other threads before crashing.

 I don't know yet if this only affects MSVC and the default
 basic_fixedsize_stack used on Windows, or if other stack allocators are
 broken as well.

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/12592>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:20 UTC