Re: @MLton load-word and MacOSX 10.7 (Lion)

Matthew Fluet <[email protected]> Mon, 18 Jun 2012 11:16:55 -0400
Newsgroups gmane.comp.lang.ml.mlton.devel
Message-ID <CAMrhFL6+ScAVSdikTnnP=kvBJ-GsqBCaFF+dURP1Ko_3nSNOuQ@mail.gmail.com>
On Wed, Jun 13, 2012 at 6:05 PM, Wesley W. Terpstra <[email protected]> wrote:
> On Tue, Jun 12, 2012 at 11:08 PM, Matthew Fluet <[email protected]> wrote:
>> The problem seems to be that MLton is generating position-independent
>> code (PIC) code for executables and Lion introduced address-space
>> layout randomization (ASLR) for executables.
>
> Interesting problem.
>
> So, to summarize:
> The MLton heap keeps a pointer to the gcState object
> On reloading the program, the gcState object has moved

Correct.

> It seems to me that this symptom is only the tip of the iceberg. Not
> just 'gcState' but also pointers to every global object is
> invalidated... all function pointers are invalidated too. I don't
> think a fix should be targetting 'gcState', but rather the larger
> problem.

You are correct that there may be other global objects referenced, but
there actually aren't that many.  Performing "grep -r '_symbol' *" in
the Basis Library implementation reveals only a few problematic ones.
There are some Real{32,64} constants that are loaded from C, but they
are, indeed, constants, so wouldn't need to be reloaded upon a
'load-world'.  There are also CommandLine.* and Posix.ProcEnv.environ
implementations.

Note that anything _import-ed isn't a problem, because such references
end up as direct function calls, so the global object reference is in
the code segment (and not the SML heap) and will be properly handled
by the loader/dynamic linker (and the PIC access).  They would be
problematic if we implemented an _import-ed function call as a (pure)
fetch the address of the called function and an (impure) indirect call
through the address, because in that case, the address could be saved
in the SML heap.

But, it turns out that there is another class of code pointers that
are saved in the SML heap --- return addresses on stacks/threads saved
in the SML heap.  Even in a simple SML program that doesn't use
threads, there will be one stack/thread that ends with the call to
MLton.World.save.  This is only problematic for the native codegens,
because they save return addresses as code labels; the C codegen saves
return addresses as trampoline-table indices, so they are just
integers.

> There are a few options that spring to mind:
> a) disable ASLR (but not PIC) in MLton executables
> b) somehow tag and rewrite pointers in the heap
> c) make all _symbol address results 'volatile'
> ... any other choices?
>
> (b) seems tricky since not every pointer points to a global object.
> You could identify which shared object a pointer points at (if any),
> but it would require more operating system calls than we've typically
> needed in MLton. Once you know the shared object and displacement, you
> could fix the pointer up on load-world. Of course, load-world has
> never worked (and will never work) in any program with state stored by
> FFI'd libraries, so this is probably overkill.
>
> Personally, I think (a) makes the most sense (if possible). ASLR is
> designed to defend against stack smashing which should be impossible
> in SML.

I agree that trying to fixup all of the code pointers would be
difficult.  One technique is the one used by the ML-NLFFI Library for
dynamically loaded libraries:
        (* a handle remembers an address and the era of its creation as
         * well as a function to re-create the address when necessary *)
        type h = (addr * era) ref * (unit -> addr)
An 'era' is incremented every time the runtime system is started anew.
 Of course, this still assumes that one can get back to SML and start
executing to perform the re-creates when necessary.

I agree that (a) makes the most sense.  I'll add a note to the
documentation on MLton.World that saving and loading worlds won't work
with position-independent executables.  As I noted before, '-link-opt
-fno-PIE' seems to do the trick on MacOSX Lion.

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/