• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "android_common.h"
2 
3 // For 'system', 'system_ext' (optional), 'product' (optional), 'vendor' (mandatory)
4 // and/or 'odm' (optional).
5 #define MAX_FILE_CONTEXT_SIZE 5
6 
7 #ifdef __ANDROID_VNDK__
8 #ifndef LOG_EVENT_STRING
9 #define LOG_EVENT_STRING(...)
10 #endif  // LOG_EVENT_STRING
11 #endif  // __ANDROID_VNDK__
12 
13 static const struct selinux_opt seopts_service_plat[] = {
14     { SELABEL_OPT_PATH, "/system/etc/selinux/plat_service_contexts" },
15     { SELABEL_OPT_PATH, "/plat_service_contexts" }
16 };
17 static const struct selinux_opt seopts_service_apex[] = {
18     { SELABEL_OPT_PATH, "/dev/selinux/apex_service_contexts" }
19 };
20 static const struct selinux_opt seopts_service_system_ext[] = {
21     { SELABEL_OPT_PATH, "/system_ext/etc/selinux/system_ext_service_contexts" },
22     { SELABEL_OPT_PATH, "/system_ext_service_contexts" }
23 };
24 static const struct selinux_opt seopts_service_product[] = {
25     { SELABEL_OPT_PATH, "/product/etc/selinux/product_service_contexts" },
26     { SELABEL_OPT_PATH, "/product_service_contexts" }
27 };
28 static const struct selinux_opt seopts_service_vendor[] = {
29     { SELABEL_OPT_PATH, "/vendor/etc/selinux/vendor_service_contexts" },
30     { SELABEL_OPT_PATH, "/vendor_service_contexts" }
31 };
32 
33 static const struct selinux_opt seopts_hwservice_plat[] = {
34     { SELABEL_OPT_PATH, "/system/etc/selinux/plat_hwservice_contexts" },
35     { SELABEL_OPT_PATH, "/plat_hwservice_contexts" }
36 };
37 static const struct selinux_opt seopts_hwservice_system_ext[] = {
38     { SELABEL_OPT_PATH, "/system_ext/etc/selinux/system_ext_hwservice_contexts" },
39     { SELABEL_OPT_PATH, "/system_ext_hwservice_contexts" }
40 };
41 static const struct selinux_opt seopts_hwservice_product[] = {
42     { SELABEL_OPT_PATH, "/product/etc/selinux/product_hwservice_contexts" },
43     { SELABEL_OPT_PATH, "/product_hwservice_contexts" }
44 };
45 static const struct selinux_opt seopts_hwservice_vendor[] = {
46     { SELABEL_OPT_PATH, "/vendor/etc/selinux/vendor_hwservice_contexts" },
47     { SELABEL_OPT_PATH, "/vendor_hwservice_contexts" }
48 };
49 static const struct selinux_opt seopts_hwservice_odm[] = {
50     { SELABEL_OPT_PATH, "/odm/etc/selinux/odm_hwservice_contexts" },
51     { SELABEL_OPT_PATH, "/odm_hwservice_contexts" }
52 };
53 
54 static const struct selinux_opt seopts_vndservice =
55     { SELABEL_OPT_PATH, "/vendor/etc/selinux/vndservice_contexts" };
56 
57 static const struct selinux_opt seopts_vndservice_rootfs =
58     { SELABEL_OPT_PATH, "/vndservice_contexts" };
59 
60 static const struct selinux_opt seopts_keystore2_key_plat[] = {
61     { SELABEL_OPT_PATH, "/system/etc/selinux/plat_keystore2_key_contexts" },
62     { SELABEL_OPT_PATH, "/plat_keystore2_key_contexts" }
63 };
64 static const struct selinux_opt seopts_keystore2_key_system_ext[] = {
65     { SELABEL_OPT_PATH, "/system_ext/etc/selinux/system_ext_keystore2_key_contexts" },
66     { SELABEL_OPT_PATH, "/system_ext_keystore2_key_contexts" }
67 };
68 static const struct selinux_opt seopts_keystore2_key_product[] = {
69     { SELABEL_OPT_PATH, "/product/etc/selinux/product_keystore2_key_contexts" },
70     { SELABEL_OPT_PATH, "/product_keystore2_key_contexts" }
71 };
72 static const struct selinux_opt seopts_keystore2_key_vendor[] = {
73     { SELABEL_OPT_PATH, "/vendor/etc/selinux/vendor_keystore2_key_contexts" },
74     { SELABEL_OPT_PATH, "/vendor_keystore2_key_contexts" },
75 };
76 
selinux_android_service_open_context_handle(const struct selinux_opt * seopts_service,unsigned nopts)77 struct selabel_handle* selinux_android_service_open_context_handle(const struct selinux_opt* seopts_service,
78                                                                    unsigned nopts)
79 {
80     struct selabel_handle* sehandle;
81 
82     sehandle = selabel_open(SELABEL_CTX_ANDROID_SERVICE,
83             seopts_service, nopts);
84 
85     if (!sehandle) {
86         selinux_log(SELINUX_ERROR, "%s: Error getting service context handle (%s)\n",
87                 __FUNCTION__, strerror(errno));
88         return NULL;
89     }
90     selinux_log(SELINUX_INFO, "SELinux: Loaded service_contexts from:\n");
91     for (unsigned i = 0; i < nopts; i++) {
92         selinux_log(SELINUX_INFO, "    %s\n", seopts_service[i].value);
93     }
94     return sehandle;
95 }
96 
selinux_android_keystore2_key_open_context_handle(const struct selinux_opt * seopts_service,unsigned nopts)97 struct selabel_handle* selinux_android_keystore2_key_open_context_handle(const struct selinux_opt* seopts_service,
98                                                                    unsigned nopts)
99 {
100     struct selabel_handle* sehandle;
101 
102     sehandle = selabel_open(SELABEL_CTX_ANDROID_KEYSTORE2_KEY,
103             seopts_service, nopts);
104 
105     if (!sehandle) {
106         selinux_log(SELINUX_ERROR, "%s: Error getting keystore key context handle (%s)\n",
107                 __FUNCTION__, strerror(errno));
108         return NULL;
109     }
110     selinux_log(SELINUX_INFO, "SELinux: Loaded keystore2_key_contexts from:\n");
111     for (unsigned i = 0; i < nopts; i++) {
112         selinux_log(SELINUX_INFO, "    %s\n", seopts_service[i].value);
113     }
114     return sehandle;
115 }
116 
selinux_android_service_context_handle(void)117 struct selabel_handle* selinux_android_service_context_handle(void)
118 {
119     struct selinux_opt seopts_service[MAX_FILE_CONTEXT_SIZE];
120     int size = 0;
121     unsigned int i;
122     for (i = 0; i < ARRAY_SIZE(seopts_service_plat); i++) {
123         if (access(seopts_service_plat[i].value, R_OK) != -1) {
124             seopts_service[size++] = seopts_service_plat[i];
125             break;
126         }
127     }
128     for (i = 0; i < ARRAY_SIZE(seopts_service_apex); i++) {
129         if (access(seopts_service_apex[i].value, R_OK) != -1) {
130             seopts_service[size++] = seopts_service_apex[i];
131             break;
132         }
133     }
134     for (i = 0; i < ARRAY_SIZE(seopts_service_system_ext); i++) {
135         if (access(seopts_service_system_ext[i].value, R_OK) != -1) {
136             seopts_service[size++] = seopts_service_system_ext[i];
137             break;
138         }
139     }
140     for (i = 0; i < ARRAY_SIZE(seopts_service_product); i++) {
141         if (access(seopts_service_product[i].value, R_OK) != -1) {
142             seopts_service[size++] = seopts_service_product[i];
143             break;
144         }
145     }
146     for (i = 0; i < ARRAY_SIZE(seopts_service_vendor); i++) {
147         if (access(seopts_service_vendor[i].value, R_OK) != -1) {
148             seopts_service[size++] = seopts_service_vendor[i];
149             break;
150         }
151     }
152 
153     return selinux_android_service_open_context_handle(seopts_service, size);
154 }
155 
selinux_android_hw_service_context_handle(void)156 struct selabel_handle* selinux_android_hw_service_context_handle(void)
157 {
158     struct selinux_opt seopts_service[MAX_FILE_CONTEXT_SIZE];
159     int size = 0;
160     unsigned int i;
161     for (i = 0; i < ARRAY_SIZE(seopts_hwservice_plat); i++) {
162         if (access(seopts_hwservice_plat[i].value, R_OK) != -1) {
163             seopts_service[size++] = seopts_hwservice_plat[i];
164             break;
165         }
166     }
167     for (i = 0; i < ARRAY_SIZE(seopts_hwservice_system_ext); i++) {
168         if (access(seopts_hwservice_system_ext[i].value, R_OK) != -1) {
169             seopts_service[size++] = seopts_hwservice_system_ext[i];
170             break;
171         }
172     }
173     for (i = 0; i < ARRAY_SIZE(seopts_hwservice_product); i++) {
174         if (access(seopts_hwservice_product[i].value, R_OK) != -1) {
175             seopts_service[size++] = seopts_hwservice_product[i];
176             break;
177         }
178     }
179     for (i = 0; i < ARRAY_SIZE(seopts_hwservice_vendor); i++) {
180         if (access(seopts_hwservice_vendor[i].value, R_OK) != -1) {
181             seopts_service[size++] = seopts_hwservice_vendor[i];
182             break;
183         }
184     }
185     for (i = 0; i < ARRAY_SIZE(seopts_hwservice_odm); i++) {
186         if (access(seopts_hwservice_odm[i].value, R_OK) != -1) {
187             seopts_service[size++] = seopts_hwservice_odm[i];
188             break;
189         }
190     }
191     return selinux_android_service_open_context_handle(seopts_service, size);
192 }
193 
selinux_android_vendor_service_context_handle(void)194 struct selabel_handle* selinux_android_vendor_service_context_handle(void)
195 {
196     const struct selinux_opt* seopts_service;
197     if (access(seopts_vndservice.value, R_OK) != -1) {
198         seopts_service = &seopts_vndservice;
199     } else {
200         seopts_service = &seopts_vndservice_rootfs;
201     }
202 
203     return selinux_android_service_open_context_handle(seopts_service, 1);
204 }
205 
selinux_android_keystore2_key_context_handle(void)206 struct selabel_handle* selinux_android_keystore2_key_context_handle(void)
207 {
208     struct selinux_opt seopts_keystore2_key[MAX_FILE_CONTEXT_SIZE];
209     int size = 0;
210     unsigned int i;
211     for (i = 0; i < ARRAY_SIZE(seopts_keystore2_key_plat); i++) {
212         if (access(seopts_keystore2_key_plat[i].value, R_OK) != -1) {
213             seopts_keystore2_key[size++] = seopts_keystore2_key_plat[i];
214             break;
215         }
216     }
217     for (i = 0; i < ARRAY_SIZE(seopts_keystore2_key_system_ext); i++) {
218         if (access(seopts_keystore2_key_system_ext[i].value, R_OK) != -1) {
219             seopts_keystore2_key[size++] = seopts_keystore2_key_system_ext[i];
220             break;
221         }
222     }
223     for (i = 0; i < ARRAY_SIZE(seopts_keystore2_key_product); i++) {
224         if (access(seopts_keystore2_key_product[i].value, R_OK) != -1) {
225             seopts_keystore2_key[size++] = seopts_keystore2_key_product[i];
226             break;
227         }
228     }
229     for (i = 0; i < ARRAY_SIZE(seopts_keystore2_key_vendor); i++) {
230         if (access(seopts_keystore2_key_vendor[i].value, R_OK) != -1) {
231             seopts_keystore2_key[size++] = seopts_keystore2_key_vendor[i];
232             break;
233         }
234     }
235 
236     return selinux_android_keystore2_key_open_context_handle(seopts_keystore2_key, size);
237 }
238 
selinux_log_callback(int type,const char * fmt,...)239 int selinux_log_callback(int type, const char *fmt, ...)
240 {
241     va_list ap;
242     int priority;
243     char *strp;
244 
245     switch(type) {
246     case SELINUX_WARNING:
247         priority = ANDROID_LOG_WARN;
248         break;
249     case SELINUX_INFO:
250         priority = ANDROID_LOG_INFO;
251         break;
252     default:
253         priority = ANDROID_LOG_ERROR;
254         break;
255     }
256 
257     va_start(ap, fmt);
258     if (vasprintf(&strp, fmt, ap) != -1) {
259         LOG_PRI(priority, "SELinux", "%s", strp);
260         LOG_EVENT_STRING(AUDITD_LOG_TAG, strp);
261         free(strp);
262     }
263     va_end(ap);
264     return 0;
265 }
266 
selinux_vendor_log_callback(int type,const char * fmt,...)267 int selinux_vendor_log_callback(int type, const char *fmt, ...)
268 {
269     va_list ap;
270     int priority;
271     char *strp;
272 
273     switch(type) {
274     case SELINUX_WARNING:
275         priority = ANDROID_LOG_WARN;
276         break;
277     case SELINUX_INFO:
278         priority = ANDROID_LOG_INFO;
279         break;
280     default:
281         priority = ANDROID_LOG_ERROR;
282         break;
283     }
284 
285     va_start(ap, fmt);
286     if (vasprintf(&strp, fmt, ap) != -1) {
287         LOG_PRI(priority, "SELinux", "%s", strp);
288         free(strp);
289     }
290     va_end(ap);
291     return 0;
292 }
293