1 #include "android_common.h"
2
3 // For 'system', 'product' (optional), 'vendor' (mandatory) and/or 'odm' (optional).
4 #define MAX_FILE_CONTEXT_SIZE 4
5
6 #ifdef __ANDROID_VNDK__
7 #ifndef LOG_EVENT_STRING
8 #define LOG_EVENT_STRING(...)
9 #endif // LOG_EVENT_STRING
10 #endif // __ANDROID_VNDK__
11
12 static const struct selinux_opt seopts_service_plat[] = {
13 { SELABEL_OPT_PATH, "/system/etc/selinux/plat_service_contexts" },
14 { SELABEL_OPT_PATH, "/plat_service_contexts" }
15 };
16 static const struct selinux_opt seopts_service_product[] = {
17 { SELABEL_OPT_PATH, "/product/etc/selinux/product_service_contexts" },
18 { SELABEL_OPT_PATH, "/product_service_contexts" }
19 };
20 static const struct selinux_opt seopts_service_vendor[] = {
21 { SELABEL_OPT_PATH, "/vendor/etc/selinux/vendor_service_contexts" },
22 { SELABEL_OPT_PATH, "/vendor_service_contexts" },
23 // TODO: remove nonplat* when no need to retain backward compatibility.
24 { SELABEL_OPT_PATH, "/vendor/etc/selinux/nonplat_service_contexts" },
25 { SELABEL_OPT_PATH, "/nonplat_service_contexts" }
26 };
27
28 static const struct selinux_opt seopts_hwservice_plat[] = {
29 { SELABEL_OPT_PATH, "/system/etc/selinux/plat_hwservice_contexts" },
30 { SELABEL_OPT_PATH, "/plat_hwservice_contexts" }
31 };
32 static const struct selinux_opt seopts_hwservice_product[] = {
33 { SELABEL_OPT_PATH, "/product/etc/selinux/product_hwservice_contexts" },
34 { SELABEL_OPT_PATH, "/product_hwservice_contexts" }
35 };
36 static const struct selinux_opt seopts_hwservice_vendor[] = {
37 { SELABEL_OPT_PATH, "/vendor/etc/selinux/vendor_hwservice_contexts" },
38 { SELABEL_OPT_PATH, "/vendor_hwservice_contexts" },
39 // TODO: remove nonplat* when no need to retain backward compatibility.
40 { SELABEL_OPT_PATH, "/vendor/etc/selinux/nonplat_hwservice_contexts" },
41 { SELABEL_OPT_PATH, "/nonplat_hwservice_contexts" }
42 };
43 static const struct selinux_opt seopts_hwservice_odm[] = {
44 { SELABEL_OPT_PATH, "/odm/etc/selinux/odm_hwservice_contexts" },
45 { SELABEL_OPT_PATH, "/odm_hwservice_contexts" }
46 };
47
48 static const struct selinux_opt seopts_vndservice =
49 { SELABEL_OPT_PATH, "/vendor/etc/selinux/vndservice_contexts" };
50
51 static const struct selinux_opt seopts_vndservice_rootfs =
52 { SELABEL_OPT_PATH, "/vndservice_contexts" };
53
selinux_android_service_open_context_handle(const struct selinux_opt * seopts_service,unsigned nopts)54 struct selabel_handle* selinux_android_service_open_context_handle(const struct selinux_opt* seopts_service,
55 unsigned nopts)
56 {
57 struct selabel_handle* sehandle;
58
59 sehandle = selabel_open(SELABEL_CTX_ANDROID_SERVICE,
60 seopts_service, nopts);
61
62 if (!sehandle) {
63 selinux_log(SELINUX_ERROR, "%s: Error getting service context handle (%s)\n",
64 __FUNCTION__, strerror(errno));
65 return NULL;
66 }
67 selinux_log(SELINUX_INFO, "SELinux: Loaded service_contexts from:\n");
68 for (unsigned i = 0; i < nopts; i++) {
69 selinux_log(SELINUX_INFO, " %s\n", seopts_service[i].value);
70 }
71 return sehandle;
72 }
73
selinux_android_service_context_handle(void)74 struct selabel_handle* selinux_android_service_context_handle(void)
75 {
76 struct selinux_opt seopts_service[MAX_FILE_CONTEXT_SIZE];
77 int size = 0;
78 unsigned int i;
79 for (i = 0; i < ARRAY_SIZE(seopts_service_plat); i++) {
80 if (access(seopts_service_plat[i].value, R_OK) != -1) {
81 seopts_service[size++] = seopts_service_plat[i];
82 break;
83 }
84 }
85 for (i = 0; i < ARRAY_SIZE(seopts_service_product); i++) {
86 if (access(seopts_service_product[i].value, R_OK) != -1) {
87 seopts_service[size++] = seopts_service_product[i];
88 break;
89 }
90 }
91 for (i = 0; i < ARRAY_SIZE(seopts_service_vendor); i++) {
92 if (access(seopts_service_vendor[i].value, R_OK) != -1) {
93 seopts_service[size++] = seopts_service_vendor[i];
94 break;
95 }
96 }
97
98 return selinux_android_service_open_context_handle(seopts_service, size);
99 }
100
selinux_android_hw_service_context_handle(void)101 struct selabel_handle* selinux_android_hw_service_context_handle(void)
102 {
103 struct selinux_opt seopts_service[MAX_FILE_CONTEXT_SIZE];
104 int size = 0;
105 unsigned int i;
106 for (i = 0; i < ARRAY_SIZE(seopts_hwservice_plat); i++) {
107 if (access(seopts_hwservice_plat[i].value, R_OK) != -1) {
108 seopts_service[size++] = seopts_hwservice_plat[i];
109 break;
110 }
111 }
112 for (i = 0; i < ARRAY_SIZE(seopts_hwservice_product); i++) {
113 if (access(seopts_hwservice_product[i].value, R_OK) != -1) {
114 seopts_service[size++] = seopts_hwservice_product[i];
115 break;
116 }
117 }
118 for (i = 0; i < ARRAY_SIZE(seopts_hwservice_vendor); i++) {
119 if (access(seopts_hwservice_vendor[i].value, R_OK) != -1) {
120 seopts_service[size++] = seopts_hwservice_vendor[i];
121 break;
122 }
123 }
124 for (i = 0; i < ARRAY_SIZE(seopts_hwservice_odm); i++) {
125 if (access(seopts_hwservice_odm[i].value, R_OK) != -1) {
126 seopts_service[size++] = seopts_hwservice_odm[i];
127 break;
128 }
129 }
130 return selinux_android_service_open_context_handle(seopts_service, size);
131 }
132
selinux_android_vendor_service_context_handle(void)133 struct selabel_handle* selinux_android_vendor_service_context_handle(void)
134 {
135 const struct selinux_opt* seopts_service;
136 if (access(seopts_vndservice.value, R_OK) != -1) {
137 seopts_service = &seopts_vndservice;
138 } else {
139 seopts_service = &seopts_vndservice_rootfs;
140 }
141
142 return selinux_android_service_open_context_handle(seopts_service, 1);
143 }
144
selinux_log_callback(int type,const char * fmt,...)145 int selinux_log_callback(int type, const char *fmt, ...)
146 {
147 va_list ap;
148 int priority;
149 char *strp;
150
151 switch(type) {
152 case SELINUX_WARNING:
153 priority = ANDROID_LOG_WARN;
154 break;
155 case SELINUX_INFO:
156 priority = ANDROID_LOG_INFO;
157 break;
158 default:
159 priority = ANDROID_LOG_ERROR;
160 break;
161 }
162
163 va_start(ap, fmt);
164 if (vasprintf(&strp, fmt, ap) != -1) {
165 LOG_PRI(priority, "SELinux", "%s", strp);
166 LOG_EVENT_STRING(AUDITD_LOG_TAG, strp);
167 free(strp);
168 }
169 va_end(ap);
170 return 0;
171 }
172
selinux_vendor_log_callback(int type,const char * fmt,...)173 int selinux_vendor_log_callback(int type, const char *fmt, ...)
174 {
175 va_list ap;
176 int priority;
177 char *strp;
178
179 switch(type) {
180 case SELINUX_WARNING:
181 priority = ANDROID_LOG_WARN;
182 break;
183 case SELINUX_INFO:
184 priority = ANDROID_LOG_INFO;
185 break;
186 default:
187 priority = ANDROID_LOG_ERROR;
188 break;
189 }
190
191 va_start(ap, fmt);
192 if (vasprintf(&strp, fmt, ap) != -1) {
193 LOG_PRI(priority, "SELinux", "%s", strp);
194 free(strp);
195 }
196 va_end(ap);
197 return 0;
198 }
199