1*2d543d20SAndroid Build Coastguard Worker /*
2*2d543d20SAndroid Build Coastguard Worker * String representation support for classes and permissions.
3*2d543d20SAndroid Build Coastguard Worker */
4*2d543d20SAndroid Build Coastguard Worker #include <sys/stat.h>
5*2d543d20SAndroid Build Coastguard Worker #include <dirent.h>
6*2d543d20SAndroid Build Coastguard Worker #include <fcntl.h>
7*2d543d20SAndroid Build Coastguard Worker #include <limits.h>
8*2d543d20SAndroid Build Coastguard Worker #include <unistd.h>
9*2d543d20SAndroid Build Coastguard Worker #include <errno.h>
10*2d543d20SAndroid Build Coastguard Worker #include <stddef.h>
11*2d543d20SAndroid Build Coastguard Worker #include <stdio.h>
12*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
13*2d543d20SAndroid Build Coastguard Worker #include <string.h>
14*2d543d20SAndroid Build Coastguard Worker #include <stdint.h>
15*2d543d20SAndroid Build Coastguard Worker #include <ctype.h>
16*2d543d20SAndroid Build Coastguard Worker #include "selinux_internal.h"
17*2d543d20SAndroid Build Coastguard Worker #include "policy.h"
18*2d543d20SAndroid Build Coastguard Worker #include "mapping.h"
19*2d543d20SAndroid Build Coastguard Worker
20*2d543d20SAndroid Build Coastguard Worker #define MAXVECTORS 8*sizeof(access_vector_t)
21*2d543d20SAndroid Build Coastguard Worker
22*2d543d20SAndroid Build Coastguard Worker struct discover_class_node {
23*2d543d20SAndroid Build Coastguard Worker char *name;
24*2d543d20SAndroid Build Coastguard Worker security_class_t value;
25*2d543d20SAndroid Build Coastguard Worker char **perms;
26*2d543d20SAndroid Build Coastguard Worker
27*2d543d20SAndroid Build Coastguard Worker struct discover_class_node *next;
28*2d543d20SAndroid Build Coastguard Worker };
29*2d543d20SAndroid Build Coastguard Worker
30*2d543d20SAndroid Build Coastguard Worker static struct discover_class_node *discover_class_cache = NULL;
31*2d543d20SAndroid Build Coastguard Worker
get_class_cache_entry_name(const char * s)32*2d543d20SAndroid Build Coastguard Worker static struct discover_class_node * get_class_cache_entry_name(const char *s)
33*2d543d20SAndroid Build Coastguard Worker {
34*2d543d20SAndroid Build Coastguard Worker struct discover_class_node *node = discover_class_cache;
35*2d543d20SAndroid Build Coastguard Worker
36*2d543d20SAndroid Build Coastguard Worker for (; node != NULL && strcmp(s,node->name) != 0; node = node->next);
37*2d543d20SAndroid Build Coastguard Worker
38*2d543d20SAndroid Build Coastguard Worker return node;
39*2d543d20SAndroid Build Coastguard Worker }
40*2d543d20SAndroid Build Coastguard Worker
get_class_cache_entry_value(security_class_t c)41*2d543d20SAndroid Build Coastguard Worker static struct discover_class_node * get_class_cache_entry_value(security_class_t c)
42*2d543d20SAndroid Build Coastguard Worker {
43*2d543d20SAndroid Build Coastguard Worker struct discover_class_node *node = discover_class_cache;
44*2d543d20SAndroid Build Coastguard Worker
45*2d543d20SAndroid Build Coastguard Worker for (; node != NULL && c != node->value; node = node->next);
46*2d543d20SAndroid Build Coastguard Worker
47*2d543d20SAndroid Build Coastguard Worker return node;
48*2d543d20SAndroid Build Coastguard Worker }
49*2d543d20SAndroid Build Coastguard Worker
discover_class(const char * s)50*2d543d20SAndroid Build Coastguard Worker static struct discover_class_node * discover_class(const char *s)
51*2d543d20SAndroid Build Coastguard Worker {
52*2d543d20SAndroid Build Coastguard Worker int fd, ret;
53*2d543d20SAndroid Build Coastguard Worker char path[PATH_MAX];
54*2d543d20SAndroid Build Coastguard Worker char buf[20];
55*2d543d20SAndroid Build Coastguard Worker DIR *dir;
56*2d543d20SAndroid Build Coastguard Worker struct dirent *dentry;
57*2d543d20SAndroid Build Coastguard Worker size_t i;
58*2d543d20SAndroid Build Coastguard Worker
59*2d543d20SAndroid Build Coastguard Worker struct discover_class_node *node;
60*2d543d20SAndroid Build Coastguard Worker
61*2d543d20SAndroid Build Coastguard Worker if (!selinux_mnt) {
62*2d543d20SAndroid Build Coastguard Worker errno = ENOENT;
63*2d543d20SAndroid Build Coastguard Worker return NULL;
64*2d543d20SAndroid Build Coastguard Worker }
65*2d543d20SAndroid Build Coastguard Worker
66*2d543d20SAndroid Build Coastguard Worker if (strchr(s, '/') != NULL)
67*2d543d20SAndroid Build Coastguard Worker return NULL;
68*2d543d20SAndroid Build Coastguard Worker
69*2d543d20SAndroid Build Coastguard Worker /* allocate a node */
70*2d543d20SAndroid Build Coastguard Worker node = malloc(sizeof(struct discover_class_node));
71*2d543d20SAndroid Build Coastguard Worker if (node == NULL)
72*2d543d20SAndroid Build Coastguard Worker return NULL;
73*2d543d20SAndroid Build Coastguard Worker
74*2d543d20SAndroid Build Coastguard Worker /* allocate array for perms */
75*2d543d20SAndroid Build Coastguard Worker node->perms = calloc(MAXVECTORS,sizeof(char*));
76*2d543d20SAndroid Build Coastguard Worker if (node->perms == NULL)
77*2d543d20SAndroid Build Coastguard Worker goto err1;
78*2d543d20SAndroid Build Coastguard Worker
79*2d543d20SAndroid Build Coastguard Worker /* load up the name */
80*2d543d20SAndroid Build Coastguard Worker node->name = strdup(s);
81*2d543d20SAndroid Build Coastguard Worker if (node->name == NULL)
82*2d543d20SAndroid Build Coastguard Worker goto err2;
83*2d543d20SAndroid Build Coastguard Worker
84*2d543d20SAndroid Build Coastguard Worker /* load up class index */
85*2d543d20SAndroid Build Coastguard Worker ret = snprintf(path, sizeof path, "%s/class/%s/index", selinux_mnt,s);
86*2d543d20SAndroid Build Coastguard Worker if (ret < 0 || (size_t)ret >= sizeof path)
87*2d543d20SAndroid Build Coastguard Worker goto err3;
88*2d543d20SAndroid Build Coastguard Worker
89*2d543d20SAndroid Build Coastguard Worker fd = open(path, O_RDONLY | O_CLOEXEC);
90*2d543d20SAndroid Build Coastguard Worker if (fd < 0)
91*2d543d20SAndroid Build Coastguard Worker goto err3;
92*2d543d20SAndroid Build Coastguard Worker
93*2d543d20SAndroid Build Coastguard Worker memset(buf, 0, sizeof(buf));
94*2d543d20SAndroid Build Coastguard Worker ret = read(fd, buf, sizeof(buf) - 1);
95*2d543d20SAndroid Build Coastguard Worker close(fd);
96*2d543d20SAndroid Build Coastguard Worker if (ret < 0)
97*2d543d20SAndroid Build Coastguard Worker goto err3;
98*2d543d20SAndroid Build Coastguard Worker
99*2d543d20SAndroid Build Coastguard Worker if (sscanf(buf, "%hu", &node->value) != 1)
100*2d543d20SAndroid Build Coastguard Worker goto err3;
101*2d543d20SAndroid Build Coastguard Worker
102*2d543d20SAndroid Build Coastguard Worker /* load up permission indices */
103*2d543d20SAndroid Build Coastguard Worker ret = snprintf(path, sizeof path, "%s/class/%s/perms",selinux_mnt,s);
104*2d543d20SAndroid Build Coastguard Worker if (ret < 0 || (size_t)ret >= sizeof path)
105*2d543d20SAndroid Build Coastguard Worker goto err3;
106*2d543d20SAndroid Build Coastguard Worker
107*2d543d20SAndroid Build Coastguard Worker dir = opendir(path);
108*2d543d20SAndroid Build Coastguard Worker if (dir == NULL)
109*2d543d20SAndroid Build Coastguard Worker goto err3;
110*2d543d20SAndroid Build Coastguard Worker
111*2d543d20SAndroid Build Coastguard Worker dentry = readdir(dir);
112*2d543d20SAndroid Build Coastguard Worker while (dentry != NULL) {
113*2d543d20SAndroid Build Coastguard Worker unsigned int value;
114*2d543d20SAndroid Build Coastguard Worker struct stat m;
115*2d543d20SAndroid Build Coastguard Worker
116*2d543d20SAndroid Build Coastguard Worker ret = snprintf(path, sizeof path, "%s/class/%s/perms/%s", selinux_mnt,s,dentry->d_name);
117*2d543d20SAndroid Build Coastguard Worker if (ret < 0 || (size_t)ret >= sizeof path)
118*2d543d20SAndroid Build Coastguard Worker goto err4;
119*2d543d20SAndroid Build Coastguard Worker
120*2d543d20SAndroid Build Coastguard Worker fd = open(path, O_RDONLY | O_CLOEXEC);
121*2d543d20SAndroid Build Coastguard Worker if (fd < 0)
122*2d543d20SAndroid Build Coastguard Worker goto err4;
123*2d543d20SAndroid Build Coastguard Worker
124*2d543d20SAndroid Build Coastguard Worker if (fstat(fd, &m) < 0) {
125*2d543d20SAndroid Build Coastguard Worker close(fd);
126*2d543d20SAndroid Build Coastguard Worker goto err4;
127*2d543d20SAndroid Build Coastguard Worker }
128*2d543d20SAndroid Build Coastguard Worker
129*2d543d20SAndroid Build Coastguard Worker if (m.st_mode & S_IFDIR) {
130*2d543d20SAndroid Build Coastguard Worker close(fd);
131*2d543d20SAndroid Build Coastguard Worker dentry = readdir(dir);
132*2d543d20SAndroid Build Coastguard Worker continue;
133*2d543d20SAndroid Build Coastguard Worker }
134*2d543d20SAndroid Build Coastguard Worker
135*2d543d20SAndroid Build Coastguard Worker memset(buf, 0, sizeof(buf));
136*2d543d20SAndroid Build Coastguard Worker ret = read(fd, buf, sizeof(buf) - 1);
137*2d543d20SAndroid Build Coastguard Worker close(fd);
138*2d543d20SAndroid Build Coastguard Worker if (ret < 0)
139*2d543d20SAndroid Build Coastguard Worker goto err4;
140*2d543d20SAndroid Build Coastguard Worker
141*2d543d20SAndroid Build Coastguard Worker if (sscanf(buf, "%u", &value) != 1)
142*2d543d20SAndroid Build Coastguard Worker goto err4;
143*2d543d20SAndroid Build Coastguard Worker
144*2d543d20SAndroid Build Coastguard Worker if (value == 0 || value > MAXVECTORS)
145*2d543d20SAndroid Build Coastguard Worker goto err4;
146*2d543d20SAndroid Build Coastguard Worker
147*2d543d20SAndroid Build Coastguard Worker node->perms[value-1] = strdup(dentry->d_name);
148*2d543d20SAndroid Build Coastguard Worker if (node->perms[value-1] == NULL)
149*2d543d20SAndroid Build Coastguard Worker goto err4;
150*2d543d20SAndroid Build Coastguard Worker
151*2d543d20SAndroid Build Coastguard Worker dentry = readdir(dir);
152*2d543d20SAndroid Build Coastguard Worker }
153*2d543d20SAndroid Build Coastguard Worker closedir(dir);
154*2d543d20SAndroid Build Coastguard Worker
155*2d543d20SAndroid Build Coastguard Worker node->next = discover_class_cache;
156*2d543d20SAndroid Build Coastguard Worker discover_class_cache = node;
157*2d543d20SAndroid Build Coastguard Worker
158*2d543d20SAndroid Build Coastguard Worker return node;
159*2d543d20SAndroid Build Coastguard Worker
160*2d543d20SAndroid Build Coastguard Worker err4:
161*2d543d20SAndroid Build Coastguard Worker closedir(dir);
162*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < MAXVECTORS; i++)
163*2d543d20SAndroid Build Coastguard Worker free(node->perms[i]);
164*2d543d20SAndroid Build Coastguard Worker err3:
165*2d543d20SAndroid Build Coastguard Worker free(node->name);
166*2d543d20SAndroid Build Coastguard Worker err2:
167*2d543d20SAndroid Build Coastguard Worker free(node->perms);
168*2d543d20SAndroid Build Coastguard Worker err1:
169*2d543d20SAndroid Build Coastguard Worker free(node);
170*2d543d20SAndroid Build Coastguard Worker return NULL;
171*2d543d20SAndroid Build Coastguard Worker }
172*2d543d20SAndroid Build Coastguard Worker
selinux_flush_class_cache(void)173*2d543d20SAndroid Build Coastguard Worker void selinux_flush_class_cache(void)
174*2d543d20SAndroid Build Coastguard Worker {
175*2d543d20SAndroid Build Coastguard Worker struct discover_class_node *cur = discover_class_cache, *prev = NULL;
176*2d543d20SAndroid Build Coastguard Worker size_t i;
177*2d543d20SAndroid Build Coastguard Worker
178*2d543d20SAndroid Build Coastguard Worker while (cur != NULL) {
179*2d543d20SAndroid Build Coastguard Worker free(cur->name);
180*2d543d20SAndroid Build Coastguard Worker
181*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < MAXVECTORS; i++)
182*2d543d20SAndroid Build Coastguard Worker free(cur->perms[i]);
183*2d543d20SAndroid Build Coastguard Worker
184*2d543d20SAndroid Build Coastguard Worker free(cur->perms);
185*2d543d20SAndroid Build Coastguard Worker
186*2d543d20SAndroid Build Coastguard Worker prev = cur;
187*2d543d20SAndroid Build Coastguard Worker cur = cur->next;
188*2d543d20SAndroid Build Coastguard Worker
189*2d543d20SAndroid Build Coastguard Worker free(prev);
190*2d543d20SAndroid Build Coastguard Worker }
191*2d543d20SAndroid Build Coastguard Worker
192*2d543d20SAndroid Build Coastguard Worker discover_class_cache = NULL;
193*2d543d20SAndroid Build Coastguard Worker }
194*2d543d20SAndroid Build Coastguard Worker
195*2d543d20SAndroid Build Coastguard Worker
string_to_security_class(const char * s)196*2d543d20SAndroid Build Coastguard Worker security_class_t string_to_security_class(const char *s)
197*2d543d20SAndroid Build Coastguard Worker {
198*2d543d20SAndroid Build Coastguard Worker struct discover_class_node *node;
199*2d543d20SAndroid Build Coastguard Worker
200*2d543d20SAndroid Build Coastguard Worker node = get_class_cache_entry_name(s);
201*2d543d20SAndroid Build Coastguard Worker if (node == NULL) {
202*2d543d20SAndroid Build Coastguard Worker node = discover_class(s);
203*2d543d20SAndroid Build Coastguard Worker
204*2d543d20SAndroid Build Coastguard Worker if (node == NULL) {
205*2d543d20SAndroid Build Coastguard Worker errno = EINVAL;
206*2d543d20SAndroid Build Coastguard Worker return 0;
207*2d543d20SAndroid Build Coastguard Worker }
208*2d543d20SAndroid Build Coastguard Worker }
209*2d543d20SAndroid Build Coastguard Worker
210*2d543d20SAndroid Build Coastguard Worker return map_class(node->value);
211*2d543d20SAndroid Build Coastguard Worker }
212*2d543d20SAndroid Build Coastguard Worker
mode_to_security_class(mode_t m)213*2d543d20SAndroid Build Coastguard Worker security_class_t mode_to_security_class(mode_t m) {
214*2d543d20SAndroid Build Coastguard Worker
215*2d543d20SAndroid Build Coastguard Worker if (S_ISREG(m))
216*2d543d20SAndroid Build Coastguard Worker return string_to_security_class("file");
217*2d543d20SAndroid Build Coastguard Worker if (S_ISDIR(m))
218*2d543d20SAndroid Build Coastguard Worker return string_to_security_class("dir");
219*2d543d20SAndroid Build Coastguard Worker if (S_ISCHR(m))
220*2d543d20SAndroid Build Coastguard Worker return string_to_security_class("chr_file");
221*2d543d20SAndroid Build Coastguard Worker if (S_ISBLK(m))
222*2d543d20SAndroid Build Coastguard Worker return string_to_security_class("blk_file");
223*2d543d20SAndroid Build Coastguard Worker if (S_ISFIFO(m))
224*2d543d20SAndroid Build Coastguard Worker return string_to_security_class("fifo_file");
225*2d543d20SAndroid Build Coastguard Worker if (S_ISLNK(m))
226*2d543d20SAndroid Build Coastguard Worker return string_to_security_class("lnk_file");
227*2d543d20SAndroid Build Coastguard Worker if (S_ISSOCK(m))
228*2d543d20SAndroid Build Coastguard Worker return string_to_security_class("sock_file");
229*2d543d20SAndroid Build Coastguard Worker
230*2d543d20SAndroid Build Coastguard Worker errno = EINVAL;
231*2d543d20SAndroid Build Coastguard Worker return 0;
232*2d543d20SAndroid Build Coastguard Worker }
233*2d543d20SAndroid Build Coastguard Worker
string_to_av_perm(security_class_t tclass,const char * s)234*2d543d20SAndroid Build Coastguard Worker access_vector_t string_to_av_perm(security_class_t tclass, const char *s)
235*2d543d20SAndroid Build Coastguard Worker {
236*2d543d20SAndroid Build Coastguard Worker struct discover_class_node *node;
237*2d543d20SAndroid Build Coastguard Worker security_class_t kclass = unmap_class(tclass);
238*2d543d20SAndroid Build Coastguard Worker
239*2d543d20SAndroid Build Coastguard Worker node = get_class_cache_entry_value(kclass);
240*2d543d20SAndroid Build Coastguard Worker if (node != NULL) {
241*2d543d20SAndroid Build Coastguard Worker size_t i;
242*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < MAXVECTORS && node->perms[i] != NULL; i++)
243*2d543d20SAndroid Build Coastguard Worker if (strcmp(node->perms[i],s) == 0)
244*2d543d20SAndroid Build Coastguard Worker return map_perm(tclass, UINT32_C(1)<<i);
245*2d543d20SAndroid Build Coastguard Worker }
246*2d543d20SAndroid Build Coastguard Worker
247*2d543d20SAndroid Build Coastguard Worker errno = EINVAL;
248*2d543d20SAndroid Build Coastguard Worker return 0;
249*2d543d20SAndroid Build Coastguard Worker }
250*2d543d20SAndroid Build Coastguard Worker
security_class_to_string(security_class_t tclass)251*2d543d20SAndroid Build Coastguard Worker const char *security_class_to_string(security_class_t tclass)
252*2d543d20SAndroid Build Coastguard Worker {
253*2d543d20SAndroid Build Coastguard Worker struct discover_class_node *node;
254*2d543d20SAndroid Build Coastguard Worker
255*2d543d20SAndroid Build Coastguard Worker tclass = unmap_class(tclass);
256*2d543d20SAndroid Build Coastguard Worker
257*2d543d20SAndroid Build Coastguard Worker node = get_class_cache_entry_value(tclass);
258*2d543d20SAndroid Build Coastguard Worker if (node == NULL)
259*2d543d20SAndroid Build Coastguard Worker return NULL;
260*2d543d20SAndroid Build Coastguard Worker else
261*2d543d20SAndroid Build Coastguard Worker return node->name;
262*2d543d20SAndroid Build Coastguard Worker }
263*2d543d20SAndroid Build Coastguard Worker
security_av_perm_to_string(security_class_t tclass,access_vector_t av)264*2d543d20SAndroid Build Coastguard Worker const char *security_av_perm_to_string(security_class_t tclass,
265*2d543d20SAndroid Build Coastguard Worker access_vector_t av)
266*2d543d20SAndroid Build Coastguard Worker {
267*2d543d20SAndroid Build Coastguard Worker struct discover_class_node *node;
268*2d543d20SAndroid Build Coastguard Worker size_t i;
269*2d543d20SAndroid Build Coastguard Worker
270*2d543d20SAndroid Build Coastguard Worker av = unmap_perm(tclass, av);
271*2d543d20SAndroid Build Coastguard Worker tclass = unmap_class(tclass);
272*2d543d20SAndroid Build Coastguard Worker
273*2d543d20SAndroid Build Coastguard Worker node = get_class_cache_entry_value(tclass);
274*2d543d20SAndroid Build Coastguard Worker if (av && node)
275*2d543d20SAndroid Build Coastguard Worker for (i = 0; i<MAXVECTORS; i++)
276*2d543d20SAndroid Build Coastguard Worker if ((UINT32_C(1)<<i) & av)
277*2d543d20SAndroid Build Coastguard Worker return node->perms[i];
278*2d543d20SAndroid Build Coastguard Worker
279*2d543d20SAndroid Build Coastguard Worker return NULL;
280*2d543d20SAndroid Build Coastguard Worker }
281*2d543d20SAndroid Build Coastguard Worker
security_av_string(security_class_t tclass,access_vector_t av,char ** res)282*2d543d20SAndroid Build Coastguard Worker int security_av_string(security_class_t tclass, access_vector_t av, char **res)
283*2d543d20SAndroid Build Coastguard Worker {
284*2d543d20SAndroid Build Coastguard Worker unsigned int i;
285*2d543d20SAndroid Build Coastguard Worker size_t len = 5;
286*2d543d20SAndroid Build Coastguard Worker access_vector_t tmp = av;
287*2d543d20SAndroid Build Coastguard Worker int rc = 0;
288*2d543d20SAndroid Build Coastguard Worker const char *str;
289*2d543d20SAndroid Build Coastguard Worker char *ptr;
290*2d543d20SAndroid Build Coastguard Worker
291*2d543d20SAndroid Build Coastguard Worker /* first pass computes the required length */
292*2d543d20SAndroid Build Coastguard Worker for (i = 0; tmp; tmp >>= 1, i++) {
293*2d543d20SAndroid Build Coastguard Worker if (tmp & 1) {
294*2d543d20SAndroid Build Coastguard Worker str = security_av_perm_to_string(tclass, av & (UINT32_C(1)<<i));
295*2d543d20SAndroid Build Coastguard Worker if (str)
296*2d543d20SAndroid Build Coastguard Worker len += strlen(str) + 1;
297*2d543d20SAndroid Build Coastguard Worker }
298*2d543d20SAndroid Build Coastguard Worker }
299*2d543d20SAndroid Build Coastguard Worker
300*2d543d20SAndroid Build Coastguard Worker *res = malloc(len);
301*2d543d20SAndroid Build Coastguard Worker if (!*res) {
302*2d543d20SAndroid Build Coastguard Worker rc = -1;
303*2d543d20SAndroid Build Coastguard Worker goto out;
304*2d543d20SAndroid Build Coastguard Worker }
305*2d543d20SAndroid Build Coastguard Worker
306*2d543d20SAndroid Build Coastguard Worker /* second pass constructs the string */
307*2d543d20SAndroid Build Coastguard Worker tmp = av;
308*2d543d20SAndroid Build Coastguard Worker ptr = *res;
309*2d543d20SAndroid Build Coastguard Worker
310*2d543d20SAndroid Build Coastguard Worker if (!av) {
311*2d543d20SAndroid Build Coastguard Worker sprintf(ptr, "null");
312*2d543d20SAndroid Build Coastguard Worker goto out;
313*2d543d20SAndroid Build Coastguard Worker }
314*2d543d20SAndroid Build Coastguard Worker
315*2d543d20SAndroid Build Coastguard Worker ptr += sprintf(ptr, "{ ");
316*2d543d20SAndroid Build Coastguard Worker for (i = 0; tmp; tmp >>= 1, i++) {
317*2d543d20SAndroid Build Coastguard Worker if (tmp & 1) {
318*2d543d20SAndroid Build Coastguard Worker str = security_av_perm_to_string(tclass, av & (UINT32_C(1)<<i));
319*2d543d20SAndroid Build Coastguard Worker if (str)
320*2d543d20SAndroid Build Coastguard Worker ptr += sprintf(ptr, "%s ", str);
321*2d543d20SAndroid Build Coastguard Worker }
322*2d543d20SAndroid Build Coastguard Worker }
323*2d543d20SAndroid Build Coastguard Worker sprintf(ptr, "}");
324*2d543d20SAndroid Build Coastguard Worker out:
325*2d543d20SAndroid Build Coastguard Worker return rc;
326*2d543d20SAndroid Build Coastguard Worker }
327*2d543d20SAndroid Build Coastguard Worker
print_access_vector(security_class_t tclass,access_vector_t av)328*2d543d20SAndroid Build Coastguard Worker void print_access_vector(security_class_t tclass, access_vector_t av)
329*2d543d20SAndroid Build Coastguard Worker {
330*2d543d20SAndroid Build Coastguard Worker const char *permstr;
331*2d543d20SAndroid Build Coastguard Worker access_vector_t bit = 1;
332*2d543d20SAndroid Build Coastguard Worker
333*2d543d20SAndroid Build Coastguard Worker if (av == 0) {
334*2d543d20SAndroid Build Coastguard Worker printf(" null");
335*2d543d20SAndroid Build Coastguard Worker return;
336*2d543d20SAndroid Build Coastguard Worker }
337*2d543d20SAndroid Build Coastguard Worker
338*2d543d20SAndroid Build Coastguard Worker printf(" {");
339*2d543d20SAndroid Build Coastguard Worker
340*2d543d20SAndroid Build Coastguard Worker for (;;) {
341*2d543d20SAndroid Build Coastguard Worker if (av & bit) {
342*2d543d20SAndroid Build Coastguard Worker permstr = security_av_perm_to_string(tclass, bit);
343*2d543d20SAndroid Build Coastguard Worker if (!permstr)
344*2d543d20SAndroid Build Coastguard Worker break;
345*2d543d20SAndroid Build Coastguard Worker printf(" %s", permstr);
346*2d543d20SAndroid Build Coastguard Worker av &= ~bit;
347*2d543d20SAndroid Build Coastguard Worker if (!av)
348*2d543d20SAndroid Build Coastguard Worker break;
349*2d543d20SAndroid Build Coastguard Worker }
350*2d543d20SAndroid Build Coastguard Worker bit <<= 1;
351*2d543d20SAndroid Build Coastguard Worker }
352*2d543d20SAndroid Build Coastguard Worker
353*2d543d20SAndroid Build Coastguard Worker if (av)
354*2d543d20SAndroid Build Coastguard Worker printf(" 0x%x", av);
355*2d543d20SAndroid Build Coastguard Worker printf(" }");
356*2d543d20SAndroid Build Coastguard Worker }
357