summaryrefslogtreecommitdiff
blob: c811450ba396ee92daac28792e559e515a8f6ad5 (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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
From 32773a99b1f0cf2b61b5f5a33359684b18aab1ed Mon Sep 17 00:00:00 2001
From: Stephen Smalley <sds@tycho.nsa.gov>
Date: Fri, 13 May 2016 11:59:47 -0400
Subject: [PATCH] Avoid mounting /proc outside of selinux_init_load_policy().

Temporarily mounting /proc within selinuxfs_exists() can cause
problems since it can be called by a libselinux constructor and
therefore may be invoked by every program linked with libselinux.
Since this was only motivated originally by a situation where
selinuxfs_exists() was called from selinux_init_load_policy()
before /proc was mounted, fix it in selinux_init_load_policy() instead.

This reverts commit 5a8d8c499b2ef80eaa7b5abe2ec68d7101e613bf
("libselinux: only mount /proc if necessary") and
commit 9df498884665d79474b79f0f30d1cd67df11bd3e
("libselinux: Mount procfs before checking /proc/filesystems").

Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
---
 libselinux/src/init.c        | 27 +++------------------------
 libselinux/src/load_policy.c | 15 ++++++++++-----
 2 files changed, 13 insertions(+), 29 deletions(-)

diff --git a/libselinux/src/init.c b/libselinux/src/init.c
index 3530594..3c687a2 100644
--- libselinux/src/init.c
+++ libselinux/src/init.c
@@ -11,8 +11,6 @@
 #include <sys/vfs.h>
 #include <stdint.h>
 #include <limits.h>
-#include <sys/mount.h>
-#include <linux/magic.h>
 
 #include "dso.h"
 #include "policy.h"
@@ -58,26 +56,15 @@ static int verify_selinuxmnt(const char *mnt)
 
 int selinuxfs_exists(void)
 {
-	int exists = 0, mnt_rc = -1, rc;
-	struct statfs sb;
+	int exists = 0;
 	FILE *fp = NULL;
 	char *buf = NULL;
 	size_t len;
 	ssize_t num;
 
-	do {
-		rc = statfs("/proc", &sb);
-	} while (rc < 0 && errno == EINTR);
-
-	if (rc == 0 && ((uint32_t)sb.f_type != (uint32_t)PROC_SUPER_MAGIC))
-		mnt_rc = mount("proc", "/proc", "proc", 0, 0);
-
 	fp = fopen("/proc/filesystems", "r");
-	if (!fp) {
-		exists = 1; /* Fail as if it exists */
-		goto out;
-	}
-
+	if (!fp)
+		return 1; /* Fail as if it exists */
 	__fsetlocking(fp, FSETLOCKING_BYCALLER);
 
 	num = getline(&buf, &len, fp);
@@ -91,14 +78,6 @@ int selinuxfs_exists(void)
 
 	free(buf);
 	fclose(fp);
-
-out:
-#ifndef MNT_DETACH
-#define MNT_DETACH 2
-#endif
-	if (mnt_rc == 0)
-		umount2("/proc", MNT_DETACH);
-
 	return exists;
 }
 hidden_def(selinuxfs_exists)
diff --git a/libselinux/src/load_policy.c b/libselinux/src/load_policy.c
index 21ee58b..4f39fc7 100644
--- libselinux/src/load_policy.c
+++ libselinux/src/load_policy.c
@@ -17,6 +17,10 @@
 #include "policy.h"
 #include <limits.h>
 
+#ifndef MNT_DETACH
+#define MNT_DETACH 2
+#endif
+
 int security_load_policy(void *data, size_t len)
 {
 	char path[PATH_MAX];
@@ -348,11 +352,6 @@ int selinux_init_load_policy(int *enforce)
 		fclose(cfg);
 		free(buf);
 	}
-#ifndef MNT_DETACH
-#define MNT_DETACH 2
-#endif
-	if (rc == 0)
-		umount2("/proc", MNT_DETACH);
 
 	/* 
 	 * Determine the final desired mode.
@@ -400,11 +399,17 @@ int selinux_init_load_policy(int *enforce)
 			/* Only emit this error if selinux was not disabled */
 			fprintf(stderr, "Mount failed for selinuxfs on %s:  %s\n", SELINUXMNT, strerror(errno));
 		}
+
+		if (rc == 0)
+			umount2("/proc", MNT_DETACH);
                 
 		goto noload;
 	}
 	set_selinuxmnt(mntpoint);
 
+	if (rc == 0)
+		umount2("/proc", MNT_DETACH);
+
 	/*
 	 * Note:  The following code depends on having selinuxfs 
 	 * already mounted and selinuxmnt set above.
-- 
2.7.3