Jump to content
TFuto

SELinux alert on sysc/2.1/forkjoin/.libs/lt-test access to execheap

Recommended Posts

As the title says.

On CentOS 7.5, x86_64, SystemC 2.3.2, --enable-debug, --disable-optimization, I get an execheap alert from SELinux on sysc/2.1/forkjoin/.libs/lt-test during make check. Also, several tests failed.

This does not happen on the non-debug, optimization-enabled make check.

execheap is a bad thing.

I re-run the entire build and the alert did not show up, and all tests passed,  so this should be some transient error.

Please have a look where you potentially make heap executable.

 

Share this post


Link to post
Share on other sites
On 10/26/2018 at 6:58 AM, TFuto said:

On CentOS 7.5, x86_64, SystemC 2.3.2, --enable-debug, --disable-optimization, I get an execheap alert from SELinux on sysc/2.1/forkjoin/.libs/lt-test during make check. Also, several tests failed.

This is strange. Does it give any hint where execution jumps to the heap? forkjoin test is very simple and should not generate any code on heap.

Share this post


Link to post
Share on other sites

I'm not aware of any executable heap usage in SystemC either.  However, there is a known issue around executable stacks in the QuickThreads implementation on some SELinux-enabled machines.  Quoting the RELEASENOTES file:

  - When building the SystemC library with QuickThreads support, the
    resulting shared library is marked as requiring an executable stack
    by certain compilers/assemblers (or rather not marked as not needing
    one).  As a result, some system security systems (like SELinux) might
    refuse to load the library.  As a workaround for GNU (compatible)
    assemblers, pass the assembler flags variable with the option
      CCASFLAGS="-Wa,--noexecstack"
    to the `configure' script call before building the SystemC library.

In case you can reproduce the effect again, can you try the suggested flag on the configure script?

Hope that helps,
  Philipp

Share this post


Link to post
Share on other sites

Thanks guys for the responses.

I did not get any detailed information from SELinux where the offending call was made.

However, I found it in the QT source in kernel/sc_cor_qt.cpp. Note the PROT_EXEC flag:
 

void
sc_cor_qt::stack_protect( bool enable )
{
...

   // Enable the red zone at the end of the stack so that references within
    // it will cause an interrupt.

    if( enable ) {
        ret = mprotect( redzone, pagesize - 1, PROT_NONE );
    }

    // Revert the red zone to normal memory usage. Try to make it read - write -
    // execute. If that does not work then settle for read - write

    else {
        ret = mprotect( redzone, pagesize - 1, PROT_READ|PROT_WRITE|PROT_EXEC);
        if ( ret != 0 )
            ret = mprotect( redzone, pagesize - 1, PROT_READ | PROT_WRITE );
    }

    sc_assert( ret == 0 );
}

I have no clue why this PROT_EXEC is needed at all. Also, the SELinux denial is random because it seems to be memory layout dependent at the time of the call. (It is a pity that the QT source does not include a config section and supporting files for a standalone x86_64 compile and testing.)

I will try Philipp's workaround, and will try to reproduce the error.

Thanks again,

Tibor

Share this post


Link to post
Share on other sites
39 minutes ago, TFuto said:

I have no clue why this PROT_EXEC is needed at all. 

Neither do I.  From my point of view making stack for SC_THREAD executable makes no sense.  Probably this was a requirement for some outdated systems and needs to be revisited.

Share this post


Link to post
Share on other sites

Hi Tibor,

the stack_protect function is called upon creation and destruction of the thread.  Upon creation, a special guard page after the end of the stack is allocated and protected against accesses to catch (some) stack overflows.  Upon deletion of the thread, this protection is removed.

Quoting https://danwalsh.livejournal.com/6117.html (highlighting mine):

Quote

The POSIX specification does not permit it, but the Linux implementation of mprotect allows changing the access protection of memory on the heap (e.g., allocated using malloc). This error indicates that heap memory was supposed to be made executable. Doing this is really a bad idea. If anonymous, executable memory is needed it should be allocated using mmap which is the only portable mechanism.

Therefore, I agree that we probably don't need to try adding PROT_EXEC to the page's permissions and can only keep the read/write settings:

    // Revert the red zone to normal memory usage.

    else {
        ret = mprotect( redzone, pagesize - 1, PROT_READ|PROT_WRITE);
    }

Can you try with this change again?

Thanks and Greetings from Duisburg,
  Philipp

Edited by Philipp A Hartmann
fix link

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×