ghc, rts/Linker.c, OpenBSD and WXNEEDED and NOPIE

Hi, tl;dr: with shared / dynamic libs, is anything from rts/Linker.c still in use? If so, where and why? I hope this hasn't already been discussed in the past, and I apolotzie if all this is no longer relevant for ghc-8.8 or newer (I'm still at 8.6)... On OpenBSD, I had to explicitely mark ghc as WXNEEDED (i.e. allow it to map pages both as writable and executable), which I would like to get rid of. Likewise, I had to do some dances to explicitely disable PIE. If my memory doesn't fail completely, most (if not all) oft his was because of rts/Linker.c mmapping objects to be loaded at runtime and kind of simulating what dlopen() does for shared objects. Recently, thanks to Greg Steuck (who helped me a lot with this), we updated our ghc port to ghc-8.6 and also enabled shared (or dynamic, if you prefer this term) libraries. So my hope was that the code in rts/Linker.c were no longer used (because dynamic loading as done by ghci or template Haskell) could be done with dlopen(). However, after building ghc-8.6 with all the WXNNEDED stuff removed, and running ghci from this build, I still get an abort because pages are mapped both writable and executable (I've configured my system to abort processes when a W^X violation happens). Here's a backtrace in case it's helpfull at all: #0 _thread_sys___syscall () at -:3 #1 0x00000002010bb179 in _libc_mmap (addr=Variable "addr" is not available.) at /usr/src/lib/libc/sys/mmap.c:47 #2 0x000000021be22374 in mmapForLinker (bytes=Variable "bytes" is not available.) at rts/Linker.c:1029 #3 0x000000021be3e99b in m32_allocator_init () at rts/linker/M32Alloc.c:160 #4 0x00000002fd518be1 in cimc_info () from /usr/local/lib/ghc/bin/../ghci-8.6.4/libHSghci-8.6.4-ghc8.6.4.so #5 0x0000000000000000 in ?? () Any thougts about this? And, since W|X (and nopie) isn't good on any system: is anyone working on getting rid of this for other unixes? Thanks in advance for any help. Ciao, Kili

Matthias Kilian
Hi,
Hi Matthias, ...
However, after building ghc-8.6 with all the WXNNEDED stuff removed, and running ghci from this build, I still get an abort because pages are mapped both writable and executable (I've configured my system to abort processes when a W^X violation happens). Here's a backtrace in case it's helpfull at all:
#0 _thread_sys___syscall () at -:3 #1 0x00000002010bb179 in _libc_mmap (addr=Variable "addr" is not available.) at /usr/src/lib/libc/sys/mmap.c:47 #2 0x000000021be22374 in mmapForLinker (bytes=Variable "bytes" is not available.) at rts/Linker.c:1029 #3 0x000000021be3e99b in m32_allocator_init () at rts/linker/M32Alloc.c:160 #4 0x00000002fd518be1 in cimc_info () from /usr/local/lib/ghc/bin/../ghci-8.6.4/libHSghci-8.6.4-ghc8.6.4.so #5 0x0000000000000000 in ?? ()
Any thougts about this?
I suspect what you ran into here is GHCi loading a static archive: I tried running GHCi compiled with debug information under GDB, set a breakpoint on m32_allocator_init and found the following: >>> bt #0 m32_allocator_init () at rts/linker/M32Alloc.c:155 #1 0x00007ffff2d680b7 in ghcizm8zi9zi0zi20191022_GHCiziRun_run1_info () from _build/stage1/lib/../lib/x86_64-linux-ghc-8.9.0.20191022/libHSghci-8.9.0.20191022-ghc8.9.0.20191022.so #2 0x0000000000000000 in ?? () While the backtrace doesn't reveal this, the caller appears to be initLinker_ which I suspect is called by GHCi.ObjLink.initObjLinker (which is in turn called by GHCi.Run.run). I have opened #17407 to track this.
And, since W|X (and nopie) isn't good on any system: is anyone working on getting rid of this for other unixes?
There has been some work on this on Darwin (see #13624). Unfortunately no work has been put into ridding other platforms of W|X mappings (e.g. see #12657). It would be great if you felt you could contribute some help! Cheers, - Ben
participants (2)
-
Ben Gamari
-
Matthias Kilian