Open edwintorok opened 14 years ago
I'm the numba user, to whom Antoine was referring. To help getting this bug fix, I just placed a bugbounty of 250$ on getting this fixed in a way, so that numba plays nicely together with selinux.
https://www.bountysource.com/issues/29603275-doesn-t-work-with-selinux
Hello,
r99762 should fix the crash.
It seems that change is unfortunately obsolete. A Numba user reported a crash with SELinux enabled: https://github.com/numba/numba/issues/1288
I don't have a SELinux-enabled machine at hand, but by digging a bit it seems the error probably happens in sys::Memory::protectMappedMemory(), called from SectionMemoryManager::applyMemoryGroupPermissions(), called from SectionMemoryManager::finalizeMemory(), called from ObjectLinkingLayer::finalize() where the error return is ignored.
Note this is on master. On 3.6, the same problem happens in MCJIT::finalizeLoadedModules() which ignores LinkingMemoryManager::finalizeMemory()'s error return.
It would be nice to reenable the check and subsequent error message.
Hmm, instead of the 2 buffer approach, we could initially allocate a memory that is only writable, and then later we change it to executable only.
I see that something similar is already done for ARM with setRangeWritable(..), setRangeExecutable(...). This should be generalized to all JIT targets.
We could do this at least in eager JIT mode, since we shouldn't need self-modifying stubs then.
We shouldn't crash though, but tell user to turn 'execmem' off.
r99762 should fix the crash.
FWIW on fc13-alpha a message is printed that allocation of RWX memory failed, and lli fails to work. This happens when FC13 is run in enforcing mode (the default).
We shouldn't crash though, but tell user to turn 'execmem' off.
On a second thought that workaround for SELinux sounds silly, and I don't think it adds any security.
Unfortunately the address of those 2 mapping will be different, so relocations/and absolute address emission will need to be done with the executable mapping, and actually writing the code on the writable mapping.
Extended Description
SELinux disallows both writable and executable memory. In enforcing mode LLVM crashes when trying to write: #
0 0x0000003772c7b444 in memset () from /lib64/libc.so.6
# No symbol table info available. #
1 0x00002af2af41e1d2 in allocateNewSlab (this=0xf339000, size=) at llvm/lib/ExecutionEngine/JIT/JITMemoryManager.cpp:624
# ErrMsg = {static npos = 18446744073709551615, # _M_dataplus = {<std::allocator> = {<__gnu_cxx::new_allocator> = {}, }, _M_p = 0xf358af8 '�' <repeats 200 times>...}}
#
LastSlabPtr =
#
B = {Address = 0xf3390e0, Size = 255037664}
#
And in non-enforcing mode SELinux logs an audit message: type=AVC msg=audit(1269527244.925:38384): avc: denied { execmem } for pid=11936 comm="clamscan" scontext=user_u:system_r:clamscan_t:s0 tcontext=user_u:system_r:clamscan_t:s0 tclass=processss pid=11936 comm="clamscan" scontext=user_u:sys
Turning execmem off is not an option, but here is some information on how to write self-modifying code with execmem: http://people.redhat.com/drepper/selinux-mem.html
Basically you map same file twice, once as writable, once as executable. You write JITed code to one, and execute the other.