Re: [PATCH v3 3/4] selinux: use vma_is_initial_stack() and vma_is_initial_heap()

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

 





On 2024/8/8 14:43, Kefeng Wang wrote:

On 2024/8/8 9:10, Paul Moore wrote:
On Wed, Aug 7, 2024 at 5:26 PM Marc Reisner <reisner.marc@xxxxxxxxx> wrote:

It looks like this issue is still not fixed. There has been some
investigation on going in this Bugzilla for Fedora:

https://bugzilla.redhat.com/show_bug.cgi?id=2254434

FWIW, I recently learned there was also a report in the kernel
bugzilla about the same issue:

https://bugzilla.kernel.org/show_bug.cgi?id=218258

The behavior we are seeing is that when a process has no heap and
mmap(2) is called with MAP_PRIVATE | MAP_ANONYMOUS, it allocates memory
on the heap.

If the address space returned by mmap(2) is later on made executable
with mprotect(2), that triggers an execheap avc.

...

This has been reproduced on kernels >= 6.6.

I try the reproducer, but fails to reproduce on my 6.6

After enable selinux then trigger the issue.


In reviewing the code, my best guess is that this is caused by the
scenario where brk == start_brk not being handled, though I am not

Is there vma_start,end and start_brk,brk infos, adding some debug print.

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 81fbfa5b80d4..b66c381c558e 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3848,6 +3848,9 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
                 if (vma_is_initial_heap(vma)) {
                         rc = avc_has_perm(sid, sid, SECCLASS_PROCESS,
                                           PROCESS__EXECHEAP, NULL);
+                       if (rc)
+                               pr_err("DEBUG: vma_start,end=%lx,%lx, start_brk,brk=%lx,%lx\n", +                                       vma->vm_start, vma->vm_end, vma->vm_mm->start_brk, vma->vm_mm->brk);
                 } else if (!vma->vm_file && (vma_is_initial_stack(vma) ||
                             vma_is_stack_for_current(vma))) {
                         rc = avc_has_perm(sid, sid, SECCLASS_PROCESS,


[ 3520.913952] DEBUG: pid=769674,comm=test-vma, vma:start,end=1e9c000,21e9c000, start_brk,brk=2310000,2310000


vma_start <  start_brk = brk  < vma_end


expert enough in kernel code to know. If the start address allocated
by mmap is before the starting program break, and the end address is
after the starting program break, then the avc will trigger. However,
I don't know how mmap deals with determining an address and if it takes
into account the program break, or if calling brk(2) later on will just
pick a new location.

I'm not a mm expert, but thankfully we have some on the To/CC line so
I'm hopeful they will be able to take a look and provide some insight.

+Cc mmap maintainers too.


To bring the relevant code into this email, prior to using the
vma_is_initial_heap() helper the SELinux execheap logic looked like
this:

   /* WORKING */
   if (vma->vm_start >= vma->vm_mm->start_brk &&
       vma->vm_end <= vma->vm_mm->brk)
     /* execheap denial */


vma range must be within heap.

... while the current vma_is_initial_heap() helper has logic that
looks like this:

   /* BUGGY */
   if (vma->vm_start < vma->vm_mm->brk &&
       vma->vm_end > vma->vm_mm->start_brk)
     /* execheap denial */

vma range intersection with brk range will be rejected, and
there's a cross in above case, so execheap denial, I not sure it
should be allowed or not, hope maintainers give some comments here.

Thanks.




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux