| From: Kefeng Wang <wangkefeng.wang@huawei.com> |
| Subject: mm: fix VMA heap bounds checking |
| Date: Thu, 7 Dec 2023 23:25:25 +0800 |
| |
| After converting selinux to VMA heap check helper, the gcl triggers an |
| execheap SELinux denial, which is caused by a changed logic check. |
| |
| Previously selinux only checked that the VMA range was within the VMA heap |
| range, and the implementation checks the intersection between the two |
| ranges, but the corner case (vm_end=start_brk, brk=vm_start) isn't handled |
| correctly. |
| |
| Since commit 11250fd12eb8 ("mm: factor out VMA stack and heap checks") was |
| only a function extraction, it seems that the issue was introduced by |
| commit 0db0c01b53a1 ("procfs: fix /proc/<pid>/maps heap check"). Let's |
| fix above corner cases, meanwhile, correct the wrong indentation of the |
| stack and heap check helpers. |
| |
| Fixes: 11250fd12eb8 ("mm: factor out VMA stack and heap checks") |
| Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com> |
| Reported-by: Ondrej Mosnacek <omosnace@redhat.com> |
| Closes: https://lore.kernel.org/selinux/CAFqZXNv0SVT0fkOK6neP9AXbj3nxJ61JAY4+zJzvxqJaeuhbFw@mail.gmail.com/ |
| Tested-by: Ondrej Mosnacek <omosnace@redhat.com> |
| Link: https://lkml.kernel.org/r/20231207152525.2607420-1-wangkefeng.wang@huawei.com |
| Cc: David Hildenbrand <david@redhat.com> |
| Cc: Paul Moore <paul@paul-moore.com> |
| Cc: Peter Zijlstra <peterz@infradead.org> |
| Cc: Stephen Smalley <stephen.smalley.work@gmail.com> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| --- |
| |
| include/linux/mm.h | 8 ++++---- |
| 1 file changed, 4 insertions(+), 4 deletions(-) |
| |
| --- a/include/linux/mm.h~mm-fix-vma-heap-bounds-checking |
| +++ a/include/linux/mm.h |
| @@ -886,8 +886,8 @@ static inline bool vma_is_anonymous(stru |
| */ |
| static inline bool vma_is_initial_heap(const struct vm_area_struct *vma) |
| { |
| - return vma->vm_start <= vma->vm_mm->brk && |
| - vma->vm_end >= vma->vm_mm->start_brk; |
| + return vma->vm_start < vma->vm_mm->brk && |
| + vma->vm_end > vma->vm_mm->start_brk; |
| } |
| |
| /* |
| @@ -901,8 +901,8 @@ static inline bool vma_is_initial_stack( |
| * its "stack". It's not even well-defined for programs written |
| * languages like Go. |
| */ |
| - return vma->vm_start <= vma->vm_mm->start_stack && |
| - vma->vm_end >= vma->vm_mm->start_stack; |
| + return vma->vm_start <= vma->vm_mm->start_stack && |
| + vma->vm_end >= vma->vm_mm->start_stack; |
| } |
| |
| static inline bool vma_is_temporary_stack(struct vm_area_struct *vma) |
| _ |