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