Bug 1290432 - PCRE-JITted code should be executed from non-writable memory to obey execmem SELinux restriction
Summary: PCRE-JITted code should be executed from non-writable memory to obey execmem ...
Keywords:
Status: CLOSED CANTFIX
Alias: None
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: pcre
Version: 7.2
Hardware: x86_64
OS: Linux
medium
medium
Target Milestone: rc
: ---
Assignee: Petr Pisar
QA Contact: BaseOS QE - Apps
Vladimír Slávik
URL: https://bugs.exim.org/show_bug.cgi?id...
Whiteboard:
Depends On:
Blocks: 1298243 1420851
TreeView+ depends on / blocked
 
Reported: 2015-12-10 13:55 UTC by Petr Lautrbach
Modified: 2018-03-02 14:48 UTC (History)
10 users (show)

Fixed In Version:
Doc Type: Known Issue
Doc Text:
Performance of regular expressions cannot be boosted with the JIT technique if executable stack is disabled When the *SELinux* policy disallows executable stack, the *PCRE* library cannot use JIT compilation to speed up regular expressions. As a result, attempting JIT compilation for regular expressions is ignored and their performance is not boosted. To work around this problem, amend the *SELinux* policy with a rule for enabling the "execmem" action on affected *SELinux* domains to enable JIT compilation. Some of the rules are already provided and can be enabled by specific SELinux booleans. To list these booleans, see the output of the following command: getsebool -a | grep execmem An alternative workaround is changing application code to not request JIT compilation with calls to the *pcre_study()* function.
Clone Of: 1290205
Environment:
Last Closed: 2018-03-02 14:48:02 UTC


Attachments (Terms of Use)

Description Petr Lautrbach 2015-12-10 13:55:48 UTC
+++ This bug was initially created as a clone of Bug #1290205 +++

Description of problem:

When rear is being executed, e.g. /usr/sbin/rear mkrescue an SELinux AVC is generated. 

type=AVC msg=audit(1448377615.693:35710): avc:  denied  { execmem } for  pid=21398 comm="grep" scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tcontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tclass=process

type=SYSCALL msg=audit(1448377615.693:35710): arch=x86_64 syscall=mmap success=no exit=EACCES a0=0 a1=10000 a2=7 a3=22 items=0 ppid=9928 pid=21398 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=4294967295 comm=grep exe=/usr/bin/grep subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)

SELinux is preventing /usr/bin/grep from using the execmem access on a process. The root cause seems to be the usage of "grep -P".


The problem is in sljit/sljitExecAllocator.c:

 97 static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
 98 {
 99         void* retval;
100 
101 #ifdef MAP_ANON
102         retval = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0);
103 #else
104         if (dev_zero < 0) {
105                 if (open_dev_zero())
106                         return NULL;
107         }
108         retval = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, dev_zero, 0);
109 #endif
110 
111         return (retval != MAP_FAILED) ? retval : NULL;
112 }

where it tries to map anonymous memory with PROT_WRITE and PROT_EXEC. Would it be possible to change this according to Ulrich Drepper's suggestion [1] ?

[1] http://www.akkadia.org/drepper/selinux-mem.html

Comment 1 Petr Pisar 2015-12-10 14:38:45 UTC
pcre-8.32-15.el7 is affected.

Comment 3 Petr Pisar 2015-12-10 15:16:57 UTC
Enhancement request forwarded to PCRE upstream <https://bugs.exim.org/show_bug.cgi?id=1749>.

Comment 7 Remi Collet 2016-11-25 07:57:51 UTC
Notice: this may also affects rh-php70 SCL when pcre.jit=1 (but default value is 0)

Comment 8 Petr Pisar 2017-01-12 14:59:28 UTC
Upstream is working on the double mapping technique (currently x86, x86_64 and aarch64 JIT compilers work). But the technique has a drawback of a need for temporary files. If a process is not allowed to create them, the JIT compilation will fail. Therefore PCRE applications are still will be advised to cope with unavailable JIT at run time.

Comment 17 Petr Pisar 2018-03-02 14:48:02 UTC
We tried hard together with PCRE authors to bring a reliable solution. However it turned there are corner cases where it does not work (multi-threaded applications calling fork()).

At the end any solution would actually break the security hardening: If a policy disallows modifying an executable memory, then it's on a purpose. Just-in-time compilation is intrinsically incompatible with this restriction and the tested imperfect implementation only relied on imperfect policy enforcement in the Linux kernel.

Therefore we officially decline this request for enhancing pcre package. This resolution applies to pcre as well as to pcre2 software.

Users who want to benefit from a JIT have to enable execmem action on affected SELinux domains (or stop enforcing noexecmem global policy). If users are missing such knob in existing SELinux policy (getsebool -a | grep execmem), they should report a future request against the affected program or against selinux-policy Bugzilla component.


Note You need to log in before you can comment on or make changes to this bug.