1 #include <unistd.h>
2 #include <fcntl.h>
3 #include <string.h>
4 #include <stdlib.h>
5 #include <errno.h>
6 #include <ctype.h>
7 #include <stdio.h>
8 #include <dlfcn.h>
9 
10 #ifdef DARWIN
11 #include <sys/param.h>
12 #include <sys/mount.h>
13 #else
14 #include <sys/vfs.h>
15 #endif
16 
17 #include <stdint.h>
18 #include <limits.h>
19 
20 #include "dso.h"
21 #include "policy.h"
22 #include "selinux_internal.h"
23 
24 char *selinux_mnt = NULL;
25 int selinux_page_size = 0;
26 
init_selinuxmnt(void)27 static void init_selinuxmnt(void)
28 {
29 	char buf[BUFSIZ], *p;
30 	FILE *fp=NULL;
31 	struct statfs sfbuf;
32 	int rc;
33 	char *bufp;
34 	int exists = 0;
35 
36 	if (selinux_mnt)
37 		return;
38 
39 	/* We check to see if the preferred mount point for selinux file
40 	 * system has a selinuxfs. */
41 	do {
42 		rc = statfs(SELINUXMNT, &sfbuf);
43 	} while (rc < 0 && errno == EINTR);
44 	if (rc == 0) {
45 		if ((uint32_t)sfbuf.f_type == (uint32_t)SELINUX_MAGIC) {
46 			selinux_mnt = strdup(SELINUXMNT);
47 			return;
48 		}
49 	}
50 
51 	/* Drop back to detecting it the long way. */
52 	fp = fopen("/proc/filesystems", "r");
53 	if (!fp)
54 		return;
55 
56 	while ((bufp = fgets(buf, sizeof buf - 1, fp)) != NULL) {
57 		if (strstr(buf, "selinuxfs")) {
58 			exists = 1;
59 			break;
60 		}
61 	}
62 
63 	if (!exists)
64 		goto out;
65 
66 	fclose(fp);
67 
68 	/* At this point, the usual spot doesn't have an selinuxfs so
69 	 * we look around for it */
70 	fp = fopen("/proc/mounts", "r");
71 	if (!fp)
72 		goto out;
73 
74 	while ((bufp = fgets(buf, sizeof buf - 1, fp)) != NULL) {
75 		char *tmp;
76 		p = strchr(buf, ' ');
77 		if (!p)
78 			goto out;
79 		p++;
80 		tmp = strchr(p, ' ');
81 		if (!tmp)
82 			goto out;
83 		if (!strncmp(tmp + 1, "selinuxfs ", 10)) {
84 			*tmp = '\0';
85 			break;
86 		}
87 	}
88 
89 	/* If we found something, dup it */
90 	if (bufp)
91 		selinux_mnt = strdup(p);
92 
93       out:
94 	if (fp)
95 		fclose(fp);
96 	return;
97 }
98 
fini_selinuxmnt(void)99 void fini_selinuxmnt(void)
100 {
101 	free(selinux_mnt);
102 	selinux_mnt = NULL;
103 }
104 
set_selinuxmnt(const char * mnt)105 void set_selinuxmnt(const char *mnt)
106 {
107 	selinux_mnt = strdup(mnt);
108 }
109 
110 hidden_def(set_selinuxmnt)
111 
112 static void init_lib(void) __attribute__ ((constructor));
init_lib(void)113 static void init_lib(void)
114 {
115 	selinux_page_size = sysconf(_SC_PAGE_SIZE);
116 	init_selinuxmnt();
117 }
118 
119 static void fini_lib(void) __attribute__ ((destructor));
fini_lib(void)120 static void fini_lib(void)
121 {
122 	fini_selinuxmnt();
123 }
124