1*2d543d20SAndroid Build Coastguard Worker /* Author: Trusted Computer Solutions, Inc.
2*2d543d20SAndroid Build Coastguard Worker *
3*2d543d20SAndroid Build Coastguard Worker * Modified:
4*2d543d20SAndroid Build Coastguard Worker * Yuichi Nakamura <[email protected]>
5*2d543d20SAndroid Build Coastguard Worker - Stubs are used when DISABLE_SETRANS is defined,
6*2d543d20SAndroid Build Coastguard Worker it is to reduce size for such as embedded devices.
7*2d543d20SAndroid Build Coastguard Worker */
8*2d543d20SAndroid Build Coastguard Worker
9*2d543d20SAndroid Build Coastguard Worker #include <sys/types.h>
10*2d543d20SAndroid Build Coastguard Worker #include <sys/socket.h>
11*2d543d20SAndroid Build Coastguard Worker #include <sys/un.h>
12*2d543d20SAndroid Build Coastguard Worker
13*2d543d20SAndroid Build Coastguard Worker #include <errno.h>
14*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
15*2d543d20SAndroid Build Coastguard Worker #include <netdb.h>
16*2d543d20SAndroid Build Coastguard Worker #include <fcntl.h>
17*2d543d20SAndroid Build Coastguard Worker #include <stdio.h>
18*2d543d20SAndroid Build Coastguard Worker #include <string.h>
19*2d543d20SAndroid Build Coastguard Worker #include <ctype.h>
20*2d543d20SAndroid Build Coastguard Worker #include <unistd.h>
21*2d543d20SAndroid Build Coastguard Worker #include <sys/uio.h>
22*2d543d20SAndroid Build Coastguard Worker #include "selinux_internal.h"
23*2d543d20SAndroid Build Coastguard Worker #include "setrans_internal.h"
24*2d543d20SAndroid Build Coastguard Worker
25*2d543d20SAndroid Build Coastguard Worker #ifndef DISABLE_SETRANS
26*2d543d20SAndroid Build Coastguard Worker static unsigned char has_setrans;
27*2d543d20SAndroid Build Coastguard Worker
28*2d543d20SAndroid Build Coastguard Worker // Simple cache
29*2d543d20SAndroid Build Coastguard Worker static __thread char * prev_t2r_trans = NULL;
30*2d543d20SAndroid Build Coastguard Worker static __thread char * prev_t2r_raw = NULL;
31*2d543d20SAndroid Build Coastguard Worker static __thread char * prev_r2t_trans = NULL;
32*2d543d20SAndroid Build Coastguard Worker static __thread char * prev_r2t_raw = NULL;
33*2d543d20SAndroid Build Coastguard Worker static __thread char *prev_r2c_trans = NULL;
34*2d543d20SAndroid Build Coastguard Worker static __thread char * prev_r2c_raw = NULL;
35*2d543d20SAndroid Build Coastguard Worker
36*2d543d20SAndroid Build Coastguard Worker static pthread_once_t once = PTHREAD_ONCE_INIT;
37*2d543d20SAndroid Build Coastguard Worker static pthread_key_t destructor_key;
38*2d543d20SAndroid Build Coastguard Worker static int destructor_key_initialized = 0;
39*2d543d20SAndroid Build Coastguard Worker static __thread char destructor_initialized;
40*2d543d20SAndroid Build Coastguard Worker
41*2d543d20SAndroid Build Coastguard Worker /*
42*2d543d20SAndroid Build Coastguard Worker * setransd_open
43*2d543d20SAndroid Build Coastguard Worker *
44*2d543d20SAndroid Build Coastguard Worker * This function opens a socket to the setransd.
45*2d543d20SAndroid Build Coastguard Worker * Returns: on success, a file descriptor ( >= 0 ) to the socket
46*2d543d20SAndroid Build Coastguard Worker * on error, a negative value
47*2d543d20SAndroid Build Coastguard Worker */
setransd_open(void)48*2d543d20SAndroid Build Coastguard Worker static int setransd_open(void)
49*2d543d20SAndroid Build Coastguard Worker {
50*2d543d20SAndroid Build Coastguard Worker struct sockaddr_un addr;
51*2d543d20SAndroid Build Coastguard Worker int fd;
52*2d543d20SAndroid Build Coastguard Worker #ifdef SOCK_CLOEXEC
53*2d543d20SAndroid Build Coastguard Worker fd = socket(PF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
54*2d543d20SAndroid Build Coastguard Worker if (fd < 0 && errno == EINVAL)
55*2d543d20SAndroid Build Coastguard Worker #endif
56*2d543d20SAndroid Build Coastguard Worker {
57*2d543d20SAndroid Build Coastguard Worker fd = socket(PF_UNIX, SOCK_STREAM, 0);
58*2d543d20SAndroid Build Coastguard Worker if (fd >= 0)
59*2d543d20SAndroid Build Coastguard Worker if (fcntl(fd, F_SETFD, FD_CLOEXEC)) {
60*2d543d20SAndroid Build Coastguard Worker close(fd);
61*2d543d20SAndroid Build Coastguard Worker return -1;
62*2d543d20SAndroid Build Coastguard Worker }
63*2d543d20SAndroid Build Coastguard Worker }
64*2d543d20SAndroid Build Coastguard Worker if (fd < 0)
65*2d543d20SAndroid Build Coastguard Worker return -1;
66*2d543d20SAndroid Build Coastguard Worker
67*2d543d20SAndroid Build Coastguard Worker memset(&addr, 0, sizeof(addr));
68*2d543d20SAndroid Build Coastguard Worker addr.sun_family = AF_UNIX;
69*2d543d20SAndroid Build Coastguard Worker
70*2d543d20SAndroid Build Coastguard Worker if (strlcpy(addr.sun_path, SETRANS_UNIX_SOCKET, sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) {
71*2d543d20SAndroid Build Coastguard Worker close(fd);
72*2d543d20SAndroid Build Coastguard Worker errno = EOVERFLOW;
73*2d543d20SAndroid Build Coastguard Worker return -1;
74*2d543d20SAndroid Build Coastguard Worker }
75*2d543d20SAndroid Build Coastguard Worker
76*2d543d20SAndroid Build Coastguard Worker if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
77*2d543d20SAndroid Build Coastguard Worker close(fd);
78*2d543d20SAndroid Build Coastguard Worker return -1;
79*2d543d20SAndroid Build Coastguard Worker }
80*2d543d20SAndroid Build Coastguard Worker
81*2d543d20SAndroid Build Coastguard Worker return fd;
82*2d543d20SAndroid Build Coastguard Worker }
83*2d543d20SAndroid Build Coastguard Worker
84*2d543d20SAndroid Build Coastguard Worker /* Returns: 0 on success, <0 on failure */
85*2d543d20SAndroid Build Coastguard Worker static int
send_request(int fd,uint32_t function,const char * data1,const char * data2)86*2d543d20SAndroid Build Coastguard Worker send_request(int fd, uint32_t function, const char *data1, const char *data2)
87*2d543d20SAndroid Build Coastguard Worker {
88*2d543d20SAndroid Build Coastguard Worker struct msghdr msgh;
89*2d543d20SAndroid Build Coastguard Worker struct iovec iov[5];
90*2d543d20SAndroid Build Coastguard Worker uint32_t data1_size;
91*2d543d20SAndroid Build Coastguard Worker uint32_t data2_size;
92*2d543d20SAndroid Build Coastguard Worker ssize_t count, expected;
93*2d543d20SAndroid Build Coastguard Worker unsigned int i;
94*2d543d20SAndroid Build Coastguard Worker
95*2d543d20SAndroid Build Coastguard Worker if (fd < 0) {
96*2d543d20SAndroid Build Coastguard Worker errno = EINVAL;
97*2d543d20SAndroid Build Coastguard Worker return -1;
98*2d543d20SAndroid Build Coastguard Worker }
99*2d543d20SAndroid Build Coastguard Worker
100*2d543d20SAndroid Build Coastguard Worker if (!data1)
101*2d543d20SAndroid Build Coastguard Worker data1 = "";
102*2d543d20SAndroid Build Coastguard Worker if (!data2)
103*2d543d20SAndroid Build Coastguard Worker data2 = "";
104*2d543d20SAndroid Build Coastguard Worker
105*2d543d20SAndroid Build Coastguard Worker data1_size = strlen(data1) + 1;
106*2d543d20SAndroid Build Coastguard Worker data2_size = strlen(data2) + 1;
107*2d543d20SAndroid Build Coastguard Worker
108*2d543d20SAndroid Build Coastguard Worker iov[0].iov_base = &function;
109*2d543d20SAndroid Build Coastguard Worker iov[0].iov_len = sizeof(function);
110*2d543d20SAndroid Build Coastguard Worker iov[1].iov_base = &data1_size;
111*2d543d20SAndroid Build Coastguard Worker iov[1].iov_len = sizeof(data1_size);
112*2d543d20SAndroid Build Coastguard Worker iov[2].iov_base = &data2_size;
113*2d543d20SAndroid Build Coastguard Worker iov[2].iov_len = sizeof(data2_size);
114*2d543d20SAndroid Build Coastguard Worker iov[3].iov_base = (char *)data1;
115*2d543d20SAndroid Build Coastguard Worker iov[3].iov_len = data1_size;
116*2d543d20SAndroid Build Coastguard Worker iov[4].iov_base = (char *)data2;
117*2d543d20SAndroid Build Coastguard Worker iov[4].iov_len = data2_size;
118*2d543d20SAndroid Build Coastguard Worker memset(&msgh, 0, sizeof(msgh));
119*2d543d20SAndroid Build Coastguard Worker msgh.msg_iov = iov;
120*2d543d20SAndroid Build Coastguard Worker msgh.msg_iovlen = sizeof(iov) / sizeof(iov[0]);
121*2d543d20SAndroid Build Coastguard Worker
122*2d543d20SAndroid Build Coastguard Worker expected = 0;
123*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < sizeof(iov) / sizeof(iov[0]); i++)
124*2d543d20SAndroid Build Coastguard Worker expected += iov[i].iov_len;
125*2d543d20SAndroid Build Coastguard Worker
126*2d543d20SAndroid Build Coastguard Worker while (((count = sendmsg(fd, &msgh, MSG_NOSIGNAL)) < 0)
127*2d543d20SAndroid Build Coastguard Worker && (errno == EINTR)) ;
128*2d543d20SAndroid Build Coastguard Worker if (count < 0)
129*2d543d20SAndroid Build Coastguard Worker return -1;
130*2d543d20SAndroid Build Coastguard Worker if (count != expected) {
131*2d543d20SAndroid Build Coastguard Worker errno = EBADMSG;
132*2d543d20SAndroid Build Coastguard Worker return -1;
133*2d543d20SAndroid Build Coastguard Worker }
134*2d543d20SAndroid Build Coastguard Worker
135*2d543d20SAndroid Build Coastguard Worker return 0;
136*2d543d20SAndroid Build Coastguard Worker }
137*2d543d20SAndroid Build Coastguard Worker
138*2d543d20SAndroid Build Coastguard Worker /* Returns: 0 on success, <0 on failure */
139*2d543d20SAndroid Build Coastguard Worker static int
receive_response(int fd,uint32_t function,char ** outdata,int32_t * ret_val)140*2d543d20SAndroid Build Coastguard Worker receive_response(int fd, uint32_t function, char **outdata, int32_t * ret_val)
141*2d543d20SAndroid Build Coastguard Worker {
142*2d543d20SAndroid Build Coastguard Worker struct iovec resp_hdr[3];
143*2d543d20SAndroid Build Coastguard Worker uint32_t func;
144*2d543d20SAndroid Build Coastguard Worker uint32_t data_size;
145*2d543d20SAndroid Build Coastguard Worker char *data;
146*2d543d20SAndroid Build Coastguard Worker struct iovec resp_data;
147*2d543d20SAndroid Build Coastguard Worker ssize_t count;
148*2d543d20SAndroid Build Coastguard Worker
149*2d543d20SAndroid Build Coastguard Worker if (fd < 0) {
150*2d543d20SAndroid Build Coastguard Worker errno = EINVAL;
151*2d543d20SAndroid Build Coastguard Worker return -1;
152*2d543d20SAndroid Build Coastguard Worker }
153*2d543d20SAndroid Build Coastguard Worker
154*2d543d20SAndroid Build Coastguard Worker resp_hdr[0].iov_base = &func;
155*2d543d20SAndroid Build Coastguard Worker resp_hdr[0].iov_len = sizeof(func);
156*2d543d20SAndroid Build Coastguard Worker resp_hdr[1].iov_base = &data_size;
157*2d543d20SAndroid Build Coastguard Worker resp_hdr[1].iov_len = sizeof(data_size);
158*2d543d20SAndroid Build Coastguard Worker resp_hdr[2].iov_base = ret_val;
159*2d543d20SAndroid Build Coastguard Worker resp_hdr[2].iov_len = sizeof(*ret_val);
160*2d543d20SAndroid Build Coastguard Worker
161*2d543d20SAndroid Build Coastguard Worker while (((count = readv(fd, resp_hdr, 3)) < 0) && (errno == EINTR)) ;
162*2d543d20SAndroid Build Coastguard Worker if (count < 0) {
163*2d543d20SAndroid Build Coastguard Worker return -1;
164*2d543d20SAndroid Build Coastguard Worker }
165*2d543d20SAndroid Build Coastguard Worker
166*2d543d20SAndroid Build Coastguard Worker if (count != (sizeof(func) + sizeof(data_size) + sizeof(*ret_val))) {
167*2d543d20SAndroid Build Coastguard Worker errno = EBADMSG;
168*2d543d20SAndroid Build Coastguard Worker return -1;
169*2d543d20SAndroid Build Coastguard Worker }
170*2d543d20SAndroid Build Coastguard Worker
171*2d543d20SAndroid Build Coastguard Worker if (func != function || !data_size || data_size > MAX_DATA_BUF) {
172*2d543d20SAndroid Build Coastguard Worker errno = EBADMSG;
173*2d543d20SAndroid Build Coastguard Worker return -1;
174*2d543d20SAndroid Build Coastguard Worker }
175*2d543d20SAndroid Build Coastguard Worker
176*2d543d20SAndroid Build Coastguard Worker data = malloc(data_size);
177*2d543d20SAndroid Build Coastguard Worker if (!data)
178*2d543d20SAndroid Build Coastguard Worker return -1;
179*2d543d20SAndroid Build Coastguard Worker /* coveriety doesn't realize that data will be initialized in readv */
180*2d543d20SAndroid Build Coastguard Worker memset(data, 0, data_size);
181*2d543d20SAndroid Build Coastguard Worker
182*2d543d20SAndroid Build Coastguard Worker resp_data.iov_base = data;
183*2d543d20SAndroid Build Coastguard Worker resp_data.iov_len = data_size;
184*2d543d20SAndroid Build Coastguard Worker
185*2d543d20SAndroid Build Coastguard Worker while (((count = readv(fd, &resp_data, 1))) < 0 && (errno == EINTR)) ;
186*2d543d20SAndroid Build Coastguard Worker if (count < 0 || (uint32_t) count != data_size ||
187*2d543d20SAndroid Build Coastguard Worker data[data_size - 1] != '\0') {
188*2d543d20SAndroid Build Coastguard Worker free(data);
189*2d543d20SAndroid Build Coastguard Worker if (count >= 0)
190*2d543d20SAndroid Build Coastguard Worker errno = EBADMSG;
191*2d543d20SAndroid Build Coastguard Worker return -1;
192*2d543d20SAndroid Build Coastguard Worker }
193*2d543d20SAndroid Build Coastguard Worker *outdata = data;
194*2d543d20SAndroid Build Coastguard Worker return 0;
195*2d543d20SAndroid Build Coastguard Worker }
196*2d543d20SAndroid Build Coastguard Worker
raw_to_trans_context(const char * raw,char ** transp)197*2d543d20SAndroid Build Coastguard Worker static int raw_to_trans_context(const char *raw, char **transp)
198*2d543d20SAndroid Build Coastguard Worker {
199*2d543d20SAndroid Build Coastguard Worker int ret;
200*2d543d20SAndroid Build Coastguard Worker int32_t ret_val;
201*2d543d20SAndroid Build Coastguard Worker int fd;
202*2d543d20SAndroid Build Coastguard Worker
203*2d543d20SAndroid Build Coastguard Worker *transp = NULL;
204*2d543d20SAndroid Build Coastguard Worker
205*2d543d20SAndroid Build Coastguard Worker fd = setransd_open();
206*2d543d20SAndroid Build Coastguard Worker if (fd < 0)
207*2d543d20SAndroid Build Coastguard Worker return fd;
208*2d543d20SAndroid Build Coastguard Worker
209*2d543d20SAndroid Build Coastguard Worker ret = send_request(fd, RAW_TO_TRANS_CONTEXT, raw, NULL);
210*2d543d20SAndroid Build Coastguard Worker if (ret)
211*2d543d20SAndroid Build Coastguard Worker goto out;
212*2d543d20SAndroid Build Coastguard Worker
213*2d543d20SAndroid Build Coastguard Worker ret = receive_response(fd, RAW_TO_TRANS_CONTEXT, transp, &ret_val);
214*2d543d20SAndroid Build Coastguard Worker if (ret)
215*2d543d20SAndroid Build Coastguard Worker goto out;
216*2d543d20SAndroid Build Coastguard Worker
217*2d543d20SAndroid Build Coastguard Worker ret = ret_val;
218*2d543d20SAndroid Build Coastguard Worker out:
219*2d543d20SAndroid Build Coastguard Worker close(fd);
220*2d543d20SAndroid Build Coastguard Worker return ret;
221*2d543d20SAndroid Build Coastguard Worker }
222*2d543d20SAndroid Build Coastguard Worker
trans_to_raw_context(const char * trans,char ** rawp)223*2d543d20SAndroid Build Coastguard Worker static int trans_to_raw_context(const char *trans, char **rawp)
224*2d543d20SAndroid Build Coastguard Worker {
225*2d543d20SAndroid Build Coastguard Worker int ret;
226*2d543d20SAndroid Build Coastguard Worker int32_t ret_val;
227*2d543d20SAndroid Build Coastguard Worker int fd;
228*2d543d20SAndroid Build Coastguard Worker
229*2d543d20SAndroid Build Coastguard Worker *rawp = NULL;
230*2d543d20SAndroid Build Coastguard Worker
231*2d543d20SAndroid Build Coastguard Worker fd = setransd_open();
232*2d543d20SAndroid Build Coastguard Worker if (fd < 0)
233*2d543d20SAndroid Build Coastguard Worker return fd;
234*2d543d20SAndroid Build Coastguard Worker ret = send_request(fd, TRANS_TO_RAW_CONTEXT, trans, NULL);
235*2d543d20SAndroid Build Coastguard Worker if (ret)
236*2d543d20SAndroid Build Coastguard Worker goto out;
237*2d543d20SAndroid Build Coastguard Worker
238*2d543d20SAndroid Build Coastguard Worker ret = receive_response(fd, TRANS_TO_RAW_CONTEXT, rawp, &ret_val);
239*2d543d20SAndroid Build Coastguard Worker if (ret)
240*2d543d20SAndroid Build Coastguard Worker goto out;
241*2d543d20SAndroid Build Coastguard Worker
242*2d543d20SAndroid Build Coastguard Worker ret = ret_val;
243*2d543d20SAndroid Build Coastguard Worker out:
244*2d543d20SAndroid Build Coastguard Worker close(fd);
245*2d543d20SAndroid Build Coastguard Worker return ret;
246*2d543d20SAndroid Build Coastguard Worker }
247*2d543d20SAndroid Build Coastguard Worker
raw_context_to_color(const char * raw,char ** colors)248*2d543d20SAndroid Build Coastguard Worker static int raw_context_to_color(const char *raw, char **colors)
249*2d543d20SAndroid Build Coastguard Worker {
250*2d543d20SAndroid Build Coastguard Worker int ret;
251*2d543d20SAndroid Build Coastguard Worker int32_t ret_val;
252*2d543d20SAndroid Build Coastguard Worker int fd;
253*2d543d20SAndroid Build Coastguard Worker
254*2d543d20SAndroid Build Coastguard Worker fd = setransd_open();
255*2d543d20SAndroid Build Coastguard Worker if (fd < 0)
256*2d543d20SAndroid Build Coastguard Worker return fd;
257*2d543d20SAndroid Build Coastguard Worker
258*2d543d20SAndroid Build Coastguard Worker ret = send_request(fd, RAW_CONTEXT_TO_COLOR, raw, NULL);
259*2d543d20SAndroid Build Coastguard Worker if (ret)
260*2d543d20SAndroid Build Coastguard Worker goto out;
261*2d543d20SAndroid Build Coastguard Worker
262*2d543d20SAndroid Build Coastguard Worker ret = receive_response(fd, RAW_CONTEXT_TO_COLOR, colors, &ret_val);
263*2d543d20SAndroid Build Coastguard Worker if (ret)
264*2d543d20SAndroid Build Coastguard Worker goto out;
265*2d543d20SAndroid Build Coastguard Worker
266*2d543d20SAndroid Build Coastguard Worker ret = ret_val;
267*2d543d20SAndroid Build Coastguard Worker out:
268*2d543d20SAndroid Build Coastguard Worker close(fd);
269*2d543d20SAndroid Build Coastguard Worker return ret;
270*2d543d20SAndroid Build Coastguard Worker }
271*2d543d20SAndroid Build Coastguard Worker
setrans_thread_destructor(void * unused)272*2d543d20SAndroid Build Coastguard Worker static void setrans_thread_destructor(void __attribute__((unused)) *unused)
273*2d543d20SAndroid Build Coastguard Worker {
274*2d543d20SAndroid Build Coastguard Worker free(prev_t2r_trans);
275*2d543d20SAndroid Build Coastguard Worker free(prev_t2r_raw);
276*2d543d20SAndroid Build Coastguard Worker free(prev_r2t_trans);
277*2d543d20SAndroid Build Coastguard Worker free(prev_r2t_raw);
278*2d543d20SAndroid Build Coastguard Worker free(prev_r2c_trans);
279*2d543d20SAndroid Build Coastguard Worker free(prev_r2c_raw);
280*2d543d20SAndroid Build Coastguard Worker }
281*2d543d20SAndroid Build Coastguard Worker
282*2d543d20SAndroid Build Coastguard Worker void __attribute__((destructor)) setrans_lib_destructor(void);
283*2d543d20SAndroid Build Coastguard Worker
setrans_lib_destructor(void)284*2d543d20SAndroid Build Coastguard Worker void __attribute__((destructor)) setrans_lib_destructor(void)
285*2d543d20SAndroid Build Coastguard Worker {
286*2d543d20SAndroid Build Coastguard Worker if (!has_setrans)
287*2d543d20SAndroid Build Coastguard Worker return;
288*2d543d20SAndroid Build Coastguard Worker if (destructor_key_initialized)
289*2d543d20SAndroid Build Coastguard Worker __selinux_key_delete(destructor_key);
290*2d543d20SAndroid Build Coastguard Worker }
291*2d543d20SAndroid Build Coastguard Worker
init_thread_destructor(void)292*2d543d20SAndroid Build Coastguard Worker static inline void init_thread_destructor(void)
293*2d543d20SAndroid Build Coastguard Worker {
294*2d543d20SAndroid Build Coastguard Worker if (!has_setrans)
295*2d543d20SAndroid Build Coastguard Worker return;
296*2d543d20SAndroid Build Coastguard Worker if (destructor_initialized == 0) {
297*2d543d20SAndroid Build Coastguard Worker __selinux_setspecific(destructor_key, /* some valid address to please GCC */ &selinux_page_size);
298*2d543d20SAndroid Build Coastguard Worker destructor_initialized = 1;
299*2d543d20SAndroid Build Coastguard Worker }
300*2d543d20SAndroid Build Coastguard Worker }
301*2d543d20SAndroid Build Coastguard Worker
init_context_translations(void)302*2d543d20SAndroid Build Coastguard Worker static void init_context_translations(void)
303*2d543d20SAndroid Build Coastguard Worker {
304*2d543d20SAndroid Build Coastguard Worker has_setrans = (access(SETRANS_UNIX_SOCKET, F_OK) == 0);
305*2d543d20SAndroid Build Coastguard Worker if (!has_setrans)
306*2d543d20SAndroid Build Coastguard Worker return;
307*2d543d20SAndroid Build Coastguard Worker if (__selinux_key_create(&destructor_key, setrans_thread_destructor) == 0)
308*2d543d20SAndroid Build Coastguard Worker destructor_key_initialized = 1;
309*2d543d20SAndroid Build Coastguard Worker }
310*2d543d20SAndroid Build Coastguard Worker
selinux_trans_to_raw_context(const char * trans,char ** rawp)311*2d543d20SAndroid Build Coastguard Worker int selinux_trans_to_raw_context(const char * trans,
312*2d543d20SAndroid Build Coastguard Worker char ** rawp)
313*2d543d20SAndroid Build Coastguard Worker {
314*2d543d20SAndroid Build Coastguard Worker if (!trans) {
315*2d543d20SAndroid Build Coastguard Worker *rawp = NULL;
316*2d543d20SAndroid Build Coastguard Worker return 0;
317*2d543d20SAndroid Build Coastguard Worker }
318*2d543d20SAndroid Build Coastguard Worker
319*2d543d20SAndroid Build Coastguard Worker __selinux_once(once, init_context_translations);
320*2d543d20SAndroid Build Coastguard Worker init_thread_destructor();
321*2d543d20SAndroid Build Coastguard Worker
322*2d543d20SAndroid Build Coastguard Worker if (!has_setrans) {
323*2d543d20SAndroid Build Coastguard Worker *rawp = strdup(trans);
324*2d543d20SAndroid Build Coastguard Worker goto out;
325*2d543d20SAndroid Build Coastguard Worker }
326*2d543d20SAndroid Build Coastguard Worker
327*2d543d20SAndroid Build Coastguard Worker if (prev_t2r_trans && strcmp(prev_t2r_trans, trans) == 0) {
328*2d543d20SAndroid Build Coastguard Worker *rawp = strdup(prev_t2r_raw);
329*2d543d20SAndroid Build Coastguard Worker } else {
330*2d543d20SAndroid Build Coastguard Worker free(prev_t2r_trans);
331*2d543d20SAndroid Build Coastguard Worker prev_t2r_trans = NULL;
332*2d543d20SAndroid Build Coastguard Worker free(prev_t2r_raw);
333*2d543d20SAndroid Build Coastguard Worker prev_t2r_raw = NULL;
334*2d543d20SAndroid Build Coastguard Worker if (trans_to_raw_context(trans, rawp))
335*2d543d20SAndroid Build Coastguard Worker *rawp = strdup(trans);
336*2d543d20SAndroid Build Coastguard Worker if (*rawp) {
337*2d543d20SAndroid Build Coastguard Worker prev_t2r_trans = strdup(trans);
338*2d543d20SAndroid Build Coastguard Worker if (!prev_t2r_trans)
339*2d543d20SAndroid Build Coastguard Worker goto out;
340*2d543d20SAndroid Build Coastguard Worker prev_t2r_raw = strdup(*rawp);
341*2d543d20SAndroid Build Coastguard Worker if (!prev_t2r_raw) {
342*2d543d20SAndroid Build Coastguard Worker free(prev_t2r_trans);
343*2d543d20SAndroid Build Coastguard Worker prev_t2r_trans = NULL;
344*2d543d20SAndroid Build Coastguard Worker }
345*2d543d20SAndroid Build Coastguard Worker }
346*2d543d20SAndroid Build Coastguard Worker }
347*2d543d20SAndroid Build Coastguard Worker out:
348*2d543d20SAndroid Build Coastguard Worker return *rawp ? 0 : -1;
349*2d543d20SAndroid Build Coastguard Worker }
350*2d543d20SAndroid Build Coastguard Worker
351*2d543d20SAndroid Build Coastguard Worker
selinux_raw_to_trans_context(const char * raw,char ** transp)352*2d543d20SAndroid Build Coastguard Worker int selinux_raw_to_trans_context(const char * raw,
353*2d543d20SAndroid Build Coastguard Worker char ** transp)
354*2d543d20SAndroid Build Coastguard Worker {
355*2d543d20SAndroid Build Coastguard Worker if (!raw) {
356*2d543d20SAndroid Build Coastguard Worker *transp = NULL;
357*2d543d20SAndroid Build Coastguard Worker return 0;
358*2d543d20SAndroid Build Coastguard Worker }
359*2d543d20SAndroid Build Coastguard Worker
360*2d543d20SAndroid Build Coastguard Worker __selinux_once(once, init_context_translations);
361*2d543d20SAndroid Build Coastguard Worker init_thread_destructor();
362*2d543d20SAndroid Build Coastguard Worker
363*2d543d20SAndroid Build Coastguard Worker if (!has_setrans) {
364*2d543d20SAndroid Build Coastguard Worker *transp = strdup(raw);
365*2d543d20SAndroid Build Coastguard Worker goto out;
366*2d543d20SAndroid Build Coastguard Worker }
367*2d543d20SAndroid Build Coastguard Worker
368*2d543d20SAndroid Build Coastguard Worker if (prev_r2t_raw && strcmp(prev_r2t_raw, raw) == 0) {
369*2d543d20SAndroid Build Coastguard Worker *transp = strdup(prev_r2t_trans);
370*2d543d20SAndroid Build Coastguard Worker } else {
371*2d543d20SAndroid Build Coastguard Worker free(prev_r2t_raw);
372*2d543d20SAndroid Build Coastguard Worker prev_r2t_raw = NULL;
373*2d543d20SAndroid Build Coastguard Worker free(prev_r2t_trans);
374*2d543d20SAndroid Build Coastguard Worker prev_r2t_trans = NULL;
375*2d543d20SAndroid Build Coastguard Worker if (raw_to_trans_context(raw, transp))
376*2d543d20SAndroid Build Coastguard Worker *transp = strdup(raw);
377*2d543d20SAndroid Build Coastguard Worker if (*transp) {
378*2d543d20SAndroid Build Coastguard Worker prev_r2t_raw = strdup(raw);
379*2d543d20SAndroid Build Coastguard Worker if (!prev_r2t_raw)
380*2d543d20SAndroid Build Coastguard Worker goto out;
381*2d543d20SAndroid Build Coastguard Worker prev_r2t_trans = strdup(*transp);
382*2d543d20SAndroid Build Coastguard Worker if (!prev_r2t_trans) {
383*2d543d20SAndroid Build Coastguard Worker free(prev_r2t_raw);
384*2d543d20SAndroid Build Coastguard Worker prev_r2t_raw = NULL;
385*2d543d20SAndroid Build Coastguard Worker }
386*2d543d20SAndroid Build Coastguard Worker }
387*2d543d20SAndroid Build Coastguard Worker }
388*2d543d20SAndroid Build Coastguard Worker out:
389*2d543d20SAndroid Build Coastguard Worker return *transp ? 0 : -1;
390*2d543d20SAndroid Build Coastguard Worker }
391*2d543d20SAndroid Build Coastguard Worker
392*2d543d20SAndroid Build Coastguard Worker
selinux_raw_context_to_color(const char * raw,char ** transp)393*2d543d20SAndroid Build Coastguard Worker int selinux_raw_context_to_color(const char * raw, char **transp)
394*2d543d20SAndroid Build Coastguard Worker {
395*2d543d20SAndroid Build Coastguard Worker if (!raw) {
396*2d543d20SAndroid Build Coastguard Worker *transp = NULL;
397*2d543d20SAndroid Build Coastguard Worker return -1;
398*2d543d20SAndroid Build Coastguard Worker }
399*2d543d20SAndroid Build Coastguard Worker
400*2d543d20SAndroid Build Coastguard Worker __selinux_once(once, init_context_translations);
401*2d543d20SAndroid Build Coastguard Worker init_thread_destructor();
402*2d543d20SAndroid Build Coastguard Worker
403*2d543d20SAndroid Build Coastguard Worker if (!has_setrans) {
404*2d543d20SAndroid Build Coastguard Worker *transp = strdup(raw);
405*2d543d20SAndroid Build Coastguard Worker goto out;
406*2d543d20SAndroid Build Coastguard Worker }
407*2d543d20SAndroid Build Coastguard Worker
408*2d543d20SAndroid Build Coastguard Worker if (prev_r2c_raw && strcmp(prev_r2c_raw, raw) == 0) {
409*2d543d20SAndroid Build Coastguard Worker *transp = strdup(prev_r2c_trans);
410*2d543d20SAndroid Build Coastguard Worker } else {
411*2d543d20SAndroid Build Coastguard Worker free(prev_r2c_raw);
412*2d543d20SAndroid Build Coastguard Worker prev_r2c_raw = NULL;
413*2d543d20SAndroid Build Coastguard Worker free(prev_r2c_trans);
414*2d543d20SAndroid Build Coastguard Worker prev_r2c_trans = NULL;
415*2d543d20SAndroid Build Coastguard Worker if (raw_context_to_color(raw, transp))
416*2d543d20SAndroid Build Coastguard Worker return -1;
417*2d543d20SAndroid Build Coastguard Worker if (*transp) {
418*2d543d20SAndroid Build Coastguard Worker prev_r2c_raw = strdup(raw);
419*2d543d20SAndroid Build Coastguard Worker if (!prev_r2c_raw)
420*2d543d20SAndroid Build Coastguard Worker goto out;
421*2d543d20SAndroid Build Coastguard Worker prev_r2c_trans = strdup(*transp);
422*2d543d20SAndroid Build Coastguard Worker if (!prev_r2c_trans) {
423*2d543d20SAndroid Build Coastguard Worker free(prev_r2c_raw);
424*2d543d20SAndroid Build Coastguard Worker prev_r2c_raw = NULL;
425*2d543d20SAndroid Build Coastguard Worker }
426*2d543d20SAndroid Build Coastguard Worker }
427*2d543d20SAndroid Build Coastguard Worker }
428*2d543d20SAndroid Build Coastguard Worker out:
429*2d543d20SAndroid Build Coastguard Worker return *transp ? 0 : -1;
430*2d543d20SAndroid Build Coastguard Worker }
431*2d543d20SAndroid Build Coastguard Worker
432*2d543d20SAndroid Build Coastguard Worker #else /*DISABLE_SETRANS*/
433*2d543d20SAndroid Build Coastguard Worker
selinux_trans_to_raw_context(const char * trans,char ** rawp)434*2d543d20SAndroid Build Coastguard Worker int selinux_trans_to_raw_context(const char * trans,
435*2d543d20SAndroid Build Coastguard Worker char ** rawp)
436*2d543d20SAndroid Build Coastguard Worker {
437*2d543d20SAndroid Build Coastguard Worker if (!trans) {
438*2d543d20SAndroid Build Coastguard Worker *rawp = NULL;
439*2d543d20SAndroid Build Coastguard Worker return 0;
440*2d543d20SAndroid Build Coastguard Worker }
441*2d543d20SAndroid Build Coastguard Worker
442*2d543d20SAndroid Build Coastguard Worker *rawp = strdup(trans);
443*2d543d20SAndroid Build Coastguard Worker
444*2d543d20SAndroid Build Coastguard Worker return *rawp ? 0 : -1;
445*2d543d20SAndroid Build Coastguard Worker }
446*2d543d20SAndroid Build Coastguard Worker
447*2d543d20SAndroid Build Coastguard Worker
selinux_raw_to_trans_context(const char * raw,char ** transp)448*2d543d20SAndroid Build Coastguard Worker int selinux_raw_to_trans_context(const char * raw,
449*2d543d20SAndroid Build Coastguard Worker char ** transp)
450*2d543d20SAndroid Build Coastguard Worker {
451*2d543d20SAndroid Build Coastguard Worker if (!raw) {
452*2d543d20SAndroid Build Coastguard Worker *transp = NULL;
453*2d543d20SAndroid Build Coastguard Worker return 0;
454*2d543d20SAndroid Build Coastguard Worker }
455*2d543d20SAndroid Build Coastguard Worker *transp = strdup(raw);
456*2d543d20SAndroid Build Coastguard Worker
457*2d543d20SAndroid Build Coastguard Worker return *transp ? 0 : -1;
458*2d543d20SAndroid Build Coastguard Worker }
459*2d543d20SAndroid Build Coastguard Worker
460*2d543d20SAndroid Build Coastguard Worker #endif /*DISABLE_SETRANS*/
461