Re: [Haskell-cafe] GHC 6.6.1 and SELinux issues
On Mon, Sep 03, 2007 at 02:56:52AM +0200, Bertram Felgenhauer wrote: Here is a small complete example for illustration: Thank you for detailed explanation! It is very helpful! Note that this function receives no additional context in its arguments. This is convenient but it means that each call to mkCallback has to return a different function pointer, so it is necessary to generate a small piece of code dynamically to implement it. This seems to be very different from usual FFI. In Ocaml and Python a special function is used that takes a function and an arguments. For example: value caml_callback(value closure, value arg); http://caml.inria.fr/pub/docs/manual-ocaml/manual032.html#htoc233 PyObject* PyObject_CallObject(PyObject *func, PyObject *args) http://docs.python.org/api/object.html Why not use the same convention in Haskell? Anyway, have you any ideas about making this work under SELinux? It seems that dynamic code generation is used in many programs and there are some tricks to make it work. See for example http://people.redhat.com/drepper/selinux-mem.html section Example code to avoid execmem violations Is this possible to use this technique in GHC? With best regards, Alexander. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re[2]: [Haskell-cafe] GHC 6.6.1 and SELinux issues
Hello Alexander, Monday, September 3, 2007, 11:46:56 AM, you wrote: In Ocaml and Python a special function is used that takes a function and an arguments. For example: value caml_callback(value closure, value arg); PyObject* PyObject_CallObject(PyObject *func, PyObject *args) both uses dynamic typing while Haskell wrappers are statically typed (and Haskell just doesn't supported any analog of value/PyObject at time of Haskell98) -- Best regards, Bulatmailto:[EMAIL PROTECTED] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] GHC 6.6.1 and SELinux issues
On Wed, Aug 29, 2007 at 01:03:56PM -0700, Stefan O'Rear wrote: So it is not clear if GHC does really need this PROT_EXEC. Can someone familiar with GHC internals answer why PROT_EXEC is used in getMBlocks? It's not possible to correctly implement 'foreign import ccall wrapper' without self-modifying code on any mainstream computer architecture. Does this program work on your no-PROT_EXEC ghc? : {-# OPTIONS_GHC -ffi #-} import Foreign foreign import ccall wrapper wrap :: IO () - IO (FunPtr (IO ())) foreign import ccall dynamic call :: FunPtr (IO ()) - IO () main = call = wrap (print hi!) Thanks, that is exactly what I asked for. This program compiles with my no-PROT_EXEC ghc, but doesn't work: $ ghc -o 1 1.hs $ ./1 1: internal error: makeExecutable: failed to protect 0x0x2b115597e000 (GHC version 6.6.1 for x86_64_unknown_linux) Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug Aborted $ The errors comes from rts/posix/OSMem.c, function setExecutable which tries to mprotect block of memory with PROT_EXEC and PROT_WRITE. What is so special about wrapper and dynamic functions? I've never used Haskell FFI, but I've heavily used Python-C interface and Ocaml-C interface, calling both C from Ocaml and Ocaml from C and even Ocaml from Python via C and etc. It all worked fine without any runtime code generation or self-modifying code. Can you please give some ideas how self-modifying code can be used in FFI implementation? With best regards, Alexander. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] GHC 6.6.1 and SELinux issues
Alexander Vodomerov wrote: On Wed, Aug 29, 2007 at 01:03:56PM -0700, Stefan O'Rear wrote: [snip] What is so special about wrapper and dynamic functions? Can you please give some ideas how self-modifying code can be used in FFI implementation? It's not self-modifying code really, it's dynamically generated code. Here is a small complete example for illustration: V.hs import Foreign import Foreign.C foreign import ccall wrapper mkCallback :: (CInt - CInt) - IO (FunPtr (CInt - CInt)) foreign import ccall v.h foo c_foo :: FunPtr (CInt - CInt) - IO CInt main = do add_21 - mkCallback (+21) c_foo add_21 = print v.c #include v.h int foo(callback_t fun) { return fun(fun(0)); } v.h typedef int (* callback_t)(int); int foo(callback_t fun); (compile with ghc -ffi V.hs v.c) This program takes a function that adds 21 to a CInt, wraps it into a C function pointer of type callback_t, and then calls this function from the C side two times; it prints 42. In particular, the wrapper mkCallback takes any *Haskell* function of type CInt - CInt and returns a *C* function pointer that represents the same function. Note that this function receives no additional context in its arguments. This is convenient but it means that each call to mkCallback has to return a different function pointer, so it is necessary to generate a small piece of code dynamically to implement it. HTH, Bertram ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] GHC 6.6.1 and SELinux issues
On Tue, Aug 28, 2007 at 08:53:05PM -0600, Stuart Jansen wrote: On Wed, 2007-08-29 at 00:59 +0400, Alexander Vodomerov wrote: In what domain do you run GHC? Sorry about that, should've dug deeper. And here we have the difference: $ ls -Z /usr/lib/ghc-6.6.1/ghc-6.6.1 -rwxr-xr-x root root system_u:object_r:unconfined_execmem_exec_t /usr/lib/ghc-6.6.1/ghc-6.6.1 This explains that GHC works fine. unconfined_execmem_exec_t gives permission to map memory with PROT_EXEC and PROT_WRITE simultaneously. I've put GHC in unconfined_execmem_t and it started to work fine. But the problem is not in GHC -- it is in programs compiled by GHC. They also require exec/write memory. Only root can grant unconfined_execmem privileges, so simple user can not run binaries compiled by GHC. How do you solve this problem? Does Fedora GHC package has any additional patches? With best regards, Alexander. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] GHC 6.6.1 and SELinux issues
Alexander Vodomerov wrote: I've put GHC in unconfined_execmem_t and it started to work fine. But the problem is not in GHC -- it is in programs compiled by GHC. They also require exec/write memory. Only root can grant unconfined_execmem privileges, so simple user can not run binaries compiled by GHC. How do you solve this problem? Running chcon -t unconfined_execmem_exec_t as root will let you run the binaries, which you probably already knew. The underlying problem is harder to fix: the default SELinux policy doesn't allow PROT_EXEC pages to be mapped with PROT_WRITE, for obvious reasons. The solution is expensive in terms of address space and TLB entries: map the same pages twice, once only with PROT_EXEC, and once only with PROT_WRITE. There's already a Trac ticket filed against this problem, but Simon Marlow marked it as closed because he couldn't test the code he wrote to try to fix it, and nobody stepped in to help out at the time: http://hackage.haskell.org/trac/ghc/ticket/738 b ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] GHC 6.6.1 and SELinux issues
On Wed, Aug 29, 2007 at 08:41:12AM -0700, Bryan O'Sullivan wrote: The underlying problem is harder to fix: the default SELinux policy doesn't allow PROT_EXEC pages to be mapped with PROT_WRITE, for obvious reasons. The solution is expensive in terms of address space and TLB entries: map the same pages twice, once only with PROT_EXEC, and once only with PROT_WRITE. Just for experiment I've removed PROT_EXEC from my_mmap function in rts/MBlock.c and recompiled GHC. The resulting GHC was able to compile itself and my code. Binaries, produced by it worked fine with SELinux. However, another problem related to GHCi ocurred. More details are available at the 738 ticket you mentioned. So it is not clear if GHC does really need this PROT_EXEC. Can someone familiar with GHC internals answer why PROT_EXEC is used in getMBlocks? There's already a Trac ticket filed against this problem, but Simon Marlow marked it as closed because he couldn't test the code he wrote to try to fix it, and nobody stepped in to help out at the time: http://hackage.haskell.org/trac/ghc/ticket/738 Yes, I reopened the bug some days ago. I can also provide a shell access to Simon Marlow (or someone else willing to help) on a machine to experiment with. Both x86 and x86_64 boxes are available. With best regards, Alexander. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] GHC 6.6.1 and SELinux issues
On Wed, Aug 29, 2007 at 10:40:41PM +0400, Alexander Vodomerov wrote: On Wed, Aug 29, 2007 at 08:41:12AM -0700, Bryan O'Sullivan wrote: The underlying problem is harder to fix: the default SELinux policy doesn't allow PROT_EXEC pages to be mapped with PROT_WRITE, for obvious reasons. The solution is expensive in terms of address space and TLB entries: map the same pages twice, once only with PROT_EXEC, and once only with PROT_WRITE. Just for experiment I've removed PROT_EXEC from my_mmap function in rts/MBlock.c and recompiled GHC. The resulting GHC was able to compile itself and my code. Binaries, produced by it worked fine with SELinux. However, another problem related to GHCi ocurred. More details are available at the 738 ticket you mentioned. So it is not clear if GHC does really need this PROT_EXEC. Can someone familiar with GHC internals answer why PROT_EXEC is used in getMBlocks? It's not possible to correctly implement 'foreign import ccall wrapper' without self-modifying code on any mainstream computer architecture. Does this program work on your no-PROT_EXEC ghc? : {-# OPTIONS_GHC -ffi #-} import Foreign foreign import ccall wrapper wrap :: IO () - IO (FunPtr (IO ())) foreign import ccall dynamic call :: FunPtr (IO ()) - IO () main = call = wrap (print hi!) Stefan signature.asc Description: Digital signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] GHC 6.6.1 and SELinux issues
Hello! Does anybody here uses GHC on Linux with SELinux turned on? I've just installed SELinux and run into GHC/SELinux incompatibility. It seems that the similar problem was reported some time ago and was fixed in 6.4.3. However, I use 6.6.1 and the problem is still here. $ ghc ghc-6.6.1: internal error: getMBlock: mmap: Permission denied (GHC version 6.6.1 for i386_unknown_linux) Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug Exactly the same bug is appearing on x86_64 architecture. Much more details is available at http://hackage.haskell.org/trac/ghc/ticket/738 Any ideas? With best regards, Alexander. PS. Is it possible to turn on global allow_execmem boolean in SELinux policy, thus enabling executable memory mapping. This solves the problem. However, this is major drawback for system security and should be avoided at any cost. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] GHC 6.6.1 and SELinux issues
On Tue, Aug 28, 2007 at 08:05:02AM -0600, Stuart Jansen wrote: I'm using it on Fedora 7 without any problems. $ ls -Z $(which ghc) lrwxrwxrwx root root system_u:object_r:bin_t /usr/bin/ghc - ghc-6.6.1* $ ls -Z $(which ghci) lrwxrwxrwx root root system_u:object_r:bin_t /usr/bin/ghci - ghci-6.6.1* In what domain do you run GHC? The commands about just show that /usr/bin/ghc has the bin_t type, however it is just a symlink or shell wrapper. Real GHC executable may have another permission. See for example (taken from my Debian box): $ ls -Z `which ghc` lrwxrwxrwx root root system_u:object_r:bin_t:s0 /usr/bin/ghc - /etc/alternatives/ghc $ ls -Z /usr/lib/ghc-6.6.1/bin/ghc-6.6.1 -rwxr-xr-x root root system_u:object_r:bin_t:s0 /usr/lib/ghc-6.6.1/bin/ghc-6.6.1 $ file /usr/lib/ghc-6.6.1/bin/ghc-6.6.1 /usr/lib/ghc-6.6.1/bin/ghc-6.6.1: POSIX shell script text executable $ cat /usr/lib/ghc-6.6.1/bin/ghc-6.6.1 #!/bin/sh GHCBIN=/usr/lib/ghc-6.6.1/ghc-6.6.1; TOPDIROPT=-B/usr/lib/ghc-6.6.1; # Mini-driver for GHC exec $GHCBIN $TOPDIROPT ${1+$@} $ file /usr/lib/ghc-6.6.1/ghc-6.6.1 /usr/lib/ghc-6.6.1/ghc-6.6.1: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.1, dynamically linked (uses shared libs), stripped $ ls -Z /usr/lib/ghc-6.6.1/ghc-6.6.1 -rwxr-xr-x root root system_u:object_r:lib_t:s0 /usr/lib/ghc-6.6.1/ghc-6.6.1 In this case the real domain for ghc is lib_t, not bin_t. With best regards, Alexander. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe