aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorPaul Moore <pmoore@redhat.com>2014-03-19 16:46:11 -0400
committerPaul Moore <pmoore@redhat.com>2014-03-19 16:46:11 -0400
commit98883bfd9d603a2760f6d53eccfaa3ae2c053e72 (patch)
tree48454c4cd6d2c490796be28f0376d4f21dad227c /security
parent2c5f5c9a1d1b3559cbbda8e014706eb359566c00 (diff)
selinux: put the mmap() DAC controls before the MAC controls
It turns out that doing the SELinux MAC checks for mmap() before the DAC checks was causing users and the SELinux policy folks headaches as users were seeing a lot of SELinux AVC denials for the memprotect:mmap_zero permission that would have also been denied by the normal DAC capability checks (CAP_SYS_RAWIO). Example: # cat mmap_test.c #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <sys/mman.h> int main(int argc, char *argv[]) { int rc; void *mem; mem = mmap(0x0, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); if (mem == MAP_FAILED) return errno; printf("mem = %p\n", mem); munmap(mem, 4096); return 0; } # gcc -g -O0 -o mmap_test mmap_test.c # ./mmap_test mem = (nil) # ausearch -m AVC | grep mmap_zero type=AVC msg=audit(...): avc: denied { mmap_zero } for pid=1025 comm="mmap_test" scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tcontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tclass=memprotect This patch corrects things so that when the above example is run by a user without CAP_SYS_RAWIO the SELinux AVC is no longer generated as the DAC capability check fails before the SELinux permission check. Signed-off-by: Paul Moore <pmoore@redhat.com> Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Diffstat (limited to 'security')
-rw-r--r--security/selinux/hooks.c20
1 files changed, 8 insertions, 12 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 0e68bdbe020a..1dd948485e48 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3188,24 +3188,20 @@ error:
3188 3188
3189static int selinux_mmap_addr(unsigned long addr) 3189static int selinux_mmap_addr(unsigned long addr)
3190{ 3190{
3191 int rc = 0; 3191 int rc;
3192 u32 sid = current_sid(); 3192
3193 /* do DAC check on address space usage */
3194 rc = cap_mmap_addr(addr);
3195 if (rc)
3196 return rc;
3193 3197
3194 /*
3195 * notice that we are intentionally putting the SELinux check before
3196 * the secondary cap_file_mmap check. This is such a likely attempt
3197 * at bad behaviour/exploit that we always want to get the AVC, even
3198 * if DAC would have also denied the operation.
3199 */
3200 if (addr < CONFIG_LSM_MMAP_MIN_ADDR) { 3198 if (addr < CONFIG_LSM_MMAP_MIN_ADDR) {
3199 u32 sid = current_sid();
3201 rc = avc_has_perm(sid, sid, SECCLASS_MEMPROTECT, 3200 rc = avc_has_perm(sid, sid, SECCLASS_MEMPROTECT,
3202 MEMPROTECT__MMAP_ZERO, NULL); 3201 MEMPROTECT__MMAP_ZERO, NULL);
3203 if (rc)
3204 return rc;
3205 } 3202 }
3206 3203
3207 /* do DAC check on address space usage */ 3204 return rc;
3208 return cap_mmap_addr(addr);
3209} 3205}
3210 3206
3211static int selinux_mmap_file(struct file *file, unsigned long reqprot, 3207static int selinux_mmap_file(struct file *file, unsigned long reqprot,