• 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_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