"static_wrapper" imports in the FFI

Simon Marlow marlowsd at gmail.com
Thu Mar 18 10:17:30 EDT 2010

On 17/03/2010 23:13, Iavor Diatchki wrote:
> Hello,
> My point was that in many cases we can simply avoid run-time code
> generation, rather then trying to work around the system's SE Linux
> policy.  While I believe that using the foreign "export" gives us the
> same functional behavior, the generated code is certainly not the
> same.  I wrote a small benchmark to compare the two approaches and it
> seems that the generated code is ~30% slower when using a foreign
> export.  As I mentioned in a previous post, I think that this is
> because of the extra indirection that we have to follow.  I am
> attaching my GHC patch and the benchmark if anyone is interested in
> playing around with it (Ganesh, thanks for the darcs tip---using
> "darcs optimize --reorder" did the trick!)

Part of the reason is that deRefStablePtr# isn't inlined in Haskell, 
whereas it is in C, so there's a lot of extra shuffling going on to make 
an out-of-line call to the deRefStablePtr# primop.  If we care about 
this it can be fixed quite easily.

Furthermore, if we really care about callback performance there's 
probably a factor of 2 to be had just by generating better code in the 
stub.  Currently we make one call to allocate() for each closure, and we 
make a chain of application nodes.  If instead we made one call to 
allocate(), generated inline code to create the closures, and used a 
multi-argument application, that would speed things up a lot.

So I guess I'm saying the particular optimisation of static_wrapper 
seems less urgent than some others we could do which would benefit 
everyone and don't require adding extensions or changing programs.

> -Iavor
> PS: As a concrete example, Gtk2Hs uses numerous 'import "wrapper"'
> declarations, which means that just adding a GUI to a Haskell app
> requires you to allow making executable memory at run time.  I've had
> fairly serious difficulties when trying to explain why this happens to
> programmers who are not Haskell implementors.

So are you saying you've run into problems where SE Linux is refusing to 
run GHC-compiled binaries?  Is that because the system is using a strict 
SE Linux configuration of some kind?

Do these same people understand why ld.so needs to allocate executable 
and writable memory?  Or Firefox?  etc.  Don't other languages (e.g. 
Python) use libffi too?


> On Wed, Mar 17, 2010 at 8:21 AM, Tyson Whitehead<twhitehead at gmail.com>  wrote:
>> On March 16, 2010 20:01:32 Iavor Diatchki wrote:
>>> Optionally disabling executable heap blocks would be a separate patch.
>>>   As far as I know, the only reason that the heap is executable is to
>>> support the adjustor thunks used to implement "wrapper" imports.  The
>>> "static_wrapper" patch provides a way to install Haskell callbacks in
>>> many C libraries without the need for adjustor thunks.
>> I believe this is the code in "rts/Adjustor.c" and "rts/sm/Storage.c".  It (or
>> it gets ffi to) write a small bit of assembler that adds a hard coded pointer
>> (to a StablePtr) to the argument list and jump to a hard coded address.  It
>> then has to fiddle with the executable bits on the memory page it wrote the
>> code into in order to allow the system the execute it.
>> This leaves me to ask though, could you not also tighten up the security here
>> by just getting the the system to turn off the writable bit when it also turns
>> on the executable one?  I realize this implies that you will only get one of
>> these per page, but still that might not be that bad if  you don't generate
>> very many and recycle them.
>> As a compromise, you could also just temporarily make pages writable when you
>> add to them, thus greatly minimizing the attack window.  If you could get the
>> OS could freeze all other threads while doing this there would be no window.
>> If there generation and usage is/could be localized to OS threads, then
>> modification would always be safe if OS thread works on their own page.
>> I scanned the ghc source (all c, h, cmm, hs, and lhs files), and the only usage
>> of import "wrappers" seems to be in System.Console.Terminfo.Base.
>> Cheers!  -Tyson
>> _______________________________________________
>> Glasgow-haskell-users mailing list
>> Glasgow-haskell-users at haskell.org
>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

More information about the Glasgow-haskell-users mailing list