Boost logo

Boost :

Subject: [boost] [context review] Windows ABI requirements
From: Holger Grund (holger.grund_at_[hidden])
Date: 2011-03-21 18:39:35


Hi,

I've had a very brief look at the x64 ASM Windows code as I think I raised
concerns about this before. As always, I'm pretty busy and I probably won't
be able to properly review the entire lib.

Looking at the fcontext_x86_64_ms_pe_masm.asm it would seem that several ABI
requirements are violated and it is not clear to me why this would always
work.

For instance, the stack is not properly aligned in the call to _exit &
set_fcontext. At least _exit can call into user code, IIRC (preterminators &
terminator registered via .crt$x* sections) and that code may require a
properly aligned stack.

I don't see proper unwind descriptors. What happens if an async exception is
triggered in the middle of set_fcontext? The x86 Windows version seems to
have similar problems. IIRC, the dispatch logic checks for EH registration
nodes to be on the stack for x86.

What happens if an untrapped exception is trigger in a code path called from
the context entrypoint? It would seem that there is an unwind chain via
make_fcontext (which doesn't appear to have any unwind description and would
therefore assumed to be a leaf function). Is its state necessarily live when
set_fcontext is called?

What guarantees are there that poking a few fields in the TIB is good enough
to properly switch the context? At least FLS has more than one field in the
TIB. There's also bookkeeping for whether registered callbacks have been
called.

Why is saving the register you save enough? Why wouldn't a future version of
Windows just take down the process if it detects stack hacks. I believe, the
unwinder checks the stack pointer in the unwind context against stack limits
and for 8-byte align at each caller in the chain until a barrier is found.

How are you certain that kernel32/kernelbase/ntdll don't assume that there's
a guard page (where guard page has the Windows defined meaning as in
PAGE_GUARD) at the end of the stack?

Even if that all works today, how can you be sure it will on Win8, 9 and
beyond?

To be honest, I don't think a library outside the operating system is not
the proper place to do this kind of thing at all (and even if you're part of
the OS it's an incredibly hard thing to get right -- UMS had tons of
problems in Win7 RTM)

BTW, glancing over the docs, an implicit conversion from size_t to
protected_stack seems weird, but that might just be a glitch in the doc
build.

Thanks!
-hg


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk