Commit 9d590679 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'selinux-pr-20240814' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux

Pull selinux fixes from Paul Moore:

 - Fix a xperms counting problem where we adding to the xperms count
   even if we failed to add the xperm.

 - Propogate errors from avc_add_xperms_decision() back to the caller so
   that we can trigger the proper cleanup and error handling.

 - Revert our use of vma_is_initial_heap() in favor of our older logic
   as vma_is_initial_heap() doesn't correctly handle the no-heap case
   and it is causing issues with the SELinux process/execheap access
   control. While the older SELinux logic may not be perfect, it
   restores the expected user visible behavior.

   Hopefully we will be able to resolve the problem with the
   vma_is_initial_heap() macro with the mm folks, but we need to fix
   this in the meantime.

* tag 'selinux-pr-20240814' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux:
  selinux: revert our use of vma_is_initial_heap()
  selinux: add the processing of the failure of avc_add_xperms_decision()
  selinux: fix potential counting error in avc_add_xperms_decision()
parents 4ac0f08f 05a3d6e9
...@@ -330,12 +330,12 @@ static int avc_add_xperms_decision(struct avc_node *node, ...@@ -330,12 +330,12 @@ static int avc_add_xperms_decision(struct avc_node *node,
{ {
struct avc_xperms_decision_node *dest_xpd; struct avc_xperms_decision_node *dest_xpd;
node->ae.xp_node->xp.len++;
dest_xpd = avc_xperms_decision_alloc(src->used); dest_xpd = avc_xperms_decision_alloc(src->used);
if (!dest_xpd) if (!dest_xpd)
return -ENOMEM; return -ENOMEM;
avc_copy_xperms_decision(&dest_xpd->xpd, src); avc_copy_xperms_decision(&dest_xpd->xpd, src);
list_add(&dest_xpd->xpd_list, &node->ae.xp_node->xpd_head); list_add(&dest_xpd->xpd_list, &node->ae.xp_node->xpd_head);
node->ae.xp_node->xp.len++;
return 0; return 0;
} }
...@@ -907,7 +907,11 @@ static int avc_update_node(u32 event, u32 perms, u8 driver, u8 xperm, u32 ssid, ...@@ -907,7 +907,11 @@ static int avc_update_node(u32 event, u32 perms, u8 driver, u8 xperm, u32 ssid,
node->ae.avd.auditdeny &= ~perms; node->ae.avd.auditdeny &= ~perms;
break; break;
case AVC_CALLBACK_ADD_XPERMS: case AVC_CALLBACK_ADD_XPERMS:
avc_add_xperms_decision(node, xpd); rc = avc_add_xperms_decision(node, xpd);
if (rc) {
avc_node_kill(node);
goto out_unlock;
}
break; break;
} }
avc_node_replace(node, orig); avc_node_replace(node, orig);
......
...@@ -3852,7 +3852,17 @@ static int selinux_file_mprotect(struct vm_area_struct *vma, ...@@ -3852,7 +3852,17 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
if (default_noexec && if (default_noexec &&
(prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) { (prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) {
int rc = 0; int rc = 0;
if (vma_is_initial_heap(vma)) { /*
* We don't use the vma_is_initial_heap() helper as it has
* a history of problems and is currently broken on systems
* where there is no heap, e.g. brk == start_brk. Before
* replacing the conditional below with vma_is_initial_heap(),
* or something similar, please ensure that the logic is the
* same as what we have below or you have tested every possible
* corner case you can think to test.
*/
if (vma->vm_start >= vma->vm_mm->start_brk &&
vma->vm_end <= vma->vm_mm->brk) {
rc = avc_has_perm(sid, sid, SECCLASS_PROCESS, rc = avc_has_perm(sid, sid, SECCLASS_PROCESS,
PROCESS__EXECHEAP, NULL); PROCESS__EXECHEAP, NULL);
} else if (!vma->vm_file && (vma_is_initial_stack(vma) || } else if (!vma->vm_file && (vma_is_initial_stack(vma) ||
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment