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(char * mnt)105 void set_selinuxmnt(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