summaryrefslogtreecommitdiffstats
path: root/selinux-put-the-mmap-DAC-controls-before-the-MAC-controls.patch
blob: 5d9a4ff4a585effc30d10f0e4063041107cd59ba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
Bugzilla: 1013466
Upstream-status: 3.15 (commit 98883bfd9d603a2760f6d53eccfaa3ae2c053e72)

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>
---
 security/selinux/hooks.c |   20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 57b0b49..e3664ae 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3205,24 +3205,20 @@ error:
 
 static int selinux_mmap_addr(unsigned long addr)
 {
-	int rc = 0;
-	u32 sid = current_sid();
+	int rc;
+
+	/* do DAC check on address space usage */
+	rc = cap_mmap_addr(addr);
+	if (rc)
+		return rc;
 
-	/*
-	 * notice that we are intentionally putting the SELinux check before
-	 * the secondary cap_file_mmap check.  This is such a likely attempt
-	 * at bad behaviour/exploit that we always want to get the AVC, even
-	 * if DAC would have also denied the operation.
-	 */
 	if (addr < CONFIG_LSM_MMAP_MIN_ADDR) {
+		u32 sid = current_sid();
 		rc = avc_has_perm(sid, sid, SECCLASS_MEMPROTECT,
 				  MEMPROTECT__MMAP_ZERO, NULL);
-		if (rc)
-			return rc;
 	}
 
-	/* do DAC check on address space usage */
-	return cap_mmap_addr(addr);
+	return rc;
 }
 
 static int selinux_mmap_file(struct file *file, unsigned long reqprot,

_______________________________________________
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to Selinux-leave@tycho.nsa.gov.
To get help, send an email containing "help" to Selinux-request@tycho.nsa.gov.