xref: /aosp_15_r20/external/selinux/libselinux/src/init.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1*2d543d20SAndroid Build Coastguard Worker #include <unistd.h>
2*2d543d20SAndroid Build Coastguard Worker #include <fcntl.h>
3*2d543d20SAndroid Build Coastguard Worker #include <string.h>
4*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
5*2d543d20SAndroid Build Coastguard Worker #include <errno.h>
6*2d543d20SAndroid Build Coastguard Worker #include <ctype.h>
7*2d543d20SAndroid Build Coastguard Worker #include <stdio.h>
8*2d543d20SAndroid Build Coastguard Worker #include <stdio_ext.h>
9*2d543d20SAndroid Build Coastguard Worker #include <dlfcn.h>
10*2d543d20SAndroid Build Coastguard Worker #include <sys/statvfs.h>
11*2d543d20SAndroid Build Coastguard Worker #include <sys/vfs.h>
12*2d543d20SAndroid Build Coastguard Worker #include <stdint.h>
13*2d543d20SAndroid Build Coastguard Worker #include <limits.h>
14*2d543d20SAndroid Build Coastguard Worker 
15*2d543d20SAndroid Build Coastguard Worker #include "policy.h"
16*2d543d20SAndroid Build Coastguard Worker #include "selinux_internal.h"
17*2d543d20SAndroid Build Coastguard Worker #include "setrans_internal.h"
18*2d543d20SAndroid Build Coastguard Worker 
19*2d543d20SAndroid Build Coastguard Worker char *selinux_mnt = NULL;
20*2d543d20SAndroid Build Coastguard Worker int selinux_page_size = 0;
21*2d543d20SAndroid Build Coastguard Worker 
22*2d543d20SAndroid Build Coastguard Worker int has_selinux_config = 0;
23*2d543d20SAndroid Build Coastguard Worker 
24*2d543d20SAndroid Build Coastguard Worker /* Verify the mount point for selinux file system has a selinuxfs.
25*2d543d20SAndroid Build Coastguard Worker    If the file system:
26*2d543d20SAndroid Build Coastguard Worker    * Exist,
27*2d543d20SAndroid Build Coastguard Worker    * Is mounted with an selinux file system,
28*2d543d20SAndroid Build Coastguard Worker    * The file system is read/write
29*2d543d20SAndroid Build Coastguard Worker    * then set this as the default file system.
30*2d543d20SAndroid Build Coastguard Worker */
verify_selinuxmnt(const char * mnt)31*2d543d20SAndroid Build Coastguard Worker static int verify_selinuxmnt(const char *mnt)
32*2d543d20SAndroid Build Coastguard Worker {
33*2d543d20SAndroid Build Coastguard Worker 	struct statfs sfbuf;
34*2d543d20SAndroid Build Coastguard Worker 	int rc;
35*2d543d20SAndroid Build Coastguard Worker 
36*2d543d20SAndroid Build Coastguard Worker 	do {
37*2d543d20SAndroid Build Coastguard Worker 		rc = statfs(mnt, &sfbuf);
38*2d543d20SAndroid Build Coastguard Worker 	} while (rc < 0 && errno == EINTR);
39*2d543d20SAndroid Build Coastguard Worker 	if (rc == 0) {
40*2d543d20SAndroid Build Coastguard Worker 		if ((uint32_t)sfbuf.f_type == (uint32_t)SELINUX_MAGIC) {
41*2d543d20SAndroid Build Coastguard Worker 			struct statvfs vfsbuf;
42*2d543d20SAndroid Build Coastguard Worker 			rc = statvfs(mnt, &vfsbuf);
43*2d543d20SAndroid Build Coastguard Worker 			if (rc == 0) {
44*2d543d20SAndroid Build Coastguard Worker 				if (!(vfsbuf.f_flag & ST_RDONLY)) {
45*2d543d20SAndroid Build Coastguard Worker 					set_selinuxmnt(mnt);
46*2d543d20SAndroid Build Coastguard Worker 				}
47*2d543d20SAndroid Build Coastguard Worker 				return 0;
48*2d543d20SAndroid Build Coastguard Worker 			}
49*2d543d20SAndroid Build Coastguard Worker 		}
50*2d543d20SAndroid Build Coastguard Worker 	}
51*2d543d20SAndroid Build Coastguard Worker 
52*2d543d20SAndroid Build Coastguard Worker 	return -1;
53*2d543d20SAndroid Build Coastguard Worker }
54*2d543d20SAndroid Build Coastguard Worker 
selinuxfs_exists(void)55*2d543d20SAndroid Build Coastguard Worker int selinuxfs_exists(void)
56*2d543d20SAndroid Build Coastguard Worker {
57*2d543d20SAndroid Build Coastguard Worker 	int exists = 0;
58*2d543d20SAndroid Build Coastguard Worker 	FILE *fp = NULL;
59*2d543d20SAndroid Build Coastguard Worker 	char *buf = NULL;
60*2d543d20SAndroid Build Coastguard Worker 	size_t len;
61*2d543d20SAndroid Build Coastguard Worker 	ssize_t num;
62*2d543d20SAndroid Build Coastguard Worker 
63*2d543d20SAndroid Build Coastguard Worker 	fp = fopen("/proc/filesystems", "re");
64*2d543d20SAndroid Build Coastguard Worker 	if (!fp)
65*2d543d20SAndroid Build Coastguard Worker 		return 1; /* Fail as if it exists */
66*2d543d20SAndroid Build Coastguard Worker 	__fsetlocking(fp, FSETLOCKING_BYCALLER);
67*2d543d20SAndroid Build Coastguard Worker 
68*2d543d20SAndroid Build Coastguard Worker 	num = getline(&buf, &len, fp);
69*2d543d20SAndroid Build Coastguard Worker 	while (num != -1) {
70*2d543d20SAndroid Build Coastguard Worker 		if (strstr(buf, SELINUXFS)) {
71*2d543d20SAndroid Build Coastguard Worker 			exists = 1;
72*2d543d20SAndroid Build Coastguard Worker 			break;
73*2d543d20SAndroid Build Coastguard Worker 		}
74*2d543d20SAndroid Build Coastguard Worker 		num = getline(&buf, &len, fp);
75*2d543d20SAndroid Build Coastguard Worker 	}
76*2d543d20SAndroid Build Coastguard Worker 
77*2d543d20SAndroid Build Coastguard Worker 	free(buf);
78*2d543d20SAndroid Build Coastguard Worker 	fclose(fp);
79*2d543d20SAndroid Build Coastguard Worker 	return exists;
80*2d543d20SAndroid Build Coastguard Worker }
81*2d543d20SAndroid Build Coastguard Worker 
init_selinuxmnt(void)82*2d543d20SAndroid Build Coastguard Worker static void init_selinuxmnt(void)
83*2d543d20SAndroid Build Coastguard Worker {
84*2d543d20SAndroid Build Coastguard Worker 	char *buf = NULL, *p;
85*2d543d20SAndroid Build Coastguard Worker 	FILE *fp = NULL;
86*2d543d20SAndroid Build Coastguard Worker 	size_t len;
87*2d543d20SAndroid Build Coastguard Worker 	ssize_t num;
88*2d543d20SAndroid Build Coastguard Worker 
89*2d543d20SAndroid Build Coastguard Worker 	if (selinux_mnt)
90*2d543d20SAndroid Build Coastguard Worker 		return;
91*2d543d20SAndroid Build Coastguard Worker 
92*2d543d20SAndroid Build Coastguard Worker 	if (verify_selinuxmnt(SELINUXMNT) == 0) return;
93*2d543d20SAndroid Build Coastguard Worker 
94*2d543d20SAndroid Build Coastguard Worker 	if (verify_selinuxmnt(OLDSELINUXMNT) == 0) return;
95*2d543d20SAndroid Build Coastguard Worker 
96*2d543d20SAndroid Build Coastguard Worker 	/* Drop back to detecting it the long way. */
97*2d543d20SAndroid Build Coastguard Worker 	if (!selinuxfs_exists())
98*2d543d20SAndroid Build Coastguard Worker 		goto out;
99*2d543d20SAndroid Build Coastguard Worker 
100*2d543d20SAndroid Build Coastguard Worker 	/* At this point, the usual spot doesn't have an selinuxfs so
101*2d543d20SAndroid Build Coastguard Worker 	 * we look around for it */
102*2d543d20SAndroid Build Coastguard Worker 	fp = fopen("/proc/mounts", "re");
103*2d543d20SAndroid Build Coastguard Worker 	if (!fp)
104*2d543d20SAndroid Build Coastguard Worker 		goto out;
105*2d543d20SAndroid Build Coastguard Worker 
106*2d543d20SAndroid Build Coastguard Worker 	__fsetlocking(fp, FSETLOCKING_BYCALLER);
107*2d543d20SAndroid Build Coastguard Worker 	while ((num = getline(&buf, &len, fp)) != -1) {
108*2d543d20SAndroid Build Coastguard Worker 		char *tmp;
109*2d543d20SAndroid Build Coastguard Worker 		p = strchr(buf, ' ');
110*2d543d20SAndroid Build Coastguard Worker 		if (!p)
111*2d543d20SAndroid Build Coastguard Worker 			goto out;
112*2d543d20SAndroid Build Coastguard Worker 		p++;
113*2d543d20SAndroid Build Coastguard Worker 		tmp = strchr(p, ' ');
114*2d543d20SAndroid Build Coastguard Worker 		if (!tmp)
115*2d543d20SAndroid Build Coastguard Worker 			goto out;
116*2d543d20SAndroid Build Coastguard Worker 		if (!strncmp(tmp + 1, SELINUXFS" ", strlen(SELINUXFS)+1)) {
117*2d543d20SAndroid Build Coastguard Worker 			*tmp = '\0';
118*2d543d20SAndroid Build Coastguard Worker 			break;
119*2d543d20SAndroid Build Coastguard Worker 		}
120*2d543d20SAndroid Build Coastguard Worker 	}
121*2d543d20SAndroid Build Coastguard Worker 
122*2d543d20SAndroid Build Coastguard Worker 	/* If we found something, dup it */
123*2d543d20SAndroid Build Coastguard Worker 	if (num > 0)
124*2d543d20SAndroid Build Coastguard Worker 		verify_selinuxmnt(p);
125*2d543d20SAndroid Build Coastguard Worker 
126*2d543d20SAndroid Build Coastguard Worker       out:
127*2d543d20SAndroid Build Coastguard Worker 	free(buf);
128*2d543d20SAndroid Build Coastguard Worker 	if (fp)
129*2d543d20SAndroid Build Coastguard Worker 		fclose(fp);
130*2d543d20SAndroid Build Coastguard Worker 	return;
131*2d543d20SAndroid Build Coastguard Worker }
132*2d543d20SAndroid Build Coastguard Worker 
fini_selinuxmnt(void)133*2d543d20SAndroid Build Coastguard Worker void fini_selinuxmnt(void)
134*2d543d20SAndroid Build Coastguard Worker {
135*2d543d20SAndroid Build Coastguard Worker 	free(selinux_mnt);
136*2d543d20SAndroid Build Coastguard Worker 	selinux_mnt = NULL;
137*2d543d20SAndroid Build Coastguard Worker }
138*2d543d20SAndroid Build Coastguard Worker 
139*2d543d20SAndroid Build Coastguard Worker 
set_selinuxmnt(const char * mnt)140*2d543d20SAndroid Build Coastguard Worker void set_selinuxmnt(const char *mnt)
141*2d543d20SAndroid Build Coastguard Worker {
142*2d543d20SAndroid Build Coastguard Worker 	selinux_mnt = strdup(mnt);
143*2d543d20SAndroid Build Coastguard Worker }
144*2d543d20SAndroid Build Coastguard Worker 
145*2d543d20SAndroid Build Coastguard Worker 
146*2d543d20SAndroid Build Coastguard Worker static void init_lib(void) __attribute__ ((constructor));
init_lib(void)147*2d543d20SAndroid Build Coastguard Worker static void init_lib(void)
148*2d543d20SAndroid Build Coastguard Worker {
149*2d543d20SAndroid Build Coastguard Worker 	selinux_page_size = sysconf(_SC_PAGE_SIZE);
150*2d543d20SAndroid Build Coastguard Worker #ifndef ANDROID_UNIT_TESTING
151*2d543d20SAndroid Build Coastguard Worker 	init_selinuxmnt();
152*2d543d20SAndroid Build Coastguard Worker #ifndef ANDROID
153*2d543d20SAndroid Build Coastguard Worker 	has_selinux_config = (access(SELINUXCONFIG, F_OK) == 0);
154*2d543d20SAndroid Build Coastguard Worker #endif
155*2d543d20SAndroid Build Coastguard Worker #endif
156*2d543d20SAndroid Build Coastguard Worker }
157*2d543d20SAndroid Build Coastguard Worker 
158*2d543d20SAndroid Build Coastguard Worker static void fini_lib(void) __attribute__ ((destructor));
fini_lib(void)159*2d543d20SAndroid Build Coastguard Worker static void fini_lib(void)
160*2d543d20SAndroid Build Coastguard Worker {
161*2d543d20SAndroid Build Coastguard Worker #ifndef ANDROID_UNIT_TESTING
162*2d543d20SAndroid Build Coastguard Worker 	fini_selinuxmnt();
163*2d543d20SAndroid Build Coastguard Worker #endif
164*2d543d20SAndroid Build Coastguard Worker }
165