xref: /aosp_15_r20/external/selinux/libselinux/src/android/android.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1*2d543d20SAndroid Build Coastguard Worker #include <errno.h>
2*2d543d20SAndroid Build Coastguard Worker #include <fnmatch.h>
3*2d543d20SAndroid Build Coastguard Worker #include <stdio.h>
4*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
5*2d543d20SAndroid Build Coastguard Worker #include <unistd.h>
6*2d543d20SAndroid Build Coastguard Worker 
7*2d543d20SAndroid Build Coastguard Worker #include <log/log.h>
8*2d543d20SAndroid Build Coastguard Worker #include <selinux/android.h>
9*2d543d20SAndroid Build Coastguard Worker #include <selinux/label.h>
10*2d543d20SAndroid Build Coastguard Worker 
11*2d543d20SAndroid Build Coastguard Worker #include "android_internal.h"
12*2d543d20SAndroid Build Coastguard Worker #include "callbacks.h"
13*2d543d20SAndroid Build Coastguard Worker 
14*2d543d20SAndroid Build Coastguard Worker #ifdef __ANDROID_VNDK__
15*2d543d20SAndroid Build Coastguard Worker #ifndef LOG_EVENT_STRING
16*2d543d20SAndroid Build Coastguard Worker #define LOG_EVENT_STRING(...)
17*2d543d20SAndroid Build Coastguard Worker #endif  // LOG_EVENT_STRING
18*2d543d20SAndroid Build Coastguard Worker #endif  // __ANDROID_VNDK__
19*2d543d20SAndroid Build Coastguard Worker 
20*2d543d20SAndroid Build Coastguard Worker static const path_alts_t service_context_paths = { .paths = {
21*2d543d20SAndroid Build Coastguard Worker 	{
22*2d543d20SAndroid Build Coastguard Worker 		"/system/etc/selinux/plat_service_contexts",
23*2d543d20SAndroid Build Coastguard Worker 		"/plat_service_contexts"
24*2d543d20SAndroid Build Coastguard Worker 	},
25*2d543d20SAndroid Build Coastguard Worker 	{
26*2d543d20SAndroid Build Coastguard Worker 		"/system_ext/etc/selinux/system_ext_service_contexts",
27*2d543d20SAndroid Build Coastguard Worker 		"/system_ext_service_contexts"
28*2d543d20SAndroid Build Coastguard Worker 	},
29*2d543d20SAndroid Build Coastguard Worker 	{
30*2d543d20SAndroid Build Coastguard Worker 		"/product/etc/selinux/product_service_contexts",
31*2d543d20SAndroid Build Coastguard Worker 		"/product_service_contexts"
32*2d543d20SAndroid Build Coastguard Worker 	},
33*2d543d20SAndroid Build Coastguard Worker 	{
34*2d543d20SAndroid Build Coastguard Worker 		"/vendor/etc/selinux/vendor_service_contexts",
35*2d543d20SAndroid Build Coastguard Worker 		"/vendor_service_contexts"
36*2d543d20SAndroid Build Coastguard Worker 	},
37*2d543d20SAndroid Build Coastguard Worker 	{
38*2d543d20SAndroid Build Coastguard Worker 		"/odm/etc/selinux/odm_service_contexts",
39*2d543d20SAndroid Build Coastguard Worker 	}
40*2d543d20SAndroid Build Coastguard Worker }};
41*2d543d20SAndroid Build Coastguard Worker 
42*2d543d20SAndroid Build Coastguard Worker static const path_alts_t hwservice_context_paths = { .paths = {
43*2d543d20SAndroid Build Coastguard Worker 	{
44*2d543d20SAndroid Build Coastguard Worker 		"/system/etc/selinux/plat_hwservice_contexts",
45*2d543d20SAndroid Build Coastguard Worker 		"/plat_hwservice_contexts"
46*2d543d20SAndroid Build Coastguard Worker 	},
47*2d543d20SAndroid Build Coastguard Worker 	{
48*2d543d20SAndroid Build Coastguard Worker 		"/system_ext/etc/selinux/system_ext_hwservice_contexts",
49*2d543d20SAndroid Build Coastguard Worker 		"/system_ext_hwservice_contexts"
50*2d543d20SAndroid Build Coastguard Worker 	},
51*2d543d20SAndroid Build Coastguard Worker 	{
52*2d543d20SAndroid Build Coastguard Worker 		"/product/etc/selinux/product_hwservice_contexts",
53*2d543d20SAndroid Build Coastguard Worker 		"/product_hwservice_contexts"
54*2d543d20SAndroid Build Coastguard Worker 	},
55*2d543d20SAndroid Build Coastguard Worker 	{
56*2d543d20SAndroid Build Coastguard Worker 		"/vendor/etc/selinux/vendor_hwservice_contexts",
57*2d543d20SAndroid Build Coastguard Worker 		"/vendor_hwservice_contexts"
58*2d543d20SAndroid Build Coastguard Worker 	},
59*2d543d20SAndroid Build Coastguard Worker 	{
60*2d543d20SAndroid Build Coastguard Worker 		"/odm/etc/selinux/odm_hwservice_contexts",
61*2d543d20SAndroid Build Coastguard Worker 		"/odm_hwservice_contexts"
62*2d543d20SAndroid Build Coastguard Worker 	},
63*2d543d20SAndroid Build Coastguard Worker }};
64*2d543d20SAndroid Build Coastguard Worker 
65*2d543d20SAndroid Build Coastguard Worker static const path_alts_t vndservice_context_paths = { .paths = {
66*2d543d20SAndroid Build Coastguard Worker 	{
67*2d543d20SAndroid Build Coastguard Worker 		"/vendor/etc/selinux/vndservice_contexts",
68*2d543d20SAndroid Build Coastguard Worker 		"/vndservice_contexts"
69*2d543d20SAndroid Build Coastguard Worker 	}
70*2d543d20SAndroid Build Coastguard Worker }};
71*2d543d20SAndroid Build Coastguard Worker 
72*2d543d20SAndroid Build Coastguard Worker static const path_alts_t keystore2_context_paths = { .paths = {
73*2d543d20SAndroid Build Coastguard Worker 	{
74*2d543d20SAndroid Build Coastguard Worker 		"/system/etc/selinux/plat_keystore2_key_contexts",
75*2d543d20SAndroid Build Coastguard Worker 		"/plat_keystore2_key_contexts"
76*2d543d20SAndroid Build Coastguard Worker 	},
77*2d543d20SAndroid Build Coastguard Worker 	{
78*2d543d20SAndroid Build Coastguard Worker 		"/system_ext/etc/selinux/system_ext_keystore2_key_contexts",
79*2d543d20SAndroid Build Coastguard Worker 		"/system_ext_keystore2_key_contexts"
80*2d543d20SAndroid Build Coastguard Worker 	},
81*2d543d20SAndroid Build Coastguard Worker 	{
82*2d543d20SAndroid Build Coastguard Worker 		"/product/etc/selinux/product_keystore2_key_contexts",
83*2d543d20SAndroid Build Coastguard Worker 		"/product_keystore2_key_contexts"
84*2d543d20SAndroid Build Coastguard Worker 	},
85*2d543d20SAndroid Build Coastguard Worker 	{
86*2d543d20SAndroid Build Coastguard Worker 		"/vendor/etc/selinux/vendor_keystore2_key_contexts",
87*2d543d20SAndroid Build Coastguard Worker 		"/vendor_keystore2_key_contexts"
88*2d543d20SAndroid Build Coastguard Worker 	}
89*2d543d20SAndroid Build Coastguard Worker }};
90*2d543d20SAndroid Build Coastguard Worker 
91*2d543d20SAndroid Build Coastguard Worker static const path_alts_t tee_service_context_paths = { .paths = {
92*2d543d20SAndroid Build Coastguard Worker 	{
93*2d543d20SAndroid Build Coastguard Worker 		"/system/etc/selinux/plat_tee_service_contexts",
94*2d543d20SAndroid Build Coastguard Worker 		"/plat_tee_service_contexts"
95*2d543d20SAndroid Build Coastguard Worker 	},
96*2d543d20SAndroid Build Coastguard Worker 	{
97*2d543d20SAndroid Build Coastguard Worker 		"/system_ext/etc/selinux/system_ext_tee_service_contexts",
98*2d543d20SAndroid Build Coastguard Worker 		"/system_ext_tee_service_contexts"
99*2d543d20SAndroid Build Coastguard Worker 	},
100*2d543d20SAndroid Build Coastguard Worker 	{
101*2d543d20SAndroid Build Coastguard Worker 		"/product/etc/selinux/product_tee_service_contexts",
102*2d543d20SAndroid Build Coastguard Worker 		"/product_tee_service_contexts"
103*2d543d20SAndroid Build Coastguard Worker 	},
104*2d543d20SAndroid Build Coastguard Worker 	{
105*2d543d20SAndroid Build Coastguard Worker 		"/vendor/etc/selinux/vendor_tee_service_contexts",
106*2d543d20SAndroid Build Coastguard Worker 		"/vendor_tee_service_contexts"
107*2d543d20SAndroid Build Coastguard Worker 	}
108*2d543d20SAndroid Build Coastguard Worker }};
109*2d543d20SAndroid Build Coastguard Worker 
find_existing_files(const path_alts_t * path_sets,const char * paths[MAX_CONTEXT_PATHS])110*2d543d20SAndroid Build Coastguard Worker size_t find_existing_files(
111*2d543d20SAndroid Build Coastguard Worker 		const path_alts_t *path_sets,
112*2d543d20SAndroid Build Coastguard Worker 		const char* paths[MAX_CONTEXT_PATHS])
113*2d543d20SAndroid Build Coastguard Worker {
114*2d543d20SAndroid Build Coastguard Worker 	return find_existing_files_with_partitions(
115*2d543d20SAndroid Build Coastguard Worker 		path_sets,
116*2d543d20SAndroid Build Coastguard Worker 		paths,
117*2d543d20SAndroid Build Coastguard Worker 		NULL
118*2d543d20SAndroid Build Coastguard Worker 	);
119*2d543d20SAndroid Build Coastguard Worker }
120*2d543d20SAndroid Build Coastguard Worker 
find_existing_files_with_partitions(const path_alts_t * path_sets,const char * paths[MAX_CONTEXT_PATHS],const char * partitions[MAX_CONTEXT_PATHS])121*2d543d20SAndroid Build Coastguard Worker size_t find_existing_files_with_partitions(
122*2d543d20SAndroid Build Coastguard Worker 		const path_alts_t *path_sets,
123*2d543d20SAndroid Build Coastguard Worker 		const char* paths[MAX_CONTEXT_PATHS],
124*2d543d20SAndroid Build Coastguard Worker 		const char* partitions[MAX_CONTEXT_PATHS])
125*2d543d20SAndroid Build Coastguard Worker {
126*2d543d20SAndroid Build Coastguard Worker 	size_t i, j, len = 0;
127*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < MAX_CONTEXT_PATHS; i++) {
128*2d543d20SAndroid Build Coastguard Worker 		for (j = 0; j < MAX_ALT_CONTEXT_PATHS; j++) {
129*2d543d20SAndroid Build Coastguard Worker 			const char* file = path_sets->paths[i][j];
130*2d543d20SAndroid Build Coastguard Worker 			if (file && access(file, R_OK) != -1) {
131*2d543d20SAndroid Build Coastguard Worker 				if (partitions) {
132*2d543d20SAndroid Build Coastguard Worker 					partitions[len] = path_sets->partitions[i];
133*2d543d20SAndroid Build Coastguard Worker 				}
134*2d543d20SAndroid Build Coastguard Worker 				paths[len++] = file;
135*2d543d20SAndroid Build Coastguard Worker 				/* Within each set, only the first valid entry is used */
136*2d543d20SAndroid Build Coastguard Worker 				break;
137*2d543d20SAndroid Build Coastguard Worker 			}
138*2d543d20SAndroid Build Coastguard Worker 		}
139*2d543d20SAndroid Build Coastguard Worker 	}
140*2d543d20SAndroid Build Coastguard Worker 	return len;
141*2d543d20SAndroid Build Coastguard Worker }
142*2d543d20SAndroid Build Coastguard Worker 
paths_to_opts(const char * paths[MAX_CONTEXT_PATHS],size_t npaths,struct selinux_opt * const opts)143*2d543d20SAndroid Build Coastguard Worker void paths_to_opts(const char* paths[MAX_CONTEXT_PATHS],
144*2d543d20SAndroid Build Coastguard Worker 		size_t npaths,
145*2d543d20SAndroid Build Coastguard Worker 		struct selinux_opt* const opts)
146*2d543d20SAndroid Build Coastguard Worker {
147*2d543d20SAndroid Build Coastguard Worker 	for (size_t i = 0; i < npaths; i++) {
148*2d543d20SAndroid Build Coastguard Worker 		opts[i].type = SELABEL_OPT_PATH;
149*2d543d20SAndroid Build Coastguard Worker 		opts[i].value = paths[i];
150*2d543d20SAndroid Build Coastguard Worker 	}
151*2d543d20SAndroid Build Coastguard Worker }
152*2d543d20SAndroid Build Coastguard Worker 
initialize_backend(unsigned int backend,const char * name,const struct selinux_opt * opts,size_t nopts)153*2d543d20SAndroid Build Coastguard Worker struct selabel_handle* initialize_backend(
154*2d543d20SAndroid Build Coastguard Worker 		unsigned int backend,
155*2d543d20SAndroid Build Coastguard Worker 		const char* name,
156*2d543d20SAndroid Build Coastguard Worker 		const struct selinux_opt* opts,
157*2d543d20SAndroid Build Coastguard Worker 		size_t nopts)
158*2d543d20SAndroid Build Coastguard Worker {
159*2d543d20SAndroid Build Coastguard Worker 		struct selabel_handle* sehandle;
160*2d543d20SAndroid Build Coastguard Worker 
161*2d543d20SAndroid Build Coastguard Worker 		sehandle = selabel_open(backend, opts, nopts);
162*2d543d20SAndroid Build Coastguard Worker 
163*2d543d20SAndroid Build Coastguard Worker 		if (!sehandle) {
164*2d543d20SAndroid Build Coastguard Worker 				selinux_log(SELINUX_ERROR, "%s: Error getting %s handle (%s)\n",
165*2d543d20SAndroid Build Coastguard Worker 								__FUNCTION__, name, strerror(errno));
166*2d543d20SAndroid Build Coastguard Worker 				return NULL;
167*2d543d20SAndroid Build Coastguard Worker 		}
168*2d543d20SAndroid Build Coastguard Worker 		selinux_log(SELINUX_INFO, "SELinux: Loaded %s context from:\n", name);
169*2d543d20SAndroid Build Coastguard Worker 		for (unsigned i = 0; i < nopts; i++) {
170*2d543d20SAndroid Build Coastguard Worker 			if (opts[i].type == SELABEL_OPT_PATH)
171*2d543d20SAndroid Build Coastguard Worker 				selinux_log(SELINUX_INFO, "		%s\n", opts[i].value);
172*2d543d20SAndroid Build Coastguard Worker 		}
173*2d543d20SAndroid Build Coastguard Worker 		return sehandle;
174*2d543d20SAndroid Build Coastguard Worker }
175*2d543d20SAndroid Build Coastguard Worker 
context_handle(unsigned int backend,const path_alts_t * context_paths,const char * name)176*2d543d20SAndroid Build Coastguard Worker struct selabel_handle* context_handle(
177*2d543d20SAndroid Build Coastguard Worker 		unsigned int backend,
178*2d543d20SAndroid Build Coastguard Worker 		const path_alts_t *context_paths,
179*2d543d20SAndroid Build Coastguard Worker 		const char *name)
180*2d543d20SAndroid Build Coastguard Worker {
181*2d543d20SAndroid Build Coastguard Worker 	const char* existing_paths[MAX_CONTEXT_PATHS];
182*2d543d20SAndroid Build Coastguard Worker 	struct selinux_opt opts[MAX_CONTEXT_PATHS];
183*2d543d20SAndroid Build Coastguard Worker 	int size = 0;
184*2d543d20SAndroid Build Coastguard Worker 
185*2d543d20SAndroid Build Coastguard Worker 	size = find_existing_files(context_paths, existing_paths);
186*2d543d20SAndroid Build Coastguard Worker 	paths_to_opts(existing_paths, size, opts);
187*2d543d20SAndroid Build Coastguard Worker 
188*2d543d20SAndroid Build Coastguard Worker 	return initialize_backend(backend, name, opts, size);
189*2d543d20SAndroid Build Coastguard Worker }
190*2d543d20SAndroid Build Coastguard Worker 
selinux_android_service_context_handle(void)191*2d543d20SAndroid Build Coastguard Worker struct selabel_handle* selinux_android_service_context_handle(void)
192*2d543d20SAndroid Build Coastguard Worker {
193*2d543d20SAndroid Build Coastguard Worker 	return context_handle(SELABEL_CTX_ANDROID_SERVICE, &service_context_paths, "service");
194*2d543d20SAndroid Build Coastguard Worker }
195*2d543d20SAndroid Build Coastguard Worker 
selinux_android_hw_service_context_handle(void)196*2d543d20SAndroid Build Coastguard Worker struct selabel_handle* selinux_android_hw_service_context_handle(void)
197*2d543d20SAndroid Build Coastguard Worker {
198*2d543d20SAndroid Build Coastguard Worker 	return context_handle(SELABEL_CTX_ANDROID_SERVICE, &hwservice_context_paths, "hwservice");
199*2d543d20SAndroid Build Coastguard Worker }
200*2d543d20SAndroid Build Coastguard Worker 
selinux_android_vendor_service_context_handle(void)201*2d543d20SAndroid Build Coastguard Worker struct selabel_handle* selinux_android_vendor_service_context_handle(void)
202*2d543d20SAndroid Build Coastguard Worker {
203*2d543d20SAndroid Build Coastguard Worker 	return context_handle(SELABEL_CTX_ANDROID_SERVICE, &vndservice_context_paths, "vndservice");
204*2d543d20SAndroid Build Coastguard Worker }
205*2d543d20SAndroid Build Coastguard Worker 
selinux_android_keystore2_key_context_handle(void)206*2d543d20SAndroid Build Coastguard Worker struct selabel_handle* selinux_android_keystore2_key_context_handle(void)
207*2d543d20SAndroid Build Coastguard Worker {
208*2d543d20SAndroid Build Coastguard Worker 	return context_handle(SELABEL_CTX_ANDROID_KEYSTORE2_KEY, &keystore2_context_paths, "keystore2");
209*2d543d20SAndroid Build Coastguard Worker }
210*2d543d20SAndroid Build Coastguard Worker 
selinux_android_tee_service_context_handle(void)211*2d543d20SAndroid Build Coastguard Worker struct selabel_handle* selinux_android_tee_service_context_handle(void)
212*2d543d20SAndroid Build Coastguard Worker {
213*2d543d20SAndroid Build Coastguard Worker 	return context_handle(SELABEL_CTX_ANDROID_SERVICE, &tee_service_context_paths, "tee_service");
214*2d543d20SAndroid Build Coastguard Worker }
215*2d543d20SAndroid Build Coastguard Worker 
216*2d543d20SAndroid Build Coastguard Worker /* The contents of these paths are encrypted on FBE devices until user
217*2d543d20SAndroid Build Coastguard Worker  * credentials are presented (filenames inside are mangled), so we need
218*2d543d20SAndroid Build Coastguard Worker  * to delay restorecon of those until vold explicitly requests it. */
219*2d543d20SAndroid Build Coastguard Worker // NOTE: these paths need to be kept in sync with vold
220*2d543d20SAndroid Build Coastguard Worker #define DATA_SYSTEM_CE_PATH "/data/system_ce"
221*2d543d20SAndroid Build Coastguard Worker #define DATA_VENDOR_CE_PATH "/data/vendor_ce"
222*2d543d20SAndroid Build Coastguard Worker #define DATA_MISC_CE_PATH "/data/misc_ce"
223*2d543d20SAndroid Build Coastguard Worker 
224*2d543d20SAndroid Build Coastguard Worker /* The path prefixes of package data directories. */
225*2d543d20SAndroid Build Coastguard Worker #define DATA_DATA_PATH "/data/data"
226*2d543d20SAndroid Build Coastguard Worker #define DATA_USER_PATH "/data/user"
227*2d543d20SAndroid Build Coastguard Worker #define DATA_USER_DE_PATH "/data/user_de"
228*2d543d20SAndroid Build Coastguard Worker #define DATA_MISC_DE_PATH "/data/misc_de"
229*2d543d20SAndroid Build Coastguard Worker #define DATA_STORAGE_AREA_PATH "/data/storage_area"
230*2d543d20SAndroid Build Coastguard Worker #define SDK_SANDBOX_DATA_CE_PATH "/data/misc_ce/*/sdksandbox"
231*2d543d20SAndroid Build Coastguard Worker #define SDK_SANDBOX_DATA_DE_PATH "/data/misc_de/*/sdksandbox"
232*2d543d20SAndroid Build Coastguard Worker 
233*2d543d20SAndroid Build Coastguard Worker #define EXPAND_MNT_PATH "/mnt/expand/\?\?\?\?\?\?\?\?-\?\?\?\?-\?\?\?\?-\?\?\?\?-\?\?\?\?\?\?\?\?\?\?\?\?"
234*2d543d20SAndroid Build Coastguard Worker #define EXPAND_USER_PATH EXPAND_MNT_PATH "/user"
235*2d543d20SAndroid Build Coastguard Worker #define EXPAND_USER_DE_PATH EXPAND_MNT_PATH "/user_de"
236*2d543d20SAndroid Build Coastguard Worker #define EXPAND_SDK_CE_PATH EXPAND_MNT_PATH "/misc_ce/*/sdksandbox"
237*2d543d20SAndroid Build Coastguard Worker #define EXPAND_SDK_DE_PATH EXPAND_MNT_PATH "/misc_de/*/sdksandbox"
238*2d543d20SAndroid Build Coastguard Worker 
239*2d543d20SAndroid Build Coastguard Worker #define DATA_DATA_PREFIX DATA_DATA_PATH "/"
240*2d543d20SAndroid Build Coastguard Worker #define DATA_USER_PREFIX DATA_USER_PATH "/"
241*2d543d20SAndroid Build Coastguard Worker #define DATA_USER_DE_PREFIX DATA_USER_DE_PATH "/"
242*2d543d20SAndroid Build Coastguard Worker #define DATA_STORAGE_AREA_PREFIX DATA_STORAGE_AREA_PATH "/"
243*2d543d20SAndroid Build Coastguard Worker #define DATA_MISC_CE_PREFIX DATA_MISC_CE_PATH "/"
244*2d543d20SAndroid Build Coastguard Worker #define DATA_MISC_DE_PREFIX DATA_MISC_DE_PATH "/"
245*2d543d20SAndroid Build Coastguard Worker #define EXPAND_MNT_PATH_PREFIX EXPAND_MNT_PATH "/"
246*2d543d20SAndroid Build Coastguard Worker 
is_app_data_path(const char * pathname)247*2d543d20SAndroid Build Coastguard Worker bool is_app_data_path(const char *pathname) {
248*2d543d20SAndroid Build Coastguard Worker 	int flags = FNM_LEADING_DIR|FNM_PATHNAME;
249*2d543d20SAndroid Build Coastguard Worker #ifdef SELINUX_FLAGS_DATA_DATA_IGNORE
250*2d543d20SAndroid Build Coastguard Worker 	if (!strcmp(pathname, DATA_DATA_PATH)) {
251*2d543d20SAndroid Build Coastguard Worker 		return true;
252*2d543d20SAndroid Build Coastguard Worker 	}
253*2d543d20SAndroid Build Coastguard Worker #endif
254*2d543d20SAndroid Build Coastguard Worker 	return (!strncmp(pathname, DATA_DATA_PREFIX, sizeof(DATA_DATA_PREFIX)-1) ||
255*2d543d20SAndroid Build Coastguard Worker 		!strncmp(pathname, DATA_USER_PREFIX, sizeof(DATA_USER_PREFIX)-1) ||
256*2d543d20SAndroid Build Coastguard Worker 		!strncmp(pathname, DATA_USER_DE_PREFIX, sizeof(DATA_USER_DE_PREFIX)-1) ||
257*2d543d20SAndroid Build Coastguard Worker 		!strncmp(pathname, DATA_STORAGE_AREA_PREFIX, sizeof(DATA_STORAGE_AREA_PREFIX)-1) ||
258*2d543d20SAndroid Build Coastguard Worker 		!fnmatch(EXPAND_USER_PATH, pathname, flags) ||
259*2d543d20SAndroid Build Coastguard Worker 		!fnmatch(EXPAND_USER_DE_PATH, pathname, flags) ||
260*2d543d20SAndroid Build Coastguard Worker 		!fnmatch(SDK_SANDBOX_DATA_CE_PATH, pathname, flags) ||
261*2d543d20SAndroid Build Coastguard Worker 		!fnmatch(SDK_SANDBOX_DATA_DE_PATH, pathname, flags) ||
262*2d543d20SAndroid Build Coastguard Worker 		!fnmatch(EXPAND_SDK_CE_PATH, pathname, flags) ||
263*2d543d20SAndroid Build Coastguard Worker 		!fnmatch(EXPAND_SDK_DE_PATH, pathname, flags));
264*2d543d20SAndroid Build Coastguard Worker }
265*2d543d20SAndroid Build Coastguard Worker 
is_credential_encrypted_path(const char * pathname)266*2d543d20SAndroid Build Coastguard Worker bool is_credential_encrypted_path(const char *pathname) {
267*2d543d20SAndroid Build Coastguard Worker 	return !strncmp(pathname, DATA_SYSTEM_CE_PATH, sizeof(DATA_SYSTEM_CE_PATH)-1) ||
268*2d543d20SAndroid Build Coastguard Worker 	       !strncmp(pathname, DATA_MISC_CE_PATH, sizeof(DATA_MISC_CE_PATH)-1) ||
269*2d543d20SAndroid Build Coastguard Worker 	       !strncmp(pathname, DATA_VENDOR_CE_PATH, sizeof(DATA_VENDOR_CE_PATH)-1);
270*2d543d20SAndroid Build Coastguard Worker }
271*2d543d20SAndroid Build Coastguard Worker 
272*2d543d20SAndroid Build Coastguard Worker /*
273*2d543d20SAndroid Build Coastguard Worker  * Extract the userid from a path.
274*2d543d20SAndroid Build Coastguard Worker  * On success, pathname is updated past the userid.
275*2d543d20SAndroid Build Coastguard Worker  * Returns 0 on success, -1 on error
276*2d543d20SAndroid Build Coastguard Worker  */
extract_userid(const char ** pathname,unsigned int * userid)277*2d543d20SAndroid Build Coastguard Worker static int extract_userid(const char **pathname, unsigned int *userid)
278*2d543d20SAndroid Build Coastguard Worker {
279*2d543d20SAndroid Build Coastguard Worker 	char *end = NULL;
280*2d543d20SAndroid Build Coastguard Worker 
281*2d543d20SAndroid Build Coastguard Worker 	errno = 0;
282*2d543d20SAndroid Build Coastguard Worker 	*userid = strtoul(*pathname, &end, 10);
283*2d543d20SAndroid Build Coastguard Worker 	if (errno) {
284*2d543d20SAndroid Build Coastguard Worker 		selinux_log(SELINUX_ERROR, "SELinux: Could not parse userid %s: %s.\n",
285*2d543d20SAndroid Build Coastguard Worker 			*pathname, strerror(errno));
286*2d543d20SAndroid Build Coastguard Worker 		return -1;
287*2d543d20SAndroid Build Coastguard Worker 	}
288*2d543d20SAndroid Build Coastguard Worker 	if (*pathname == end) {
289*2d543d20SAndroid Build Coastguard Worker 		return -1;
290*2d543d20SAndroid Build Coastguard Worker 	}
291*2d543d20SAndroid Build Coastguard Worker 	if (*userid > 1000) {
292*2d543d20SAndroid Build Coastguard Worker 		return -1;
293*2d543d20SAndroid Build Coastguard Worker 	}
294*2d543d20SAndroid Build Coastguard Worker 	*pathname = end;
295*2d543d20SAndroid Build Coastguard Worker 	return 0;
296*2d543d20SAndroid Build Coastguard Worker }
297*2d543d20SAndroid Build Coastguard Worker 
extract_pkgname_and_userid(const char * pathname,char ** pkgname,unsigned int * userid)298*2d543d20SAndroid Build Coastguard Worker int extract_pkgname_and_userid(const char *pathname, char **pkgname, unsigned int *userid)
299*2d543d20SAndroid Build Coastguard Worker {
300*2d543d20SAndroid Build Coastguard Worker 	char *end = NULL;
301*2d543d20SAndroid Build Coastguard Worker 
302*2d543d20SAndroid Build Coastguard Worker 	if (pkgname == NULL || *pkgname != NULL || userid == NULL) {
303*2d543d20SAndroid Build Coastguard Worker 		errno = EINVAL;
304*2d543d20SAndroid Build Coastguard Worker 		return -2;
305*2d543d20SAndroid Build Coastguard Worker 	}
306*2d543d20SAndroid Build Coastguard Worker 
307*2d543d20SAndroid Build Coastguard Worker 	/* Skip directory prefix before package name. */
308*2d543d20SAndroid Build Coastguard Worker 	if (!strncmp(pathname, DATA_DATA_PREFIX, sizeof(DATA_DATA_PREFIX)-1)) {
309*2d543d20SAndroid Build Coastguard Worker 		pathname += sizeof(DATA_DATA_PREFIX) - 1;
310*2d543d20SAndroid Build Coastguard Worker 	} else if (!strncmp(pathname, DATA_USER_PREFIX, sizeof(DATA_USER_PREFIX)-1)) {
311*2d543d20SAndroid Build Coastguard Worker 		pathname += sizeof(DATA_USER_PREFIX) - 1;
312*2d543d20SAndroid Build Coastguard Worker 		int rc = extract_userid(&pathname, userid);
313*2d543d20SAndroid Build Coastguard Worker 		if (rc)
314*2d543d20SAndroid Build Coastguard Worker 			return -1;
315*2d543d20SAndroid Build Coastguard Worker 		if (*pathname == '/')
316*2d543d20SAndroid Build Coastguard Worker 			pathname++;
317*2d543d20SAndroid Build Coastguard Worker 		else
318*2d543d20SAndroid Build Coastguard Worker 			return -1;
319*2d543d20SAndroid Build Coastguard Worker 	} else if (!strncmp(pathname, DATA_USER_DE_PREFIX, sizeof(DATA_USER_DE_PREFIX)-1)) {
320*2d543d20SAndroid Build Coastguard Worker 		pathname += sizeof(DATA_USER_DE_PREFIX) - 1;
321*2d543d20SAndroid Build Coastguard Worker 		int rc = extract_userid(&pathname, userid);
322*2d543d20SAndroid Build Coastguard Worker 		if (rc)
323*2d543d20SAndroid Build Coastguard Worker 			return -1;
324*2d543d20SAndroid Build Coastguard Worker 		if (*pathname == '/')
325*2d543d20SAndroid Build Coastguard Worker 			pathname++;
326*2d543d20SAndroid Build Coastguard Worker 		else
327*2d543d20SAndroid Build Coastguard Worker 			return -1;
328*2d543d20SAndroid Build Coastguard Worker 	} else if (!strncmp(pathname, DATA_STORAGE_AREA_PREFIX, sizeof(DATA_STORAGE_AREA_PREFIX)-1)) {
329*2d543d20SAndroid Build Coastguard Worker 		pathname += sizeof(DATA_STORAGE_AREA_PREFIX) - 1;
330*2d543d20SAndroid Build Coastguard Worker 		int rc = extract_userid(&pathname, userid);
331*2d543d20SAndroid Build Coastguard Worker 		if (rc)
332*2d543d20SAndroid Build Coastguard Worker 			return -1;
333*2d543d20SAndroid Build Coastguard Worker 		if (*pathname == '/')
334*2d543d20SAndroid Build Coastguard Worker 			pathname++;
335*2d543d20SAndroid Build Coastguard Worker 		else
336*2d543d20SAndroid Build Coastguard Worker 			return -1;
337*2d543d20SAndroid Build Coastguard Worker 	} else if (!fnmatch(EXPAND_USER_PATH, pathname, FNM_LEADING_DIR|FNM_PATHNAME)) {
338*2d543d20SAndroid Build Coastguard Worker 		pathname += sizeof(EXPAND_USER_PATH);
339*2d543d20SAndroid Build Coastguard Worker 		int rc = extract_userid(&pathname, userid);
340*2d543d20SAndroid Build Coastguard Worker 		if (rc)
341*2d543d20SAndroid Build Coastguard Worker 			return -1;
342*2d543d20SAndroid Build Coastguard Worker 		if (*pathname == '/')
343*2d543d20SAndroid Build Coastguard Worker 			pathname++;
344*2d543d20SAndroid Build Coastguard Worker 		else
345*2d543d20SAndroid Build Coastguard Worker 			return -1;
346*2d543d20SAndroid Build Coastguard Worker 	} else if (!fnmatch(EXPAND_USER_DE_PATH, pathname, FNM_LEADING_DIR|FNM_PATHNAME)) {
347*2d543d20SAndroid Build Coastguard Worker 		pathname += sizeof(EXPAND_USER_DE_PATH);
348*2d543d20SAndroid Build Coastguard Worker 		int rc = extract_userid(&pathname, userid);
349*2d543d20SAndroid Build Coastguard Worker 		if (rc)
350*2d543d20SAndroid Build Coastguard Worker 			return -1;
351*2d543d20SAndroid Build Coastguard Worker 		if (*pathname == '/')
352*2d543d20SAndroid Build Coastguard Worker 			pathname++;
353*2d543d20SAndroid Build Coastguard Worker 		else
354*2d543d20SAndroid Build Coastguard Worker 			return -1;
355*2d543d20SAndroid Build Coastguard Worker 	} else if (!strncmp(pathname, DATA_MISC_CE_PREFIX, sizeof(DATA_MISC_CE_PREFIX)-1)) {
356*2d543d20SAndroid Build Coastguard Worker 		pathname += sizeof(DATA_MISC_CE_PREFIX) - 1;
357*2d543d20SAndroid Build Coastguard Worker 		int rc = extract_userid(&pathname, userid);
358*2d543d20SAndroid Build Coastguard Worker 		if (rc)
359*2d543d20SAndroid Build Coastguard Worker 			return -1;
360*2d543d20SAndroid Build Coastguard Worker 		if (!strncmp(pathname, "/sdksandbox/", sizeof("/sdksandbox/")-1))
361*2d543d20SAndroid Build Coastguard Worker 			pathname += sizeof("/sdksandbox/") - 1;
362*2d543d20SAndroid Build Coastguard Worker 		else
363*2d543d20SAndroid Build Coastguard Worker 			return -1;
364*2d543d20SAndroid Build Coastguard Worker 	} else if (!strncmp(pathname, DATA_MISC_DE_PREFIX, sizeof(DATA_MISC_DE_PREFIX)-1)) {
365*2d543d20SAndroid Build Coastguard Worker 		pathname += sizeof(DATA_MISC_DE_PREFIX) - 1;
366*2d543d20SAndroid Build Coastguard Worker 		int rc = extract_userid(&pathname, userid);
367*2d543d20SAndroid Build Coastguard Worker 		if (rc)
368*2d543d20SAndroid Build Coastguard Worker 			return -1;
369*2d543d20SAndroid Build Coastguard Worker 		if (!strncmp(pathname, "/sdksandbox/", sizeof("/sdksandbox/")-1))
370*2d543d20SAndroid Build Coastguard Worker 			pathname += sizeof("/sdksandbox/") - 1;
371*2d543d20SAndroid Build Coastguard Worker 		else
372*2d543d20SAndroid Build Coastguard Worker 			return -1;
373*2d543d20SAndroid Build Coastguard Worker 	} else if (!fnmatch(EXPAND_SDK_CE_PATH, pathname, FNM_LEADING_DIR|FNM_PATHNAME)) {
374*2d543d20SAndroid Build Coastguard Worker 		pathname += sizeof(EXPAND_MNT_PATH_PREFIX) - 1;
375*2d543d20SAndroid Build Coastguard Worker 		pathname += sizeof("misc_ce/") - 1;
376*2d543d20SAndroid Build Coastguard Worker 		int rc = extract_userid(&pathname, userid);
377*2d543d20SAndroid Build Coastguard Worker 		if (rc)
378*2d543d20SAndroid Build Coastguard Worker 			return -1;
379*2d543d20SAndroid Build Coastguard Worker 		if (!strncmp(pathname, "/sdksandbox/", sizeof("/sdksandbox/")-1))
380*2d543d20SAndroid Build Coastguard Worker 			pathname += sizeof("/sdksandbox/") - 1;
381*2d543d20SAndroid Build Coastguard Worker 		else
382*2d543d20SAndroid Build Coastguard Worker 			return -1;
383*2d543d20SAndroid Build Coastguard Worker 	} else if (!fnmatch(EXPAND_SDK_DE_PATH, pathname, FNM_LEADING_DIR|FNM_PATHNAME)) {
384*2d543d20SAndroid Build Coastguard Worker 		pathname += sizeof(EXPAND_MNT_PATH_PREFIX) - 1;
385*2d543d20SAndroid Build Coastguard Worker 		pathname += sizeof("misc_de/") - 1;
386*2d543d20SAndroid Build Coastguard Worker 		int rc = extract_userid(&pathname, userid);
387*2d543d20SAndroid Build Coastguard Worker 		if (rc)
388*2d543d20SAndroid Build Coastguard Worker 			return -1;
389*2d543d20SAndroid Build Coastguard Worker 		if (!strncmp(pathname, "/sdksandbox/", sizeof("/sdksandbox/")-1))
390*2d543d20SAndroid Build Coastguard Worker 			pathname += sizeof("/sdksandbox/") - 1;
391*2d543d20SAndroid Build Coastguard Worker 		else
392*2d543d20SAndroid Build Coastguard Worker 			return -1;
393*2d543d20SAndroid Build Coastguard Worker 	} else
394*2d543d20SAndroid Build Coastguard Worker 		return -1;
395*2d543d20SAndroid Build Coastguard Worker 
396*2d543d20SAndroid Build Coastguard Worker 	if (!(*pathname))
397*2d543d20SAndroid Build Coastguard Worker 		return -1;
398*2d543d20SAndroid Build Coastguard Worker 
399*2d543d20SAndroid Build Coastguard Worker 	*pkgname = strdup(pathname);
400*2d543d20SAndroid Build Coastguard Worker 	if (!(*pkgname))
401*2d543d20SAndroid Build Coastguard Worker 		return -2;
402*2d543d20SAndroid Build Coastguard Worker 
403*2d543d20SAndroid Build Coastguard Worker 	// Trim pkgname.
404*2d543d20SAndroid Build Coastguard Worker 	for (end = *pkgname; *end && *end != '/'; end++);
405*2d543d20SAndroid Build Coastguard Worker 	*end = '\0';
406*2d543d20SAndroid Build Coastguard Worker 
407*2d543d20SAndroid Build Coastguard Worker 	return 0;
408*2d543d20SAndroid Build Coastguard Worker }
409*2d543d20SAndroid Build Coastguard Worker 
__selinux_log_callback(bool add_to_event_log,int type,const char * fmt,va_list ap)410*2d543d20SAndroid Build Coastguard Worker static void __selinux_log_callback(bool add_to_event_log, int type, const char *fmt, va_list ap) {
411*2d543d20SAndroid Build Coastguard Worker 	int priority;
412*2d543d20SAndroid Build Coastguard Worker 	char *strp;
413*2d543d20SAndroid Build Coastguard Worker 
414*2d543d20SAndroid Build Coastguard Worker 	switch(type) {
415*2d543d20SAndroid Build Coastguard Worker 	case SELINUX_WARNING:
416*2d543d20SAndroid Build Coastguard Worker 		priority = ANDROID_LOG_WARN;
417*2d543d20SAndroid Build Coastguard Worker 		break;
418*2d543d20SAndroid Build Coastguard Worker 	case SELINUX_INFO:
419*2d543d20SAndroid Build Coastguard Worker 		priority = ANDROID_LOG_INFO;
420*2d543d20SAndroid Build Coastguard Worker 		break;
421*2d543d20SAndroid Build Coastguard Worker 	default:
422*2d543d20SAndroid Build Coastguard Worker 		priority = ANDROID_LOG_ERROR;
423*2d543d20SAndroid Build Coastguard Worker 		break;
424*2d543d20SAndroid Build Coastguard Worker 	}
425*2d543d20SAndroid Build Coastguard Worker 
426*2d543d20SAndroid Build Coastguard Worker 	int len = vasprintf(&strp, fmt, ap);
427*2d543d20SAndroid Build Coastguard Worker 	if (len < 0) {
428*2d543d20SAndroid Build Coastguard Worker 		return;
429*2d543d20SAndroid Build Coastguard Worker 	}
430*2d543d20SAndroid Build Coastguard Worker 
431*2d543d20SAndroid Build Coastguard Worker 	/* libselinux log messages usually contain a new line character, while
432*2d543d20SAndroid Build Coastguard Worker 	 * Android LOG() does not expect it. Remove it to avoid empty lines in
433*2d543d20SAndroid Build Coastguard Worker 	 * the log buffers.
434*2d543d20SAndroid Build Coastguard Worker 	 */
435*2d543d20SAndroid Build Coastguard Worker 	if (len > 0 && strp[len - 1] == '\n') {
436*2d543d20SAndroid Build Coastguard Worker 		strp[len - 1] = '\0';
437*2d543d20SAndroid Build Coastguard Worker 	}
438*2d543d20SAndroid Build Coastguard Worker 	LOG_PRI(priority, "SELinux", "%s", strp);
439*2d543d20SAndroid Build Coastguard Worker 	if (add_to_event_log) {
440*2d543d20SAndroid Build Coastguard Worker 		LOG_EVENT_STRING(AUDITD_LOG_TAG, strp);
441*2d543d20SAndroid Build Coastguard Worker 	}
442*2d543d20SAndroid Build Coastguard Worker 	free(strp);
443*2d543d20SAndroid Build Coastguard Worker }
444*2d543d20SAndroid Build Coastguard Worker 
selinux_log_callback(int type,const char * fmt,...)445*2d543d20SAndroid Build Coastguard Worker int selinux_log_callback(int type, const char *fmt, ...)
446*2d543d20SAndroid Build Coastguard Worker {
447*2d543d20SAndroid Build Coastguard Worker 	va_list ap;
448*2d543d20SAndroid Build Coastguard Worker 	va_start(ap, fmt);
449*2d543d20SAndroid Build Coastguard Worker 	__selinux_log_callback(true, type, fmt, ap);
450*2d543d20SAndroid Build Coastguard Worker 	va_end(ap);
451*2d543d20SAndroid Build Coastguard Worker 	return 0;
452*2d543d20SAndroid Build Coastguard Worker }
453*2d543d20SAndroid Build Coastguard Worker 
selinux_vendor_log_callback(int type,const char * fmt,...)454*2d543d20SAndroid Build Coastguard Worker int selinux_vendor_log_callback(int type, const char *fmt, ...)
455*2d543d20SAndroid Build Coastguard Worker {
456*2d543d20SAndroid Build Coastguard Worker 	va_list ap;
457*2d543d20SAndroid Build Coastguard Worker 	va_start(ap, fmt);
458*2d543d20SAndroid Build Coastguard Worker 	__selinux_log_callback(false, type, fmt, ap);
459*2d543d20SAndroid Build Coastguard Worker 	va_end(ap);
460*2d543d20SAndroid Build Coastguard Worker 	return 0;
461*2d543d20SAndroid Build Coastguard Worker }
462