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