• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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