Re: MAP_STACK and execstack

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 10/02/2015 04:44 PM, Nick Kralevich wrote:
Currently, SELinux implements the "execstack" capability using the
following code:

security/selinux/hooks.c
function: selinux_file_mprotect()

} else if (!vma->vm_file &&
               vma->vm_start <= vma->vm_mm->start_stack &&
               vma->vm_end >= vma->vm_mm->start_stack) {
     rc = current_has_perm(current, PROCESS__EXECSTACK);
}

However, at least on Android, this check doesn't work for pthread
allocated stacks. Those stacks are allocated in libc via mmap(), and
aren't accounted for in the kernel as stack pages. As a result,
attempting to mprotect(PROT_EXEC) a pthread stack page requires the
"execmem" permission, not the "execstack" permission.

"man mmap" defines MAP_STACK, which is currently a no-op in the kernel
indicating that the memory is intended to be used as a stack. In
theory, Android's libc could set this flag for memory intended to be
used as a stack, but doing so is useless if the kernel ignores it.

Is there any reason why SELinux shouldn't use MAP_STACK to determine
whether the execmem or execstack capability is checked? In Android,
this would be a net security win, since nobody is granted execstack
today.

To clarify, execstack is a check on mprotect() in addition to (not instead of) execmem when the mapping is part of the stack. execmem is always required.

At the time execstack was added, /proc/pid/maps / show_map_vma only identified the main process stack and the same logic was used to identify it for the execstack check.

Since that time, /proc/pid/maps has been augmented to also identify thread stacks, so the logic from show_map_vma could be reused for the execstack check as well.

Using MAP_STACK as the basis for the check seems less desirable, as it is entirely at the discretion of the program (so can be easily omitted, thereby making the check opt-in), is only passed on mmap() not mprotect() and doesn't appear to be saved anywhere, so it isn't available on mprotect() calls, and is ignored by the kernel. The commit that added it said:

commit cd98a04a59e2f94fa64d5bf1e26498d27427d5e7
Author: Ingo Molnar <mingo@xxxxxxx>
Date:   Wed Aug 13 18:02:18 2008 +0200

    x86: add MAP_STACK mmap flag

    as per this discussion:

       http://lkml.org/lkml/2008/8/12/423

    Pardo reported that 64-bit threaded apps, if their stacks exceed the
combined size of ~4GB, slow down drastically in pthread_create() - because
    glibc uses MAP_32BIT to allocate the stacks. The use of MAP_32BIT is
    a legacy hack - to speed up context switching on certain early model
    64-bit P4 CPUs.

    So introduce a new flag to be used by glibc instead, to not constrain
    64-bit apps like this.

    glibc can switch to this new flag straight away - it will be ignored
    by the kernel. If those old CPUs ever matter to anyone, support for
    it can be implemented.
_______________________________________________
Selinux mailing list
Selinux@xxxxxxxxxxxxx
To unsubscribe, send email to Selinux-leave@xxxxxxxxxxxxx.
To get help, send an email containing "help" to Selinux-request@xxxxxxxxxxxxx.



[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux