diff options
author | Stephen Smalley <sds@tycho.nsa.gov> | 2006-02-01 06:05:54 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-02-01 11:53:18 -0500 |
commit | db4c9641def55d36a6f9df79deb8a949292313ca (patch) | |
tree | f3b786a346f0c987d796784e1e08154338263ad3 /security/selinux | |
parent | ee13d785eac1fbe7e79ecca77bf7e902734a0b30 (diff) |
[PATCH] selinux: fix and cleanup mprotect checks
Fix the SELinux mprotect checks on executable mappings so that they are not
re-applied when the mapping is already executable as well as cleaning up
the code. This avoids a situation where e.g. an application is prevented
from removing PROT_WRITE on an already executable mapping previously
authorized via execmem permission due to an execmod denial.
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
Acked-by: James Morris <jmorris@namei.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'security/selinux')
-rw-r--r-- | security/selinux/hooks.c | 50 |
1 files changed, 21 insertions, 29 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index b9f8d9731c3d..1bb5eea3b8c1 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -2454,35 +2454,27 @@ static int selinux_file_mprotect(struct vm_area_struct *vma, | |||
2454 | prot = reqprot; | 2454 | prot = reqprot; |
2455 | 2455 | ||
2456 | #ifndef CONFIG_PPC32 | 2456 | #ifndef CONFIG_PPC32 |
2457 | if ((prot & PROT_EXEC) && !(vma->vm_flags & VM_EXECUTABLE) && | 2457 | if ((prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) { |
2458 | (vma->vm_start >= vma->vm_mm->start_brk && | 2458 | rc = 0; |
2459 | vma->vm_end <= vma->vm_mm->brk)) { | 2459 | if (vma->vm_start >= vma->vm_mm->start_brk && |
2460 | /* | 2460 | vma->vm_end <= vma->vm_mm->brk) { |
2461 | * We are making an executable mapping in the brk region. | 2461 | rc = task_has_perm(current, current, |
2462 | * This has an additional execheap check. | 2462 | PROCESS__EXECHEAP); |
2463 | */ | 2463 | } else if (!vma->vm_file && |
2464 | rc = task_has_perm(current, current, PROCESS__EXECHEAP); | 2464 | vma->vm_start <= vma->vm_mm->start_stack && |
2465 | if (rc) | 2465 | vma->vm_end >= vma->vm_mm->start_stack) { |
2466 | return rc; | 2466 | rc = task_has_perm(current, current, PROCESS__EXECSTACK); |
2467 | } | 2467 | } else if (vma->vm_file && vma->anon_vma) { |
2468 | if (vma->vm_file != NULL && vma->anon_vma != NULL && (prot & PROT_EXEC)) { | 2468 | /* |
2469 | /* | 2469 | * We are making executable a file mapping that has |
2470 | * We are making executable a file mapping that has | 2470 | * had some COW done. Since pages might have been |
2471 | * had some COW done. Since pages might have been written, | 2471 | * written, check ability to execute the possibly |
2472 | * check ability to execute the possibly modified content. | 2472 | * modified content. This typically should only |
2473 | * This typically should only occur for text relocations. | 2473 | * occur for text relocations. |
2474 | */ | 2474 | */ |
2475 | int rc = file_has_perm(current, vma->vm_file, FILE__EXECMOD); | 2475 | rc = file_has_perm(current, vma->vm_file, |
2476 | if (rc) | 2476 | FILE__EXECMOD); |
2477 | return rc; | 2477 | } |
2478 | } | ||
2479 | if (!vma->vm_file && (prot & PROT_EXEC) && | ||
2480 | vma->vm_start <= vma->vm_mm->start_stack && | ||
2481 | vma->vm_end >= vma->vm_mm->start_stack) { | ||
2482 | /* Attempt to make the process stack executable. | ||
2483 | * This has an additional execstack check. | ||
2484 | */ | ||
2485 | rc = task_has_perm(current, current, PROCESS__EXECSTACK); | ||
2486 | if (rc) | 2478 | if (rc) |
2487 | return rc; | 2479 | return rc; |
2488 | } | 2480 | } |