llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.24k stars 12.07k forks source link

Doesn't work with SELinux #7073

Open edwintorok opened 14 years ago

edwintorok commented 14 years ago
Bugzilla Link 6701
Version unspecified
OS Linux
CC @hfinkel,@pitrou

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.

llvmbot commented 8 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

pitrou commented 9 years ago

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.

edwintorok commented 14 years ago

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.

edwintorok commented 14 years ago

We shouldn't crash though, but tell user to turn 'execmem' off.

r99762 should fix the crash.

edwintorok commented 14 years ago

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).

edwintorok commented 14 years ago

We shouldn't crash though, but tell user to turn 'execmem' off.

edwintorok commented 14 years ago

On a second thought that workaround for SELinux sounds silly, and I don't think it adds any security.

edwintorok commented 14 years ago

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.