1 #include "android_common.h"
2
3 #ifdef __ANDROID_VNDK__
4 #ifndef LOG_EVENT_STRING
5 #define LOG_EVENT_STRING(...)
6 #endif // LOG_EVENT_STRING
7 #endif // __ANDROID_VNDK__
8
9 static const struct selinux_opt seopts_service_split[] = {
10 { SELABEL_OPT_PATH, "/system/etc/selinux/plat_service_contexts" },
11 { SELABEL_OPT_PATH, "/vendor/etc/selinux/nonplat_service_contexts" }
12 };
13
14 static const struct selinux_opt seopts_service_rootfs[] = {
15 { SELABEL_OPT_PATH, "/plat_service_contexts" },
16 { SELABEL_OPT_PATH, "/nonplat_service_contexts" }
17 };
18
19 static const struct selinux_opt seopts_hwservice_split[] = {
20 { SELABEL_OPT_PATH, "/system/etc/selinux/plat_hwservice_contexts" },
21 { SELABEL_OPT_PATH, "/vendor/etc/selinux/nonplat_hwservice_contexts" }
22 };
23
24 static const struct selinux_opt seopts_hwservice_rootfs[] = {
25 { SELABEL_OPT_PATH, "/plat_hwservice_contexts" },
26 { SELABEL_OPT_PATH, "/nonplat_hwservice_contexts" }
27 };
28
29 static const struct selinux_opt seopts_vndservice =
30 { SELABEL_OPT_PATH, "/vendor/etc/selinux/vndservice_contexts" };
31
32 static const struct selinux_opt seopts_vndservice_rootfs =
33 { SELABEL_OPT_PATH, "/vndservice_contexts" };
34
selinux_android_service_open_context_handle(const struct selinux_opt * seopts_service,unsigned nopts)35 struct selabel_handle* selinux_android_service_open_context_handle(const struct selinux_opt* seopts_service,
36 unsigned nopts)
37 {
38 struct selabel_handle* sehandle;
39
40 sehandle = selabel_open(SELABEL_CTX_ANDROID_SERVICE,
41 seopts_service, nopts);
42
43 if (!sehandle) {
44 selinux_log(SELINUX_ERROR, "%s: Error getting service context handle (%s)\n",
45 __FUNCTION__, strerror(errno));
46 return NULL;
47 }
48 selinux_log(SELINUX_INFO, "SELinux: Loaded service_contexts from:\n");
49 for (unsigned i = 0; i < nopts; i++) {
50 selinux_log(SELINUX_INFO, " %s\n", seopts_service[i].value);
51 }
52 return sehandle;
53 }
54
selinux_android_service_context_handle(void)55 struct selabel_handle* selinux_android_service_context_handle(void)
56 {
57 const struct selinux_opt* seopts_service;
58
59 // Prefer files from /system & /vendor, fall back to files from /
60 if (access(seopts_service_split[0].value, R_OK) != -1) {
61 seopts_service = seopts_service_split;
62 } else {
63 seopts_service = seopts_service_rootfs;
64 }
65
66 #ifdef FULL_TREBLE
67 // Treble compliant devices can only serve plat_service_contexts from servicemanager
68 return selinux_android_service_open_context_handle(seopts_service, 1);
69 #else
70 return selinux_android_service_open_context_handle(seopts_service, 2);
71 #endif
72 }
73
selinux_android_hw_service_context_handle(void)74 struct selabel_handle* selinux_android_hw_service_context_handle(void)
75 {
76 const struct selinux_opt* seopts_service;
77 if (access(seopts_hwservice_split[0].value, R_OK) != -1) {
78 seopts_service = seopts_hwservice_split;
79 } else {
80 seopts_service = seopts_hwservice_rootfs;
81 }
82
83 return selinux_android_service_open_context_handle(seopts_service, 2);
84 }
85
selinux_android_vendor_service_context_handle(void)86 struct selabel_handle* selinux_android_vendor_service_context_handle(void)
87 {
88 const struct selinux_opt* seopts_service;
89 if (access(seopts_vndservice.value, R_OK) != -1) {
90 seopts_service = &seopts_vndservice;
91 } else {
92 seopts_service = &seopts_vndservice_rootfs;
93 }
94
95 return selinux_android_service_open_context_handle(seopts_service, 1);
96 }
97
selinux_log_callback(int type,const char * fmt,...)98 int selinux_log_callback(int type, const char *fmt, ...)
99 {
100 va_list ap;
101 int priority;
102 char *strp;
103
104 switch(type) {
105 case SELINUX_WARNING:
106 priority = ANDROID_LOG_WARN;
107 break;
108 case SELINUX_INFO:
109 priority = ANDROID_LOG_INFO;
110 break;
111 default:
112 priority = ANDROID_LOG_ERROR;
113 break;
114 }
115
116 va_start(ap, fmt);
117 if (vasprintf(&strp, fmt, ap) != -1) {
118 LOG_PRI(priority, "SELinux", "%s", strp);
119 LOG_EVENT_STRING(AUDITD_LOG_TAG, strp);
120 free(strp);
121 }
122 va_end(ap);
123 return 0;
124 }
125