1*2d543d20SAndroid Build Coastguard Worker /* Authors: Steve Lawrence <[email protected]>
2*2d543d20SAndroid Build Coastguard Worker *
3*2d543d20SAndroid Build Coastguard Worker * Functions to convert policy module to CIL
4*2d543d20SAndroid Build Coastguard Worker *
5*2d543d20SAndroid Build Coastguard Worker * Copyright (C) 2015 Tresys Technology, LLC
6*2d543d20SAndroid Build Coastguard Worker * Copyright (C) 2017 Mellanox Technologies Inc.
7*2d543d20SAndroid Build Coastguard Worker *
8*2d543d20SAndroid Build Coastguard Worker * This library is free software; you can redistribute it and/or
9*2d543d20SAndroid Build Coastguard Worker * modify it under the terms of the GNU Lesser General Public
10*2d543d20SAndroid Build Coastguard Worker * License as published by the Free Software Foundation; either
11*2d543d20SAndroid Build Coastguard Worker * version 2.1 of the License, or (at your option) any later version.
12*2d543d20SAndroid Build Coastguard Worker *
13*2d543d20SAndroid Build Coastguard Worker * This library is distributed in the hope that it will be useful,
14*2d543d20SAndroid Build Coastguard Worker * but WITHOUT ANY WARRANTY; without even the implied warranty of
15*2d543d20SAndroid Build Coastguard Worker * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16*2d543d20SAndroid Build Coastguard Worker * Lesser General Public License for more details.
17*2d543d20SAndroid Build Coastguard Worker *
18*2d543d20SAndroid Build Coastguard Worker * You should have received a copy of the GNU Lesser General Public
19*2d543d20SAndroid Build Coastguard Worker * License along with this library; if not, write to the Free Software
20*2d543d20SAndroid Build Coastguard Worker * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21*2d543d20SAndroid Build Coastguard Worker */
22*2d543d20SAndroid Build Coastguard Worker
23*2d543d20SAndroid Build Coastguard Worker #include <arpa/inet.h>
24*2d543d20SAndroid Build Coastguard Worker #include <ctype.h>
25*2d543d20SAndroid Build Coastguard Worker #include <errno.h>
26*2d543d20SAndroid Build Coastguard Worker #include <fcntl.h>
27*2d543d20SAndroid Build Coastguard Worker #include <getopt.h>
28*2d543d20SAndroid Build Coastguard Worker #include <libgen.h>
29*2d543d20SAndroid Build Coastguard Worker #include <netinet/in.h>
30*2d543d20SAndroid Build Coastguard Worker #ifndef IPPROTO_DCCP
31*2d543d20SAndroid Build Coastguard Worker #define IPPROTO_DCCP 33
32*2d543d20SAndroid Build Coastguard Worker #endif
33*2d543d20SAndroid Build Coastguard Worker #ifndef IPPROTO_SCTP
34*2d543d20SAndroid Build Coastguard Worker #define IPPROTO_SCTP 132
35*2d543d20SAndroid Build Coastguard Worker #endif
36*2d543d20SAndroid Build Coastguard Worker #include <signal.h>
37*2d543d20SAndroid Build Coastguard Worker #include <stdarg.h>
38*2d543d20SAndroid Build Coastguard Worker #include <stdio.h>
39*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
40*2d543d20SAndroid Build Coastguard Worker #include <string.h>
41*2d543d20SAndroid Build Coastguard Worker #include <inttypes.h>
42*2d543d20SAndroid Build Coastguard Worker #include <sys/types.h>
43*2d543d20SAndroid Build Coastguard Worker #include <sys/stat.h>
44*2d543d20SAndroid Build Coastguard Worker #include <unistd.h>
45*2d543d20SAndroid Build Coastguard Worker
46*2d543d20SAndroid Build Coastguard Worker #include <sepol/module.h>
47*2d543d20SAndroid Build Coastguard Worker #include <sepol/module_to_cil.h>
48*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/conditional.h>
49*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/hashtab.h>
50*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/polcaps.h>
51*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/policydb.h>
52*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/services.h>
53*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/util.h>
54*2d543d20SAndroid Build Coastguard Worker
55*2d543d20SAndroid Build Coastguard Worker #include "debug.h"
56*2d543d20SAndroid Build Coastguard Worker #include "kernel_to_common.h"
57*2d543d20SAndroid Build Coastguard Worker #include "private.h"
58*2d543d20SAndroid Build Coastguard Worker #include "module_internal.h"
59*2d543d20SAndroid Build Coastguard Worker
60*2d543d20SAndroid Build Coastguard Worker #ifdef __GNUC__
61*2d543d20SAndroid Build Coastguard Worker # define UNUSED(x) UNUSED_ ## x __attribute__((__unused__))
62*2d543d20SAndroid Build Coastguard Worker #else
63*2d543d20SAndroid Build Coastguard Worker # define UNUSED(x) UNUSED_ ## x
64*2d543d20SAndroid Build Coastguard Worker #endif
65*2d543d20SAndroid Build Coastguard Worker
66*2d543d20SAndroid Build Coastguard Worker static FILE *out_file;
67*2d543d20SAndroid Build Coastguard Worker
68*2d543d20SAndroid Build Coastguard Worker #define STACK_SIZE 16
69*2d543d20SAndroid Build Coastguard Worker #define DEFAULT_LEVEL "systemlow"
70*2d543d20SAndroid Build Coastguard Worker #define DEFAULT_OBJECT "object_r"
71*2d543d20SAndroid Build Coastguard Worker #define GEN_REQUIRE_ATTR "cil_gen_require" /* Also in libsepol/cil/src/cil_post.c */
72*2d543d20SAndroid Build Coastguard Worker #define TYPEATTR_INFIX "_typeattr_" /* Also in libsepol/cil/src/cil_post.c */
73*2d543d20SAndroid Build Coastguard Worker #define ROLEATTR_INFIX "_roleattr_"
74*2d543d20SAndroid Build Coastguard Worker
cil_indent(int indent)75*2d543d20SAndroid Build Coastguard Worker static void cil_indent(int indent)
76*2d543d20SAndroid Build Coastguard Worker {
77*2d543d20SAndroid Build Coastguard Worker if (fprintf(out_file, "%*s", indent * 4, "") < 0) {
78*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Failed to write to output");
79*2d543d20SAndroid Build Coastguard Worker _exit(EXIT_FAILURE);
80*2d543d20SAndroid Build Coastguard Worker }
81*2d543d20SAndroid Build Coastguard Worker }
82*2d543d20SAndroid Build Coastguard Worker
83*2d543d20SAndroid Build Coastguard Worker __attribute__ ((format(printf, 1, 2)))
cil_printf(const char * fmt,...)84*2d543d20SAndroid Build Coastguard Worker static void cil_printf(const char *fmt, ...) {
85*2d543d20SAndroid Build Coastguard Worker va_list argptr;
86*2d543d20SAndroid Build Coastguard Worker va_start(argptr, fmt);
87*2d543d20SAndroid Build Coastguard Worker if (vfprintf(out_file, fmt, argptr) < 0) {
88*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Failed to write to output");
89*2d543d20SAndroid Build Coastguard Worker _exit(EXIT_FAILURE);
90*2d543d20SAndroid Build Coastguard Worker }
91*2d543d20SAndroid Build Coastguard Worker va_end(argptr);
92*2d543d20SAndroid Build Coastguard Worker }
93*2d543d20SAndroid Build Coastguard Worker
94*2d543d20SAndroid Build Coastguard Worker __attribute__ ((format(printf, 2, 3)))
cil_println(int indent,const char * fmt,...)95*2d543d20SAndroid Build Coastguard Worker static void cil_println(int indent, const char *fmt, ...)
96*2d543d20SAndroid Build Coastguard Worker {
97*2d543d20SAndroid Build Coastguard Worker va_list argptr;
98*2d543d20SAndroid Build Coastguard Worker cil_indent(indent);
99*2d543d20SAndroid Build Coastguard Worker va_start(argptr, fmt);
100*2d543d20SAndroid Build Coastguard Worker if (vfprintf(out_file, fmt, argptr) < 0) {
101*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Failed to write to output");
102*2d543d20SAndroid Build Coastguard Worker _exit(EXIT_FAILURE);
103*2d543d20SAndroid Build Coastguard Worker }
104*2d543d20SAndroid Build Coastguard Worker va_end(argptr);
105*2d543d20SAndroid Build Coastguard Worker if (fprintf(out_file, "\n") < 0) {
106*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Failed to write to output");
107*2d543d20SAndroid Build Coastguard Worker _exit(EXIT_FAILURE);
108*2d543d20SAndroid Build Coastguard Worker }
109*2d543d20SAndroid Build Coastguard Worker }
110*2d543d20SAndroid Build Coastguard Worker
get_line(char ** start,char * end,char ** line)111*2d543d20SAndroid Build Coastguard Worker static int get_line(char **start, char *end, char **line)
112*2d543d20SAndroid Build Coastguard Worker {
113*2d543d20SAndroid Build Coastguard Worker int rc = 1;
114*2d543d20SAndroid Build Coastguard Worker char *p = NULL;
115*2d543d20SAndroid Build Coastguard Worker size_t len = 0;
116*2d543d20SAndroid Build Coastguard Worker
117*2d543d20SAndroid Build Coastguard Worker *line = NULL;
118*2d543d20SAndroid Build Coastguard Worker
119*2d543d20SAndroid Build Coastguard Worker for (p = *start; p < end && isspace(*p); p++);
120*2d543d20SAndroid Build Coastguard Worker
121*2d543d20SAndroid Build Coastguard Worker *start = p;
122*2d543d20SAndroid Build Coastguard Worker
123*2d543d20SAndroid Build Coastguard Worker for (len = 0; p < end && *p != '\n' && *p != '\0'; p++, len++);
124*2d543d20SAndroid Build Coastguard Worker
125*2d543d20SAndroid Build Coastguard Worker if (zero_or_saturated(len)) {
126*2d543d20SAndroid Build Coastguard Worker rc = 0;
127*2d543d20SAndroid Build Coastguard Worker goto exit;
128*2d543d20SAndroid Build Coastguard Worker }
129*2d543d20SAndroid Build Coastguard Worker
130*2d543d20SAndroid Build Coastguard Worker *line = malloc(len+1);
131*2d543d20SAndroid Build Coastguard Worker if (*line == NULL) {
132*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Out of memory");
133*2d543d20SAndroid Build Coastguard Worker rc = -1;
134*2d543d20SAndroid Build Coastguard Worker goto exit;
135*2d543d20SAndroid Build Coastguard Worker }
136*2d543d20SAndroid Build Coastguard Worker
137*2d543d20SAndroid Build Coastguard Worker memcpy(*line, *start, len);
138*2d543d20SAndroid Build Coastguard Worker (*line)[len] = '\0';
139*2d543d20SAndroid Build Coastguard Worker
140*2d543d20SAndroid Build Coastguard Worker *start = p;
141*2d543d20SAndroid Build Coastguard Worker
142*2d543d20SAndroid Build Coastguard Worker return rc;
143*2d543d20SAndroid Build Coastguard Worker
144*2d543d20SAndroid Build Coastguard Worker exit:
145*2d543d20SAndroid Build Coastguard Worker *start = NULL;
146*2d543d20SAndroid Build Coastguard Worker return rc;
147*2d543d20SAndroid Build Coastguard Worker }
148*2d543d20SAndroid Build Coastguard Worker
149*2d543d20SAndroid Build Coastguard Worker struct map_args {
150*2d543d20SAndroid Build Coastguard Worker struct policydb *pdb;
151*2d543d20SAndroid Build Coastguard Worker struct avrule_block *block;
152*2d543d20SAndroid Build Coastguard Worker struct stack *decl_stack;
153*2d543d20SAndroid Build Coastguard Worker int scope;
154*2d543d20SAndroid Build Coastguard Worker int indent;
155*2d543d20SAndroid Build Coastguard Worker int sym_index;
156*2d543d20SAndroid Build Coastguard Worker };
157*2d543d20SAndroid Build Coastguard Worker
158*2d543d20SAndroid Build Coastguard Worker struct stack {
159*2d543d20SAndroid Build Coastguard Worker void **stack;
160*2d543d20SAndroid Build Coastguard Worker int pos;
161*2d543d20SAndroid Build Coastguard Worker int size;
162*2d543d20SAndroid Build Coastguard Worker };
163*2d543d20SAndroid Build Coastguard Worker
164*2d543d20SAndroid Build Coastguard Worker struct role_list_node {
165*2d543d20SAndroid Build Coastguard Worker char *role_name;
166*2d543d20SAndroid Build Coastguard Worker role_datum_t *role;
167*2d543d20SAndroid Build Coastguard Worker };
168*2d543d20SAndroid Build Coastguard Worker
169*2d543d20SAndroid Build Coastguard Worker struct attr_list_node {
170*2d543d20SAndroid Build Coastguard Worker char *attr_name;
171*2d543d20SAndroid Build Coastguard Worker int is_type;
172*2d543d20SAndroid Build Coastguard Worker void *set;
173*2d543d20SAndroid Build Coastguard Worker };
174*2d543d20SAndroid Build Coastguard Worker
175*2d543d20SAndroid Build Coastguard Worker struct list_node {
176*2d543d20SAndroid Build Coastguard Worker void *data;
177*2d543d20SAndroid Build Coastguard Worker struct list_node *next;
178*2d543d20SAndroid Build Coastguard Worker };
179*2d543d20SAndroid Build Coastguard Worker
180*2d543d20SAndroid Build Coastguard Worker struct list {
181*2d543d20SAndroid Build Coastguard Worker struct list_node *head;
182*2d543d20SAndroid Build Coastguard Worker };
183*2d543d20SAndroid Build Coastguard Worker
184*2d543d20SAndroid Build Coastguard Worker /* A linked list of all roles stored in the pdb
185*2d543d20SAndroid Build Coastguard Worker * which is iterated to determine types associated
186*2d543d20SAndroid Build Coastguard Worker * with each role when printing role_type statements
187*2d543d20SAndroid Build Coastguard Worker */
188*2d543d20SAndroid Build Coastguard Worker static struct list *role_list;
189*2d543d20SAndroid Build Coastguard Worker
list_destroy(struct list ** list)190*2d543d20SAndroid Build Coastguard Worker static void list_destroy(struct list **list)
191*2d543d20SAndroid Build Coastguard Worker {
192*2d543d20SAndroid Build Coastguard Worker struct list_node *curr = (*list)->head;
193*2d543d20SAndroid Build Coastguard Worker struct list_node *tmp;
194*2d543d20SAndroid Build Coastguard Worker
195*2d543d20SAndroid Build Coastguard Worker while (curr != NULL) {
196*2d543d20SAndroid Build Coastguard Worker tmp = curr->next;
197*2d543d20SAndroid Build Coastguard Worker free(curr);
198*2d543d20SAndroid Build Coastguard Worker curr = tmp;
199*2d543d20SAndroid Build Coastguard Worker }
200*2d543d20SAndroid Build Coastguard Worker
201*2d543d20SAndroid Build Coastguard Worker free(*list);
202*2d543d20SAndroid Build Coastguard Worker *list = NULL;
203*2d543d20SAndroid Build Coastguard Worker }
204*2d543d20SAndroid Build Coastguard Worker
role_list_destroy(void)205*2d543d20SAndroid Build Coastguard Worker static void role_list_destroy(void)
206*2d543d20SAndroid Build Coastguard Worker {
207*2d543d20SAndroid Build Coastguard Worker struct list_node *curr;
208*2d543d20SAndroid Build Coastguard Worker
209*2d543d20SAndroid Build Coastguard Worker if (role_list == NULL) {
210*2d543d20SAndroid Build Coastguard Worker return;
211*2d543d20SAndroid Build Coastguard Worker }
212*2d543d20SAndroid Build Coastguard Worker curr = role_list->head;
213*2d543d20SAndroid Build Coastguard Worker
214*2d543d20SAndroid Build Coastguard Worker while (curr != NULL) {
215*2d543d20SAndroid Build Coastguard Worker free(curr->data);
216*2d543d20SAndroid Build Coastguard Worker curr->data = NULL;
217*2d543d20SAndroid Build Coastguard Worker curr = curr->next;
218*2d543d20SAndroid Build Coastguard Worker }
219*2d543d20SAndroid Build Coastguard Worker
220*2d543d20SAndroid Build Coastguard Worker list_destroy(&role_list);
221*2d543d20SAndroid Build Coastguard Worker }
222*2d543d20SAndroid Build Coastguard Worker
attr_list_destroy(struct list ** attr_list)223*2d543d20SAndroid Build Coastguard Worker static void attr_list_destroy(struct list **attr_list)
224*2d543d20SAndroid Build Coastguard Worker {
225*2d543d20SAndroid Build Coastguard Worker struct list_node *curr;
226*2d543d20SAndroid Build Coastguard Worker struct attr_list_node *attr;
227*2d543d20SAndroid Build Coastguard Worker
228*2d543d20SAndroid Build Coastguard Worker if (attr_list == NULL || *attr_list == NULL) {
229*2d543d20SAndroid Build Coastguard Worker return;
230*2d543d20SAndroid Build Coastguard Worker }
231*2d543d20SAndroid Build Coastguard Worker
232*2d543d20SAndroid Build Coastguard Worker curr = (*attr_list)->head;
233*2d543d20SAndroid Build Coastguard Worker
234*2d543d20SAndroid Build Coastguard Worker while (curr != NULL) {
235*2d543d20SAndroid Build Coastguard Worker attr = curr->data;
236*2d543d20SAndroid Build Coastguard Worker if (attr != NULL) {
237*2d543d20SAndroid Build Coastguard Worker free(attr->attr_name);
238*2d543d20SAndroid Build Coastguard Worker }
239*2d543d20SAndroid Build Coastguard Worker
240*2d543d20SAndroid Build Coastguard Worker free(curr->data);
241*2d543d20SAndroid Build Coastguard Worker curr->data = NULL;
242*2d543d20SAndroid Build Coastguard Worker curr = curr->next;
243*2d543d20SAndroid Build Coastguard Worker }
244*2d543d20SAndroid Build Coastguard Worker
245*2d543d20SAndroid Build Coastguard Worker list_destroy(attr_list);
246*2d543d20SAndroid Build Coastguard Worker }
247*2d543d20SAndroid Build Coastguard Worker
list_init(struct list ** list)248*2d543d20SAndroid Build Coastguard Worker static int list_init(struct list **list)
249*2d543d20SAndroid Build Coastguard Worker {
250*2d543d20SAndroid Build Coastguard Worker struct list *l = calloc(1, sizeof(*l));
251*2d543d20SAndroid Build Coastguard Worker if (l == NULL) {
252*2d543d20SAndroid Build Coastguard Worker return -1;
253*2d543d20SAndroid Build Coastguard Worker }
254*2d543d20SAndroid Build Coastguard Worker
255*2d543d20SAndroid Build Coastguard Worker *list = l;
256*2d543d20SAndroid Build Coastguard Worker return 0;
257*2d543d20SAndroid Build Coastguard Worker }
258*2d543d20SAndroid Build Coastguard Worker
list_prepend(struct list * list,void * data)259*2d543d20SAndroid Build Coastguard Worker static int list_prepend(struct list *list, void *data)
260*2d543d20SAndroid Build Coastguard Worker {
261*2d543d20SAndroid Build Coastguard Worker int rc = -1;
262*2d543d20SAndroid Build Coastguard Worker struct list_node *node = calloc(1, sizeof(*node));
263*2d543d20SAndroid Build Coastguard Worker if (node == NULL) {
264*2d543d20SAndroid Build Coastguard Worker goto exit;
265*2d543d20SAndroid Build Coastguard Worker }
266*2d543d20SAndroid Build Coastguard Worker
267*2d543d20SAndroid Build Coastguard Worker node->data = data;
268*2d543d20SAndroid Build Coastguard Worker node->next = list->head;
269*2d543d20SAndroid Build Coastguard Worker list->head = node;
270*2d543d20SAndroid Build Coastguard Worker
271*2d543d20SAndroid Build Coastguard Worker rc = 0;
272*2d543d20SAndroid Build Coastguard Worker
273*2d543d20SAndroid Build Coastguard Worker exit:
274*2d543d20SAndroid Build Coastguard Worker return rc;
275*2d543d20SAndroid Build Coastguard Worker }
276*2d543d20SAndroid Build Coastguard Worker
roles_gather_map(char * key,void * data,void * args)277*2d543d20SAndroid Build Coastguard Worker static int roles_gather_map(char *key, void *data, void *args)
278*2d543d20SAndroid Build Coastguard Worker {
279*2d543d20SAndroid Build Coastguard Worker struct role_list_node *role_node;
280*2d543d20SAndroid Build Coastguard Worker role_datum_t *role = data;
281*2d543d20SAndroid Build Coastguard Worker int rc = -1;
282*2d543d20SAndroid Build Coastguard Worker
283*2d543d20SAndroid Build Coastguard Worker role_node = calloc(1, sizeof(*role_node));
284*2d543d20SAndroid Build Coastguard Worker if (role_node == NULL) {
285*2d543d20SAndroid Build Coastguard Worker return rc;
286*2d543d20SAndroid Build Coastguard Worker }
287*2d543d20SAndroid Build Coastguard Worker
288*2d543d20SAndroid Build Coastguard Worker role_node->role_name = key;
289*2d543d20SAndroid Build Coastguard Worker role_node->role = role;
290*2d543d20SAndroid Build Coastguard Worker
291*2d543d20SAndroid Build Coastguard Worker rc = list_prepend((struct list *)args, role_node);
292*2d543d20SAndroid Build Coastguard Worker if (rc != 0)
293*2d543d20SAndroid Build Coastguard Worker free(role_node);
294*2d543d20SAndroid Build Coastguard Worker return rc;
295*2d543d20SAndroid Build Coastguard Worker }
296*2d543d20SAndroid Build Coastguard Worker
role_list_create(hashtab_t roles_tab)297*2d543d20SAndroid Build Coastguard Worker static int role_list_create(hashtab_t roles_tab)
298*2d543d20SAndroid Build Coastguard Worker {
299*2d543d20SAndroid Build Coastguard Worker int rc = -1;
300*2d543d20SAndroid Build Coastguard Worker
301*2d543d20SAndroid Build Coastguard Worker rc = list_init(&role_list);
302*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
303*2d543d20SAndroid Build Coastguard Worker goto exit;
304*2d543d20SAndroid Build Coastguard Worker }
305*2d543d20SAndroid Build Coastguard Worker
306*2d543d20SAndroid Build Coastguard Worker rc = hashtab_map(roles_tab, roles_gather_map, role_list);
307*2d543d20SAndroid Build Coastguard Worker
308*2d543d20SAndroid Build Coastguard Worker exit:
309*2d543d20SAndroid Build Coastguard Worker return rc;
310*2d543d20SAndroid Build Coastguard Worker }
311*2d543d20SAndroid Build Coastguard Worker
312*2d543d20SAndroid Build Coastguard Worker // array of lists, where each list contains all the aliases defined in the scope at index i
313*2d543d20SAndroid Build Coastguard Worker static struct list **typealias_lists;
314*2d543d20SAndroid Build Coastguard Worker static uint32_t typealias_lists_len;
315*2d543d20SAndroid Build Coastguard Worker
typealiases_gather_map(char * key,void * data,void * arg)316*2d543d20SAndroid Build Coastguard Worker static int typealiases_gather_map(char *key, void *data, void *arg)
317*2d543d20SAndroid Build Coastguard Worker {
318*2d543d20SAndroid Build Coastguard Worker int rc = -1;
319*2d543d20SAndroid Build Coastguard Worker struct type_datum *type = data;
320*2d543d20SAndroid Build Coastguard Worker struct policydb *pdb = arg;
321*2d543d20SAndroid Build Coastguard Worker struct scope_datum *scope;
322*2d543d20SAndroid Build Coastguard Worker uint32_t len;
323*2d543d20SAndroid Build Coastguard Worker uint32_t scope_id;
324*2d543d20SAndroid Build Coastguard Worker
325*2d543d20SAndroid Build Coastguard Worker if (type->primary != 1) {
326*2d543d20SAndroid Build Coastguard Worker scope = hashtab_search(pdb->scope[SYM_TYPES].table, key);
327*2d543d20SAndroid Build Coastguard Worker if (scope == NULL) {
328*2d543d20SAndroid Build Coastguard Worker return -1;
329*2d543d20SAndroid Build Coastguard Worker }
330*2d543d20SAndroid Build Coastguard Worker
331*2d543d20SAndroid Build Coastguard Worker len = scope->decl_ids_len;
332*2d543d20SAndroid Build Coastguard Worker if (len > 0) {
333*2d543d20SAndroid Build Coastguard Worker scope_id = scope->decl_ids[len-1];
334*2d543d20SAndroid Build Coastguard Worker if (typealias_lists[scope_id] == NULL) {
335*2d543d20SAndroid Build Coastguard Worker rc = list_init(&typealias_lists[scope_id]);
336*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
337*2d543d20SAndroid Build Coastguard Worker goto exit;
338*2d543d20SAndroid Build Coastguard Worker }
339*2d543d20SAndroid Build Coastguard Worker }
340*2d543d20SAndroid Build Coastguard Worker /* As typealias_lists[scope_id] does not hold the
341*2d543d20SAndroid Build Coastguard Worker * ownership of its items (typealias_list_destroy does
342*2d543d20SAndroid Build Coastguard Worker * not free the list items), "key" does not need to be
343*2d543d20SAndroid Build Coastguard Worker * strdup'ed before it is inserted in the list.
344*2d543d20SAndroid Build Coastguard Worker */
345*2d543d20SAndroid Build Coastguard Worker list_prepend(typealias_lists[scope_id], key);
346*2d543d20SAndroid Build Coastguard Worker }
347*2d543d20SAndroid Build Coastguard Worker }
348*2d543d20SAndroid Build Coastguard Worker
349*2d543d20SAndroid Build Coastguard Worker return 0;
350*2d543d20SAndroid Build Coastguard Worker
351*2d543d20SAndroid Build Coastguard Worker exit:
352*2d543d20SAndroid Build Coastguard Worker return rc;
353*2d543d20SAndroid Build Coastguard Worker }
354*2d543d20SAndroid Build Coastguard Worker
typealias_list_destroy(void)355*2d543d20SAndroid Build Coastguard Worker static void typealias_list_destroy(void)
356*2d543d20SAndroid Build Coastguard Worker {
357*2d543d20SAndroid Build Coastguard Worker uint32_t i;
358*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < typealias_lists_len; i++) {
359*2d543d20SAndroid Build Coastguard Worker if (typealias_lists[i] != NULL) {
360*2d543d20SAndroid Build Coastguard Worker list_destroy(&typealias_lists[i]);
361*2d543d20SAndroid Build Coastguard Worker }
362*2d543d20SAndroid Build Coastguard Worker }
363*2d543d20SAndroid Build Coastguard Worker typealias_lists_len = 0;
364*2d543d20SAndroid Build Coastguard Worker free(typealias_lists);
365*2d543d20SAndroid Build Coastguard Worker typealias_lists = NULL;
366*2d543d20SAndroid Build Coastguard Worker }
367*2d543d20SAndroid Build Coastguard Worker
typealias_list_create(struct policydb * pdb)368*2d543d20SAndroid Build Coastguard Worker static int typealias_list_create(struct policydb *pdb)
369*2d543d20SAndroid Build Coastguard Worker {
370*2d543d20SAndroid Build Coastguard Worker uint32_t max_decl_id = 0;
371*2d543d20SAndroid Build Coastguard Worker struct avrule_decl *decl;
372*2d543d20SAndroid Build Coastguard Worker struct avrule_block *block;
373*2d543d20SAndroid Build Coastguard Worker uint32_t rc = -1;
374*2d543d20SAndroid Build Coastguard Worker
375*2d543d20SAndroid Build Coastguard Worker for (block = pdb->global; block != NULL; block = block->next) {
376*2d543d20SAndroid Build Coastguard Worker decl = block->branch_list;
377*2d543d20SAndroid Build Coastguard Worker if (decl != NULL && decl->decl_id > max_decl_id) {
378*2d543d20SAndroid Build Coastguard Worker max_decl_id = decl->decl_id;
379*2d543d20SAndroid Build Coastguard Worker }
380*2d543d20SAndroid Build Coastguard Worker }
381*2d543d20SAndroid Build Coastguard Worker
382*2d543d20SAndroid Build Coastguard Worker typealias_lists = calloc(max_decl_id + 1, sizeof(*typealias_lists));
383*2d543d20SAndroid Build Coastguard Worker if (!typealias_lists)
384*2d543d20SAndroid Build Coastguard Worker goto exit;
385*2d543d20SAndroid Build Coastguard Worker typealias_lists_len = max_decl_id + 1;
386*2d543d20SAndroid Build Coastguard Worker
387*2d543d20SAndroid Build Coastguard Worker rc = hashtab_map(pdb->p_types.table, typealiases_gather_map, pdb);
388*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
389*2d543d20SAndroid Build Coastguard Worker goto exit;
390*2d543d20SAndroid Build Coastguard Worker }
391*2d543d20SAndroid Build Coastguard Worker
392*2d543d20SAndroid Build Coastguard Worker return 0;
393*2d543d20SAndroid Build Coastguard Worker
394*2d543d20SAndroid Build Coastguard Worker exit:
395*2d543d20SAndroid Build Coastguard Worker typealias_list_destroy();
396*2d543d20SAndroid Build Coastguard Worker
397*2d543d20SAndroid Build Coastguard Worker return rc;
398*2d543d20SAndroid Build Coastguard Worker }
399*2d543d20SAndroid Build Coastguard Worker
400*2d543d20SAndroid Build Coastguard Worker
stack_destroy(struct stack ** stack)401*2d543d20SAndroid Build Coastguard Worker static int stack_destroy(struct stack **stack)
402*2d543d20SAndroid Build Coastguard Worker {
403*2d543d20SAndroid Build Coastguard Worker if (stack == NULL || *stack == NULL) {
404*2d543d20SAndroid Build Coastguard Worker return 0;
405*2d543d20SAndroid Build Coastguard Worker }
406*2d543d20SAndroid Build Coastguard Worker
407*2d543d20SAndroid Build Coastguard Worker free((*stack)->stack);
408*2d543d20SAndroid Build Coastguard Worker free(*stack);
409*2d543d20SAndroid Build Coastguard Worker *stack = NULL;
410*2d543d20SAndroid Build Coastguard Worker
411*2d543d20SAndroid Build Coastguard Worker return 0;
412*2d543d20SAndroid Build Coastguard Worker }
413*2d543d20SAndroid Build Coastguard Worker
stack_init(struct stack ** stack)414*2d543d20SAndroid Build Coastguard Worker static int stack_init(struct stack **stack)
415*2d543d20SAndroid Build Coastguard Worker {
416*2d543d20SAndroid Build Coastguard Worker int rc = -1;
417*2d543d20SAndroid Build Coastguard Worker struct stack *s = calloc(1, sizeof(*s));
418*2d543d20SAndroid Build Coastguard Worker if (s == NULL) {
419*2d543d20SAndroid Build Coastguard Worker goto exit;
420*2d543d20SAndroid Build Coastguard Worker }
421*2d543d20SAndroid Build Coastguard Worker
422*2d543d20SAndroid Build Coastguard Worker s->stack = calloc(STACK_SIZE, sizeof(*s->stack));
423*2d543d20SAndroid Build Coastguard Worker if (s->stack == NULL) {
424*2d543d20SAndroid Build Coastguard Worker goto exit;
425*2d543d20SAndroid Build Coastguard Worker }
426*2d543d20SAndroid Build Coastguard Worker
427*2d543d20SAndroid Build Coastguard Worker s->pos = -1;
428*2d543d20SAndroid Build Coastguard Worker s->size = STACK_SIZE;
429*2d543d20SAndroid Build Coastguard Worker
430*2d543d20SAndroid Build Coastguard Worker *stack = s;
431*2d543d20SAndroid Build Coastguard Worker
432*2d543d20SAndroid Build Coastguard Worker return 0;
433*2d543d20SAndroid Build Coastguard Worker
434*2d543d20SAndroid Build Coastguard Worker exit:
435*2d543d20SAndroid Build Coastguard Worker stack_destroy(&s);
436*2d543d20SAndroid Build Coastguard Worker return rc;
437*2d543d20SAndroid Build Coastguard Worker }
438*2d543d20SAndroid Build Coastguard Worker
stack_push(struct stack * stack,void * ptr)439*2d543d20SAndroid Build Coastguard Worker static int stack_push(struct stack *stack, void *ptr)
440*2d543d20SAndroid Build Coastguard Worker {
441*2d543d20SAndroid Build Coastguard Worker int rc = -1;
442*2d543d20SAndroid Build Coastguard Worker void *new_stack;
443*2d543d20SAndroid Build Coastguard Worker
444*2d543d20SAndroid Build Coastguard Worker if (stack->pos + 1 == stack->size) {
445*2d543d20SAndroid Build Coastguard Worker new_stack = reallocarray(stack->stack, stack->size * 2, sizeof(*stack->stack));
446*2d543d20SAndroid Build Coastguard Worker if (new_stack == NULL) {
447*2d543d20SAndroid Build Coastguard Worker goto exit;
448*2d543d20SAndroid Build Coastguard Worker }
449*2d543d20SAndroid Build Coastguard Worker stack->stack = new_stack;
450*2d543d20SAndroid Build Coastguard Worker stack->size *= 2;
451*2d543d20SAndroid Build Coastguard Worker }
452*2d543d20SAndroid Build Coastguard Worker
453*2d543d20SAndroid Build Coastguard Worker stack->pos++;
454*2d543d20SAndroid Build Coastguard Worker stack->stack[stack->pos] = ptr;
455*2d543d20SAndroid Build Coastguard Worker
456*2d543d20SAndroid Build Coastguard Worker rc = 0;
457*2d543d20SAndroid Build Coastguard Worker exit:
458*2d543d20SAndroid Build Coastguard Worker return rc;
459*2d543d20SAndroid Build Coastguard Worker }
460*2d543d20SAndroid Build Coastguard Worker
stack_pop(struct stack * stack)461*2d543d20SAndroid Build Coastguard Worker static void *stack_pop(struct stack *stack)
462*2d543d20SAndroid Build Coastguard Worker {
463*2d543d20SAndroid Build Coastguard Worker if (stack->pos == -1) {
464*2d543d20SAndroid Build Coastguard Worker return NULL;
465*2d543d20SAndroid Build Coastguard Worker }
466*2d543d20SAndroid Build Coastguard Worker
467*2d543d20SAndroid Build Coastguard Worker stack->pos--;
468*2d543d20SAndroid Build Coastguard Worker return stack->stack[stack->pos + 1];
469*2d543d20SAndroid Build Coastguard Worker }
470*2d543d20SAndroid Build Coastguard Worker
stack_peek(struct stack * stack)471*2d543d20SAndroid Build Coastguard Worker static void *stack_peek(struct stack *stack)
472*2d543d20SAndroid Build Coastguard Worker {
473*2d543d20SAndroid Build Coastguard Worker if (stack->pos == -1) {
474*2d543d20SAndroid Build Coastguard Worker return NULL;
475*2d543d20SAndroid Build Coastguard Worker }
476*2d543d20SAndroid Build Coastguard Worker
477*2d543d20SAndroid Build Coastguard Worker return stack->stack[stack->pos];
478*2d543d20SAndroid Build Coastguard Worker }
479*2d543d20SAndroid Build Coastguard Worker
is_id_in_scope_with_start(struct policydb * pdb,struct stack * decl_stack,int start,uint32_t symbol_type,char * id)480*2d543d20SAndroid Build Coastguard Worker static int is_id_in_scope_with_start(struct policydb *pdb, struct stack *decl_stack, int start, uint32_t symbol_type, char *id)
481*2d543d20SAndroid Build Coastguard Worker {
482*2d543d20SAndroid Build Coastguard Worker int i;
483*2d543d20SAndroid Build Coastguard Worker uint32_t j;
484*2d543d20SAndroid Build Coastguard Worker struct avrule_decl *decl;
485*2d543d20SAndroid Build Coastguard Worker struct scope_datum *scope;
486*2d543d20SAndroid Build Coastguard Worker
487*2d543d20SAndroid Build Coastguard Worker scope = hashtab_search(pdb->scope[symbol_type].table, id);
488*2d543d20SAndroid Build Coastguard Worker if (scope == NULL) {
489*2d543d20SAndroid Build Coastguard Worker return 0;
490*2d543d20SAndroid Build Coastguard Worker }
491*2d543d20SAndroid Build Coastguard Worker
492*2d543d20SAndroid Build Coastguard Worker for (i = start; i >= 0; i--) {
493*2d543d20SAndroid Build Coastguard Worker decl = decl_stack->stack[i];
494*2d543d20SAndroid Build Coastguard Worker
495*2d543d20SAndroid Build Coastguard Worker for (j = 0; j < scope->decl_ids_len; j++) {
496*2d543d20SAndroid Build Coastguard Worker if (scope->decl_ids[j] == decl->decl_id) {
497*2d543d20SAndroid Build Coastguard Worker return 1;
498*2d543d20SAndroid Build Coastguard Worker }
499*2d543d20SAndroid Build Coastguard Worker }
500*2d543d20SAndroid Build Coastguard Worker }
501*2d543d20SAndroid Build Coastguard Worker
502*2d543d20SAndroid Build Coastguard Worker return 0;
503*2d543d20SAndroid Build Coastguard Worker }
504*2d543d20SAndroid Build Coastguard Worker
is_id_in_ancestor_scope(struct policydb * pdb,struct stack * decl_stack,char * type,uint32_t symbol_type)505*2d543d20SAndroid Build Coastguard Worker static int is_id_in_ancestor_scope(struct policydb *pdb, struct stack *decl_stack, char *type, uint32_t symbol_type)
506*2d543d20SAndroid Build Coastguard Worker {
507*2d543d20SAndroid Build Coastguard Worker int start = decl_stack->pos - 1;
508*2d543d20SAndroid Build Coastguard Worker
509*2d543d20SAndroid Build Coastguard Worker return is_id_in_scope_with_start(pdb, decl_stack, start, symbol_type, type);
510*2d543d20SAndroid Build Coastguard Worker }
511*2d543d20SAndroid Build Coastguard Worker
is_id_in_scope(struct policydb * pdb,struct stack * decl_stack,char * type,uint32_t symbol_type)512*2d543d20SAndroid Build Coastguard Worker static int is_id_in_scope(struct policydb *pdb, struct stack *decl_stack, char *type, uint32_t symbol_type)
513*2d543d20SAndroid Build Coastguard Worker {
514*2d543d20SAndroid Build Coastguard Worker int start = decl_stack->pos;
515*2d543d20SAndroid Build Coastguard Worker
516*2d543d20SAndroid Build Coastguard Worker return is_id_in_scope_with_start(pdb, decl_stack, start, symbol_type, type);
517*2d543d20SAndroid Build Coastguard Worker }
518*2d543d20SAndroid Build Coastguard Worker
semantic_level_to_cil(struct policydb * pdb,int sens_offset,struct mls_semantic_level * level)519*2d543d20SAndroid Build Coastguard Worker static int semantic_level_to_cil(struct policydb *pdb, int sens_offset, struct mls_semantic_level *level)
520*2d543d20SAndroid Build Coastguard Worker {
521*2d543d20SAndroid Build Coastguard Worker struct mls_semantic_cat *cat;
522*2d543d20SAndroid Build Coastguard Worker
523*2d543d20SAndroid Build Coastguard Worker cil_printf("(%s ", pdb->p_sens_val_to_name[level->sens - sens_offset]);
524*2d543d20SAndroid Build Coastguard Worker
525*2d543d20SAndroid Build Coastguard Worker if (level->cat != NULL) {
526*2d543d20SAndroid Build Coastguard Worker cil_printf("(");
527*2d543d20SAndroid Build Coastguard Worker }
528*2d543d20SAndroid Build Coastguard Worker
529*2d543d20SAndroid Build Coastguard Worker for (cat = level->cat; cat != NULL; cat = cat->next) {
530*2d543d20SAndroid Build Coastguard Worker if (cat->low == cat->high) {
531*2d543d20SAndroid Build Coastguard Worker cil_printf("%s", pdb->p_cat_val_to_name[cat->low - 1]);
532*2d543d20SAndroid Build Coastguard Worker } else {
533*2d543d20SAndroid Build Coastguard Worker cil_printf("range %s %s", pdb->p_cat_val_to_name[cat->low - 1], pdb->p_cat_val_to_name[cat->high - 1]);
534*2d543d20SAndroid Build Coastguard Worker }
535*2d543d20SAndroid Build Coastguard Worker
536*2d543d20SAndroid Build Coastguard Worker if (cat->next != NULL) {
537*2d543d20SAndroid Build Coastguard Worker cil_printf(" ");
538*2d543d20SAndroid Build Coastguard Worker }
539*2d543d20SAndroid Build Coastguard Worker }
540*2d543d20SAndroid Build Coastguard Worker
541*2d543d20SAndroid Build Coastguard Worker if (level->cat != NULL) {
542*2d543d20SAndroid Build Coastguard Worker cil_printf(")");
543*2d543d20SAndroid Build Coastguard Worker }
544*2d543d20SAndroid Build Coastguard Worker
545*2d543d20SAndroid Build Coastguard Worker cil_printf(")");
546*2d543d20SAndroid Build Coastguard Worker
547*2d543d20SAndroid Build Coastguard Worker return 0;
548*2d543d20SAndroid Build Coastguard Worker }
549*2d543d20SAndroid Build Coastguard Worker
avrule_to_cil(int indent,struct policydb * pdb,uint32_t type,const char * src,const char * tgt,const struct class_perm_node * classperms)550*2d543d20SAndroid Build Coastguard Worker static int avrule_to_cil(int indent, struct policydb *pdb, uint32_t type, const char *src, const char *tgt, const struct class_perm_node *classperms)
551*2d543d20SAndroid Build Coastguard Worker {
552*2d543d20SAndroid Build Coastguard Worker int rc = -1;
553*2d543d20SAndroid Build Coastguard Worker const char *rule;
554*2d543d20SAndroid Build Coastguard Worker const struct class_perm_node *classperm;
555*2d543d20SAndroid Build Coastguard Worker char *perms;
556*2d543d20SAndroid Build Coastguard Worker
557*2d543d20SAndroid Build Coastguard Worker switch (type) {
558*2d543d20SAndroid Build Coastguard Worker case AVRULE_ALLOWED:
559*2d543d20SAndroid Build Coastguard Worker rule = "allow";
560*2d543d20SAndroid Build Coastguard Worker break;
561*2d543d20SAndroid Build Coastguard Worker case AVRULE_AUDITALLOW:
562*2d543d20SAndroid Build Coastguard Worker rule = "auditallow";
563*2d543d20SAndroid Build Coastguard Worker break;
564*2d543d20SAndroid Build Coastguard Worker case AVRULE_AUDITDENY:
565*2d543d20SAndroid Build Coastguard Worker rule = "auditdeny";
566*2d543d20SAndroid Build Coastguard Worker break;
567*2d543d20SAndroid Build Coastguard Worker case AVRULE_DONTAUDIT:
568*2d543d20SAndroid Build Coastguard Worker rule = "dontaudit";
569*2d543d20SAndroid Build Coastguard Worker break;
570*2d543d20SAndroid Build Coastguard Worker case AVRULE_NEVERALLOW:
571*2d543d20SAndroid Build Coastguard Worker rule = "neverallow";
572*2d543d20SAndroid Build Coastguard Worker break;
573*2d543d20SAndroid Build Coastguard Worker case AVRULE_TRANSITION:
574*2d543d20SAndroid Build Coastguard Worker rule = "typetransition";
575*2d543d20SAndroid Build Coastguard Worker break;
576*2d543d20SAndroid Build Coastguard Worker case AVRULE_MEMBER:
577*2d543d20SAndroid Build Coastguard Worker rule = "typemember";
578*2d543d20SAndroid Build Coastguard Worker break;
579*2d543d20SAndroid Build Coastguard Worker case AVRULE_CHANGE:
580*2d543d20SAndroid Build Coastguard Worker rule = "typechange";
581*2d543d20SAndroid Build Coastguard Worker break;
582*2d543d20SAndroid Build Coastguard Worker default:
583*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Unknown avrule type: %i", type);
584*2d543d20SAndroid Build Coastguard Worker rc = -1;
585*2d543d20SAndroid Build Coastguard Worker goto exit;
586*2d543d20SAndroid Build Coastguard Worker }
587*2d543d20SAndroid Build Coastguard Worker
588*2d543d20SAndroid Build Coastguard Worker for (classperm = classperms; classperm != NULL; classperm = classperm->next) {
589*2d543d20SAndroid Build Coastguard Worker if (type & AVRULE_AV) {
590*2d543d20SAndroid Build Coastguard Worker perms = sepol_av_to_string(pdb, classperm->tclass, classperm->data);
591*2d543d20SAndroid Build Coastguard Worker if (perms == NULL) {
592*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Failed to generate permission string");
593*2d543d20SAndroid Build Coastguard Worker rc = -1;
594*2d543d20SAndroid Build Coastguard Worker goto exit;
595*2d543d20SAndroid Build Coastguard Worker }
596*2d543d20SAndroid Build Coastguard Worker if (*perms == '\0') {
597*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "No permissions in permission string");
598*2d543d20SAndroid Build Coastguard Worker free(perms);
599*2d543d20SAndroid Build Coastguard Worker rc = -1;
600*2d543d20SAndroid Build Coastguard Worker goto exit;
601*2d543d20SAndroid Build Coastguard Worker }
602*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(%s %s %s (%s (%s)))",
603*2d543d20SAndroid Build Coastguard Worker rule, src, tgt,
604*2d543d20SAndroid Build Coastguard Worker pdb->p_class_val_to_name[classperm->tclass - 1],
605*2d543d20SAndroid Build Coastguard Worker perms + 1);
606*2d543d20SAndroid Build Coastguard Worker free(perms);
607*2d543d20SAndroid Build Coastguard Worker } else {
608*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(%s %s %s %s %s)",
609*2d543d20SAndroid Build Coastguard Worker rule, src, tgt,
610*2d543d20SAndroid Build Coastguard Worker pdb->p_class_val_to_name[classperm->tclass - 1],
611*2d543d20SAndroid Build Coastguard Worker pdb->p_type_val_to_name[classperm->data - 1]);
612*2d543d20SAndroid Build Coastguard Worker }
613*2d543d20SAndroid Build Coastguard Worker }
614*2d543d20SAndroid Build Coastguard Worker
615*2d543d20SAndroid Build Coastguard Worker return 0;
616*2d543d20SAndroid Build Coastguard Worker
617*2d543d20SAndroid Build Coastguard Worker exit:
618*2d543d20SAndroid Build Coastguard Worker return rc;
619*2d543d20SAndroid Build Coastguard Worker }
620*2d543d20SAndroid Build Coastguard Worker
621*2d543d20SAndroid Build Coastguard Worker #define next_bit_in_range(i, p) (((i) + 1 < sizeof(p)*8) && xperm_test(((i) + 1), p))
622*2d543d20SAndroid Build Coastguard Worker
xperms_to_cil(const av_extended_perms_t * xperms)623*2d543d20SAndroid Build Coastguard Worker static int xperms_to_cil(const av_extended_perms_t *xperms)
624*2d543d20SAndroid Build Coastguard Worker {
625*2d543d20SAndroid Build Coastguard Worker uint16_t value;
626*2d543d20SAndroid Build Coastguard Worker uint16_t low_bit;
627*2d543d20SAndroid Build Coastguard Worker uint16_t low_value;
628*2d543d20SAndroid Build Coastguard Worker unsigned int bit;
629*2d543d20SAndroid Build Coastguard Worker unsigned int in_range = 0;
630*2d543d20SAndroid Build Coastguard Worker int first = 1;
631*2d543d20SAndroid Build Coastguard Worker
632*2d543d20SAndroid Build Coastguard Worker if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
633*2d543d20SAndroid Build Coastguard Worker && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)
634*2d543d20SAndroid Build Coastguard Worker && (xperms->specified != AVTAB_XPERMS_NLMSG))
635*2d543d20SAndroid Build Coastguard Worker return -1;
636*2d543d20SAndroid Build Coastguard Worker
637*2d543d20SAndroid Build Coastguard Worker for (bit = 0; bit < sizeof(xperms->perms)*8; bit++) {
638*2d543d20SAndroid Build Coastguard Worker if (!xperm_test(bit, xperms->perms))
639*2d543d20SAndroid Build Coastguard Worker continue;
640*2d543d20SAndroid Build Coastguard Worker
641*2d543d20SAndroid Build Coastguard Worker if (in_range && next_bit_in_range(bit, xperms->perms)) {
642*2d543d20SAndroid Build Coastguard Worker /* continue until high value found */
643*2d543d20SAndroid Build Coastguard Worker continue;
644*2d543d20SAndroid Build Coastguard Worker } else if (next_bit_in_range(bit, xperms->perms)) {
645*2d543d20SAndroid Build Coastguard Worker /* low value */
646*2d543d20SAndroid Build Coastguard Worker low_bit = bit;
647*2d543d20SAndroid Build Coastguard Worker in_range = 1;
648*2d543d20SAndroid Build Coastguard Worker continue;
649*2d543d20SAndroid Build Coastguard Worker }
650*2d543d20SAndroid Build Coastguard Worker
651*2d543d20SAndroid Build Coastguard Worker if (!first)
652*2d543d20SAndroid Build Coastguard Worker cil_printf(" ");
653*2d543d20SAndroid Build Coastguard Worker else
654*2d543d20SAndroid Build Coastguard Worker first = 0;
655*2d543d20SAndroid Build Coastguard Worker
656*2d543d20SAndroid Build Coastguard Worker if ((xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION)
657*2d543d20SAndroid Build Coastguard Worker || (xperms->specified == AVTAB_XPERMS_NLMSG)) {
658*2d543d20SAndroid Build Coastguard Worker value = xperms->driver<<8 | bit;
659*2d543d20SAndroid Build Coastguard Worker if (in_range) {
660*2d543d20SAndroid Build Coastguard Worker low_value = xperms->driver<<8 | low_bit;
661*2d543d20SAndroid Build Coastguard Worker cil_printf("(range 0x%hx 0x%hx)", low_value, value);
662*2d543d20SAndroid Build Coastguard Worker in_range = 0;
663*2d543d20SAndroid Build Coastguard Worker } else {
664*2d543d20SAndroid Build Coastguard Worker cil_printf("0x%hx", value);
665*2d543d20SAndroid Build Coastguard Worker }
666*2d543d20SAndroid Build Coastguard Worker } else if (xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) {
667*2d543d20SAndroid Build Coastguard Worker value = bit << 8;
668*2d543d20SAndroid Build Coastguard Worker if (in_range) {
669*2d543d20SAndroid Build Coastguard Worker low_value = low_bit << 8;
670*2d543d20SAndroid Build Coastguard Worker cil_printf("(range 0x%hx 0x%hx)", low_value, (uint16_t) (value|0xff));
671*2d543d20SAndroid Build Coastguard Worker in_range = 0;
672*2d543d20SAndroid Build Coastguard Worker } else {
673*2d543d20SAndroid Build Coastguard Worker cil_printf("(range 0x%hx 0x%hx)", value, (uint16_t) (value|0xff));
674*2d543d20SAndroid Build Coastguard Worker }
675*2d543d20SAndroid Build Coastguard Worker }
676*2d543d20SAndroid Build Coastguard Worker }
677*2d543d20SAndroid Build Coastguard Worker
678*2d543d20SAndroid Build Coastguard Worker return 0;
679*2d543d20SAndroid Build Coastguard Worker }
680*2d543d20SAndroid Build Coastguard Worker
avrulex_to_cil(int indent,struct policydb * pdb,uint32_t type,const char * src,const char * tgt,const class_perm_node_t * classperms,const av_extended_perms_t * xperms)681*2d543d20SAndroid Build Coastguard Worker static int avrulex_to_cil(int indent, struct policydb *pdb, uint32_t type, const char *src, const char *tgt, const class_perm_node_t *classperms, const av_extended_perms_t *xperms)
682*2d543d20SAndroid Build Coastguard Worker {
683*2d543d20SAndroid Build Coastguard Worker int rc = -1;
684*2d543d20SAndroid Build Coastguard Worker const char *rule;
685*2d543d20SAndroid Build Coastguard Worker const char *xperm;
686*2d543d20SAndroid Build Coastguard Worker const struct class_perm_node *classperm;
687*2d543d20SAndroid Build Coastguard Worker
688*2d543d20SAndroid Build Coastguard Worker switch (type) {
689*2d543d20SAndroid Build Coastguard Worker case AVRULE_XPERMS_ALLOWED:
690*2d543d20SAndroid Build Coastguard Worker rule = "allowx";
691*2d543d20SAndroid Build Coastguard Worker break;
692*2d543d20SAndroid Build Coastguard Worker case AVRULE_XPERMS_AUDITALLOW:
693*2d543d20SAndroid Build Coastguard Worker rule = "auditallowx";
694*2d543d20SAndroid Build Coastguard Worker break;
695*2d543d20SAndroid Build Coastguard Worker case AVRULE_XPERMS_DONTAUDIT:
696*2d543d20SAndroid Build Coastguard Worker rule = "dontauditx";
697*2d543d20SAndroid Build Coastguard Worker break;
698*2d543d20SAndroid Build Coastguard Worker case AVRULE_XPERMS_NEVERALLOW:
699*2d543d20SAndroid Build Coastguard Worker rule = "neverallowx";
700*2d543d20SAndroid Build Coastguard Worker break;
701*2d543d20SAndroid Build Coastguard Worker default:
702*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Unknown avrule xperm type: %i", type);
703*2d543d20SAndroid Build Coastguard Worker rc = -1;
704*2d543d20SAndroid Build Coastguard Worker goto exit;
705*2d543d20SAndroid Build Coastguard Worker }
706*2d543d20SAndroid Build Coastguard Worker
707*2d543d20SAndroid Build Coastguard Worker if (xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION || xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) {
708*2d543d20SAndroid Build Coastguard Worker xperm = "ioctl";
709*2d543d20SAndroid Build Coastguard Worker } else if (xperms->specified == AVTAB_XPERMS_NLMSG) {
710*2d543d20SAndroid Build Coastguard Worker xperm = "nlmsg";
711*2d543d20SAndroid Build Coastguard Worker } else {
712*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Unkown avrule xperms->specified: %i", xperms->specified);
713*2d543d20SAndroid Build Coastguard Worker rc = -1;
714*2d543d20SAndroid Build Coastguard Worker goto exit;
715*2d543d20SAndroid Build Coastguard Worker }
716*2d543d20SAndroid Build Coastguard Worker for (classperm = classperms; classperm != NULL; classperm = classperm->next) {
717*2d543d20SAndroid Build Coastguard Worker cil_indent(indent);
718*2d543d20SAndroid Build Coastguard Worker cil_printf("(%s %s %s (%s %s (", rule, src, tgt,
719*2d543d20SAndroid Build Coastguard Worker xperm, pdb->p_class_val_to_name[classperm->tclass - 1]);
720*2d543d20SAndroid Build Coastguard Worker xperms_to_cil(xperms);
721*2d543d20SAndroid Build Coastguard Worker cil_printf(")))\n");
722*2d543d20SAndroid Build Coastguard Worker }
723*2d543d20SAndroid Build Coastguard Worker
724*2d543d20SAndroid Build Coastguard Worker return 0;
725*2d543d20SAndroid Build Coastguard Worker
726*2d543d20SAndroid Build Coastguard Worker exit:
727*2d543d20SAndroid Build Coastguard Worker return rc;
728*2d543d20SAndroid Build Coastguard Worker }
729*2d543d20SAndroid Build Coastguard Worker
num_digits(unsigned int n)730*2d543d20SAndroid Build Coastguard Worker static unsigned int num_digits(unsigned int n)
731*2d543d20SAndroid Build Coastguard Worker {
732*2d543d20SAndroid Build Coastguard Worker unsigned int num = 1;
733*2d543d20SAndroid Build Coastguard Worker while (n >= 10) {
734*2d543d20SAndroid Build Coastguard Worker n /= 10;
735*2d543d20SAndroid Build Coastguard Worker num++;
736*2d543d20SAndroid Build Coastguard Worker }
737*2d543d20SAndroid Build Coastguard Worker return num;
738*2d543d20SAndroid Build Coastguard Worker }
739*2d543d20SAndroid Build Coastguard Worker
ebitmap_to_cil(struct policydb * pdb,struct ebitmap * map,int type)740*2d543d20SAndroid Build Coastguard Worker static int ebitmap_to_cil(struct policydb *pdb, struct ebitmap *map, int type)
741*2d543d20SAndroid Build Coastguard Worker {
742*2d543d20SAndroid Build Coastguard Worker struct ebitmap_node *node;
743*2d543d20SAndroid Build Coastguard Worker uint32_t i;
744*2d543d20SAndroid Build Coastguard Worker char **val_to_name = pdb->sym_val_to_name[type];
745*2d543d20SAndroid Build Coastguard Worker
746*2d543d20SAndroid Build Coastguard Worker ebitmap_for_each_positive_bit(map, node, i) {
747*2d543d20SAndroid Build Coastguard Worker cil_printf("%s ", val_to_name[i]);
748*2d543d20SAndroid Build Coastguard Worker }
749*2d543d20SAndroid Build Coastguard Worker
750*2d543d20SAndroid Build Coastguard Worker return 0;
751*2d543d20SAndroid Build Coastguard Worker }
752*2d543d20SAndroid Build Coastguard Worker
get_new_attr_name(struct policydb * pdb,int is_type)753*2d543d20SAndroid Build Coastguard Worker static char *get_new_attr_name(struct policydb *pdb, int is_type)
754*2d543d20SAndroid Build Coastguard Worker {
755*2d543d20SAndroid Build Coastguard Worker static unsigned int num_attrs = 0;
756*2d543d20SAndroid Build Coastguard Worker int len, rlen;
757*2d543d20SAndroid Build Coastguard Worker const char *infix;
758*2d543d20SAndroid Build Coastguard Worker char *attr_name = NULL;
759*2d543d20SAndroid Build Coastguard Worker
760*2d543d20SAndroid Build Coastguard Worker num_attrs++;
761*2d543d20SAndroid Build Coastguard Worker
762*2d543d20SAndroid Build Coastguard Worker if (is_type) {
763*2d543d20SAndroid Build Coastguard Worker infix = TYPEATTR_INFIX;
764*2d543d20SAndroid Build Coastguard Worker } else {
765*2d543d20SAndroid Build Coastguard Worker infix = ROLEATTR_INFIX;
766*2d543d20SAndroid Build Coastguard Worker }
767*2d543d20SAndroid Build Coastguard Worker
768*2d543d20SAndroid Build Coastguard Worker len = strlen(pdb->name) + strlen(infix) + num_digits(num_attrs) + 1;
769*2d543d20SAndroid Build Coastguard Worker attr_name = malloc(len);
770*2d543d20SAndroid Build Coastguard Worker if (!attr_name) {
771*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Out of memory");
772*2d543d20SAndroid Build Coastguard Worker goto exit;
773*2d543d20SAndroid Build Coastguard Worker }
774*2d543d20SAndroid Build Coastguard Worker
775*2d543d20SAndroid Build Coastguard Worker rlen = snprintf(attr_name, len, "%s%s%i", pdb->name, infix, num_attrs);
776*2d543d20SAndroid Build Coastguard Worker if (rlen < 0 || rlen >= len) {
777*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Failed to generate attribute name");
778*2d543d20SAndroid Build Coastguard Worker free(attr_name);
779*2d543d20SAndroid Build Coastguard Worker attr_name = NULL;
780*2d543d20SAndroid Build Coastguard Worker goto exit;
781*2d543d20SAndroid Build Coastguard Worker }
782*2d543d20SAndroid Build Coastguard Worker
783*2d543d20SAndroid Build Coastguard Worker exit:
784*2d543d20SAndroid Build Coastguard Worker return attr_name;
785*2d543d20SAndroid Build Coastguard Worker }
786*2d543d20SAndroid Build Coastguard Worker
cil_add_attr_to_list(struct list * attr_list,char * attr_name,int is_type,void * set)787*2d543d20SAndroid Build Coastguard Worker static int cil_add_attr_to_list(struct list *attr_list, char *attr_name, int is_type, void *set)
788*2d543d20SAndroid Build Coastguard Worker {
789*2d543d20SAndroid Build Coastguard Worker struct attr_list_node *attr_list_node = NULL;
790*2d543d20SAndroid Build Coastguard Worker int rc = 0;
791*2d543d20SAndroid Build Coastguard Worker
792*2d543d20SAndroid Build Coastguard Worker attr_list_node = calloc(1, sizeof(*attr_list_node));
793*2d543d20SAndroid Build Coastguard Worker if (attr_list_node == NULL) {
794*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Out of memory");
795*2d543d20SAndroid Build Coastguard Worker rc = -1;
796*2d543d20SAndroid Build Coastguard Worker goto exit;
797*2d543d20SAndroid Build Coastguard Worker }
798*2d543d20SAndroid Build Coastguard Worker
799*2d543d20SAndroid Build Coastguard Worker rc = list_prepend(attr_list, attr_list_node);
800*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
801*2d543d20SAndroid Build Coastguard Worker goto exit;
802*2d543d20SAndroid Build Coastguard Worker }
803*2d543d20SAndroid Build Coastguard Worker
804*2d543d20SAndroid Build Coastguard Worker attr_list_node->attr_name = attr_name;
805*2d543d20SAndroid Build Coastguard Worker attr_list_node->is_type = is_type;
806*2d543d20SAndroid Build Coastguard Worker attr_list_node->set = set;
807*2d543d20SAndroid Build Coastguard Worker
808*2d543d20SAndroid Build Coastguard Worker return rc;
809*2d543d20SAndroid Build Coastguard Worker
810*2d543d20SAndroid Build Coastguard Worker exit:
811*2d543d20SAndroid Build Coastguard Worker free(attr_list_node);
812*2d543d20SAndroid Build Coastguard Worker return rc;
813*2d543d20SAndroid Build Coastguard Worker }
814*2d543d20SAndroid Build Coastguard Worker
cil_print_attr_strs(int indent,struct policydb * pdb,int is_type,void * set,char * attr_name)815*2d543d20SAndroid Build Coastguard Worker static int cil_print_attr_strs(int indent, struct policydb *pdb, int is_type, void *set, char *attr_name)
816*2d543d20SAndroid Build Coastguard Worker {
817*2d543d20SAndroid Build Coastguard Worker // CIL doesn't support anonymous positive/negative/complemented sets. So
818*2d543d20SAndroid Build Coastguard Worker // instead we create a CIL type/roleattributeset that matches the set. If
819*2d543d20SAndroid Build Coastguard Worker // the set has a negative set, then convert it to is (P & !N), where P is
820*2d543d20SAndroid Build Coastguard Worker // the list of members in the positive set and N is the list of members
821*2d543d20SAndroid Build Coastguard Worker // in the negative set. Additionally, if the set is complemented, then wrap
822*2d543d20SAndroid Build Coastguard Worker // the whole thing with a negation.
823*2d543d20SAndroid Build Coastguard Worker
824*2d543d20SAndroid Build Coastguard Worker struct ebitmap_node *node;
825*2d543d20SAndroid Build Coastguard Worker struct ebitmap *pos, *neg;
826*2d543d20SAndroid Build Coastguard Worker uint32_t flags;
827*2d543d20SAndroid Build Coastguard Worker unsigned i;
828*2d543d20SAndroid Build Coastguard Worker struct type_set *ts;
829*2d543d20SAndroid Build Coastguard Worker struct role_set *rs;
830*2d543d20SAndroid Build Coastguard Worker int has_positive, has_negative;
831*2d543d20SAndroid Build Coastguard Worker const char *kind;
832*2d543d20SAndroid Build Coastguard Worker char **val_to_name;
833*2d543d20SAndroid Build Coastguard Worker int rc = 0;
834*2d543d20SAndroid Build Coastguard Worker
835*2d543d20SAndroid Build Coastguard Worker if (is_type) {
836*2d543d20SAndroid Build Coastguard Worker kind = "type";
837*2d543d20SAndroid Build Coastguard Worker val_to_name = pdb->p_type_val_to_name;
838*2d543d20SAndroid Build Coastguard Worker ts = (struct type_set *)set;
839*2d543d20SAndroid Build Coastguard Worker pos = &ts->types;
840*2d543d20SAndroid Build Coastguard Worker neg = &ts->negset;
841*2d543d20SAndroid Build Coastguard Worker flags = ts->flags;
842*2d543d20SAndroid Build Coastguard Worker has_positive = pos && !ebitmap_is_empty(pos);
843*2d543d20SAndroid Build Coastguard Worker has_negative = neg && !ebitmap_is_empty(neg);
844*2d543d20SAndroid Build Coastguard Worker } else {
845*2d543d20SAndroid Build Coastguard Worker kind = "role";
846*2d543d20SAndroid Build Coastguard Worker val_to_name = pdb->p_role_val_to_name;
847*2d543d20SAndroid Build Coastguard Worker rs = (struct role_set *)set;
848*2d543d20SAndroid Build Coastguard Worker pos = &rs->roles;
849*2d543d20SAndroid Build Coastguard Worker neg = NULL;
850*2d543d20SAndroid Build Coastguard Worker flags = rs->flags;
851*2d543d20SAndroid Build Coastguard Worker has_positive = pos && !ebitmap_is_empty(pos);
852*2d543d20SAndroid Build Coastguard Worker has_negative = 0;
853*2d543d20SAndroid Build Coastguard Worker }
854*2d543d20SAndroid Build Coastguard Worker
855*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(%sattribute %s)", kind, attr_name);
856*2d543d20SAndroid Build Coastguard Worker cil_indent(indent);
857*2d543d20SAndroid Build Coastguard Worker cil_printf("(%sattributeset %s ", kind, attr_name);
858*2d543d20SAndroid Build Coastguard Worker
859*2d543d20SAndroid Build Coastguard Worker if (flags & TYPE_STAR) {
860*2d543d20SAndroid Build Coastguard Worker cil_printf("(all)");
861*2d543d20SAndroid Build Coastguard Worker }
862*2d543d20SAndroid Build Coastguard Worker
863*2d543d20SAndroid Build Coastguard Worker if (flags & TYPE_COMP) {
864*2d543d20SAndroid Build Coastguard Worker cil_printf("(not ");
865*2d543d20SAndroid Build Coastguard Worker }
866*2d543d20SAndroid Build Coastguard Worker
867*2d543d20SAndroid Build Coastguard Worker if (has_positive && has_negative) {
868*2d543d20SAndroid Build Coastguard Worker cil_printf("(and ");
869*2d543d20SAndroid Build Coastguard Worker }
870*2d543d20SAndroid Build Coastguard Worker
871*2d543d20SAndroid Build Coastguard Worker if (has_positive) {
872*2d543d20SAndroid Build Coastguard Worker cil_printf("(");
873*2d543d20SAndroid Build Coastguard Worker ebitmap_for_each_positive_bit(pos, node, i) {
874*2d543d20SAndroid Build Coastguard Worker cil_printf("%s ", val_to_name[i]);
875*2d543d20SAndroid Build Coastguard Worker }
876*2d543d20SAndroid Build Coastguard Worker cil_printf(") ");
877*2d543d20SAndroid Build Coastguard Worker }
878*2d543d20SAndroid Build Coastguard Worker
879*2d543d20SAndroid Build Coastguard Worker if (has_negative) {
880*2d543d20SAndroid Build Coastguard Worker cil_printf("(not (");
881*2d543d20SAndroid Build Coastguard Worker
882*2d543d20SAndroid Build Coastguard Worker ebitmap_for_each_positive_bit(neg, node, i) {
883*2d543d20SAndroid Build Coastguard Worker cil_printf("%s ", val_to_name[i]);
884*2d543d20SAndroid Build Coastguard Worker }
885*2d543d20SAndroid Build Coastguard Worker
886*2d543d20SAndroid Build Coastguard Worker cil_printf("))");
887*2d543d20SAndroid Build Coastguard Worker }
888*2d543d20SAndroid Build Coastguard Worker
889*2d543d20SAndroid Build Coastguard Worker if (has_positive && has_negative) {
890*2d543d20SAndroid Build Coastguard Worker cil_printf(")");
891*2d543d20SAndroid Build Coastguard Worker }
892*2d543d20SAndroid Build Coastguard Worker
893*2d543d20SAndroid Build Coastguard Worker if (flags & TYPE_COMP) {
894*2d543d20SAndroid Build Coastguard Worker cil_printf(")");
895*2d543d20SAndroid Build Coastguard Worker }
896*2d543d20SAndroid Build Coastguard Worker
897*2d543d20SAndroid Build Coastguard Worker cil_printf(")\n");
898*2d543d20SAndroid Build Coastguard Worker
899*2d543d20SAndroid Build Coastguard Worker return rc;
900*2d543d20SAndroid Build Coastguard Worker }
901*2d543d20SAndroid Build Coastguard Worker
cil_print_attr_list(int indent,struct policydb * pdb,struct list * attr_list)902*2d543d20SAndroid Build Coastguard Worker static int cil_print_attr_list(int indent, struct policydb *pdb, struct list *attr_list)
903*2d543d20SAndroid Build Coastguard Worker {
904*2d543d20SAndroid Build Coastguard Worker struct list_node *curr;
905*2d543d20SAndroid Build Coastguard Worker struct attr_list_node *node;
906*2d543d20SAndroid Build Coastguard Worker int rc = 0;
907*2d543d20SAndroid Build Coastguard Worker
908*2d543d20SAndroid Build Coastguard Worker for (curr = attr_list->head; curr != NULL; curr = curr->next) {
909*2d543d20SAndroid Build Coastguard Worker node = curr->data;
910*2d543d20SAndroid Build Coastguard Worker rc = cil_print_attr_strs(indent, pdb, node->is_type, node->set, node->attr_name);
911*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
912*2d543d20SAndroid Build Coastguard Worker return rc;
913*2d543d20SAndroid Build Coastguard Worker }
914*2d543d20SAndroid Build Coastguard Worker }
915*2d543d20SAndroid Build Coastguard Worker
916*2d543d20SAndroid Build Coastguard Worker return rc;
917*2d543d20SAndroid Build Coastguard Worker }
918*2d543d20SAndroid Build Coastguard Worker
search_attr_list(struct list * attr_list,int is_type,void * set)919*2d543d20SAndroid Build Coastguard Worker static char *search_attr_list(struct list *attr_list, int is_type, void *set)
920*2d543d20SAndroid Build Coastguard Worker {
921*2d543d20SAndroid Build Coastguard Worker struct list_node *curr;
922*2d543d20SAndroid Build Coastguard Worker struct attr_list_node *node;
923*2d543d20SAndroid Build Coastguard Worker struct role_set *rs1 = NULL, *rs2;
924*2d543d20SAndroid Build Coastguard Worker struct type_set *ts1 = NULL, *ts2;
925*2d543d20SAndroid Build Coastguard Worker
926*2d543d20SAndroid Build Coastguard Worker if (is_type) {
927*2d543d20SAndroid Build Coastguard Worker ts1 = (struct type_set *)set;
928*2d543d20SAndroid Build Coastguard Worker } else {
929*2d543d20SAndroid Build Coastguard Worker rs1 = (struct role_set *)set;
930*2d543d20SAndroid Build Coastguard Worker }
931*2d543d20SAndroid Build Coastguard Worker
932*2d543d20SAndroid Build Coastguard Worker for (curr = attr_list->head; curr != NULL; curr = curr->next) {
933*2d543d20SAndroid Build Coastguard Worker node = curr->data;
934*2d543d20SAndroid Build Coastguard Worker if (node->is_type != is_type)
935*2d543d20SAndroid Build Coastguard Worker continue;
936*2d543d20SAndroid Build Coastguard Worker if (ts1) {
937*2d543d20SAndroid Build Coastguard Worker ts2 = (struct type_set *)node->set;
938*2d543d20SAndroid Build Coastguard Worker if (ts1->flags != ts2->flags)
939*2d543d20SAndroid Build Coastguard Worker continue;
940*2d543d20SAndroid Build Coastguard Worker if (ebitmap_cmp(&ts1->negset, &ts2->negset) == 0)
941*2d543d20SAndroid Build Coastguard Worker continue;
942*2d543d20SAndroid Build Coastguard Worker if (ebitmap_cmp(&ts1->types, &ts2->types) == 0)
943*2d543d20SAndroid Build Coastguard Worker continue;
944*2d543d20SAndroid Build Coastguard Worker return node->attr_name;
945*2d543d20SAndroid Build Coastguard Worker } else {
946*2d543d20SAndroid Build Coastguard Worker rs2 = (struct role_set *)node->set;
947*2d543d20SAndroid Build Coastguard Worker if (rs1->flags != rs2->flags)
948*2d543d20SAndroid Build Coastguard Worker continue;
949*2d543d20SAndroid Build Coastguard Worker if (ebitmap_cmp(&rs1->roles, &rs2->roles) == 0)
950*2d543d20SAndroid Build Coastguard Worker continue;
951*2d543d20SAndroid Build Coastguard Worker return node->attr_name;
952*2d543d20SAndroid Build Coastguard Worker }
953*2d543d20SAndroid Build Coastguard Worker }
954*2d543d20SAndroid Build Coastguard Worker
955*2d543d20SAndroid Build Coastguard Worker return NULL;
956*2d543d20SAndroid Build Coastguard Worker }
957*2d543d20SAndroid Build Coastguard Worker
set_to_names(struct policydb * pdb,int is_type,void * set,struct list * attr_list,char *** names,unsigned int * num_names)958*2d543d20SAndroid Build Coastguard Worker static int set_to_names(struct policydb *pdb, int is_type, void *set, struct list *attr_list, char ***names, unsigned int *num_names)
959*2d543d20SAndroid Build Coastguard Worker {
960*2d543d20SAndroid Build Coastguard Worker char *attr_name = NULL;
961*2d543d20SAndroid Build Coastguard Worker int rc = 0;
962*2d543d20SAndroid Build Coastguard Worker
963*2d543d20SAndroid Build Coastguard Worker *names = NULL;
964*2d543d20SAndroid Build Coastguard Worker *num_names = 0;
965*2d543d20SAndroid Build Coastguard Worker
966*2d543d20SAndroid Build Coastguard Worker attr_name = search_attr_list(attr_list, is_type, set);
967*2d543d20SAndroid Build Coastguard Worker
968*2d543d20SAndroid Build Coastguard Worker if (!attr_name) {
969*2d543d20SAndroid Build Coastguard Worker attr_name = get_new_attr_name(pdb, is_type);
970*2d543d20SAndroid Build Coastguard Worker if (!attr_name) {
971*2d543d20SAndroid Build Coastguard Worker rc = -1;
972*2d543d20SAndroid Build Coastguard Worker goto exit;
973*2d543d20SAndroid Build Coastguard Worker }
974*2d543d20SAndroid Build Coastguard Worker
975*2d543d20SAndroid Build Coastguard Worker rc = cil_add_attr_to_list(attr_list, attr_name, is_type, set);
976*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
977*2d543d20SAndroid Build Coastguard Worker free(attr_name);
978*2d543d20SAndroid Build Coastguard Worker goto exit;
979*2d543d20SAndroid Build Coastguard Worker }
980*2d543d20SAndroid Build Coastguard Worker }
981*2d543d20SAndroid Build Coastguard Worker
982*2d543d20SAndroid Build Coastguard Worker *names = malloc(sizeof(char *));
983*2d543d20SAndroid Build Coastguard Worker if (!*names) {
984*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Out of memory");
985*2d543d20SAndroid Build Coastguard Worker rc = -1;
986*2d543d20SAndroid Build Coastguard Worker goto exit;
987*2d543d20SAndroid Build Coastguard Worker }
988*2d543d20SAndroid Build Coastguard Worker *names[0] = attr_name;
989*2d543d20SAndroid Build Coastguard Worker *num_names = 1;
990*2d543d20SAndroid Build Coastguard Worker
991*2d543d20SAndroid Build Coastguard Worker exit:
992*2d543d20SAndroid Build Coastguard Worker return rc;
993*2d543d20SAndroid Build Coastguard Worker }
994*2d543d20SAndroid Build Coastguard Worker
ebitmap_to_names(struct ebitmap * map,char ** vals_to_names,char *** names,unsigned int * num_names)995*2d543d20SAndroid Build Coastguard Worker static int ebitmap_to_names(struct ebitmap *map, char **vals_to_names, char ***names, unsigned int *num_names)
996*2d543d20SAndroid Build Coastguard Worker {
997*2d543d20SAndroid Build Coastguard Worker int rc = 0;
998*2d543d20SAndroid Build Coastguard Worker struct ebitmap_node *node;
999*2d543d20SAndroid Build Coastguard Worker uint32_t i;
1000*2d543d20SAndroid Build Coastguard Worker unsigned int num;
1001*2d543d20SAndroid Build Coastguard Worker char **name_arr;
1002*2d543d20SAndroid Build Coastguard Worker
1003*2d543d20SAndroid Build Coastguard Worker num = 0;
1004*2d543d20SAndroid Build Coastguard Worker ebitmap_for_each_positive_bit(map, node, i) {
1005*2d543d20SAndroid Build Coastguard Worker if (num >= UINT32_MAX / sizeof(*name_arr)) {
1006*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Overflow");
1007*2d543d20SAndroid Build Coastguard Worker rc = -1;
1008*2d543d20SAndroid Build Coastguard Worker goto exit;
1009*2d543d20SAndroid Build Coastguard Worker }
1010*2d543d20SAndroid Build Coastguard Worker num++;
1011*2d543d20SAndroid Build Coastguard Worker }
1012*2d543d20SAndroid Build Coastguard Worker
1013*2d543d20SAndroid Build Coastguard Worker if (!num) {
1014*2d543d20SAndroid Build Coastguard Worker *names = NULL;
1015*2d543d20SAndroid Build Coastguard Worker *num_names = 0;
1016*2d543d20SAndroid Build Coastguard Worker goto exit;
1017*2d543d20SAndroid Build Coastguard Worker }
1018*2d543d20SAndroid Build Coastguard Worker
1019*2d543d20SAndroid Build Coastguard Worker name_arr = calloc(num, sizeof(*name_arr));
1020*2d543d20SAndroid Build Coastguard Worker if (name_arr == NULL) {
1021*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Out of memory");
1022*2d543d20SAndroid Build Coastguard Worker rc = -1;
1023*2d543d20SAndroid Build Coastguard Worker goto exit;
1024*2d543d20SAndroid Build Coastguard Worker }
1025*2d543d20SAndroid Build Coastguard Worker
1026*2d543d20SAndroid Build Coastguard Worker num = 0;
1027*2d543d20SAndroid Build Coastguard Worker ebitmap_for_each_positive_bit(map, node, i) {
1028*2d543d20SAndroid Build Coastguard Worker name_arr[num] = vals_to_names[i];
1029*2d543d20SAndroid Build Coastguard Worker num++;
1030*2d543d20SAndroid Build Coastguard Worker }
1031*2d543d20SAndroid Build Coastguard Worker
1032*2d543d20SAndroid Build Coastguard Worker *names = name_arr;
1033*2d543d20SAndroid Build Coastguard Worker *num_names = num;
1034*2d543d20SAndroid Build Coastguard Worker
1035*2d543d20SAndroid Build Coastguard Worker exit:
1036*2d543d20SAndroid Build Coastguard Worker return rc;
1037*2d543d20SAndroid Build Coastguard Worker }
1038*2d543d20SAndroid Build Coastguard Worker
process_roleset(struct policydb * pdb,struct role_set * rs,struct list * attr_list,char *** names,unsigned int * num_names)1039*2d543d20SAndroid Build Coastguard Worker static int process_roleset(struct policydb *pdb, struct role_set *rs, struct list *attr_list, char ***names, unsigned int *num_names)
1040*2d543d20SAndroid Build Coastguard Worker {
1041*2d543d20SAndroid Build Coastguard Worker int rc = 0;
1042*2d543d20SAndroid Build Coastguard Worker
1043*2d543d20SAndroid Build Coastguard Worker *names = NULL;
1044*2d543d20SAndroid Build Coastguard Worker *num_names = 0;
1045*2d543d20SAndroid Build Coastguard Worker
1046*2d543d20SAndroid Build Coastguard Worker if (rs->flags) {
1047*2d543d20SAndroid Build Coastguard Worker rc = set_to_names(pdb, 0, &rs->roles, attr_list, names, num_names);
1048*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1049*2d543d20SAndroid Build Coastguard Worker goto exit;
1050*2d543d20SAndroid Build Coastguard Worker }
1051*2d543d20SAndroid Build Coastguard Worker } else {
1052*2d543d20SAndroid Build Coastguard Worker rc = ebitmap_to_names(&rs->roles, pdb->p_role_val_to_name, names, num_names);
1053*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1054*2d543d20SAndroid Build Coastguard Worker goto exit;
1055*2d543d20SAndroid Build Coastguard Worker }
1056*2d543d20SAndroid Build Coastguard Worker }
1057*2d543d20SAndroid Build Coastguard Worker
1058*2d543d20SAndroid Build Coastguard Worker exit:
1059*2d543d20SAndroid Build Coastguard Worker return rc;
1060*2d543d20SAndroid Build Coastguard Worker }
1061*2d543d20SAndroid Build Coastguard Worker
process_typeset(struct policydb * pdb,struct type_set * ts,struct list * attr_list,char *** names,unsigned int * num_names)1062*2d543d20SAndroid Build Coastguard Worker static int process_typeset(struct policydb *pdb, struct type_set *ts, struct list *attr_list, char ***names, unsigned int *num_names)
1063*2d543d20SAndroid Build Coastguard Worker {
1064*2d543d20SAndroid Build Coastguard Worker int rc = 0;
1065*2d543d20SAndroid Build Coastguard Worker
1066*2d543d20SAndroid Build Coastguard Worker *names = NULL;
1067*2d543d20SAndroid Build Coastguard Worker *num_names = 0;
1068*2d543d20SAndroid Build Coastguard Worker
1069*2d543d20SAndroid Build Coastguard Worker if (!ebitmap_is_empty(&ts->negset) || ts->flags != 0) {
1070*2d543d20SAndroid Build Coastguard Worker rc = set_to_names(pdb, 1, ts, attr_list, names, num_names);
1071*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1072*2d543d20SAndroid Build Coastguard Worker goto exit;
1073*2d543d20SAndroid Build Coastguard Worker }
1074*2d543d20SAndroid Build Coastguard Worker } else {
1075*2d543d20SAndroid Build Coastguard Worker rc = ebitmap_to_names(&ts->types, pdb->p_type_val_to_name, names, num_names);
1076*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1077*2d543d20SAndroid Build Coastguard Worker goto exit;
1078*2d543d20SAndroid Build Coastguard Worker }
1079*2d543d20SAndroid Build Coastguard Worker }
1080*2d543d20SAndroid Build Coastguard Worker
1081*2d543d20SAndroid Build Coastguard Worker exit:
1082*2d543d20SAndroid Build Coastguard Worker return rc;
1083*2d543d20SAndroid Build Coastguard Worker }
1084*2d543d20SAndroid Build Coastguard Worker
names_destroy(char *** names,unsigned int * num_names)1085*2d543d20SAndroid Build Coastguard Worker static void names_destroy(char ***names, unsigned int *num_names)
1086*2d543d20SAndroid Build Coastguard Worker {
1087*2d543d20SAndroid Build Coastguard Worker free(*names);
1088*2d543d20SAndroid Build Coastguard Worker *names = NULL;
1089*2d543d20SAndroid Build Coastguard Worker *num_names = 0;
1090*2d543d20SAndroid Build Coastguard Worker }
1091*2d543d20SAndroid Build Coastguard Worker
roletype_role_in_ancestor_to_cil(struct policydb * pdb,struct stack * decl_stack,char * type_name,int indent)1092*2d543d20SAndroid Build Coastguard Worker static int roletype_role_in_ancestor_to_cil(struct policydb *pdb, struct stack *decl_stack, char *type_name, int indent)
1093*2d543d20SAndroid Build Coastguard Worker {
1094*2d543d20SAndroid Build Coastguard Worker struct list_node *curr;
1095*2d543d20SAndroid Build Coastguard Worker char **tnames = NULL;
1096*2d543d20SAndroid Build Coastguard Worker unsigned int num_tnames, i;
1097*2d543d20SAndroid Build Coastguard Worker struct role_list_node *role_node = NULL;
1098*2d543d20SAndroid Build Coastguard Worker int rc;
1099*2d543d20SAndroid Build Coastguard Worker struct type_set *ts;
1100*2d543d20SAndroid Build Coastguard Worker struct list *attr_list = NULL;
1101*2d543d20SAndroid Build Coastguard Worker
1102*2d543d20SAndroid Build Coastguard Worker rc = list_init(&attr_list);
1103*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1104*2d543d20SAndroid Build Coastguard Worker goto exit;
1105*2d543d20SAndroid Build Coastguard Worker }
1106*2d543d20SAndroid Build Coastguard Worker
1107*2d543d20SAndroid Build Coastguard Worker for (curr = role_list->head; curr != NULL; curr = curr->next) {
1108*2d543d20SAndroid Build Coastguard Worker role_node = curr->data;
1109*2d543d20SAndroid Build Coastguard Worker if (!is_id_in_ancestor_scope(pdb, decl_stack, role_node->role_name, SYM_ROLES)) {
1110*2d543d20SAndroid Build Coastguard Worker continue;
1111*2d543d20SAndroid Build Coastguard Worker }
1112*2d543d20SAndroid Build Coastguard Worker
1113*2d543d20SAndroid Build Coastguard Worker ts = &role_node->role->types;
1114*2d543d20SAndroid Build Coastguard Worker rc = process_typeset(pdb, ts, attr_list, &tnames, &num_tnames);
1115*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1116*2d543d20SAndroid Build Coastguard Worker goto exit;
1117*2d543d20SAndroid Build Coastguard Worker }
1118*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < num_tnames; i++) {
1119*2d543d20SAndroid Build Coastguard Worker if (!strcmp(type_name, tnames[i])) {
1120*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(roletype %s %s)", role_node->role_name, type_name);
1121*2d543d20SAndroid Build Coastguard Worker }
1122*2d543d20SAndroid Build Coastguard Worker }
1123*2d543d20SAndroid Build Coastguard Worker names_destroy(&tnames, &num_tnames);
1124*2d543d20SAndroid Build Coastguard Worker }
1125*2d543d20SAndroid Build Coastguard Worker
1126*2d543d20SAndroid Build Coastguard Worker rc = cil_print_attr_list(indent, pdb, attr_list);
1127*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1128*2d543d20SAndroid Build Coastguard Worker goto exit;
1129*2d543d20SAndroid Build Coastguard Worker }
1130*2d543d20SAndroid Build Coastguard Worker
1131*2d543d20SAndroid Build Coastguard Worker exit:
1132*2d543d20SAndroid Build Coastguard Worker attr_list_destroy(&attr_list);
1133*2d543d20SAndroid Build Coastguard Worker return rc;
1134*2d543d20SAndroid Build Coastguard Worker }
1135*2d543d20SAndroid Build Coastguard Worker
1136*2d543d20SAndroid Build Coastguard Worker
name_list_to_string(char ** names,unsigned int num_names,char ** string)1137*2d543d20SAndroid Build Coastguard Worker static int name_list_to_string(char **names, unsigned int num_names, char **string)
1138*2d543d20SAndroid Build Coastguard Worker {
1139*2d543d20SAndroid Build Coastguard Worker // create a space separated string of the names
1140*2d543d20SAndroid Build Coastguard Worker int rc = -1;
1141*2d543d20SAndroid Build Coastguard Worker size_t len = 0;
1142*2d543d20SAndroid Build Coastguard Worker unsigned int i;
1143*2d543d20SAndroid Build Coastguard Worker char *str;
1144*2d543d20SAndroid Build Coastguard Worker char *strpos;
1145*2d543d20SAndroid Build Coastguard Worker
1146*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < num_names; i++) {
1147*2d543d20SAndroid Build Coastguard Worker if (__builtin_add_overflow(len, strlen(names[i]), &len)) {
1148*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Overflow");
1149*2d543d20SAndroid Build Coastguard Worker return -1;
1150*2d543d20SAndroid Build Coastguard Worker }
1151*2d543d20SAndroid Build Coastguard Worker }
1152*2d543d20SAndroid Build Coastguard Worker
1153*2d543d20SAndroid Build Coastguard Worker // add spaces + null terminator
1154*2d543d20SAndroid Build Coastguard Worker if (__builtin_add_overflow(len, (size_t)num_names, &len)) {
1155*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Overflow");
1156*2d543d20SAndroid Build Coastguard Worker return -1;
1157*2d543d20SAndroid Build Coastguard Worker }
1158*2d543d20SAndroid Build Coastguard Worker
1159*2d543d20SAndroid Build Coastguard Worker if (!len) {
1160*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Empty list");
1161*2d543d20SAndroid Build Coastguard Worker return -1;
1162*2d543d20SAndroid Build Coastguard Worker }
1163*2d543d20SAndroid Build Coastguard Worker
1164*2d543d20SAndroid Build Coastguard Worker str = malloc(len);
1165*2d543d20SAndroid Build Coastguard Worker if (str == NULL) {
1166*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Out of memory");
1167*2d543d20SAndroid Build Coastguard Worker rc = -1;
1168*2d543d20SAndroid Build Coastguard Worker goto exit;
1169*2d543d20SAndroid Build Coastguard Worker }
1170*2d543d20SAndroid Build Coastguard Worker str[0] = 0;
1171*2d543d20SAndroid Build Coastguard Worker
1172*2d543d20SAndroid Build Coastguard Worker strpos = str;
1173*2d543d20SAndroid Build Coastguard Worker
1174*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < num_names; i++) {
1175*2d543d20SAndroid Build Coastguard Worker strpos = stpcpy(strpos, names[i]);
1176*2d543d20SAndroid Build Coastguard Worker if (i < num_names - 1) {
1177*2d543d20SAndroid Build Coastguard Worker *strpos++ = ' ';
1178*2d543d20SAndroid Build Coastguard Worker }
1179*2d543d20SAndroid Build Coastguard Worker }
1180*2d543d20SAndroid Build Coastguard Worker
1181*2d543d20SAndroid Build Coastguard Worker *string = str;
1182*2d543d20SAndroid Build Coastguard Worker
1183*2d543d20SAndroid Build Coastguard Worker return 0;
1184*2d543d20SAndroid Build Coastguard Worker exit:
1185*2d543d20SAndroid Build Coastguard Worker free(str);
1186*2d543d20SAndroid Build Coastguard Worker return rc;
1187*2d543d20SAndroid Build Coastguard Worker }
1188*2d543d20SAndroid Build Coastguard Worker
avrule_list_to_cil(int indent,struct policydb * pdb,struct avrule * avrule_list,struct list * attr_list)1189*2d543d20SAndroid Build Coastguard Worker static int avrule_list_to_cil(int indent, struct policydb *pdb, struct avrule *avrule_list, struct list *attr_list)
1190*2d543d20SAndroid Build Coastguard Worker {
1191*2d543d20SAndroid Build Coastguard Worker int rc = -1;
1192*2d543d20SAndroid Build Coastguard Worker struct avrule *avrule;
1193*2d543d20SAndroid Build Coastguard Worker char **snames = NULL;
1194*2d543d20SAndroid Build Coastguard Worker char **tnames = NULL;
1195*2d543d20SAndroid Build Coastguard Worker unsigned int s, t, num_snames, num_tnames;
1196*2d543d20SAndroid Build Coastguard Worker struct type_set *ts;
1197*2d543d20SAndroid Build Coastguard Worker
1198*2d543d20SAndroid Build Coastguard Worker for (avrule = avrule_list; avrule != NULL; avrule = avrule->next) {
1199*2d543d20SAndroid Build Coastguard Worker if ((avrule->specified & (AVRULE_NEVERALLOW|AVRULE_XPERMS_NEVERALLOW)) &&
1200*2d543d20SAndroid Build Coastguard Worker avrule->source_filename) {
1201*2d543d20SAndroid Build Coastguard Worker cil_println(0, ";;* lmx %lu %s\n",avrule->source_line, avrule->source_filename);
1202*2d543d20SAndroid Build Coastguard Worker }
1203*2d543d20SAndroid Build Coastguard Worker
1204*2d543d20SAndroid Build Coastguard Worker ts = &avrule->stypes;
1205*2d543d20SAndroid Build Coastguard Worker rc = process_typeset(pdb, ts, attr_list, &snames, &num_snames);
1206*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1207*2d543d20SAndroid Build Coastguard Worker goto exit;
1208*2d543d20SAndroid Build Coastguard Worker }
1209*2d543d20SAndroid Build Coastguard Worker
1210*2d543d20SAndroid Build Coastguard Worker if (avrule->flags & RULE_NOTSELF) {
1211*2d543d20SAndroid Build Coastguard Worker if (!ebitmap_is_empty(&avrule->ttypes.types) || !ebitmap_is_empty(&avrule->ttypes.negset)) {
1212*2d543d20SAndroid Build Coastguard Worker if (avrule->source_filename) {
1213*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "%s:%lu: Non-trivial neverallow rules with targets containing not or minus self not yet supported",
1214*2d543d20SAndroid Build Coastguard Worker avrule->source_filename, avrule->source_line);
1215*2d543d20SAndroid Build Coastguard Worker } else {
1216*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Non-trivial neverallow rules with targets containing not or minus self not yet supported");
1217*2d543d20SAndroid Build Coastguard Worker }
1218*2d543d20SAndroid Build Coastguard Worker rc = -1;
1219*2d543d20SAndroid Build Coastguard Worker goto exit;
1220*2d543d20SAndroid Build Coastguard Worker }
1221*2d543d20SAndroid Build Coastguard Worker
1222*2d543d20SAndroid Build Coastguard Worker num_tnames = 0;
1223*2d543d20SAndroid Build Coastguard Worker } else {
1224*2d543d20SAndroid Build Coastguard Worker ts = &avrule->ttypes;
1225*2d543d20SAndroid Build Coastguard Worker rc = process_typeset(pdb, ts, attr_list, &tnames, &num_tnames);
1226*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1227*2d543d20SAndroid Build Coastguard Worker goto exit;
1228*2d543d20SAndroid Build Coastguard Worker }
1229*2d543d20SAndroid Build Coastguard Worker }
1230*2d543d20SAndroid Build Coastguard Worker
1231*2d543d20SAndroid Build Coastguard Worker for (s = 0; s < num_snames; s++) {
1232*2d543d20SAndroid Build Coastguard Worker for (t = 0; t < num_tnames; t++) {
1233*2d543d20SAndroid Build Coastguard Worker if (avrule->specified & AVRULE_XPERMS) {
1234*2d543d20SAndroid Build Coastguard Worker rc = avrulex_to_cil(indent, pdb, avrule->specified, snames[s], tnames[t], avrule->perms, avrule->xperms);
1235*2d543d20SAndroid Build Coastguard Worker } else {
1236*2d543d20SAndroid Build Coastguard Worker rc = avrule_to_cil(indent, pdb, avrule->specified, snames[s], tnames[t], avrule->perms);
1237*2d543d20SAndroid Build Coastguard Worker }
1238*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1239*2d543d20SAndroid Build Coastguard Worker goto exit;
1240*2d543d20SAndroid Build Coastguard Worker }
1241*2d543d20SAndroid Build Coastguard Worker }
1242*2d543d20SAndroid Build Coastguard Worker
1243*2d543d20SAndroid Build Coastguard Worker if (avrule->flags & RULE_SELF) {
1244*2d543d20SAndroid Build Coastguard Worker if (avrule->specified & AVRULE_XPERMS) {
1245*2d543d20SAndroid Build Coastguard Worker rc = avrulex_to_cil(indent, pdb, avrule->specified, snames[s], "self", avrule->perms, avrule->xperms);
1246*2d543d20SAndroid Build Coastguard Worker } else {
1247*2d543d20SAndroid Build Coastguard Worker rc = avrule_to_cil(indent, pdb, avrule->specified, snames[s], "self", avrule->perms);
1248*2d543d20SAndroid Build Coastguard Worker }
1249*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1250*2d543d20SAndroid Build Coastguard Worker goto exit;
1251*2d543d20SAndroid Build Coastguard Worker }
1252*2d543d20SAndroid Build Coastguard Worker } else if (avrule->flags & RULE_NOTSELF) {
1253*2d543d20SAndroid Build Coastguard Worker if (avrule->specified & AVRULE_XPERMS) {
1254*2d543d20SAndroid Build Coastguard Worker rc = avrulex_to_cil(indent, pdb, avrule->specified, snames[s], "notself", avrule->perms, avrule->xperms);
1255*2d543d20SAndroid Build Coastguard Worker } else {
1256*2d543d20SAndroid Build Coastguard Worker rc = avrule_to_cil(indent, pdb, avrule->specified, snames[s], "notself", avrule->perms);
1257*2d543d20SAndroid Build Coastguard Worker }
1258*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1259*2d543d20SAndroid Build Coastguard Worker goto exit;
1260*2d543d20SAndroid Build Coastguard Worker }
1261*2d543d20SAndroid Build Coastguard Worker }
1262*2d543d20SAndroid Build Coastguard Worker }
1263*2d543d20SAndroid Build Coastguard Worker
1264*2d543d20SAndroid Build Coastguard Worker names_destroy(&snames, &num_snames);
1265*2d543d20SAndroid Build Coastguard Worker names_destroy(&tnames, &num_tnames);
1266*2d543d20SAndroid Build Coastguard Worker
1267*2d543d20SAndroid Build Coastguard Worker if ((avrule->specified & (AVRULE_NEVERALLOW|AVRULE_XPERMS_NEVERALLOW)) &&
1268*2d543d20SAndroid Build Coastguard Worker avrule->source_filename) {
1269*2d543d20SAndroid Build Coastguard Worker cil_println(0, ";;* lme\n");
1270*2d543d20SAndroid Build Coastguard Worker }
1271*2d543d20SAndroid Build Coastguard Worker }
1272*2d543d20SAndroid Build Coastguard Worker
1273*2d543d20SAndroid Build Coastguard Worker return 0;
1274*2d543d20SAndroid Build Coastguard Worker
1275*2d543d20SAndroid Build Coastguard Worker exit:
1276*2d543d20SAndroid Build Coastguard Worker names_destroy(&snames, &num_snames);
1277*2d543d20SAndroid Build Coastguard Worker names_destroy(&tnames, &num_tnames);
1278*2d543d20SAndroid Build Coastguard Worker
1279*2d543d20SAndroid Build Coastguard Worker return rc;
1280*2d543d20SAndroid Build Coastguard Worker }
1281*2d543d20SAndroid Build Coastguard Worker
cond_expr_to_cil(int indent,struct policydb * pdb,struct cond_expr * cond_expr,uint32_t flags)1282*2d543d20SAndroid Build Coastguard Worker static int cond_expr_to_cil(int indent, struct policydb *pdb, struct cond_expr *cond_expr, uint32_t flags)
1283*2d543d20SAndroid Build Coastguard Worker {
1284*2d543d20SAndroid Build Coastguard Worker int rc = 0;
1285*2d543d20SAndroid Build Coastguard Worker struct cond_expr *curr;
1286*2d543d20SAndroid Build Coastguard Worker struct stack *stack = NULL;
1287*2d543d20SAndroid Build Coastguard Worker int len = 0;
1288*2d543d20SAndroid Build Coastguard Worker int rlen;
1289*2d543d20SAndroid Build Coastguard Worker char *new_val = NULL;
1290*2d543d20SAndroid Build Coastguard Worker char *val1 = NULL;
1291*2d543d20SAndroid Build Coastguard Worker char *val2 = NULL;
1292*2d543d20SAndroid Build Coastguard Worker unsigned int num_params;
1293*2d543d20SAndroid Build Coastguard Worker const char *op;
1294*2d543d20SAndroid Build Coastguard Worker const char *sep;
1295*2d543d20SAndroid Build Coastguard Worker const char *type;
1296*2d543d20SAndroid Build Coastguard Worker
1297*2d543d20SAndroid Build Coastguard Worker rc = stack_init(&stack);
1298*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1299*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Out of memory");
1300*2d543d20SAndroid Build Coastguard Worker goto exit;
1301*2d543d20SAndroid Build Coastguard Worker }
1302*2d543d20SAndroid Build Coastguard Worker
1303*2d543d20SAndroid Build Coastguard Worker for (curr = cond_expr; curr != NULL; curr = curr->next) {
1304*2d543d20SAndroid Build Coastguard Worker if (curr->expr_type == COND_BOOL) {
1305*2d543d20SAndroid Build Coastguard Worker val1 = pdb->p_bool_val_to_name[curr->boolean - 1];
1306*2d543d20SAndroid Build Coastguard Worker // length of boolean + 2 parens + null terminator
1307*2d543d20SAndroid Build Coastguard Worker len = strlen(val1) + 2 + 1;
1308*2d543d20SAndroid Build Coastguard Worker new_val = malloc(len);
1309*2d543d20SAndroid Build Coastguard Worker if (new_val == NULL) {
1310*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Out of memory");
1311*2d543d20SAndroid Build Coastguard Worker rc = -1;
1312*2d543d20SAndroid Build Coastguard Worker goto exit;
1313*2d543d20SAndroid Build Coastguard Worker }
1314*2d543d20SAndroid Build Coastguard Worker rlen = snprintf(new_val, len, "(%s)", val1);
1315*2d543d20SAndroid Build Coastguard Worker if (rlen < 0 || rlen >= len) {
1316*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Failed to generate conditional expression");
1317*2d543d20SAndroid Build Coastguard Worker rc = -1;
1318*2d543d20SAndroid Build Coastguard Worker goto exit;
1319*2d543d20SAndroid Build Coastguard Worker }
1320*2d543d20SAndroid Build Coastguard Worker } else {
1321*2d543d20SAndroid Build Coastguard Worker switch(curr->expr_type) {
1322*2d543d20SAndroid Build Coastguard Worker case COND_NOT: op = "not"; break;
1323*2d543d20SAndroid Build Coastguard Worker case COND_OR: op = "or"; break;
1324*2d543d20SAndroid Build Coastguard Worker case COND_AND: op = "and"; break;
1325*2d543d20SAndroid Build Coastguard Worker case COND_XOR: op = "xor"; break;
1326*2d543d20SAndroid Build Coastguard Worker case COND_EQ: op = "eq"; break;
1327*2d543d20SAndroid Build Coastguard Worker case COND_NEQ: op = "neq"; break;
1328*2d543d20SAndroid Build Coastguard Worker default:
1329*2d543d20SAndroid Build Coastguard Worker rc = -1;
1330*2d543d20SAndroid Build Coastguard Worker goto exit;
1331*2d543d20SAndroid Build Coastguard Worker }
1332*2d543d20SAndroid Build Coastguard Worker
1333*2d543d20SAndroid Build Coastguard Worker num_params = curr->expr_type == COND_NOT ? 1 : 2;
1334*2d543d20SAndroid Build Coastguard Worker
1335*2d543d20SAndroid Build Coastguard Worker if (num_params == 1) {
1336*2d543d20SAndroid Build Coastguard Worker val1 = stack_pop(stack);
1337*2d543d20SAndroid Build Coastguard Worker val2 = strdup("");
1338*2d543d20SAndroid Build Coastguard Worker if (val2 == NULL) {
1339*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Out of memory");
1340*2d543d20SAndroid Build Coastguard Worker rc = -1;
1341*2d543d20SAndroid Build Coastguard Worker goto exit;
1342*2d543d20SAndroid Build Coastguard Worker }
1343*2d543d20SAndroid Build Coastguard Worker sep = "";
1344*2d543d20SAndroid Build Coastguard Worker } else {
1345*2d543d20SAndroid Build Coastguard Worker val2 = stack_pop(stack);
1346*2d543d20SAndroid Build Coastguard Worker val1 = stack_pop(stack);
1347*2d543d20SAndroid Build Coastguard Worker sep = " ";
1348*2d543d20SAndroid Build Coastguard Worker }
1349*2d543d20SAndroid Build Coastguard Worker
1350*2d543d20SAndroid Build Coastguard Worker if (val1 == NULL || val2 == NULL) {
1351*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Invalid conditional expression");
1352*2d543d20SAndroid Build Coastguard Worker rc = -1;
1353*2d543d20SAndroid Build Coastguard Worker goto exit;
1354*2d543d20SAndroid Build Coastguard Worker }
1355*2d543d20SAndroid Build Coastguard Worker
1356*2d543d20SAndroid Build Coastguard Worker // length = length of parameters +
1357*2d543d20SAndroid Build Coastguard Worker // length of operator +
1358*2d543d20SAndroid Build Coastguard Worker // 1 space preceding each parameter +
1359*2d543d20SAndroid Build Coastguard Worker // 2 parens around the whole expression
1360*2d543d20SAndroid Build Coastguard Worker // + null terminator
1361*2d543d20SAndroid Build Coastguard Worker len = strlen(val1) + strlen(val2) + strlen(op) + (num_params * 1) + 2 + 1;
1362*2d543d20SAndroid Build Coastguard Worker new_val = malloc(len);
1363*2d543d20SAndroid Build Coastguard Worker if (new_val == NULL) {
1364*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Out of memory");
1365*2d543d20SAndroid Build Coastguard Worker rc = -1;
1366*2d543d20SAndroid Build Coastguard Worker goto exit;
1367*2d543d20SAndroid Build Coastguard Worker }
1368*2d543d20SAndroid Build Coastguard Worker
1369*2d543d20SAndroid Build Coastguard Worker rlen = snprintf(new_val, len, "(%s %s%s%s)", op, val1, sep, val2);
1370*2d543d20SAndroid Build Coastguard Worker if (rlen < 0 || rlen >= len) {
1371*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Failed to generate conditional expression");
1372*2d543d20SAndroid Build Coastguard Worker rc = -1;
1373*2d543d20SAndroid Build Coastguard Worker goto exit;
1374*2d543d20SAndroid Build Coastguard Worker }
1375*2d543d20SAndroid Build Coastguard Worker
1376*2d543d20SAndroid Build Coastguard Worker free(val1);
1377*2d543d20SAndroid Build Coastguard Worker free(val2);
1378*2d543d20SAndroid Build Coastguard Worker val1 = NULL;
1379*2d543d20SAndroid Build Coastguard Worker val2 = NULL;
1380*2d543d20SAndroid Build Coastguard Worker }
1381*2d543d20SAndroid Build Coastguard Worker
1382*2d543d20SAndroid Build Coastguard Worker rc = stack_push(stack, new_val);
1383*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1384*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Out of memory");
1385*2d543d20SAndroid Build Coastguard Worker goto exit;
1386*2d543d20SAndroid Build Coastguard Worker }
1387*2d543d20SAndroid Build Coastguard Worker new_val = NULL;
1388*2d543d20SAndroid Build Coastguard Worker }
1389*2d543d20SAndroid Build Coastguard Worker
1390*2d543d20SAndroid Build Coastguard Worker if (flags & COND_NODE_FLAGS_TUNABLE) {
1391*2d543d20SAndroid Build Coastguard Worker type = "tunableif";
1392*2d543d20SAndroid Build Coastguard Worker } else {
1393*2d543d20SAndroid Build Coastguard Worker type = "booleanif";
1394*2d543d20SAndroid Build Coastguard Worker }
1395*2d543d20SAndroid Build Coastguard Worker
1396*2d543d20SAndroid Build Coastguard Worker val1 = stack_pop(stack);
1397*2d543d20SAndroid Build Coastguard Worker if (val1 == NULL || stack_peek(stack) != NULL) {
1398*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Invalid conditional expression");
1399*2d543d20SAndroid Build Coastguard Worker rc = -1;
1400*2d543d20SAndroid Build Coastguard Worker goto exit;
1401*2d543d20SAndroid Build Coastguard Worker }
1402*2d543d20SAndroid Build Coastguard Worker
1403*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(%s %s", type, val1);
1404*2d543d20SAndroid Build Coastguard Worker free(val1);
1405*2d543d20SAndroid Build Coastguard Worker val1 = NULL;
1406*2d543d20SAndroid Build Coastguard Worker
1407*2d543d20SAndroid Build Coastguard Worker rc = 0;
1408*2d543d20SAndroid Build Coastguard Worker
1409*2d543d20SAndroid Build Coastguard Worker exit:
1410*2d543d20SAndroid Build Coastguard Worker free(new_val);
1411*2d543d20SAndroid Build Coastguard Worker free(val1);
1412*2d543d20SAndroid Build Coastguard Worker free(val2);
1413*2d543d20SAndroid Build Coastguard Worker if (stack != NULL) {
1414*2d543d20SAndroid Build Coastguard Worker while ((val1 = stack_pop(stack)) != NULL) {
1415*2d543d20SAndroid Build Coastguard Worker free(val1);
1416*2d543d20SAndroid Build Coastguard Worker }
1417*2d543d20SAndroid Build Coastguard Worker stack_destroy(&stack);
1418*2d543d20SAndroid Build Coastguard Worker }
1419*2d543d20SAndroid Build Coastguard Worker return rc;
1420*2d543d20SAndroid Build Coastguard Worker }
1421*2d543d20SAndroid Build Coastguard Worker
cond_list_to_cil(int indent,struct policydb * pdb,struct cond_node * cond_list,struct list * attr_list)1422*2d543d20SAndroid Build Coastguard Worker static int cond_list_to_cil(int indent, struct policydb *pdb, struct cond_node *cond_list, struct list *attr_list)
1423*2d543d20SAndroid Build Coastguard Worker {
1424*2d543d20SAndroid Build Coastguard Worker int rc = 0;
1425*2d543d20SAndroid Build Coastguard Worker struct cond_node *cond;
1426*2d543d20SAndroid Build Coastguard Worker
1427*2d543d20SAndroid Build Coastguard Worker for (cond = cond_list; cond != NULL; cond = cond->next) {
1428*2d543d20SAndroid Build Coastguard Worker
1429*2d543d20SAndroid Build Coastguard Worker rc = cond_expr_to_cil(indent, pdb, cond->expr, cond->flags);
1430*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1431*2d543d20SAndroid Build Coastguard Worker goto exit;
1432*2d543d20SAndroid Build Coastguard Worker }
1433*2d543d20SAndroid Build Coastguard Worker
1434*2d543d20SAndroid Build Coastguard Worker if (cond->avtrue_list != NULL) {
1435*2d543d20SAndroid Build Coastguard Worker cil_println(indent + 1, "(true");
1436*2d543d20SAndroid Build Coastguard Worker rc = avrule_list_to_cil(indent + 2, pdb, cond->avtrue_list, attr_list);
1437*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1438*2d543d20SAndroid Build Coastguard Worker goto exit;
1439*2d543d20SAndroid Build Coastguard Worker }
1440*2d543d20SAndroid Build Coastguard Worker cil_println(indent + 1, ")");
1441*2d543d20SAndroid Build Coastguard Worker }
1442*2d543d20SAndroid Build Coastguard Worker
1443*2d543d20SAndroid Build Coastguard Worker if (cond->avfalse_list != NULL) {
1444*2d543d20SAndroid Build Coastguard Worker cil_println(indent + 1, "(false");
1445*2d543d20SAndroid Build Coastguard Worker rc = avrule_list_to_cil(indent + 2, pdb, cond->avfalse_list, attr_list);
1446*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1447*2d543d20SAndroid Build Coastguard Worker goto exit;
1448*2d543d20SAndroid Build Coastguard Worker }
1449*2d543d20SAndroid Build Coastguard Worker cil_println(indent + 1, ")");
1450*2d543d20SAndroid Build Coastguard Worker }
1451*2d543d20SAndroid Build Coastguard Worker
1452*2d543d20SAndroid Build Coastguard Worker cil_println(indent, ")");
1453*2d543d20SAndroid Build Coastguard Worker }
1454*2d543d20SAndroid Build Coastguard Worker
1455*2d543d20SAndroid Build Coastguard Worker exit:
1456*2d543d20SAndroid Build Coastguard Worker return rc;
1457*2d543d20SAndroid Build Coastguard Worker }
1458*2d543d20SAndroid Build Coastguard Worker
role_trans_to_cil(int indent,struct policydb * pdb,struct role_trans_rule * rules,struct list * role_attr_list,struct list * type_attr_list)1459*2d543d20SAndroid Build Coastguard Worker static int role_trans_to_cil(int indent, struct policydb *pdb, struct role_trans_rule *rules, struct list *role_attr_list, struct list *type_attr_list)
1460*2d543d20SAndroid Build Coastguard Worker {
1461*2d543d20SAndroid Build Coastguard Worker int rc = 0;
1462*2d543d20SAndroid Build Coastguard Worker struct role_trans_rule *rule;
1463*2d543d20SAndroid Build Coastguard Worker char **role_names = NULL;
1464*2d543d20SAndroid Build Coastguard Worker unsigned int num_role_names = 0;
1465*2d543d20SAndroid Build Coastguard Worker unsigned int role;
1466*2d543d20SAndroid Build Coastguard Worker char **type_names = NULL;
1467*2d543d20SAndroid Build Coastguard Worker unsigned int num_type_names = 0;
1468*2d543d20SAndroid Build Coastguard Worker unsigned int type;
1469*2d543d20SAndroid Build Coastguard Worker uint32_t i;
1470*2d543d20SAndroid Build Coastguard Worker struct ebitmap_node *node;
1471*2d543d20SAndroid Build Coastguard Worker struct type_set *ts;
1472*2d543d20SAndroid Build Coastguard Worker struct role_set *rs;
1473*2d543d20SAndroid Build Coastguard Worker
1474*2d543d20SAndroid Build Coastguard Worker for (rule = rules; rule != NULL; rule = rule->next) {
1475*2d543d20SAndroid Build Coastguard Worker rs = &rule->roles;
1476*2d543d20SAndroid Build Coastguard Worker rc = process_roleset(pdb, rs, role_attr_list, &role_names, &num_role_names);
1477*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1478*2d543d20SAndroid Build Coastguard Worker goto exit;
1479*2d543d20SAndroid Build Coastguard Worker }
1480*2d543d20SAndroid Build Coastguard Worker
1481*2d543d20SAndroid Build Coastguard Worker ts = &rule->types;
1482*2d543d20SAndroid Build Coastguard Worker rc = process_typeset(pdb, ts, type_attr_list, &type_names, &num_type_names);
1483*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1484*2d543d20SAndroid Build Coastguard Worker goto exit;
1485*2d543d20SAndroid Build Coastguard Worker }
1486*2d543d20SAndroid Build Coastguard Worker
1487*2d543d20SAndroid Build Coastguard Worker for (role = 0; role < num_role_names; role++) {
1488*2d543d20SAndroid Build Coastguard Worker for (type = 0; type < num_type_names; type++) {
1489*2d543d20SAndroid Build Coastguard Worker ebitmap_for_each_positive_bit(&rule->classes, node, i) {
1490*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(roletransition %s %s %s %s)",
1491*2d543d20SAndroid Build Coastguard Worker role_names[role], type_names[type],
1492*2d543d20SAndroid Build Coastguard Worker pdb->p_class_val_to_name[i],
1493*2d543d20SAndroid Build Coastguard Worker pdb->p_role_val_to_name[rule->new_role - 1]);
1494*2d543d20SAndroid Build Coastguard Worker }
1495*2d543d20SAndroid Build Coastguard Worker }
1496*2d543d20SAndroid Build Coastguard Worker }
1497*2d543d20SAndroid Build Coastguard Worker
1498*2d543d20SAndroid Build Coastguard Worker names_destroy(&role_names, &num_role_names);
1499*2d543d20SAndroid Build Coastguard Worker names_destroy(&type_names, &num_type_names);
1500*2d543d20SAndroid Build Coastguard Worker }
1501*2d543d20SAndroid Build Coastguard Worker
1502*2d543d20SAndroid Build Coastguard Worker exit:
1503*2d543d20SAndroid Build Coastguard Worker names_destroy(&role_names, &num_role_names);
1504*2d543d20SAndroid Build Coastguard Worker names_destroy(&type_names, &num_type_names);
1505*2d543d20SAndroid Build Coastguard Worker
1506*2d543d20SAndroid Build Coastguard Worker return rc;
1507*2d543d20SAndroid Build Coastguard Worker }
1508*2d543d20SAndroid Build Coastguard Worker
role_allows_to_cil(int indent,struct policydb * pdb,struct role_allow_rule * rules,struct list * attr_list)1509*2d543d20SAndroid Build Coastguard Worker static int role_allows_to_cil(int indent, struct policydb *pdb, struct role_allow_rule *rules, struct list *attr_list)
1510*2d543d20SAndroid Build Coastguard Worker {
1511*2d543d20SAndroid Build Coastguard Worker int rc = -1;
1512*2d543d20SAndroid Build Coastguard Worker struct role_allow_rule *rule;
1513*2d543d20SAndroid Build Coastguard Worker char **roles = NULL;
1514*2d543d20SAndroid Build Coastguard Worker unsigned int num_roles = 0;
1515*2d543d20SAndroid Build Coastguard Worker char **new_roles = NULL;
1516*2d543d20SAndroid Build Coastguard Worker unsigned int num_new_roles = 0;
1517*2d543d20SAndroid Build Coastguard Worker unsigned int i, j;
1518*2d543d20SAndroid Build Coastguard Worker struct role_set *rs;
1519*2d543d20SAndroid Build Coastguard Worker
1520*2d543d20SAndroid Build Coastguard Worker for (rule = rules; rule != NULL; rule = rule->next) {
1521*2d543d20SAndroid Build Coastguard Worker rs = &rule->roles;
1522*2d543d20SAndroid Build Coastguard Worker rc = process_roleset(pdb, rs, attr_list, &roles, &num_roles);
1523*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1524*2d543d20SAndroid Build Coastguard Worker goto exit;
1525*2d543d20SAndroid Build Coastguard Worker }
1526*2d543d20SAndroid Build Coastguard Worker
1527*2d543d20SAndroid Build Coastguard Worker rs = &rule->new_roles;
1528*2d543d20SAndroid Build Coastguard Worker rc = process_roleset(pdb, rs, attr_list, &new_roles, &num_new_roles);
1529*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1530*2d543d20SAndroid Build Coastguard Worker goto exit;
1531*2d543d20SAndroid Build Coastguard Worker }
1532*2d543d20SAndroid Build Coastguard Worker
1533*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < num_roles; i++) {
1534*2d543d20SAndroid Build Coastguard Worker for (j = 0; j < num_new_roles; j++) {
1535*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(roleallow %s %s)", roles[i], new_roles[j]);
1536*2d543d20SAndroid Build Coastguard Worker }
1537*2d543d20SAndroid Build Coastguard Worker }
1538*2d543d20SAndroid Build Coastguard Worker
1539*2d543d20SAndroid Build Coastguard Worker names_destroy(&roles, &num_roles);
1540*2d543d20SAndroid Build Coastguard Worker names_destroy(&new_roles, &num_new_roles);
1541*2d543d20SAndroid Build Coastguard Worker }
1542*2d543d20SAndroid Build Coastguard Worker
1543*2d543d20SAndroid Build Coastguard Worker rc = 0;
1544*2d543d20SAndroid Build Coastguard Worker
1545*2d543d20SAndroid Build Coastguard Worker exit:
1546*2d543d20SAndroid Build Coastguard Worker names_destroy(&roles, &num_roles);
1547*2d543d20SAndroid Build Coastguard Worker names_destroy(&new_roles, &num_new_roles);
1548*2d543d20SAndroid Build Coastguard Worker
1549*2d543d20SAndroid Build Coastguard Worker return rc;
1550*2d543d20SAndroid Build Coastguard Worker }
1551*2d543d20SAndroid Build Coastguard Worker
range_trans_to_cil(int indent,struct policydb * pdb,struct range_trans_rule * rules,struct list * attr_list)1552*2d543d20SAndroid Build Coastguard Worker static int range_trans_to_cil(int indent, struct policydb *pdb, struct range_trans_rule *rules, struct list *attr_list)
1553*2d543d20SAndroid Build Coastguard Worker {
1554*2d543d20SAndroid Build Coastguard Worker int rc = -1;
1555*2d543d20SAndroid Build Coastguard Worker struct range_trans_rule *rule;
1556*2d543d20SAndroid Build Coastguard Worker char **stypes = NULL;
1557*2d543d20SAndroid Build Coastguard Worker unsigned int num_stypes = 0;
1558*2d543d20SAndroid Build Coastguard Worker unsigned int stype;
1559*2d543d20SAndroid Build Coastguard Worker char **ttypes = NULL;
1560*2d543d20SAndroid Build Coastguard Worker unsigned int num_ttypes = 0;
1561*2d543d20SAndroid Build Coastguard Worker unsigned int ttype;
1562*2d543d20SAndroid Build Coastguard Worker struct ebitmap_node *node;
1563*2d543d20SAndroid Build Coastguard Worker uint32_t i;
1564*2d543d20SAndroid Build Coastguard Worker struct type_set *ts;
1565*2d543d20SAndroid Build Coastguard Worker
1566*2d543d20SAndroid Build Coastguard Worker if (!pdb->mls) {
1567*2d543d20SAndroid Build Coastguard Worker return 0;
1568*2d543d20SAndroid Build Coastguard Worker }
1569*2d543d20SAndroid Build Coastguard Worker
1570*2d543d20SAndroid Build Coastguard Worker for (rule = rules; rule != NULL; rule = rule->next) {
1571*2d543d20SAndroid Build Coastguard Worker ts = &rule->stypes;
1572*2d543d20SAndroid Build Coastguard Worker rc = process_typeset(pdb, ts, attr_list, &stypes, &num_stypes);
1573*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1574*2d543d20SAndroid Build Coastguard Worker goto exit;
1575*2d543d20SAndroid Build Coastguard Worker }
1576*2d543d20SAndroid Build Coastguard Worker
1577*2d543d20SAndroid Build Coastguard Worker ts = &rule->ttypes;
1578*2d543d20SAndroid Build Coastguard Worker rc = process_typeset(pdb, ts, attr_list, &ttypes, &num_ttypes);
1579*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1580*2d543d20SAndroid Build Coastguard Worker goto exit;
1581*2d543d20SAndroid Build Coastguard Worker }
1582*2d543d20SAndroid Build Coastguard Worker
1583*2d543d20SAndroid Build Coastguard Worker for (stype = 0; stype < num_stypes; stype++) {
1584*2d543d20SAndroid Build Coastguard Worker for (ttype = 0; ttype < num_ttypes; ttype++) {
1585*2d543d20SAndroid Build Coastguard Worker ebitmap_for_each_positive_bit(&rule->tclasses, node, i) {
1586*2d543d20SAndroid Build Coastguard Worker cil_indent(indent);
1587*2d543d20SAndroid Build Coastguard Worker cil_printf("(rangetransition %s %s %s ", stypes[stype], ttypes[ttype], pdb->p_class_val_to_name[i]);
1588*2d543d20SAndroid Build Coastguard Worker
1589*2d543d20SAndroid Build Coastguard Worker cil_printf("(");
1590*2d543d20SAndroid Build Coastguard Worker
1591*2d543d20SAndroid Build Coastguard Worker rc = semantic_level_to_cil(pdb, 1, &rule->trange.level[0]);
1592*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1593*2d543d20SAndroid Build Coastguard Worker goto exit;
1594*2d543d20SAndroid Build Coastguard Worker }
1595*2d543d20SAndroid Build Coastguard Worker
1596*2d543d20SAndroid Build Coastguard Worker cil_printf(" ");
1597*2d543d20SAndroid Build Coastguard Worker
1598*2d543d20SAndroid Build Coastguard Worker rc = semantic_level_to_cil(pdb, 1, &rule->trange.level[1]);
1599*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1600*2d543d20SAndroid Build Coastguard Worker goto exit;
1601*2d543d20SAndroid Build Coastguard Worker }
1602*2d543d20SAndroid Build Coastguard Worker
1603*2d543d20SAndroid Build Coastguard Worker cil_printf("))\n");
1604*2d543d20SAndroid Build Coastguard Worker }
1605*2d543d20SAndroid Build Coastguard Worker
1606*2d543d20SAndroid Build Coastguard Worker }
1607*2d543d20SAndroid Build Coastguard Worker }
1608*2d543d20SAndroid Build Coastguard Worker
1609*2d543d20SAndroid Build Coastguard Worker names_destroy(&stypes, &num_stypes);
1610*2d543d20SAndroid Build Coastguard Worker names_destroy(&ttypes, &num_ttypes);
1611*2d543d20SAndroid Build Coastguard Worker }
1612*2d543d20SAndroid Build Coastguard Worker
1613*2d543d20SAndroid Build Coastguard Worker rc = 0;
1614*2d543d20SAndroid Build Coastguard Worker
1615*2d543d20SAndroid Build Coastguard Worker exit:
1616*2d543d20SAndroid Build Coastguard Worker names_destroy(&stypes, &num_stypes);
1617*2d543d20SAndroid Build Coastguard Worker names_destroy(&ttypes, &num_ttypes);
1618*2d543d20SAndroid Build Coastguard Worker
1619*2d543d20SAndroid Build Coastguard Worker return rc;
1620*2d543d20SAndroid Build Coastguard Worker }
1621*2d543d20SAndroid Build Coastguard Worker
filename_trans_to_cil(int indent,struct policydb * pdb,struct filename_trans_rule * rules,struct list * attr_list)1622*2d543d20SAndroid Build Coastguard Worker static int filename_trans_to_cil(int indent, struct policydb *pdb, struct filename_trans_rule *rules, struct list *attr_list)
1623*2d543d20SAndroid Build Coastguard Worker {
1624*2d543d20SAndroid Build Coastguard Worker int rc = -1;
1625*2d543d20SAndroid Build Coastguard Worker char **stypes = NULL;
1626*2d543d20SAndroid Build Coastguard Worker unsigned int num_stypes = 0;
1627*2d543d20SAndroid Build Coastguard Worker unsigned int stype;
1628*2d543d20SAndroid Build Coastguard Worker char **ttypes = NULL;
1629*2d543d20SAndroid Build Coastguard Worker unsigned int num_ttypes = 0;
1630*2d543d20SAndroid Build Coastguard Worker unsigned int ttype;
1631*2d543d20SAndroid Build Coastguard Worker struct type_set *ts;
1632*2d543d20SAndroid Build Coastguard Worker struct filename_trans_rule *rule;
1633*2d543d20SAndroid Build Coastguard Worker
1634*2d543d20SAndroid Build Coastguard Worker for (rule = rules; rule != NULL; rule = rule->next) {
1635*2d543d20SAndroid Build Coastguard Worker ts = &rule->stypes;
1636*2d543d20SAndroid Build Coastguard Worker rc = process_typeset(pdb, ts, attr_list, &stypes, &num_stypes);
1637*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1638*2d543d20SAndroid Build Coastguard Worker goto exit;
1639*2d543d20SAndroid Build Coastguard Worker }
1640*2d543d20SAndroid Build Coastguard Worker
1641*2d543d20SAndroid Build Coastguard Worker ts = &rule->ttypes;
1642*2d543d20SAndroid Build Coastguard Worker rc = process_typeset(pdb, ts, attr_list, &ttypes, &num_ttypes);
1643*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1644*2d543d20SAndroid Build Coastguard Worker goto exit;
1645*2d543d20SAndroid Build Coastguard Worker }
1646*2d543d20SAndroid Build Coastguard Worker
1647*2d543d20SAndroid Build Coastguard Worker for (stype = 0; stype < num_stypes; stype++) {
1648*2d543d20SAndroid Build Coastguard Worker for (ttype = 0; ttype < num_ttypes; ttype++) {
1649*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(typetransition %s %s %s \"%s\" %s)",
1650*2d543d20SAndroid Build Coastguard Worker stypes[stype], ttypes[ttype],
1651*2d543d20SAndroid Build Coastguard Worker pdb->p_class_val_to_name[rule->tclass - 1],
1652*2d543d20SAndroid Build Coastguard Worker rule->name,
1653*2d543d20SAndroid Build Coastguard Worker pdb->p_type_val_to_name[rule->otype - 1]);
1654*2d543d20SAndroid Build Coastguard Worker }
1655*2d543d20SAndroid Build Coastguard Worker if (rule->flags & RULE_SELF) {
1656*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(typetransition %s self %s \"%s\" %s)",
1657*2d543d20SAndroid Build Coastguard Worker stypes[stype],
1658*2d543d20SAndroid Build Coastguard Worker pdb->p_class_val_to_name[rule->tclass - 1],
1659*2d543d20SAndroid Build Coastguard Worker rule->name,
1660*2d543d20SAndroid Build Coastguard Worker pdb->p_type_val_to_name[rule->otype - 1]);
1661*2d543d20SAndroid Build Coastguard Worker }
1662*2d543d20SAndroid Build Coastguard Worker }
1663*2d543d20SAndroid Build Coastguard Worker
1664*2d543d20SAndroid Build Coastguard Worker names_destroy(&stypes, &num_stypes);
1665*2d543d20SAndroid Build Coastguard Worker names_destroy(&ttypes, &num_ttypes);
1666*2d543d20SAndroid Build Coastguard Worker }
1667*2d543d20SAndroid Build Coastguard Worker
1668*2d543d20SAndroid Build Coastguard Worker rc = 0;
1669*2d543d20SAndroid Build Coastguard Worker exit:
1670*2d543d20SAndroid Build Coastguard Worker names_destroy(&stypes, &num_stypes);
1671*2d543d20SAndroid Build Coastguard Worker names_destroy(&ttypes, &num_ttypes);
1672*2d543d20SAndroid Build Coastguard Worker
1673*2d543d20SAndroid Build Coastguard Worker return rc;
1674*2d543d20SAndroid Build Coastguard Worker }
1675*2d543d20SAndroid Build Coastguard Worker
1676*2d543d20SAndroid Build Coastguard Worker struct class_perm_datum {
1677*2d543d20SAndroid Build Coastguard Worker char *name;
1678*2d543d20SAndroid Build Coastguard Worker uint32_t val;
1679*2d543d20SAndroid Build Coastguard Worker };
1680*2d543d20SAndroid Build Coastguard Worker
1681*2d543d20SAndroid Build Coastguard Worker struct class_perm_array {
1682*2d543d20SAndroid Build Coastguard Worker struct class_perm_datum *perms;
1683*2d543d20SAndroid Build Coastguard Worker uint32_t count;
1684*2d543d20SAndroid Build Coastguard Worker };
1685*2d543d20SAndroid Build Coastguard Worker
class_perm_to_array(char * key,void * data,void * args)1686*2d543d20SAndroid Build Coastguard Worker static int class_perm_to_array(char *key, void *data, void *args)
1687*2d543d20SAndroid Build Coastguard Worker {
1688*2d543d20SAndroid Build Coastguard Worker struct class_perm_array *arr = args;
1689*2d543d20SAndroid Build Coastguard Worker struct perm_datum *datum = data;
1690*2d543d20SAndroid Build Coastguard Worker arr->perms[arr->count].name = key;
1691*2d543d20SAndroid Build Coastguard Worker arr->perms[arr->count].val = datum->s.value;
1692*2d543d20SAndroid Build Coastguard Worker arr->count++;
1693*2d543d20SAndroid Build Coastguard Worker
1694*2d543d20SAndroid Build Coastguard Worker return 0;
1695*2d543d20SAndroid Build Coastguard Worker }
1696*2d543d20SAndroid Build Coastguard Worker
class_perm_cmp(const void * a,const void * b)1697*2d543d20SAndroid Build Coastguard Worker static int class_perm_cmp(const void *a, const void *b)
1698*2d543d20SAndroid Build Coastguard Worker {
1699*2d543d20SAndroid Build Coastguard Worker const struct class_perm_datum *aa = a;
1700*2d543d20SAndroid Build Coastguard Worker const struct class_perm_datum *bb = b;
1701*2d543d20SAndroid Build Coastguard Worker
1702*2d543d20SAndroid Build Coastguard Worker return spaceship_cmp(aa->val, bb->val);
1703*2d543d20SAndroid Build Coastguard Worker }
1704*2d543d20SAndroid Build Coastguard Worker
common_to_cil(char * key,void * data,void * UNUSED (arg))1705*2d543d20SAndroid Build Coastguard Worker static int common_to_cil(char *key, void *data, void *UNUSED(arg))
1706*2d543d20SAndroid Build Coastguard Worker {
1707*2d543d20SAndroid Build Coastguard Worker int rc = -1;
1708*2d543d20SAndroid Build Coastguard Worker struct common_datum *common = data;
1709*2d543d20SAndroid Build Coastguard Worker struct class_perm_array arr;
1710*2d543d20SAndroid Build Coastguard Worker uint32_t i;
1711*2d543d20SAndroid Build Coastguard Worker
1712*2d543d20SAndroid Build Coastguard Worker arr.count = 0;
1713*2d543d20SAndroid Build Coastguard Worker arr.perms = calloc(common->permissions.nprim, sizeof(*arr.perms));
1714*2d543d20SAndroid Build Coastguard Worker if (arr.perms == NULL) {
1715*2d543d20SAndroid Build Coastguard Worker goto exit;
1716*2d543d20SAndroid Build Coastguard Worker }
1717*2d543d20SAndroid Build Coastguard Worker rc = hashtab_map(common->permissions.table, class_perm_to_array, &arr);
1718*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1719*2d543d20SAndroid Build Coastguard Worker goto exit;
1720*2d543d20SAndroid Build Coastguard Worker }
1721*2d543d20SAndroid Build Coastguard Worker
1722*2d543d20SAndroid Build Coastguard Worker qsort(arr.perms, arr.count, sizeof(*arr.perms), class_perm_cmp);
1723*2d543d20SAndroid Build Coastguard Worker
1724*2d543d20SAndroid Build Coastguard Worker cil_printf("(common %s (", key);
1725*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < arr.count; i++) {
1726*2d543d20SAndroid Build Coastguard Worker cil_printf("%s ", arr.perms[i].name);
1727*2d543d20SAndroid Build Coastguard Worker }
1728*2d543d20SAndroid Build Coastguard Worker cil_printf("))\n");
1729*2d543d20SAndroid Build Coastguard Worker
1730*2d543d20SAndroid Build Coastguard Worker rc = 0;
1731*2d543d20SAndroid Build Coastguard Worker
1732*2d543d20SAndroid Build Coastguard Worker exit:
1733*2d543d20SAndroid Build Coastguard Worker free(arr.perms);
1734*2d543d20SAndroid Build Coastguard Worker return rc;
1735*2d543d20SAndroid Build Coastguard Worker }
1736*2d543d20SAndroid Build Coastguard Worker
1737*2d543d20SAndroid Build Coastguard Worker
constraint_expr_to_string(struct policydb * pdb,struct constraint_expr * exprs,char ** expr_string)1738*2d543d20SAndroid Build Coastguard Worker static int constraint_expr_to_string(struct policydb *pdb, struct constraint_expr *exprs, char **expr_string)
1739*2d543d20SAndroid Build Coastguard Worker {
1740*2d543d20SAndroid Build Coastguard Worker int rc = -1;
1741*2d543d20SAndroid Build Coastguard Worker struct constraint_expr *expr;
1742*2d543d20SAndroid Build Coastguard Worker struct stack *stack = NULL;
1743*2d543d20SAndroid Build Coastguard Worker int len = 0;
1744*2d543d20SAndroid Build Coastguard Worker int rlen;
1745*2d543d20SAndroid Build Coastguard Worker char *new_val = NULL;
1746*2d543d20SAndroid Build Coastguard Worker char *val1 = NULL;
1747*2d543d20SAndroid Build Coastguard Worker char *val2 = NULL;
1748*2d543d20SAndroid Build Coastguard Worker uint32_t num_params;
1749*2d543d20SAndroid Build Coastguard Worker const char *op;
1750*2d543d20SAndroid Build Coastguard Worker const char *sep;
1751*2d543d20SAndroid Build Coastguard Worker const char *attr1;
1752*2d543d20SAndroid Build Coastguard Worker const char *attr2;
1753*2d543d20SAndroid Build Coastguard Worker char *names = NULL;
1754*2d543d20SAndroid Build Coastguard Worker char **name_list = NULL;
1755*2d543d20SAndroid Build Coastguard Worker unsigned int num_names = 0;
1756*2d543d20SAndroid Build Coastguard Worker struct type_set *ts;
1757*2d543d20SAndroid Build Coastguard Worker
1758*2d543d20SAndroid Build Coastguard Worker rc = stack_init(&stack);
1759*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1760*2d543d20SAndroid Build Coastguard Worker goto exit;
1761*2d543d20SAndroid Build Coastguard Worker }
1762*2d543d20SAndroid Build Coastguard Worker
1763*2d543d20SAndroid Build Coastguard Worker for (expr = exprs; expr != NULL; expr = expr->next) {
1764*2d543d20SAndroid Build Coastguard Worker if (expr->expr_type == CEXPR_ATTR || expr->expr_type == CEXPR_NAMES) {
1765*2d543d20SAndroid Build Coastguard Worker switch (expr->op) {
1766*2d543d20SAndroid Build Coastguard Worker case CEXPR_EQ: op = "eq"; break;
1767*2d543d20SAndroid Build Coastguard Worker case CEXPR_NEQ: op = "neq"; break;
1768*2d543d20SAndroid Build Coastguard Worker case CEXPR_DOM: op = "dom"; break;
1769*2d543d20SAndroid Build Coastguard Worker case CEXPR_DOMBY: op = "domby"; break;
1770*2d543d20SAndroid Build Coastguard Worker case CEXPR_INCOMP: op = "incomp"; break;
1771*2d543d20SAndroid Build Coastguard Worker default:
1772*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Unknown constraint operator type: %i", expr->op);
1773*2d543d20SAndroid Build Coastguard Worker rc = -1;
1774*2d543d20SAndroid Build Coastguard Worker goto exit;
1775*2d543d20SAndroid Build Coastguard Worker }
1776*2d543d20SAndroid Build Coastguard Worker
1777*2d543d20SAndroid Build Coastguard Worker switch (expr->attr) {
1778*2d543d20SAndroid Build Coastguard Worker case CEXPR_USER: attr1 = "u1"; attr2 = "u2"; break;
1779*2d543d20SAndroid Build Coastguard Worker case CEXPR_USER | CEXPR_TARGET: attr1 = "u2"; attr2 = ""; break;
1780*2d543d20SAndroid Build Coastguard Worker case CEXPR_USER | CEXPR_XTARGET: attr1 = "u3"; attr2 = ""; break;
1781*2d543d20SAndroid Build Coastguard Worker case CEXPR_ROLE: attr1 = "r1"; attr2 = "r2"; break;
1782*2d543d20SAndroid Build Coastguard Worker case CEXPR_ROLE | CEXPR_TARGET: attr1 = "r2"; attr2 = ""; break;
1783*2d543d20SAndroid Build Coastguard Worker case CEXPR_ROLE | CEXPR_XTARGET: attr1 = "r3"; attr2 = ""; break;
1784*2d543d20SAndroid Build Coastguard Worker case CEXPR_TYPE: attr1 = "t1"; attr2 = "t2"; break;
1785*2d543d20SAndroid Build Coastguard Worker case CEXPR_TYPE | CEXPR_TARGET: attr1 = "t2"; attr2 = ""; break;
1786*2d543d20SAndroid Build Coastguard Worker case CEXPR_TYPE | CEXPR_XTARGET: attr1 = "t3"; attr2 = ""; break;
1787*2d543d20SAndroid Build Coastguard Worker case CEXPR_L1L2: attr1 = "l1"; attr2 = "l2"; break;
1788*2d543d20SAndroid Build Coastguard Worker case CEXPR_L1H2: attr1 = "l1"; attr2 = "h2"; break;
1789*2d543d20SAndroid Build Coastguard Worker case CEXPR_H1L2: attr1 = "h1"; attr2 = "l2"; break;
1790*2d543d20SAndroid Build Coastguard Worker case CEXPR_H1H2: attr1 = "h1"; attr2 = "h2"; break;
1791*2d543d20SAndroid Build Coastguard Worker case CEXPR_L1H1: attr1 = "l1"; attr2 = "h1"; break;
1792*2d543d20SAndroid Build Coastguard Worker case CEXPR_L2H2: attr1 = "l2"; attr2 = "h2"; break;
1793*2d543d20SAndroid Build Coastguard Worker default:
1794*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Unknown expression attribute type: %i", expr->attr);
1795*2d543d20SAndroid Build Coastguard Worker rc = -1;
1796*2d543d20SAndroid Build Coastguard Worker goto exit;
1797*2d543d20SAndroid Build Coastguard Worker }
1798*2d543d20SAndroid Build Coastguard Worker
1799*2d543d20SAndroid Build Coastguard Worker if (expr->expr_type == CEXPR_ATTR) {
1800*2d543d20SAndroid Build Coastguard Worker // length of values/attrs + 2 separating spaces + 2 parens + null terminator
1801*2d543d20SAndroid Build Coastguard Worker len = strlen(op) + strlen(attr1) + strlen(attr2) + 2 + 2 + 1;
1802*2d543d20SAndroid Build Coastguard Worker new_val = malloc(len);
1803*2d543d20SAndroid Build Coastguard Worker if (new_val == NULL) {
1804*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Out of memory");
1805*2d543d20SAndroid Build Coastguard Worker rc = -1;
1806*2d543d20SAndroid Build Coastguard Worker goto exit;
1807*2d543d20SAndroid Build Coastguard Worker }
1808*2d543d20SAndroid Build Coastguard Worker rlen = snprintf(new_val, len, "(%s %s %s)", op, attr1, attr2);
1809*2d543d20SAndroid Build Coastguard Worker if (rlen < 0 || rlen >= len) {
1810*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Failed to generate constraint expression");
1811*2d543d20SAndroid Build Coastguard Worker rc = -1;
1812*2d543d20SAndroid Build Coastguard Worker goto exit;
1813*2d543d20SAndroid Build Coastguard Worker }
1814*2d543d20SAndroid Build Coastguard Worker } else {
1815*2d543d20SAndroid Build Coastguard Worker if (expr->attr & CEXPR_TYPE) {
1816*2d543d20SAndroid Build Coastguard Worker ts = expr->type_names;
1817*2d543d20SAndroid Build Coastguard Worker rc = ebitmap_to_names(&ts->types, pdb->p_type_val_to_name, &name_list, &num_names);
1818*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1819*2d543d20SAndroid Build Coastguard Worker goto exit;
1820*2d543d20SAndroid Build Coastguard Worker }
1821*2d543d20SAndroid Build Coastguard Worker } else if (expr->attr & CEXPR_USER) {
1822*2d543d20SAndroid Build Coastguard Worker rc = ebitmap_to_names(&expr->names, pdb->p_user_val_to_name, &name_list, &num_names);
1823*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1824*2d543d20SAndroid Build Coastguard Worker goto exit;
1825*2d543d20SAndroid Build Coastguard Worker }
1826*2d543d20SAndroid Build Coastguard Worker } else if (expr->attr & CEXPR_ROLE) {
1827*2d543d20SAndroid Build Coastguard Worker rc = ebitmap_to_names(&expr->names, pdb->p_role_val_to_name, &name_list, &num_names);
1828*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1829*2d543d20SAndroid Build Coastguard Worker goto exit;
1830*2d543d20SAndroid Build Coastguard Worker }
1831*2d543d20SAndroid Build Coastguard Worker }
1832*2d543d20SAndroid Build Coastguard Worker if (num_names == 0) {
1833*2d543d20SAndroid Build Coastguard Worker names = strdup("NO_IDENTIFIER");
1834*2d543d20SAndroid Build Coastguard Worker if (!names) {
1835*2d543d20SAndroid Build Coastguard Worker rc = -1;
1836*2d543d20SAndroid Build Coastguard Worker goto exit;
1837*2d543d20SAndroid Build Coastguard Worker }
1838*2d543d20SAndroid Build Coastguard Worker } else {
1839*2d543d20SAndroid Build Coastguard Worker rc = name_list_to_string(name_list, num_names, &names);
1840*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1841*2d543d20SAndroid Build Coastguard Worker goto exit;
1842*2d543d20SAndroid Build Coastguard Worker }
1843*2d543d20SAndroid Build Coastguard Worker }
1844*2d543d20SAndroid Build Coastguard Worker
1845*2d543d20SAndroid Build Coastguard Worker // length of values/oper + 2 spaces + 2 parens + null terminator
1846*2d543d20SAndroid Build Coastguard Worker len = strlen(op) + strlen(attr1) + strlen(names) + 2 + 2 + 1;
1847*2d543d20SAndroid Build Coastguard Worker if (num_names > 1) {
1848*2d543d20SAndroid Build Coastguard Worker len += 2; // 2 more parens
1849*2d543d20SAndroid Build Coastguard Worker }
1850*2d543d20SAndroid Build Coastguard Worker new_val = malloc(len);
1851*2d543d20SAndroid Build Coastguard Worker if (new_val == NULL) {
1852*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Out of memory");
1853*2d543d20SAndroid Build Coastguard Worker rc = -1;
1854*2d543d20SAndroid Build Coastguard Worker goto exit;
1855*2d543d20SAndroid Build Coastguard Worker }
1856*2d543d20SAndroid Build Coastguard Worker if (num_names > 1) {
1857*2d543d20SAndroid Build Coastguard Worker rlen = snprintf(new_val, len, "(%s %s (%s))", op, attr1, names);
1858*2d543d20SAndroid Build Coastguard Worker } else {
1859*2d543d20SAndroid Build Coastguard Worker rlen = snprintf(new_val, len, "(%s %s %s)", op, attr1, names);
1860*2d543d20SAndroid Build Coastguard Worker }
1861*2d543d20SAndroid Build Coastguard Worker if (rlen < 0 || rlen >= len) {
1862*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Failed to generate constraint expression");
1863*2d543d20SAndroid Build Coastguard Worker rc = -1;
1864*2d543d20SAndroid Build Coastguard Worker goto exit;
1865*2d543d20SAndroid Build Coastguard Worker }
1866*2d543d20SAndroid Build Coastguard Worker
1867*2d543d20SAndroid Build Coastguard Worker names_destroy(&name_list, &num_names);
1868*2d543d20SAndroid Build Coastguard Worker free(names);
1869*2d543d20SAndroid Build Coastguard Worker names = NULL;
1870*2d543d20SAndroid Build Coastguard Worker }
1871*2d543d20SAndroid Build Coastguard Worker } else {
1872*2d543d20SAndroid Build Coastguard Worker switch (expr->expr_type) {
1873*2d543d20SAndroid Build Coastguard Worker case CEXPR_NOT: op = "not"; break;
1874*2d543d20SAndroid Build Coastguard Worker case CEXPR_AND: op = "and"; break;
1875*2d543d20SAndroid Build Coastguard Worker case CEXPR_OR: op = "or"; break;
1876*2d543d20SAndroid Build Coastguard Worker default:
1877*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Unknown constraint expression type: %i", expr->expr_type);
1878*2d543d20SAndroid Build Coastguard Worker rc = -1;
1879*2d543d20SAndroid Build Coastguard Worker goto exit;
1880*2d543d20SAndroid Build Coastguard Worker }
1881*2d543d20SAndroid Build Coastguard Worker
1882*2d543d20SAndroid Build Coastguard Worker num_params = expr->expr_type == CEXPR_NOT ? 1 : 2;
1883*2d543d20SAndroid Build Coastguard Worker
1884*2d543d20SAndroid Build Coastguard Worker if (num_params == 1) {
1885*2d543d20SAndroid Build Coastguard Worker val1 = stack_pop(stack);
1886*2d543d20SAndroid Build Coastguard Worker val2 = strdup("");
1887*2d543d20SAndroid Build Coastguard Worker if (val2 == NULL) {
1888*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Out of memory");
1889*2d543d20SAndroid Build Coastguard Worker rc = -1;
1890*2d543d20SAndroid Build Coastguard Worker goto exit;
1891*2d543d20SAndroid Build Coastguard Worker }
1892*2d543d20SAndroid Build Coastguard Worker sep = "";
1893*2d543d20SAndroid Build Coastguard Worker } else {
1894*2d543d20SAndroid Build Coastguard Worker val2 = stack_pop(stack);
1895*2d543d20SAndroid Build Coastguard Worker val1 = stack_pop(stack);
1896*2d543d20SAndroid Build Coastguard Worker sep = " ";
1897*2d543d20SAndroid Build Coastguard Worker }
1898*2d543d20SAndroid Build Coastguard Worker
1899*2d543d20SAndroid Build Coastguard Worker if (val1 == NULL || val2 == NULL) {
1900*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Invalid constraint expression");
1901*2d543d20SAndroid Build Coastguard Worker rc = -1;
1902*2d543d20SAndroid Build Coastguard Worker goto exit;
1903*2d543d20SAndroid Build Coastguard Worker }
1904*2d543d20SAndroid Build Coastguard Worker
1905*2d543d20SAndroid Build Coastguard Worker // length = length of parameters +
1906*2d543d20SAndroid Build Coastguard Worker // length of operator +
1907*2d543d20SAndroid Build Coastguard Worker // 1 space preceding each parameter +
1908*2d543d20SAndroid Build Coastguard Worker // 2 parens around the whole expression
1909*2d543d20SAndroid Build Coastguard Worker // + null terminator
1910*2d543d20SAndroid Build Coastguard Worker len = strlen(val1) + strlen(val2) + strlen(op) + (num_params * 1) + 2 + 1;
1911*2d543d20SAndroid Build Coastguard Worker new_val = malloc(len);
1912*2d543d20SAndroid Build Coastguard Worker if (new_val == NULL) {
1913*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Out of memory");
1914*2d543d20SAndroid Build Coastguard Worker rc = -1;
1915*2d543d20SAndroid Build Coastguard Worker goto exit;
1916*2d543d20SAndroid Build Coastguard Worker }
1917*2d543d20SAndroid Build Coastguard Worker
1918*2d543d20SAndroid Build Coastguard Worker rlen = snprintf(new_val, len, "(%s %s%s%s)", op, val1, sep, val2);
1919*2d543d20SAndroid Build Coastguard Worker if (rlen < 0 || rlen >= len) {
1920*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Failed to generate constraint expression");
1921*2d543d20SAndroid Build Coastguard Worker rc = -1;
1922*2d543d20SAndroid Build Coastguard Worker goto exit;
1923*2d543d20SAndroid Build Coastguard Worker }
1924*2d543d20SAndroid Build Coastguard Worker
1925*2d543d20SAndroid Build Coastguard Worker free(val1);
1926*2d543d20SAndroid Build Coastguard Worker free(val2);
1927*2d543d20SAndroid Build Coastguard Worker val1 = NULL;
1928*2d543d20SAndroid Build Coastguard Worker val2 = NULL;
1929*2d543d20SAndroid Build Coastguard Worker }
1930*2d543d20SAndroid Build Coastguard Worker
1931*2d543d20SAndroid Build Coastguard Worker rc = stack_push(stack, new_val);
1932*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1933*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Out of memory");
1934*2d543d20SAndroid Build Coastguard Worker goto exit;
1935*2d543d20SAndroid Build Coastguard Worker }
1936*2d543d20SAndroid Build Coastguard Worker
1937*2d543d20SAndroid Build Coastguard Worker new_val = NULL;
1938*2d543d20SAndroid Build Coastguard Worker }
1939*2d543d20SAndroid Build Coastguard Worker
1940*2d543d20SAndroid Build Coastguard Worker new_val = stack_pop(stack);
1941*2d543d20SAndroid Build Coastguard Worker if (new_val == NULL || stack_peek(stack) != NULL) {
1942*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Invalid constraint expression");
1943*2d543d20SAndroid Build Coastguard Worker rc = -1;
1944*2d543d20SAndroid Build Coastguard Worker goto exit;
1945*2d543d20SAndroid Build Coastguard Worker }
1946*2d543d20SAndroid Build Coastguard Worker
1947*2d543d20SAndroid Build Coastguard Worker *expr_string = new_val;
1948*2d543d20SAndroid Build Coastguard Worker new_val = NULL;
1949*2d543d20SAndroid Build Coastguard Worker
1950*2d543d20SAndroid Build Coastguard Worker rc = 0;
1951*2d543d20SAndroid Build Coastguard Worker
1952*2d543d20SAndroid Build Coastguard Worker exit:
1953*2d543d20SAndroid Build Coastguard Worker names_destroy(&name_list, &num_names);
1954*2d543d20SAndroid Build Coastguard Worker free(names);
1955*2d543d20SAndroid Build Coastguard Worker
1956*2d543d20SAndroid Build Coastguard Worker free(new_val);
1957*2d543d20SAndroid Build Coastguard Worker free(val1);
1958*2d543d20SAndroid Build Coastguard Worker free(val2);
1959*2d543d20SAndroid Build Coastguard Worker if (stack != NULL) {
1960*2d543d20SAndroid Build Coastguard Worker while ((val1 = stack_pop(stack)) != NULL) {
1961*2d543d20SAndroid Build Coastguard Worker free(val1);
1962*2d543d20SAndroid Build Coastguard Worker }
1963*2d543d20SAndroid Build Coastguard Worker stack_destroy(&stack);
1964*2d543d20SAndroid Build Coastguard Worker }
1965*2d543d20SAndroid Build Coastguard Worker
1966*2d543d20SAndroid Build Coastguard Worker return rc;
1967*2d543d20SAndroid Build Coastguard Worker }
1968*2d543d20SAndroid Build Coastguard Worker
1969*2d543d20SAndroid Build Coastguard Worker
constraints_to_cil(int indent,struct policydb * pdb,char * classkey,struct class_datum * class,struct constraint_node * constraints,int is_constraint)1970*2d543d20SAndroid Build Coastguard Worker static int constraints_to_cil(int indent, struct policydb *pdb, char *classkey, struct class_datum *class, struct constraint_node *constraints, int is_constraint)
1971*2d543d20SAndroid Build Coastguard Worker {
1972*2d543d20SAndroid Build Coastguard Worker int rc = -1;
1973*2d543d20SAndroid Build Coastguard Worker struct constraint_node *node;
1974*2d543d20SAndroid Build Coastguard Worker char *expr = NULL;
1975*2d543d20SAndroid Build Coastguard Worker const char *mls;
1976*2d543d20SAndroid Build Coastguard Worker char *perms;
1977*2d543d20SAndroid Build Coastguard Worker
1978*2d543d20SAndroid Build Coastguard Worker mls = pdb->mls ? "mls" : "";
1979*2d543d20SAndroid Build Coastguard Worker
1980*2d543d20SAndroid Build Coastguard Worker for (node = constraints; node != NULL; node = node->next) {
1981*2d543d20SAndroid Build Coastguard Worker
1982*2d543d20SAndroid Build Coastguard Worker rc = constraint_expr_to_string(pdb, node->expr, &expr);
1983*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
1984*2d543d20SAndroid Build Coastguard Worker goto exit;
1985*2d543d20SAndroid Build Coastguard Worker }
1986*2d543d20SAndroid Build Coastguard Worker
1987*2d543d20SAndroid Build Coastguard Worker if (is_constraint) {
1988*2d543d20SAndroid Build Coastguard Worker perms = sepol_av_to_string(pdb, class->s.value, node->permissions);
1989*2d543d20SAndroid Build Coastguard Worker if (perms == NULL) {
1990*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Failed to generate permission string");
1991*2d543d20SAndroid Build Coastguard Worker rc = -1;
1992*2d543d20SAndroid Build Coastguard Worker goto exit;
1993*2d543d20SAndroid Build Coastguard Worker }
1994*2d543d20SAndroid Build Coastguard Worker if (*perms == '\0') {
1995*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "No permissions in permission string");
1996*2d543d20SAndroid Build Coastguard Worker free(perms);
1997*2d543d20SAndroid Build Coastguard Worker rc = -1;
1998*2d543d20SAndroid Build Coastguard Worker goto exit;
1999*2d543d20SAndroid Build Coastguard Worker }
2000*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(%sconstrain (%s (%s)) %s)", mls, classkey, perms + 1, expr);
2001*2d543d20SAndroid Build Coastguard Worker free(perms);
2002*2d543d20SAndroid Build Coastguard Worker } else {
2003*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(%svalidatetrans %s %s)", mls, classkey, expr);
2004*2d543d20SAndroid Build Coastguard Worker }
2005*2d543d20SAndroid Build Coastguard Worker
2006*2d543d20SAndroid Build Coastguard Worker free(expr);
2007*2d543d20SAndroid Build Coastguard Worker expr = NULL;
2008*2d543d20SAndroid Build Coastguard Worker }
2009*2d543d20SAndroid Build Coastguard Worker
2010*2d543d20SAndroid Build Coastguard Worker rc = 0;
2011*2d543d20SAndroid Build Coastguard Worker
2012*2d543d20SAndroid Build Coastguard Worker exit:
2013*2d543d20SAndroid Build Coastguard Worker free(expr);
2014*2d543d20SAndroid Build Coastguard Worker return rc;
2015*2d543d20SAndroid Build Coastguard Worker }
2016*2d543d20SAndroid Build Coastguard Worker
class_to_cil(int indent,struct policydb * pdb,struct avrule_block * UNUSED (block),struct stack * UNUSED (decl_stack),char * key,void * datum,int scope)2017*2d543d20SAndroid Build Coastguard Worker static int class_to_cil(int indent, struct policydb *pdb, struct avrule_block *UNUSED(block), struct stack *UNUSED(decl_stack), char *key, void *datum, int scope)
2018*2d543d20SAndroid Build Coastguard Worker {
2019*2d543d20SAndroid Build Coastguard Worker int rc = -1;
2020*2d543d20SAndroid Build Coastguard Worker struct class_datum *class = datum;
2021*2d543d20SAndroid Build Coastguard Worker const char *dflt;
2022*2d543d20SAndroid Build Coastguard Worker struct class_perm_array arr;
2023*2d543d20SAndroid Build Coastguard Worker uint32_t i;
2024*2d543d20SAndroid Build Coastguard Worker
2025*2d543d20SAndroid Build Coastguard Worker if (scope == SCOPE_REQ) {
2026*2d543d20SAndroid Build Coastguard Worker return 0;
2027*2d543d20SAndroid Build Coastguard Worker }
2028*2d543d20SAndroid Build Coastguard Worker
2029*2d543d20SAndroid Build Coastguard Worker arr.count = 0;
2030*2d543d20SAndroid Build Coastguard Worker arr.perms = calloc(class->permissions.nprim, sizeof(*arr.perms));
2031*2d543d20SAndroid Build Coastguard Worker if (arr.perms == NULL) {
2032*2d543d20SAndroid Build Coastguard Worker goto exit;
2033*2d543d20SAndroid Build Coastguard Worker }
2034*2d543d20SAndroid Build Coastguard Worker rc = hashtab_map(class->permissions.table, class_perm_to_array, &arr);
2035*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
2036*2d543d20SAndroid Build Coastguard Worker goto exit;
2037*2d543d20SAndroid Build Coastguard Worker }
2038*2d543d20SAndroid Build Coastguard Worker
2039*2d543d20SAndroid Build Coastguard Worker qsort(arr.perms, arr.count, sizeof(*arr.perms), class_perm_cmp);
2040*2d543d20SAndroid Build Coastguard Worker
2041*2d543d20SAndroid Build Coastguard Worker cil_indent(indent);
2042*2d543d20SAndroid Build Coastguard Worker cil_printf("(class %s (", key);
2043*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < arr.count; i++) {
2044*2d543d20SAndroid Build Coastguard Worker cil_printf("%s ", arr.perms[i].name);
2045*2d543d20SAndroid Build Coastguard Worker }
2046*2d543d20SAndroid Build Coastguard Worker cil_printf("))\n");
2047*2d543d20SAndroid Build Coastguard Worker
2048*2d543d20SAndroid Build Coastguard Worker if (class->comkey != NULL) {
2049*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(classcommon %s %s)", key, class->comkey);
2050*2d543d20SAndroid Build Coastguard Worker }
2051*2d543d20SAndroid Build Coastguard Worker
2052*2d543d20SAndroid Build Coastguard Worker if (class->default_user != 0) {
2053*2d543d20SAndroid Build Coastguard Worker switch (class->default_user) {
2054*2d543d20SAndroid Build Coastguard Worker case DEFAULT_SOURCE: dflt = "source"; break;
2055*2d543d20SAndroid Build Coastguard Worker case DEFAULT_TARGET: dflt = "target"; break;
2056*2d543d20SAndroid Build Coastguard Worker default:
2057*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Unknown default user value: %i", class->default_user);
2058*2d543d20SAndroid Build Coastguard Worker rc = -1;
2059*2d543d20SAndroid Build Coastguard Worker goto exit;
2060*2d543d20SAndroid Build Coastguard Worker }
2061*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(defaultuser %s %s)", key, dflt);
2062*2d543d20SAndroid Build Coastguard Worker }
2063*2d543d20SAndroid Build Coastguard Worker
2064*2d543d20SAndroid Build Coastguard Worker if (class->default_role != 0) {
2065*2d543d20SAndroid Build Coastguard Worker switch (class->default_role) {
2066*2d543d20SAndroid Build Coastguard Worker case DEFAULT_SOURCE: dflt = "source"; break;
2067*2d543d20SAndroid Build Coastguard Worker case DEFAULT_TARGET: dflt = "target"; break;
2068*2d543d20SAndroid Build Coastguard Worker default:
2069*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Unknown default role value: %i", class->default_role);
2070*2d543d20SAndroid Build Coastguard Worker rc = -1;
2071*2d543d20SAndroid Build Coastguard Worker goto exit;
2072*2d543d20SAndroid Build Coastguard Worker }
2073*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(defaultrole %s %s)", key, dflt);
2074*2d543d20SAndroid Build Coastguard Worker }
2075*2d543d20SAndroid Build Coastguard Worker
2076*2d543d20SAndroid Build Coastguard Worker if (class->default_type != 0) {
2077*2d543d20SAndroid Build Coastguard Worker switch (class->default_type) {
2078*2d543d20SAndroid Build Coastguard Worker case DEFAULT_SOURCE: dflt = "source"; break;
2079*2d543d20SAndroid Build Coastguard Worker case DEFAULT_TARGET: dflt = "target"; break;
2080*2d543d20SAndroid Build Coastguard Worker default:
2081*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Unknown default type value: %i", class->default_type);
2082*2d543d20SAndroid Build Coastguard Worker rc = -1;
2083*2d543d20SAndroid Build Coastguard Worker goto exit;
2084*2d543d20SAndroid Build Coastguard Worker }
2085*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(defaulttype %s %s)", key, dflt);
2086*2d543d20SAndroid Build Coastguard Worker }
2087*2d543d20SAndroid Build Coastguard Worker
2088*2d543d20SAndroid Build Coastguard Worker if (class->default_range != 0) {
2089*2d543d20SAndroid Build Coastguard Worker switch (class->default_range) {
2090*2d543d20SAndroid Build Coastguard Worker case DEFAULT_SOURCE_LOW: dflt = "source low"; break;
2091*2d543d20SAndroid Build Coastguard Worker case DEFAULT_SOURCE_HIGH: dflt = "source high"; break;
2092*2d543d20SAndroid Build Coastguard Worker case DEFAULT_SOURCE_LOW_HIGH: dflt = "source low-high"; break;
2093*2d543d20SAndroid Build Coastguard Worker case DEFAULT_TARGET_LOW: dflt = "target low"; break;
2094*2d543d20SAndroid Build Coastguard Worker case DEFAULT_TARGET_HIGH: dflt = "target high"; break;
2095*2d543d20SAndroid Build Coastguard Worker case DEFAULT_TARGET_LOW_HIGH: dflt = "target low-high"; break;
2096*2d543d20SAndroid Build Coastguard Worker case DEFAULT_GLBLUB: dflt = "glblub"; break;
2097*2d543d20SAndroid Build Coastguard Worker default:
2098*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Unknown default range value: %i", class->default_range);
2099*2d543d20SAndroid Build Coastguard Worker rc = -1;
2100*2d543d20SAndroid Build Coastguard Worker goto exit;
2101*2d543d20SAndroid Build Coastguard Worker }
2102*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(defaultrange %s %s)", key, dflt);
2103*2d543d20SAndroid Build Coastguard Worker
2104*2d543d20SAndroid Build Coastguard Worker }
2105*2d543d20SAndroid Build Coastguard Worker
2106*2d543d20SAndroid Build Coastguard Worker if (class->constraints != NULL) {
2107*2d543d20SAndroid Build Coastguard Worker rc = constraints_to_cil(indent, pdb, key, class, class->constraints, 1);
2108*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
2109*2d543d20SAndroid Build Coastguard Worker goto exit;
2110*2d543d20SAndroid Build Coastguard Worker }
2111*2d543d20SAndroid Build Coastguard Worker }
2112*2d543d20SAndroid Build Coastguard Worker
2113*2d543d20SAndroid Build Coastguard Worker if (class->validatetrans != NULL) {
2114*2d543d20SAndroid Build Coastguard Worker rc = constraints_to_cil(indent, pdb, key, class, class->validatetrans, 0);
2115*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
2116*2d543d20SAndroid Build Coastguard Worker goto exit;
2117*2d543d20SAndroid Build Coastguard Worker }
2118*2d543d20SAndroid Build Coastguard Worker }
2119*2d543d20SAndroid Build Coastguard Worker
2120*2d543d20SAndroid Build Coastguard Worker rc = 0;
2121*2d543d20SAndroid Build Coastguard Worker
2122*2d543d20SAndroid Build Coastguard Worker exit:
2123*2d543d20SAndroid Build Coastguard Worker free(arr.perms);
2124*2d543d20SAndroid Build Coastguard Worker return rc;
2125*2d543d20SAndroid Build Coastguard Worker }
2126*2d543d20SAndroid Build Coastguard Worker
class_order_to_cil(int indent,struct policydb * pdb,struct ebitmap order)2127*2d543d20SAndroid Build Coastguard Worker static int class_order_to_cil(int indent, struct policydb *pdb, struct ebitmap order)
2128*2d543d20SAndroid Build Coastguard Worker {
2129*2d543d20SAndroid Build Coastguard Worker struct ebitmap_node *node;
2130*2d543d20SAndroid Build Coastguard Worker uint32_t i;
2131*2d543d20SAndroid Build Coastguard Worker
2132*2d543d20SAndroid Build Coastguard Worker if (ebitmap_is_empty(&order)) {
2133*2d543d20SAndroid Build Coastguard Worker return 0;
2134*2d543d20SAndroid Build Coastguard Worker }
2135*2d543d20SAndroid Build Coastguard Worker
2136*2d543d20SAndroid Build Coastguard Worker cil_indent(indent);
2137*2d543d20SAndroid Build Coastguard Worker cil_printf("(classorder (");
2138*2d543d20SAndroid Build Coastguard Worker
2139*2d543d20SAndroid Build Coastguard Worker ebitmap_for_each_positive_bit(&order, node, i) {
2140*2d543d20SAndroid Build Coastguard Worker cil_printf("%s ", pdb->sym_val_to_name[SYM_CLASSES][i]);
2141*2d543d20SAndroid Build Coastguard Worker }
2142*2d543d20SAndroid Build Coastguard Worker
2143*2d543d20SAndroid Build Coastguard Worker cil_printf("))\n");
2144*2d543d20SAndroid Build Coastguard Worker
2145*2d543d20SAndroid Build Coastguard Worker return 0;
2146*2d543d20SAndroid Build Coastguard Worker }
2147*2d543d20SAndroid Build Coastguard Worker
role_to_cil(int indent,struct policydb * pdb,struct avrule_block * UNUSED (block),struct stack * decl_stack,char * key,void * datum,int scope)2148*2d543d20SAndroid Build Coastguard Worker static int role_to_cil(int indent, struct policydb *pdb, struct avrule_block *UNUSED(block), struct stack *decl_stack, char *key, void *datum, int scope)
2149*2d543d20SAndroid Build Coastguard Worker {
2150*2d543d20SAndroid Build Coastguard Worker int rc = -1;
2151*2d543d20SAndroid Build Coastguard Worker struct ebitmap_node *node;
2152*2d543d20SAndroid Build Coastguard Worker uint32_t i;
2153*2d543d20SAndroid Build Coastguard Worker unsigned int j;
2154*2d543d20SAndroid Build Coastguard Worker char **types = NULL;
2155*2d543d20SAndroid Build Coastguard Worker unsigned int num_types = 0;
2156*2d543d20SAndroid Build Coastguard Worker struct role_datum *role = datum;
2157*2d543d20SAndroid Build Coastguard Worker struct type_set *ts;
2158*2d543d20SAndroid Build Coastguard Worker struct list *attr_list = NULL;
2159*2d543d20SAndroid Build Coastguard Worker
2160*2d543d20SAndroid Build Coastguard Worker rc = list_init(&attr_list);
2161*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
2162*2d543d20SAndroid Build Coastguard Worker goto exit;
2163*2d543d20SAndroid Build Coastguard Worker }
2164*2d543d20SAndroid Build Coastguard Worker
2165*2d543d20SAndroid Build Coastguard Worker if (scope == SCOPE_REQ) {
2166*2d543d20SAndroid Build Coastguard Worker // if a role/roleattr is in the REQ scope, then it could cause an
2167*2d543d20SAndroid Build Coastguard Worker // optional block to fail, even if it is never used. However in CIL,
2168*2d543d20SAndroid Build Coastguard Worker // symbols must be used in order to cause an optional block to fail. So
2169*2d543d20SAndroid Build Coastguard Worker // for symbols in the REQ scope, add them to a roleattribute as a way
2170*2d543d20SAndroid Build Coastguard Worker // to 'use' them in the optional without affecting the resulting policy.
2171*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(roleattributeset " GEN_REQUIRE_ATTR " %s)", key);
2172*2d543d20SAndroid Build Coastguard Worker }
2173*2d543d20SAndroid Build Coastguard Worker
2174*2d543d20SAndroid Build Coastguard Worker switch (role->flavor) {
2175*2d543d20SAndroid Build Coastguard Worker case ROLE_ROLE:
2176*2d543d20SAndroid Build Coastguard Worker if (scope == SCOPE_DECL) {
2177*2d543d20SAndroid Build Coastguard Worker // Only declare certain roles if we are reading a base module.
2178*2d543d20SAndroid Build Coastguard Worker // These roles are defined in the base module and sometimes in
2179*2d543d20SAndroid Build Coastguard Worker // other non-base modules. If we generated the roles regardless of
2180*2d543d20SAndroid Build Coastguard Worker // the policy type, it would result in duplicate declarations,
2181*2d543d20SAndroid Build Coastguard Worker // which isn't allowed in CIL. Patches have been made to refpolicy
2182*2d543d20SAndroid Build Coastguard Worker // to remove these duplicate role declarations, but we need to be
2183*2d543d20SAndroid Build Coastguard Worker // backwards compatible and support older policies. Since we know
2184*2d543d20SAndroid Build Coastguard Worker // these roles are always declared in base, only print them when we
2185*2d543d20SAndroid Build Coastguard Worker // see them in the base module. If the declarations appear in a
2186*2d543d20SAndroid Build Coastguard Worker // non-base module, ignore their declarations.
2187*2d543d20SAndroid Build Coastguard Worker //
2188*2d543d20SAndroid Build Coastguard Worker // Note that this is a hack, and if a policy author does not define
2189*2d543d20SAndroid Build Coastguard Worker // one of these roles in base, the declaration will not appear in
2190*2d543d20SAndroid Build Coastguard Worker // the resulting policy, likely resulting in a compilation error in
2191*2d543d20SAndroid Build Coastguard Worker // CIL.
2192*2d543d20SAndroid Build Coastguard Worker //
2193*2d543d20SAndroid Build Coastguard Worker // To make things more complicated, the auditadm_r and secadm_r
2194*2d543d20SAndroid Build Coastguard Worker // roles could actually be in either the base module or a non-base
2195*2d543d20SAndroid Build Coastguard Worker // module, or both. So we can't rely on this same behavior. So for
2196*2d543d20SAndroid Build Coastguard Worker // these roles, don't declare them here, even if they are in a base
2197*2d543d20SAndroid Build Coastguard Worker // or non-base module. Instead we will just declare them in the
2198*2d543d20SAndroid Build Coastguard Worker // base module elsewhere.
2199*2d543d20SAndroid Build Coastguard Worker int is_base_role = (!strcmp(key, "user_r") ||
2200*2d543d20SAndroid Build Coastguard Worker !strcmp(key, "staff_r") ||
2201*2d543d20SAndroid Build Coastguard Worker !strcmp(key, "sysadm_r") ||
2202*2d543d20SAndroid Build Coastguard Worker !strcmp(key, "system_r") ||
2203*2d543d20SAndroid Build Coastguard Worker !strcmp(key, "unconfined_r"));
2204*2d543d20SAndroid Build Coastguard Worker int is_builtin_role = (!strcmp(key, "auditadm_r") ||
2205*2d543d20SAndroid Build Coastguard Worker !strcmp(key, "secadm_r"));
2206*2d543d20SAndroid Build Coastguard Worker if ((is_base_role && pdb->policy_type == SEPOL_POLICY_BASE) ||
2207*2d543d20SAndroid Build Coastguard Worker (!is_base_role && !is_builtin_role)) {
2208*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(role %s)", key);
2209*2d543d20SAndroid Build Coastguard Worker }
2210*2d543d20SAndroid Build Coastguard Worker }
2211*2d543d20SAndroid Build Coastguard Worker
2212*2d543d20SAndroid Build Coastguard Worker if (ebitmap_cardinality(&role->dominates) > 1) {
2213*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Warning: role 'dominance' statement unsupported in CIL. Dropping from output.");
2214*2d543d20SAndroid Build Coastguard Worker }
2215*2d543d20SAndroid Build Coastguard Worker
2216*2d543d20SAndroid Build Coastguard Worker ts = &role->types;
2217*2d543d20SAndroid Build Coastguard Worker rc = process_typeset(pdb, ts, attr_list, &types, &num_types);
2218*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
2219*2d543d20SAndroid Build Coastguard Worker goto exit;
2220*2d543d20SAndroid Build Coastguard Worker }
2221*2d543d20SAndroid Build Coastguard Worker
2222*2d543d20SAndroid Build Coastguard Worker for (j = 0; j < num_types; j++) {
2223*2d543d20SAndroid Build Coastguard Worker if (is_id_in_scope(pdb, decl_stack, types[j], SYM_TYPES)) {
2224*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(roletype %s %s)", key, types[j]);
2225*2d543d20SAndroid Build Coastguard Worker }
2226*2d543d20SAndroid Build Coastguard Worker }
2227*2d543d20SAndroid Build Coastguard Worker
2228*2d543d20SAndroid Build Coastguard Worker if (role->bounds > 0) {
2229*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(rolebounds %s %s)", key, pdb->p_role_val_to_name[role->bounds - 1]);
2230*2d543d20SAndroid Build Coastguard Worker }
2231*2d543d20SAndroid Build Coastguard Worker break;
2232*2d543d20SAndroid Build Coastguard Worker
2233*2d543d20SAndroid Build Coastguard Worker case ROLE_ATTRIB:
2234*2d543d20SAndroid Build Coastguard Worker if (scope == SCOPE_DECL) {
2235*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(roleattribute %s)", key);
2236*2d543d20SAndroid Build Coastguard Worker }
2237*2d543d20SAndroid Build Coastguard Worker
2238*2d543d20SAndroid Build Coastguard Worker if (!ebitmap_is_empty(&role->roles)) {
2239*2d543d20SAndroid Build Coastguard Worker cil_indent(indent);
2240*2d543d20SAndroid Build Coastguard Worker cil_printf("(roleattributeset %s (", key);
2241*2d543d20SAndroid Build Coastguard Worker ebitmap_for_each_positive_bit(&role->roles, node, i) {
2242*2d543d20SAndroid Build Coastguard Worker cil_printf("%s ", pdb->p_role_val_to_name[i]);
2243*2d543d20SAndroid Build Coastguard Worker }
2244*2d543d20SAndroid Build Coastguard Worker cil_printf("))\n");
2245*2d543d20SAndroid Build Coastguard Worker }
2246*2d543d20SAndroid Build Coastguard Worker
2247*2d543d20SAndroid Build Coastguard Worker ts = &role->types;
2248*2d543d20SAndroid Build Coastguard Worker rc = process_typeset(pdb, ts, attr_list, &types, &num_types);
2249*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
2250*2d543d20SAndroid Build Coastguard Worker goto exit;
2251*2d543d20SAndroid Build Coastguard Worker }
2252*2d543d20SAndroid Build Coastguard Worker
2253*2d543d20SAndroid Build Coastguard Worker
2254*2d543d20SAndroid Build Coastguard Worker for (j = 0; j < num_types; j++) {
2255*2d543d20SAndroid Build Coastguard Worker if (is_id_in_scope(pdb, decl_stack, types[j], SYM_TYPES)) {
2256*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(roletype %s %s)", key, types[j]);
2257*2d543d20SAndroid Build Coastguard Worker }
2258*2d543d20SAndroid Build Coastguard Worker }
2259*2d543d20SAndroid Build Coastguard Worker
2260*2d543d20SAndroid Build Coastguard Worker break;
2261*2d543d20SAndroid Build Coastguard Worker
2262*2d543d20SAndroid Build Coastguard Worker default:
2263*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Unknown role type: %i", role->flavor);
2264*2d543d20SAndroid Build Coastguard Worker rc = -1;
2265*2d543d20SAndroid Build Coastguard Worker goto exit;
2266*2d543d20SAndroid Build Coastguard Worker }
2267*2d543d20SAndroid Build Coastguard Worker
2268*2d543d20SAndroid Build Coastguard Worker rc = cil_print_attr_list(indent, pdb, attr_list);
2269*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
2270*2d543d20SAndroid Build Coastguard Worker goto exit;
2271*2d543d20SAndroid Build Coastguard Worker }
2272*2d543d20SAndroid Build Coastguard Worker
2273*2d543d20SAndroid Build Coastguard Worker exit:
2274*2d543d20SAndroid Build Coastguard Worker attr_list_destroy(&attr_list);
2275*2d543d20SAndroid Build Coastguard Worker names_destroy(&types, &num_types);
2276*2d543d20SAndroid Build Coastguard Worker
2277*2d543d20SAndroid Build Coastguard Worker return rc;
2278*2d543d20SAndroid Build Coastguard Worker }
2279*2d543d20SAndroid Build Coastguard Worker
type_to_cil(int indent,struct policydb * pdb,struct avrule_block * UNUSED (block),struct stack * decl_stack,char * key,void * datum,int scope)2280*2d543d20SAndroid Build Coastguard Worker static int type_to_cil(int indent, struct policydb *pdb, struct avrule_block *UNUSED(block), struct stack *decl_stack, char *key, void *datum, int scope)
2281*2d543d20SAndroid Build Coastguard Worker {
2282*2d543d20SAndroid Build Coastguard Worker int rc = -1;
2283*2d543d20SAndroid Build Coastguard Worker struct type_datum *type = datum;
2284*2d543d20SAndroid Build Coastguard Worker
2285*2d543d20SAndroid Build Coastguard Worker if (scope == SCOPE_REQ) {
2286*2d543d20SAndroid Build Coastguard Worker // if a type/typeattr is in the REQ scope, then it could cause an
2287*2d543d20SAndroid Build Coastguard Worker // optional block to fail, even if it is never used. However in CIL,
2288*2d543d20SAndroid Build Coastguard Worker // symbols must be used in order to cause an optional block to fail. So
2289*2d543d20SAndroid Build Coastguard Worker // for symbols in the REQ scope, add them to a typeattribute as a way
2290*2d543d20SAndroid Build Coastguard Worker // to 'use' them in the optional without affecting the resulting policy.
2291*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(typeattributeset " GEN_REQUIRE_ATTR " %s)", key);
2292*2d543d20SAndroid Build Coastguard Worker }
2293*2d543d20SAndroid Build Coastguard Worker
2294*2d543d20SAndroid Build Coastguard Worker rc = roletype_role_in_ancestor_to_cil(pdb, decl_stack, key, indent);
2295*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
2296*2d543d20SAndroid Build Coastguard Worker goto exit;
2297*2d543d20SAndroid Build Coastguard Worker }
2298*2d543d20SAndroid Build Coastguard Worker
2299*2d543d20SAndroid Build Coastguard Worker switch(type->flavor) {
2300*2d543d20SAndroid Build Coastguard Worker case TYPE_TYPE:
2301*2d543d20SAndroid Build Coastguard Worker if (scope == SCOPE_DECL) {
2302*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(type %s)", key);
2303*2d543d20SAndroid Build Coastguard Worker // object_r is implicit in checkmodule, but not with CIL,
2304*2d543d20SAndroid Build Coastguard Worker // create it as part of base
2305*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(roletype " DEFAULT_OBJECT " %s)", key);
2306*2d543d20SAndroid Build Coastguard Worker }
2307*2d543d20SAndroid Build Coastguard Worker
2308*2d543d20SAndroid Build Coastguard Worker if (type->flags & TYPE_FLAGS_PERMISSIVE) {
2309*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(typepermissive %s)", key);
2310*2d543d20SAndroid Build Coastguard Worker }
2311*2d543d20SAndroid Build Coastguard Worker
2312*2d543d20SAndroid Build Coastguard Worker if (type->bounds > 0) {
2313*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(typebounds %s %s)", pdb->p_type_val_to_name[type->bounds - 1], key);
2314*2d543d20SAndroid Build Coastguard Worker }
2315*2d543d20SAndroid Build Coastguard Worker break;
2316*2d543d20SAndroid Build Coastguard Worker case TYPE_ATTRIB:
2317*2d543d20SAndroid Build Coastguard Worker if (scope == SCOPE_DECL) {
2318*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(typeattribute %s)", key);
2319*2d543d20SAndroid Build Coastguard Worker }
2320*2d543d20SAndroid Build Coastguard Worker
2321*2d543d20SAndroid Build Coastguard Worker if (type->flags & TYPE_FLAGS_EXPAND_ATTR) {
2322*2d543d20SAndroid Build Coastguard Worker cil_indent(indent);
2323*2d543d20SAndroid Build Coastguard Worker cil_printf("(expandtypeattribute (%s) ", key);
2324*2d543d20SAndroid Build Coastguard Worker if (type->flags & TYPE_FLAGS_EXPAND_ATTR_TRUE) {
2325*2d543d20SAndroid Build Coastguard Worker cil_printf("true");
2326*2d543d20SAndroid Build Coastguard Worker } else if (type->flags & TYPE_FLAGS_EXPAND_ATTR_FALSE) {
2327*2d543d20SAndroid Build Coastguard Worker cil_printf("false");
2328*2d543d20SAndroid Build Coastguard Worker }
2329*2d543d20SAndroid Build Coastguard Worker cil_printf(")\n");
2330*2d543d20SAndroid Build Coastguard Worker }
2331*2d543d20SAndroid Build Coastguard Worker
2332*2d543d20SAndroid Build Coastguard Worker if (!ebitmap_is_empty(&type->types)) {
2333*2d543d20SAndroid Build Coastguard Worker cil_indent(indent);
2334*2d543d20SAndroid Build Coastguard Worker cil_printf("(typeattributeset %s (", key);
2335*2d543d20SAndroid Build Coastguard Worker ebitmap_to_cil(pdb, &type->types, SYM_TYPES);
2336*2d543d20SAndroid Build Coastguard Worker cil_printf("))\n");
2337*2d543d20SAndroid Build Coastguard Worker }
2338*2d543d20SAndroid Build Coastguard Worker break;
2339*2d543d20SAndroid Build Coastguard Worker case TYPE_ALIAS:
2340*2d543d20SAndroid Build Coastguard Worker break;
2341*2d543d20SAndroid Build Coastguard Worker default:
2342*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Unknown flavor (%i) of type %s", type->flavor, key);
2343*2d543d20SAndroid Build Coastguard Worker rc = -1;
2344*2d543d20SAndroid Build Coastguard Worker goto exit;
2345*2d543d20SAndroid Build Coastguard Worker }
2346*2d543d20SAndroid Build Coastguard Worker
2347*2d543d20SAndroid Build Coastguard Worker rc = 0;
2348*2d543d20SAndroid Build Coastguard Worker
2349*2d543d20SAndroid Build Coastguard Worker exit:
2350*2d543d20SAndroid Build Coastguard Worker return rc;
2351*2d543d20SAndroid Build Coastguard Worker }
2352*2d543d20SAndroid Build Coastguard Worker
user_to_cil(int indent,struct policydb * pdb,struct avrule_block * block,struct stack * UNUSED (decl_stack),char * key,void * datum,int scope)2353*2d543d20SAndroid Build Coastguard Worker static int user_to_cil(int indent, struct policydb *pdb, struct avrule_block *block, struct stack *UNUSED(decl_stack), char *key, void *datum, int scope)
2354*2d543d20SAndroid Build Coastguard Worker {
2355*2d543d20SAndroid Build Coastguard Worker struct user_datum *user = datum;
2356*2d543d20SAndroid Build Coastguard Worker struct ebitmap roles = user->roles.roles;
2357*2d543d20SAndroid Build Coastguard Worker struct mls_semantic_level level = user->dfltlevel;
2358*2d543d20SAndroid Build Coastguard Worker struct mls_semantic_range range = user->range;
2359*2d543d20SAndroid Build Coastguard Worker struct ebitmap_node *node;
2360*2d543d20SAndroid Build Coastguard Worker uint32_t i;
2361*2d543d20SAndroid Build Coastguard Worker int sens_offset = 1;
2362*2d543d20SAndroid Build Coastguard Worker
2363*2d543d20SAndroid Build Coastguard Worker if (scope == SCOPE_DECL) {
2364*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(user %s)", key);
2365*2d543d20SAndroid Build Coastguard Worker // object_r is implicit in checkmodule, but not with CIL, create it
2366*2d543d20SAndroid Build Coastguard Worker // as part of base
2367*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(userrole %s " DEFAULT_OBJECT ")", key);
2368*2d543d20SAndroid Build Coastguard Worker }
2369*2d543d20SAndroid Build Coastguard Worker
2370*2d543d20SAndroid Build Coastguard Worker ebitmap_for_each_positive_bit(&roles, node, i) {
2371*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(userrole %s %s)", key, pdb->p_role_val_to_name[i]);
2372*2d543d20SAndroid Build Coastguard Worker }
2373*2d543d20SAndroid Build Coastguard Worker
2374*2d543d20SAndroid Build Coastguard Worker if (block->flags & AVRULE_OPTIONAL) {
2375*2d543d20SAndroid Build Coastguard Worker // sensitivities in user statements in optionals do not have the
2376*2d543d20SAndroid Build Coastguard Worker // standard -1 offset
2377*2d543d20SAndroid Build Coastguard Worker sens_offset = 0;
2378*2d543d20SAndroid Build Coastguard Worker }
2379*2d543d20SAndroid Build Coastguard Worker
2380*2d543d20SAndroid Build Coastguard Worker cil_indent(indent);
2381*2d543d20SAndroid Build Coastguard Worker cil_printf("(userlevel %s ", key);
2382*2d543d20SAndroid Build Coastguard Worker if (pdb->mls) {
2383*2d543d20SAndroid Build Coastguard Worker semantic_level_to_cil(pdb, sens_offset, &level);
2384*2d543d20SAndroid Build Coastguard Worker } else {
2385*2d543d20SAndroid Build Coastguard Worker cil_printf(DEFAULT_LEVEL);
2386*2d543d20SAndroid Build Coastguard Worker }
2387*2d543d20SAndroid Build Coastguard Worker cil_printf(")\n");
2388*2d543d20SAndroid Build Coastguard Worker
2389*2d543d20SAndroid Build Coastguard Worker cil_indent(indent);
2390*2d543d20SAndroid Build Coastguard Worker cil_printf("(userrange %s (", key);
2391*2d543d20SAndroid Build Coastguard Worker if (pdb->mls) {
2392*2d543d20SAndroid Build Coastguard Worker semantic_level_to_cil(pdb, sens_offset, &range.level[0]);
2393*2d543d20SAndroid Build Coastguard Worker cil_printf(" ");
2394*2d543d20SAndroid Build Coastguard Worker semantic_level_to_cil(pdb, sens_offset, &range.level[1]);
2395*2d543d20SAndroid Build Coastguard Worker } else {
2396*2d543d20SAndroid Build Coastguard Worker cil_printf(DEFAULT_LEVEL " " DEFAULT_LEVEL);
2397*2d543d20SAndroid Build Coastguard Worker }
2398*2d543d20SAndroid Build Coastguard Worker cil_printf("))\n");
2399*2d543d20SAndroid Build Coastguard Worker
2400*2d543d20SAndroid Build Coastguard Worker
2401*2d543d20SAndroid Build Coastguard Worker return 0;
2402*2d543d20SAndroid Build Coastguard Worker }
2403*2d543d20SAndroid Build Coastguard Worker
boolean_to_cil(int indent,struct policydb * UNUSED (pdb),struct avrule_block * UNUSED (block),struct stack * UNUSED (decl_stack),char * key,void * datum,int scope)2404*2d543d20SAndroid Build Coastguard Worker static int boolean_to_cil(int indent, struct policydb *UNUSED(pdb), struct avrule_block *UNUSED(block), struct stack *UNUSED(decl_stack), char *key, void *datum, int scope)
2405*2d543d20SAndroid Build Coastguard Worker {
2406*2d543d20SAndroid Build Coastguard Worker struct cond_bool_datum *boolean = datum;
2407*2d543d20SAndroid Build Coastguard Worker const char *type;
2408*2d543d20SAndroid Build Coastguard Worker
2409*2d543d20SAndroid Build Coastguard Worker if (scope == SCOPE_DECL) {
2410*2d543d20SAndroid Build Coastguard Worker if (boolean->flags & COND_BOOL_FLAGS_TUNABLE) {
2411*2d543d20SAndroid Build Coastguard Worker type = "tunable";
2412*2d543d20SAndroid Build Coastguard Worker } else {
2413*2d543d20SAndroid Build Coastguard Worker type = "boolean";
2414*2d543d20SAndroid Build Coastguard Worker }
2415*2d543d20SAndroid Build Coastguard Worker
2416*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(%s %s %s)", type, key, boolean->state ? "true" : "false");
2417*2d543d20SAndroid Build Coastguard Worker }
2418*2d543d20SAndroid Build Coastguard Worker
2419*2d543d20SAndroid Build Coastguard Worker return 0;
2420*2d543d20SAndroid Build Coastguard Worker }
2421*2d543d20SAndroid Build Coastguard Worker
sens_to_cil(int indent,struct policydb * pdb,struct avrule_block * UNUSED (block),struct stack * UNUSED (decl_stack),char * key,void * datum,int scope)2422*2d543d20SAndroid Build Coastguard Worker static int sens_to_cil(int indent, struct policydb *pdb, struct avrule_block *UNUSED(block), struct stack *UNUSED(decl_stack), char *key, void *datum, int scope)
2423*2d543d20SAndroid Build Coastguard Worker {
2424*2d543d20SAndroid Build Coastguard Worker level_datum_t *level = datum;
2425*2d543d20SAndroid Build Coastguard Worker
2426*2d543d20SAndroid Build Coastguard Worker if (scope == SCOPE_DECL) {
2427*2d543d20SAndroid Build Coastguard Worker if (!level->isalias) {
2428*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(sensitivity %s)", key);
2429*2d543d20SAndroid Build Coastguard Worker } else {
2430*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(sensitivityalias %s)", key);
2431*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(sensitivityaliasactual %s %s)", key, pdb->p_sens_val_to_name[level->level->sens - 1]);
2432*2d543d20SAndroid Build Coastguard Worker }
2433*2d543d20SAndroid Build Coastguard Worker }
2434*2d543d20SAndroid Build Coastguard Worker
2435*2d543d20SAndroid Build Coastguard Worker if (!ebitmap_is_empty(&level->level->cat)) {
2436*2d543d20SAndroid Build Coastguard Worker cil_indent(indent);
2437*2d543d20SAndroid Build Coastguard Worker cil_printf("(sensitivitycategory %s (", key);
2438*2d543d20SAndroid Build Coastguard Worker ebitmap_to_cil(pdb, &level->level->cat, SYM_CATS);
2439*2d543d20SAndroid Build Coastguard Worker cil_printf("))\n");
2440*2d543d20SAndroid Build Coastguard Worker }
2441*2d543d20SAndroid Build Coastguard Worker
2442*2d543d20SAndroid Build Coastguard Worker return 0;
2443*2d543d20SAndroid Build Coastguard Worker }
2444*2d543d20SAndroid Build Coastguard Worker
sens_order_to_cil(int indent,struct policydb * pdb,struct ebitmap order)2445*2d543d20SAndroid Build Coastguard Worker static int sens_order_to_cil(int indent, struct policydb *pdb, struct ebitmap order)
2446*2d543d20SAndroid Build Coastguard Worker {
2447*2d543d20SAndroid Build Coastguard Worker struct ebitmap_node *node;
2448*2d543d20SAndroid Build Coastguard Worker uint32_t i;
2449*2d543d20SAndroid Build Coastguard Worker
2450*2d543d20SAndroid Build Coastguard Worker if (ebitmap_is_empty(&order)) {
2451*2d543d20SAndroid Build Coastguard Worker return 0;
2452*2d543d20SAndroid Build Coastguard Worker }
2453*2d543d20SAndroid Build Coastguard Worker
2454*2d543d20SAndroid Build Coastguard Worker cil_indent(indent);
2455*2d543d20SAndroid Build Coastguard Worker cil_printf("(sensitivityorder (");
2456*2d543d20SAndroid Build Coastguard Worker
2457*2d543d20SAndroid Build Coastguard Worker ebitmap_for_each_positive_bit(&order, node, i) {
2458*2d543d20SAndroid Build Coastguard Worker cil_printf("%s ", pdb->p_sens_val_to_name[i]);
2459*2d543d20SAndroid Build Coastguard Worker }
2460*2d543d20SAndroid Build Coastguard Worker
2461*2d543d20SAndroid Build Coastguard Worker cil_printf("))\n");
2462*2d543d20SAndroid Build Coastguard Worker
2463*2d543d20SAndroid Build Coastguard Worker return 0;
2464*2d543d20SAndroid Build Coastguard Worker }
2465*2d543d20SAndroid Build Coastguard Worker
cat_to_cil(int indent,struct policydb * pdb,struct avrule_block * UNUSED (block),struct stack * UNUSED (decl_stack),char * key,void * datum,int scope)2466*2d543d20SAndroid Build Coastguard Worker static int cat_to_cil(int indent, struct policydb *pdb, struct avrule_block *UNUSED(block), struct stack *UNUSED(decl_stack), char *key, void *datum, int scope)
2467*2d543d20SAndroid Build Coastguard Worker {
2468*2d543d20SAndroid Build Coastguard Worker struct cat_datum *cat = datum;
2469*2d543d20SAndroid Build Coastguard Worker
2470*2d543d20SAndroid Build Coastguard Worker if (scope == SCOPE_REQ) {
2471*2d543d20SAndroid Build Coastguard Worker return 0;
2472*2d543d20SAndroid Build Coastguard Worker }
2473*2d543d20SAndroid Build Coastguard Worker
2474*2d543d20SAndroid Build Coastguard Worker if (!cat->isalias) {
2475*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(category %s)", key);
2476*2d543d20SAndroid Build Coastguard Worker } else {
2477*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(categoryalias %s)", key);
2478*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(categoryaliasactual %s %s)", key, pdb->p_cat_val_to_name[cat->s.value - 1]);
2479*2d543d20SAndroid Build Coastguard Worker }
2480*2d543d20SAndroid Build Coastguard Worker
2481*2d543d20SAndroid Build Coastguard Worker return 0;
2482*2d543d20SAndroid Build Coastguard Worker }
2483*2d543d20SAndroid Build Coastguard Worker
cat_order_to_cil(int indent,struct policydb * pdb,struct ebitmap order)2484*2d543d20SAndroid Build Coastguard Worker static int cat_order_to_cil(int indent, struct policydb *pdb, struct ebitmap order)
2485*2d543d20SAndroid Build Coastguard Worker {
2486*2d543d20SAndroid Build Coastguard Worker int rc = -1;
2487*2d543d20SAndroid Build Coastguard Worker struct ebitmap_node *node;
2488*2d543d20SAndroid Build Coastguard Worker uint32_t i;
2489*2d543d20SAndroid Build Coastguard Worker
2490*2d543d20SAndroid Build Coastguard Worker if (ebitmap_is_empty(&order)) {
2491*2d543d20SAndroid Build Coastguard Worker rc = 0;
2492*2d543d20SAndroid Build Coastguard Worker goto exit;
2493*2d543d20SAndroid Build Coastguard Worker }
2494*2d543d20SAndroid Build Coastguard Worker
2495*2d543d20SAndroid Build Coastguard Worker cil_indent(indent);
2496*2d543d20SAndroid Build Coastguard Worker cil_printf("(categoryorder (");
2497*2d543d20SAndroid Build Coastguard Worker
2498*2d543d20SAndroid Build Coastguard Worker ebitmap_for_each_positive_bit(&order, node, i) {
2499*2d543d20SAndroid Build Coastguard Worker cil_printf("%s ", pdb->p_cat_val_to_name[i]);
2500*2d543d20SAndroid Build Coastguard Worker }
2501*2d543d20SAndroid Build Coastguard Worker
2502*2d543d20SAndroid Build Coastguard Worker cil_printf("))\n");
2503*2d543d20SAndroid Build Coastguard Worker
2504*2d543d20SAndroid Build Coastguard Worker return 0;
2505*2d543d20SAndroid Build Coastguard Worker exit:
2506*2d543d20SAndroid Build Coastguard Worker return rc;
2507*2d543d20SAndroid Build Coastguard Worker }
2508*2d543d20SAndroid Build Coastguard Worker
polcaps_to_cil(struct policydb * pdb)2509*2d543d20SAndroid Build Coastguard Worker static int polcaps_to_cil(struct policydb *pdb)
2510*2d543d20SAndroid Build Coastguard Worker {
2511*2d543d20SAndroid Build Coastguard Worker int rc = -1;
2512*2d543d20SAndroid Build Coastguard Worker struct ebitmap *map;
2513*2d543d20SAndroid Build Coastguard Worker struct ebitmap_node *node;
2514*2d543d20SAndroid Build Coastguard Worker uint32_t i;
2515*2d543d20SAndroid Build Coastguard Worker const char *name;
2516*2d543d20SAndroid Build Coastguard Worker
2517*2d543d20SAndroid Build Coastguard Worker map = &pdb->policycaps;
2518*2d543d20SAndroid Build Coastguard Worker
2519*2d543d20SAndroid Build Coastguard Worker ebitmap_for_each_positive_bit(map, node, i) {
2520*2d543d20SAndroid Build Coastguard Worker name = sepol_polcap_getname(i);
2521*2d543d20SAndroid Build Coastguard Worker if (name == NULL) {
2522*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Unknown policy capability id: %i", i);
2523*2d543d20SAndroid Build Coastguard Worker rc = -1;
2524*2d543d20SAndroid Build Coastguard Worker goto exit;
2525*2d543d20SAndroid Build Coastguard Worker }
2526*2d543d20SAndroid Build Coastguard Worker
2527*2d543d20SAndroid Build Coastguard Worker cil_println(0, "(policycap %s)", name);
2528*2d543d20SAndroid Build Coastguard Worker }
2529*2d543d20SAndroid Build Coastguard Worker
2530*2d543d20SAndroid Build Coastguard Worker return 0;
2531*2d543d20SAndroid Build Coastguard Worker exit:
2532*2d543d20SAndroid Build Coastguard Worker return rc;
2533*2d543d20SAndroid Build Coastguard Worker }
2534*2d543d20SAndroid Build Coastguard Worker
level_to_cil(struct policydb * pdb,struct mls_level * level)2535*2d543d20SAndroid Build Coastguard Worker static int level_to_cil(struct policydb *pdb, struct mls_level *level)
2536*2d543d20SAndroid Build Coastguard Worker {
2537*2d543d20SAndroid Build Coastguard Worker struct ebitmap *map = &level->cat;
2538*2d543d20SAndroid Build Coastguard Worker
2539*2d543d20SAndroid Build Coastguard Worker cil_printf("(%s", pdb->p_sens_val_to_name[level->sens - 1]);
2540*2d543d20SAndroid Build Coastguard Worker
2541*2d543d20SAndroid Build Coastguard Worker if (!ebitmap_is_empty(map)) {
2542*2d543d20SAndroid Build Coastguard Worker cil_printf("(");
2543*2d543d20SAndroid Build Coastguard Worker ebitmap_to_cil(pdb, map, SYM_CATS);
2544*2d543d20SAndroid Build Coastguard Worker cil_printf(")");
2545*2d543d20SAndroid Build Coastguard Worker }
2546*2d543d20SAndroid Build Coastguard Worker
2547*2d543d20SAndroid Build Coastguard Worker cil_printf(")");
2548*2d543d20SAndroid Build Coastguard Worker
2549*2d543d20SAndroid Build Coastguard Worker return 0;
2550*2d543d20SAndroid Build Coastguard Worker }
2551*2d543d20SAndroid Build Coastguard Worker
context_to_cil(struct policydb * pdb,struct context_struct * con)2552*2d543d20SAndroid Build Coastguard Worker static int context_to_cil(struct policydb *pdb, struct context_struct *con)
2553*2d543d20SAndroid Build Coastguard Worker {
2554*2d543d20SAndroid Build Coastguard Worker cil_printf("(%s %s %s (",
2555*2d543d20SAndroid Build Coastguard Worker pdb->p_user_val_to_name[con->user - 1],
2556*2d543d20SAndroid Build Coastguard Worker pdb->p_role_val_to_name[con->role - 1],
2557*2d543d20SAndroid Build Coastguard Worker pdb->p_type_val_to_name[con->type - 1]);
2558*2d543d20SAndroid Build Coastguard Worker
2559*2d543d20SAndroid Build Coastguard Worker if (pdb->mls) {
2560*2d543d20SAndroid Build Coastguard Worker level_to_cil(pdb, &con->range.level[0]);
2561*2d543d20SAndroid Build Coastguard Worker cil_printf(" ");
2562*2d543d20SAndroid Build Coastguard Worker level_to_cil(pdb, &con->range.level[1]);
2563*2d543d20SAndroid Build Coastguard Worker } else {
2564*2d543d20SAndroid Build Coastguard Worker cil_printf(DEFAULT_LEVEL);
2565*2d543d20SAndroid Build Coastguard Worker cil_printf(" ");
2566*2d543d20SAndroid Build Coastguard Worker cil_printf(DEFAULT_LEVEL);
2567*2d543d20SAndroid Build Coastguard Worker }
2568*2d543d20SAndroid Build Coastguard Worker
2569*2d543d20SAndroid Build Coastguard Worker cil_printf("))");
2570*2d543d20SAndroid Build Coastguard Worker
2571*2d543d20SAndroid Build Coastguard Worker return 0;
2572*2d543d20SAndroid Build Coastguard Worker }
2573*2d543d20SAndroid Build Coastguard Worker
ocontext_isid_to_cil(struct policydb * pdb,const char * const * sid_to_string,unsigned num_sids,struct ocontext * isids)2574*2d543d20SAndroid Build Coastguard Worker static int ocontext_isid_to_cil(struct policydb *pdb, const char *const *sid_to_string,
2575*2d543d20SAndroid Build Coastguard Worker unsigned num_sids, struct ocontext *isids)
2576*2d543d20SAndroid Build Coastguard Worker {
2577*2d543d20SAndroid Build Coastguard Worker int rc = -1;
2578*2d543d20SAndroid Build Coastguard Worker
2579*2d543d20SAndroid Build Coastguard Worker struct ocontext *isid;
2580*2d543d20SAndroid Build Coastguard Worker
2581*2d543d20SAndroid Build Coastguard Worker struct sid_item {
2582*2d543d20SAndroid Build Coastguard Worker char *sid_key;
2583*2d543d20SAndroid Build Coastguard Worker struct sid_item *next;
2584*2d543d20SAndroid Build Coastguard Worker };
2585*2d543d20SAndroid Build Coastguard Worker
2586*2d543d20SAndroid Build Coastguard Worker struct sid_item *head = NULL;
2587*2d543d20SAndroid Build Coastguard Worker struct sid_item *item = NULL;
2588*2d543d20SAndroid Build Coastguard Worker char *sid;
2589*2d543d20SAndroid Build Coastguard Worker char unknown[18];
2590*2d543d20SAndroid Build Coastguard Worker unsigned i;
2591*2d543d20SAndroid Build Coastguard Worker
2592*2d543d20SAndroid Build Coastguard Worker for (isid = isids; isid != NULL; isid = isid->next) {
2593*2d543d20SAndroid Build Coastguard Worker i = isid->sid[0];
2594*2d543d20SAndroid Build Coastguard Worker if (i < num_sids && sid_to_string[i]) {
2595*2d543d20SAndroid Build Coastguard Worker sid = (char*)sid_to_string[i];
2596*2d543d20SAndroid Build Coastguard Worker } else {
2597*2d543d20SAndroid Build Coastguard Worker snprintf(unknown, 18, "%s%u", "UNKNOWN", i);
2598*2d543d20SAndroid Build Coastguard Worker sid = unknown;
2599*2d543d20SAndroid Build Coastguard Worker }
2600*2d543d20SAndroid Build Coastguard Worker cil_println(0, "(sid %s)", sid);
2601*2d543d20SAndroid Build Coastguard Worker cil_printf("(sidcontext %s ", sid);
2602*2d543d20SAndroid Build Coastguard Worker context_to_cil(pdb, &isid->context[0]);
2603*2d543d20SAndroid Build Coastguard Worker cil_printf(")\n");
2604*2d543d20SAndroid Build Coastguard Worker
2605*2d543d20SAndroid Build Coastguard Worker // get the sid names in the correct order (reverse from the isids
2606*2d543d20SAndroid Build Coastguard Worker // ocontext) for sidorder statement
2607*2d543d20SAndroid Build Coastguard Worker item = malloc(sizeof(*item));
2608*2d543d20SAndroid Build Coastguard Worker if (item == NULL) {
2609*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Out of memory");
2610*2d543d20SAndroid Build Coastguard Worker rc = -1;
2611*2d543d20SAndroid Build Coastguard Worker goto exit;
2612*2d543d20SAndroid Build Coastguard Worker }
2613*2d543d20SAndroid Build Coastguard Worker item->sid_key = strdup(sid);
2614*2d543d20SAndroid Build Coastguard Worker if (!item->sid_key) {
2615*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Out of memory");
2616*2d543d20SAndroid Build Coastguard Worker free(item);
2617*2d543d20SAndroid Build Coastguard Worker rc = -1;
2618*2d543d20SAndroid Build Coastguard Worker goto exit;
2619*2d543d20SAndroid Build Coastguard Worker }
2620*2d543d20SAndroid Build Coastguard Worker item->next = head;
2621*2d543d20SAndroid Build Coastguard Worker head = item;
2622*2d543d20SAndroid Build Coastguard Worker }
2623*2d543d20SAndroid Build Coastguard Worker
2624*2d543d20SAndroid Build Coastguard Worker if (head != NULL) {
2625*2d543d20SAndroid Build Coastguard Worker cil_printf("(sidorder (");
2626*2d543d20SAndroid Build Coastguard Worker for (item = head; item != NULL; item = item->next) {
2627*2d543d20SAndroid Build Coastguard Worker cil_printf("%s ", item->sid_key);
2628*2d543d20SAndroid Build Coastguard Worker }
2629*2d543d20SAndroid Build Coastguard Worker cil_printf("))\n");
2630*2d543d20SAndroid Build Coastguard Worker }
2631*2d543d20SAndroid Build Coastguard Worker
2632*2d543d20SAndroid Build Coastguard Worker rc = 0;
2633*2d543d20SAndroid Build Coastguard Worker
2634*2d543d20SAndroid Build Coastguard Worker exit:
2635*2d543d20SAndroid Build Coastguard Worker while(head) {
2636*2d543d20SAndroid Build Coastguard Worker item = head;
2637*2d543d20SAndroid Build Coastguard Worker head = item->next;
2638*2d543d20SAndroid Build Coastguard Worker free(item->sid_key);
2639*2d543d20SAndroid Build Coastguard Worker free(item);
2640*2d543d20SAndroid Build Coastguard Worker }
2641*2d543d20SAndroid Build Coastguard Worker return rc;
2642*2d543d20SAndroid Build Coastguard Worker }
2643*2d543d20SAndroid Build Coastguard Worker
ocontext_selinux_isid_to_cil(struct policydb * pdb,struct ocontext * isids)2644*2d543d20SAndroid Build Coastguard Worker static int ocontext_selinux_isid_to_cil(struct policydb *pdb, struct ocontext *isids)
2645*2d543d20SAndroid Build Coastguard Worker {
2646*2d543d20SAndroid Build Coastguard Worker int rc = -1;
2647*2d543d20SAndroid Build Coastguard Worker
2648*2d543d20SAndroid Build Coastguard Worker rc = ocontext_isid_to_cil(pdb, selinux_sid_to_str, SELINUX_SID_SZ, isids);
2649*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
2650*2d543d20SAndroid Build Coastguard Worker goto exit;
2651*2d543d20SAndroid Build Coastguard Worker }
2652*2d543d20SAndroid Build Coastguard Worker
2653*2d543d20SAndroid Build Coastguard Worker return 0;
2654*2d543d20SAndroid Build Coastguard Worker
2655*2d543d20SAndroid Build Coastguard Worker exit:
2656*2d543d20SAndroid Build Coastguard Worker return rc;
2657*2d543d20SAndroid Build Coastguard Worker }
2658*2d543d20SAndroid Build Coastguard Worker
ocontext_selinux_fs_to_cil(struct policydb * UNUSED (pdb),struct ocontext * fss)2659*2d543d20SAndroid Build Coastguard Worker static int ocontext_selinux_fs_to_cil(struct policydb *UNUSED(pdb), struct ocontext *fss)
2660*2d543d20SAndroid Build Coastguard Worker {
2661*2d543d20SAndroid Build Coastguard Worker if (fss != NULL) {
2662*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Warning: 'fscon' statement unsupported in CIL. Dropping from output.");
2663*2d543d20SAndroid Build Coastguard Worker }
2664*2d543d20SAndroid Build Coastguard Worker
2665*2d543d20SAndroid Build Coastguard Worker return 0;
2666*2d543d20SAndroid Build Coastguard Worker }
2667*2d543d20SAndroid Build Coastguard Worker
ocontext_selinux_port_to_cil(struct policydb * pdb,struct ocontext * portcons)2668*2d543d20SAndroid Build Coastguard Worker static int ocontext_selinux_port_to_cil(struct policydb *pdb, struct ocontext *portcons)
2669*2d543d20SAndroid Build Coastguard Worker {
2670*2d543d20SAndroid Build Coastguard Worker int rc = -1;
2671*2d543d20SAndroid Build Coastguard Worker struct ocontext *portcon;
2672*2d543d20SAndroid Build Coastguard Worker const char *protocol;
2673*2d543d20SAndroid Build Coastguard Worker uint16_t high;
2674*2d543d20SAndroid Build Coastguard Worker uint16_t low;
2675*2d543d20SAndroid Build Coastguard Worker
2676*2d543d20SAndroid Build Coastguard Worker for (portcon = portcons; portcon != NULL; portcon = portcon->next) {
2677*2d543d20SAndroid Build Coastguard Worker
2678*2d543d20SAndroid Build Coastguard Worker switch (portcon->u.port.protocol) {
2679*2d543d20SAndroid Build Coastguard Worker case IPPROTO_TCP: protocol = "tcp"; break;
2680*2d543d20SAndroid Build Coastguard Worker case IPPROTO_UDP: protocol = "udp"; break;
2681*2d543d20SAndroid Build Coastguard Worker case IPPROTO_DCCP: protocol = "dccp"; break;
2682*2d543d20SAndroid Build Coastguard Worker case IPPROTO_SCTP: protocol = "sctp"; break;
2683*2d543d20SAndroid Build Coastguard Worker default:
2684*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Unknown portcon protocol: %i", portcon->u.port.protocol);
2685*2d543d20SAndroid Build Coastguard Worker rc = -1;
2686*2d543d20SAndroid Build Coastguard Worker goto exit;
2687*2d543d20SAndroid Build Coastguard Worker }
2688*2d543d20SAndroid Build Coastguard Worker
2689*2d543d20SAndroid Build Coastguard Worker low = portcon->u.port.low_port;
2690*2d543d20SAndroid Build Coastguard Worker high = portcon->u.port.high_port;
2691*2d543d20SAndroid Build Coastguard Worker
2692*2d543d20SAndroid Build Coastguard Worker if (low == high) {
2693*2d543d20SAndroid Build Coastguard Worker cil_printf("(portcon %s %i ", protocol, low);
2694*2d543d20SAndroid Build Coastguard Worker } else {
2695*2d543d20SAndroid Build Coastguard Worker cil_printf("(portcon %s (%i %i) ", protocol, low, high);
2696*2d543d20SAndroid Build Coastguard Worker }
2697*2d543d20SAndroid Build Coastguard Worker
2698*2d543d20SAndroid Build Coastguard Worker context_to_cil(pdb, &portcon->context[0]);
2699*2d543d20SAndroid Build Coastguard Worker
2700*2d543d20SAndroid Build Coastguard Worker cil_printf(")\n");
2701*2d543d20SAndroid Build Coastguard Worker }
2702*2d543d20SAndroid Build Coastguard Worker
2703*2d543d20SAndroid Build Coastguard Worker return 0;
2704*2d543d20SAndroid Build Coastguard Worker exit:
2705*2d543d20SAndroid Build Coastguard Worker return rc;
2706*2d543d20SAndroid Build Coastguard Worker }
2707*2d543d20SAndroid Build Coastguard Worker
ocontext_selinux_ibpkey_to_cil(struct policydb * pdb,struct ocontext * ibpkeycons)2708*2d543d20SAndroid Build Coastguard Worker static int ocontext_selinux_ibpkey_to_cil(struct policydb *pdb,
2709*2d543d20SAndroid Build Coastguard Worker struct ocontext *ibpkeycons)
2710*2d543d20SAndroid Build Coastguard Worker {
2711*2d543d20SAndroid Build Coastguard Worker int rc = -1;
2712*2d543d20SAndroid Build Coastguard Worker struct ocontext *ibpkeycon;
2713*2d543d20SAndroid Build Coastguard Worker char subnet_prefix_str[INET6_ADDRSTRLEN];
2714*2d543d20SAndroid Build Coastguard Worker struct in6_addr subnet_prefix = IN6ADDR_ANY_INIT;
2715*2d543d20SAndroid Build Coastguard Worker uint16_t high;
2716*2d543d20SAndroid Build Coastguard Worker uint16_t low;
2717*2d543d20SAndroid Build Coastguard Worker
2718*2d543d20SAndroid Build Coastguard Worker for (ibpkeycon = ibpkeycons; ibpkeycon; ibpkeycon = ibpkeycon->next) {
2719*2d543d20SAndroid Build Coastguard Worker low = ibpkeycon->u.ibpkey.low_pkey;
2720*2d543d20SAndroid Build Coastguard Worker high = ibpkeycon->u.ibpkey.high_pkey;
2721*2d543d20SAndroid Build Coastguard Worker memcpy(&subnet_prefix.s6_addr, &ibpkeycon->u.ibpkey.subnet_prefix,
2722*2d543d20SAndroid Build Coastguard Worker sizeof(ibpkeycon->u.ibpkey.subnet_prefix));
2723*2d543d20SAndroid Build Coastguard Worker
2724*2d543d20SAndroid Build Coastguard Worker if (inet_ntop(AF_INET6, &subnet_prefix.s6_addr,
2725*2d543d20SAndroid Build Coastguard Worker subnet_prefix_str, INET6_ADDRSTRLEN) == NULL) {
2726*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "ibpkeycon subnet_prefix is invalid: %m");
2727*2d543d20SAndroid Build Coastguard Worker rc = -1;
2728*2d543d20SAndroid Build Coastguard Worker goto exit;
2729*2d543d20SAndroid Build Coastguard Worker }
2730*2d543d20SAndroid Build Coastguard Worker
2731*2d543d20SAndroid Build Coastguard Worker if (low == high)
2732*2d543d20SAndroid Build Coastguard Worker cil_printf("(ibpkeycon %s %i ", subnet_prefix_str, low);
2733*2d543d20SAndroid Build Coastguard Worker else
2734*2d543d20SAndroid Build Coastguard Worker cil_printf("(ibpkeycon %s (%i %i) ", subnet_prefix_str, low,
2735*2d543d20SAndroid Build Coastguard Worker high);
2736*2d543d20SAndroid Build Coastguard Worker
2737*2d543d20SAndroid Build Coastguard Worker context_to_cil(pdb, &ibpkeycon->context[0]);
2738*2d543d20SAndroid Build Coastguard Worker
2739*2d543d20SAndroid Build Coastguard Worker cil_printf(")\n");
2740*2d543d20SAndroid Build Coastguard Worker }
2741*2d543d20SAndroid Build Coastguard Worker return 0;
2742*2d543d20SAndroid Build Coastguard Worker exit:
2743*2d543d20SAndroid Build Coastguard Worker return rc;
2744*2d543d20SAndroid Build Coastguard Worker }
2745*2d543d20SAndroid Build Coastguard Worker
ocontext_selinux_netif_to_cil(struct policydb * pdb,struct ocontext * netifs)2746*2d543d20SAndroid Build Coastguard Worker static int ocontext_selinux_netif_to_cil(struct policydb *pdb, struct ocontext *netifs)
2747*2d543d20SAndroid Build Coastguard Worker {
2748*2d543d20SAndroid Build Coastguard Worker struct ocontext *netif;
2749*2d543d20SAndroid Build Coastguard Worker
2750*2d543d20SAndroid Build Coastguard Worker for (netif = netifs; netif != NULL; netif = netif->next) {
2751*2d543d20SAndroid Build Coastguard Worker cil_printf("(netifcon %s ", netif->u.name);
2752*2d543d20SAndroid Build Coastguard Worker context_to_cil(pdb, &netif->context[0]);
2753*2d543d20SAndroid Build Coastguard Worker
2754*2d543d20SAndroid Build Coastguard Worker cil_printf(" ");
2755*2d543d20SAndroid Build Coastguard Worker context_to_cil(pdb, &netif->context[1]);
2756*2d543d20SAndroid Build Coastguard Worker cil_printf(")\n");
2757*2d543d20SAndroid Build Coastguard Worker }
2758*2d543d20SAndroid Build Coastguard Worker
2759*2d543d20SAndroid Build Coastguard Worker return 0;
2760*2d543d20SAndroid Build Coastguard Worker }
2761*2d543d20SAndroid Build Coastguard Worker
ocontext_selinux_node_to_cil(struct policydb * pdb,struct ocontext * nodes)2762*2d543d20SAndroid Build Coastguard Worker static int ocontext_selinux_node_to_cil(struct policydb *pdb, struct ocontext *nodes)
2763*2d543d20SAndroid Build Coastguard Worker {
2764*2d543d20SAndroid Build Coastguard Worker int rc = -1;
2765*2d543d20SAndroid Build Coastguard Worker struct ocontext *node;
2766*2d543d20SAndroid Build Coastguard Worker char addr[INET_ADDRSTRLEN];
2767*2d543d20SAndroid Build Coastguard Worker char mask[INET_ADDRSTRLEN];
2768*2d543d20SAndroid Build Coastguard Worker
2769*2d543d20SAndroid Build Coastguard Worker for (node = nodes; node != NULL; node = node->next) {
2770*2d543d20SAndroid Build Coastguard Worker if (inet_ntop(AF_INET, &node->u.node.addr, addr, INET_ADDRSTRLEN) == NULL) {
2771*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Nodecon address is invalid: %m");
2772*2d543d20SAndroid Build Coastguard Worker rc = -1;
2773*2d543d20SAndroid Build Coastguard Worker goto exit;
2774*2d543d20SAndroid Build Coastguard Worker }
2775*2d543d20SAndroid Build Coastguard Worker
2776*2d543d20SAndroid Build Coastguard Worker if (inet_ntop(AF_INET, &node->u.node.mask, mask, INET_ADDRSTRLEN) == NULL) {
2777*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Nodecon mask is invalid: %m");
2778*2d543d20SAndroid Build Coastguard Worker rc = -1;
2779*2d543d20SAndroid Build Coastguard Worker goto exit;
2780*2d543d20SAndroid Build Coastguard Worker }
2781*2d543d20SAndroid Build Coastguard Worker
2782*2d543d20SAndroid Build Coastguard Worker cil_printf("(nodecon (%s) (%s) ", addr, mask);
2783*2d543d20SAndroid Build Coastguard Worker
2784*2d543d20SAndroid Build Coastguard Worker context_to_cil(pdb, &node->context[0]);
2785*2d543d20SAndroid Build Coastguard Worker
2786*2d543d20SAndroid Build Coastguard Worker cil_printf(")\n");
2787*2d543d20SAndroid Build Coastguard Worker }
2788*2d543d20SAndroid Build Coastguard Worker
2789*2d543d20SAndroid Build Coastguard Worker return 0;
2790*2d543d20SAndroid Build Coastguard Worker exit:
2791*2d543d20SAndroid Build Coastguard Worker return rc;
2792*2d543d20SAndroid Build Coastguard Worker }
2793*2d543d20SAndroid Build Coastguard Worker
ocontext_selinux_node6_to_cil(struct policydb * pdb,struct ocontext * nodes)2794*2d543d20SAndroid Build Coastguard Worker static int ocontext_selinux_node6_to_cil(struct policydb *pdb, struct ocontext *nodes)
2795*2d543d20SAndroid Build Coastguard Worker {
2796*2d543d20SAndroid Build Coastguard Worker int rc = -1;
2797*2d543d20SAndroid Build Coastguard Worker struct ocontext *node;
2798*2d543d20SAndroid Build Coastguard Worker char addr[INET6_ADDRSTRLEN];
2799*2d543d20SAndroid Build Coastguard Worker char mask[INET6_ADDRSTRLEN];
2800*2d543d20SAndroid Build Coastguard Worker
2801*2d543d20SAndroid Build Coastguard Worker for (node = nodes; node != NULL; node = node->next) {
2802*2d543d20SAndroid Build Coastguard Worker if (inet_ntop(AF_INET6, &node->u.node6.addr, addr, INET6_ADDRSTRLEN) == NULL) {
2803*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Nodecon address is invalid: %m");
2804*2d543d20SAndroid Build Coastguard Worker rc = -1;
2805*2d543d20SAndroid Build Coastguard Worker goto exit;
2806*2d543d20SAndroid Build Coastguard Worker }
2807*2d543d20SAndroid Build Coastguard Worker
2808*2d543d20SAndroid Build Coastguard Worker if (inet_ntop(AF_INET6, &node->u.node6.mask, mask, INET6_ADDRSTRLEN) == NULL) {
2809*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Nodecon mask is invalid: %m");
2810*2d543d20SAndroid Build Coastguard Worker rc = -1;
2811*2d543d20SAndroid Build Coastguard Worker goto exit;
2812*2d543d20SAndroid Build Coastguard Worker }
2813*2d543d20SAndroid Build Coastguard Worker
2814*2d543d20SAndroid Build Coastguard Worker cil_printf("(nodecon (%s) (%s) ", addr, mask);
2815*2d543d20SAndroid Build Coastguard Worker
2816*2d543d20SAndroid Build Coastguard Worker context_to_cil(pdb, &node->context[0]);
2817*2d543d20SAndroid Build Coastguard Worker
2818*2d543d20SAndroid Build Coastguard Worker cil_printf(")\n");
2819*2d543d20SAndroid Build Coastguard Worker }
2820*2d543d20SAndroid Build Coastguard Worker
2821*2d543d20SAndroid Build Coastguard Worker return 0;
2822*2d543d20SAndroid Build Coastguard Worker exit:
2823*2d543d20SAndroid Build Coastguard Worker return rc;
2824*2d543d20SAndroid Build Coastguard Worker }
2825*2d543d20SAndroid Build Coastguard Worker
ocontext_selinux_ibendport_to_cil(struct policydb * pdb,struct ocontext * ibendports)2826*2d543d20SAndroid Build Coastguard Worker static int ocontext_selinux_ibendport_to_cil(struct policydb *pdb, struct ocontext *ibendports)
2827*2d543d20SAndroid Build Coastguard Worker {
2828*2d543d20SAndroid Build Coastguard Worker struct ocontext *ibendport;
2829*2d543d20SAndroid Build Coastguard Worker
2830*2d543d20SAndroid Build Coastguard Worker for (ibendport = ibendports; ibendport; ibendport = ibendport->next) {
2831*2d543d20SAndroid Build Coastguard Worker cil_printf("(ibendportcon %s %u ", ibendport->u.ibendport.dev_name, ibendport->u.ibendport.port);
2832*2d543d20SAndroid Build Coastguard Worker context_to_cil(pdb, &ibendport->context[0]);
2833*2d543d20SAndroid Build Coastguard Worker
2834*2d543d20SAndroid Build Coastguard Worker cil_printf(")\n");
2835*2d543d20SAndroid Build Coastguard Worker }
2836*2d543d20SAndroid Build Coastguard Worker
2837*2d543d20SAndroid Build Coastguard Worker return 0;
2838*2d543d20SAndroid Build Coastguard Worker }
2839*2d543d20SAndroid Build Coastguard Worker
ocontext_selinux_fsuse_to_cil(struct policydb * pdb,struct ocontext * fsuses)2840*2d543d20SAndroid Build Coastguard Worker static int ocontext_selinux_fsuse_to_cil(struct policydb *pdb, struct ocontext *fsuses)
2841*2d543d20SAndroid Build Coastguard Worker {
2842*2d543d20SAndroid Build Coastguard Worker int rc = -1;
2843*2d543d20SAndroid Build Coastguard Worker struct ocontext *fsuse;
2844*2d543d20SAndroid Build Coastguard Worker const char *behavior;
2845*2d543d20SAndroid Build Coastguard Worker
2846*2d543d20SAndroid Build Coastguard Worker
2847*2d543d20SAndroid Build Coastguard Worker for (fsuse = fsuses; fsuse != NULL; fsuse = fsuse->next) {
2848*2d543d20SAndroid Build Coastguard Worker switch (fsuse->v.behavior) {
2849*2d543d20SAndroid Build Coastguard Worker case SECURITY_FS_USE_XATTR: behavior = "xattr"; break;
2850*2d543d20SAndroid Build Coastguard Worker case SECURITY_FS_USE_TRANS: behavior = "trans"; break;
2851*2d543d20SAndroid Build Coastguard Worker case SECURITY_FS_USE_TASK: behavior = "task"; break;
2852*2d543d20SAndroid Build Coastguard Worker default:
2853*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Unknown fsuse behavior: %i", fsuse->v.behavior);
2854*2d543d20SAndroid Build Coastguard Worker rc = -1;
2855*2d543d20SAndroid Build Coastguard Worker goto exit;
2856*2d543d20SAndroid Build Coastguard Worker }
2857*2d543d20SAndroid Build Coastguard Worker
2858*2d543d20SAndroid Build Coastguard Worker cil_printf("(fsuse %s %s ", behavior, fsuse->u.name);
2859*2d543d20SAndroid Build Coastguard Worker
2860*2d543d20SAndroid Build Coastguard Worker context_to_cil(pdb, &fsuse->context[0]);
2861*2d543d20SAndroid Build Coastguard Worker
2862*2d543d20SAndroid Build Coastguard Worker cil_printf(")\n");
2863*2d543d20SAndroid Build Coastguard Worker
2864*2d543d20SAndroid Build Coastguard Worker }
2865*2d543d20SAndroid Build Coastguard Worker
2866*2d543d20SAndroid Build Coastguard Worker return 0;
2867*2d543d20SAndroid Build Coastguard Worker exit:
2868*2d543d20SAndroid Build Coastguard Worker return rc;
2869*2d543d20SAndroid Build Coastguard Worker }
2870*2d543d20SAndroid Build Coastguard Worker
2871*2d543d20SAndroid Build Coastguard Worker
ocontext_xen_isid_to_cil(struct policydb * pdb,struct ocontext * isids)2872*2d543d20SAndroid Build Coastguard Worker static int ocontext_xen_isid_to_cil(struct policydb *pdb, struct ocontext *isids)
2873*2d543d20SAndroid Build Coastguard Worker {
2874*2d543d20SAndroid Build Coastguard Worker int rc = -1;
2875*2d543d20SAndroid Build Coastguard Worker
2876*2d543d20SAndroid Build Coastguard Worker rc = ocontext_isid_to_cil(pdb, xen_sid_to_str, XEN_SID_SZ, isids);
2877*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
2878*2d543d20SAndroid Build Coastguard Worker goto exit;
2879*2d543d20SAndroid Build Coastguard Worker }
2880*2d543d20SAndroid Build Coastguard Worker
2881*2d543d20SAndroid Build Coastguard Worker return 0;
2882*2d543d20SAndroid Build Coastguard Worker
2883*2d543d20SAndroid Build Coastguard Worker exit:
2884*2d543d20SAndroid Build Coastguard Worker return rc;
2885*2d543d20SAndroid Build Coastguard Worker }
2886*2d543d20SAndroid Build Coastguard Worker
ocontext_xen_pirq_to_cil(struct policydb * pdb,struct ocontext * pirqs)2887*2d543d20SAndroid Build Coastguard Worker static int ocontext_xen_pirq_to_cil(struct policydb *pdb, struct ocontext *pirqs)
2888*2d543d20SAndroid Build Coastguard Worker {
2889*2d543d20SAndroid Build Coastguard Worker struct ocontext *pirq;
2890*2d543d20SAndroid Build Coastguard Worker
2891*2d543d20SAndroid Build Coastguard Worker for (pirq = pirqs; pirq != NULL; pirq = pirq->next) {
2892*2d543d20SAndroid Build Coastguard Worker cil_printf("(pirqcon %i ", pirq->u.pirq);
2893*2d543d20SAndroid Build Coastguard Worker context_to_cil(pdb, &pirq->context[0]);
2894*2d543d20SAndroid Build Coastguard Worker cil_printf(")\n");
2895*2d543d20SAndroid Build Coastguard Worker }
2896*2d543d20SAndroid Build Coastguard Worker
2897*2d543d20SAndroid Build Coastguard Worker return 0;
2898*2d543d20SAndroid Build Coastguard Worker }
2899*2d543d20SAndroid Build Coastguard Worker
ocontext_xen_ioport_to_cil(struct policydb * pdb,struct ocontext * ioports)2900*2d543d20SAndroid Build Coastguard Worker static int ocontext_xen_ioport_to_cil(struct policydb *pdb, struct ocontext *ioports)
2901*2d543d20SAndroid Build Coastguard Worker {
2902*2d543d20SAndroid Build Coastguard Worker struct ocontext *ioport;
2903*2d543d20SAndroid Build Coastguard Worker uint32_t low;
2904*2d543d20SAndroid Build Coastguard Worker uint32_t high;
2905*2d543d20SAndroid Build Coastguard Worker
2906*2d543d20SAndroid Build Coastguard Worker for (ioport = ioports; ioport != NULL; ioport = ioport->next) {
2907*2d543d20SAndroid Build Coastguard Worker low = ioport->u.ioport.low_ioport;
2908*2d543d20SAndroid Build Coastguard Worker high = ioport->u.ioport.high_ioport;
2909*2d543d20SAndroid Build Coastguard Worker
2910*2d543d20SAndroid Build Coastguard Worker if (low == high) {
2911*2d543d20SAndroid Build Coastguard Worker cil_printf("(ioportcon 0x%x ", low);
2912*2d543d20SAndroid Build Coastguard Worker } else {
2913*2d543d20SAndroid Build Coastguard Worker cil_printf("(ioportcon (0x%x 0x%x) ", low, high);
2914*2d543d20SAndroid Build Coastguard Worker }
2915*2d543d20SAndroid Build Coastguard Worker
2916*2d543d20SAndroid Build Coastguard Worker context_to_cil(pdb, &ioport->context[0]);
2917*2d543d20SAndroid Build Coastguard Worker
2918*2d543d20SAndroid Build Coastguard Worker cil_printf(")\n");
2919*2d543d20SAndroid Build Coastguard Worker }
2920*2d543d20SAndroid Build Coastguard Worker
2921*2d543d20SAndroid Build Coastguard Worker return 0;
2922*2d543d20SAndroid Build Coastguard Worker }
2923*2d543d20SAndroid Build Coastguard Worker
ocontext_xen_iomem_to_cil(struct policydb * pdb,struct ocontext * iomems)2924*2d543d20SAndroid Build Coastguard Worker static int ocontext_xen_iomem_to_cil(struct policydb *pdb, struct ocontext *iomems)
2925*2d543d20SAndroid Build Coastguard Worker {
2926*2d543d20SAndroid Build Coastguard Worker struct ocontext *iomem;
2927*2d543d20SAndroid Build Coastguard Worker uint64_t low;
2928*2d543d20SAndroid Build Coastguard Worker uint64_t high;
2929*2d543d20SAndroid Build Coastguard Worker
2930*2d543d20SAndroid Build Coastguard Worker for (iomem = iomems; iomem != NULL; iomem = iomem->next) {
2931*2d543d20SAndroid Build Coastguard Worker low = iomem->u.iomem.low_iomem;
2932*2d543d20SAndroid Build Coastguard Worker high = iomem->u.iomem.high_iomem;
2933*2d543d20SAndroid Build Coastguard Worker
2934*2d543d20SAndroid Build Coastguard Worker if (low == high) {
2935*2d543d20SAndroid Build Coastguard Worker cil_printf("(iomemcon 0x%"PRIx64" ", low);
2936*2d543d20SAndroid Build Coastguard Worker } else {
2937*2d543d20SAndroid Build Coastguard Worker cil_printf("(iomemcon (0x%"PRIx64" 0x%"PRIx64") ", low, high);
2938*2d543d20SAndroid Build Coastguard Worker }
2939*2d543d20SAndroid Build Coastguard Worker
2940*2d543d20SAndroid Build Coastguard Worker context_to_cil(pdb, &iomem->context[0]);
2941*2d543d20SAndroid Build Coastguard Worker
2942*2d543d20SAndroid Build Coastguard Worker cil_printf(")\n");
2943*2d543d20SAndroid Build Coastguard Worker }
2944*2d543d20SAndroid Build Coastguard Worker
2945*2d543d20SAndroid Build Coastguard Worker return 0;
2946*2d543d20SAndroid Build Coastguard Worker }
2947*2d543d20SAndroid Build Coastguard Worker
ocontext_xen_pcidevice_to_cil(struct policydb * pdb,struct ocontext * pcids)2948*2d543d20SAndroid Build Coastguard Worker static int ocontext_xen_pcidevice_to_cil(struct policydb *pdb, struct ocontext *pcids)
2949*2d543d20SAndroid Build Coastguard Worker {
2950*2d543d20SAndroid Build Coastguard Worker struct ocontext *pcid;
2951*2d543d20SAndroid Build Coastguard Worker
2952*2d543d20SAndroid Build Coastguard Worker for (pcid = pcids; pcid != NULL; pcid = pcid->next) {
2953*2d543d20SAndroid Build Coastguard Worker cil_printf("(pcidevicecon 0x%lx ", (unsigned long)pcid->u.device);
2954*2d543d20SAndroid Build Coastguard Worker context_to_cil(pdb, &pcid->context[0]);
2955*2d543d20SAndroid Build Coastguard Worker cil_printf(")\n");
2956*2d543d20SAndroid Build Coastguard Worker }
2957*2d543d20SAndroid Build Coastguard Worker
2958*2d543d20SAndroid Build Coastguard Worker return 0;
2959*2d543d20SAndroid Build Coastguard Worker }
2960*2d543d20SAndroid Build Coastguard Worker
ocontexts_to_cil(struct policydb * pdb)2961*2d543d20SAndroid Build Coastguard Worker static int ocontexts_to_cil(struct policydb *pdb)
2962*2d543d20SAndroid Build Coastguard Worker {
2963*2d543d20SAndroid Build Coastguard Worker int rc = -1;
2964*2d543d20SAndroid Build Coastguard Worker int ocon;
2965*2d543d20SAndroid Build Coastguard Worker
2966*2d543d20SAndroid Build Coastguard Worker static int (*const *ocon_funcs)(struct policydb *pdb, struct ocontext *ocon);
2967*2d543d20SAndroid Build Coastguard Worker static int (*const ocon_selinux_funcs[OCON_NUM])(struct policydb *pdb, struct ocontext *ocon) = {
2968*2d543d20SAndroid Build Coastguard Worker ocontext_selinux_isid_to_cil,
2969*2d543d20SAndroid Build Coastguard Worker ocontext_selinux_fs_to_cil,
2970*2d543d20SAndroid Build Coastguard Worker ocontext_selinux_port_to_cil,
2971*2d543d20SAndroid Build Coastguard Worker ocontext_selinux_netif_to_cil,
2972*2d543d20SAndroid Build Coastguard Worker ocontext_selinux_node_to_cil,
2973*2d543d20SAndroid Build Coastguard Worker ocontext_selinux_fsuse_to_cil,
2974*2d543d20SAndroid Build Coastguard Worker ocontext_selinux_node6_to_cil,
2975*2d543d20SAndroid Build Coastguard Worker ocontext_selinux_ibpkey_to_cil,
2976*2d543d20SAndroid Build Coastguard Worker ocontext_selinux_ibendport_to_cil,
2977*2d543d20SAndroid Build Coastguard Worker };
2978*2d543d20SAndroid Build Coastguard Worker static int (*const ocon_xen_funcs[OCON_NUM])(struct policydb *pdb, struct ocontext *ocon) = {
2979*2d543d20SAndroid Build Coastguard Worker ocontext_xen_isid_to_cil,
2980*2d543d20SAndroid Build Coastguard Worker ocontext_xen_pirq_to_cil,
2981*2d543d20SAndroid Build Coastguard Worker ocontext_xen_ioport_to_cil,
2982*2d543d20SAndroid Build Coastguard Worker ocontext_xen_iomem_to_cil,
2983*2d543d20SAndroid Build Coastguard Worker ocontext_xen_pcidevice_to_cil,
2984*2d543d20SAndroid Build Coastguard Worker NULL,
2985*2d543d20SAndroid Build Coastguard Worker NULL,
2986*2d543d20SAndroid Build Coastguard Worker };
2987*2d543d20SAndroid Build Coastguard Worker
2988*2d543d20SAndroid Build Coastguard Worker switch (pdb->target_platform) {
2989*2d543d20SAndroid Build Coastguard Worker case SEPOL_TARGET_SELINUX:
2990*2d543d20SAndroid Build Coastguard Worker ocon_funcs = ocon_selinux_funcs;
2991*2d543d20SAndroid Build Coastguard Worker break;
2992*2d543d20SAndroid Build Coastguard Worker case SEPOL_TARGET_XEN:
2993*2d543d20SAndroid Build Coastguard Worker ocon_funcs = ocon_xen_funcs;
2994*2d543d20SAndroid Build Coastguard Worker break;
2995*2d543d20SAndroid Build Coastguard Worker default:
2996*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Unknown target platform: %i", pdb->target_platform);
2997*2d543d20SAndroid Build Coastguard Worker rc = -1;
2998*2d543d20SAndroid Build Coastguard Worker goto exit;
2999*2d543d20SAndroid Build Coastguard Worker }
3000*2d543d20SAndroid Build Coastguard Worker
3001*2d543d20SAndroid Build Coastguard Worker for (ocon = 0; ocon < OCON_NUM; ocon++) {
3002*2d543d20SAndroid Build Coastguard Worker if (ocon_funcs[ocon] != NULL) {
3003*2d543d20SAndroid Build Coastguard Worker rc = ocon_funcs[ocon](pdb, pdb->ocontexts[ocon]);
3004*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
3005*2d543d20SAndroid Build Coastguard Worker goto exit;
3006*2d543d20SAndroid Build Coastguard Worker }
3007*2d543d20SAndroid Build Coastguard Worker }
3008*2d543d20SAndroid Build Coastguard Worker }
3009*2d543d20SAndroid Build Coastguard Worker
3010*2d543d20SAndroid Build Coastguard Worker return 0;
3011*2d543d20SAndroid Build Coastguard Worker exit:
3012*2d543d20SAndroid Build Coastguard Worker return rc;
3013*2d543d20SAndroid Build Coastguard Worker }
3014*2d543d20SAndroid Build Coastguard Worker
genfscon_to_cil(struct policydb * pdb)3015*2d543d20SAndroid Build Coastguard Worker static int genfscon_to_cil(struct policydb *pdb)
3016*2d543d20SAndroid Build Coastguard Worker {
3017*2d543d20SAndroid Build Coastguard Worker struct genfs *genfs;
3018*2d543d20SAndroid Build Coastguard Worker struct ocontext *ocon;
3019*2d543d20SAndroid Build Coastguard Worker uint32_t sclass;
3020*2d543d20SAndroid Build Coastguard Worker
3021*2d543d20SAndroid Build Coastguard Worker for (genfs = pdb->genfs; genfs != NULL; genfs = genfs->next) {
3022*2d543d20SAndroid Build Coastguard Worker for (ocon = genfs->head; ocon != NULL; ocon = ocon->next) {
3023*2d543d20SAndroid Build Coastguard Worker sclass = ocon->v.sclass;
3024*2d543d20SAndroid Build Coastguard Worker if (sclass) {
3025*2d543d20SAndroid Build Coastguard Worker const char *file_type;
3026*2d543d20SAndroid Build Coastguard Worker const char *class_name = pdb->p_class_val_to_name[sclass-1];
3027*2d543d20SAndroid Build Coastguard Worker if (strcmp(class_name, "file") == 0) {
3028*2d543d20SAndroid Build Coastguard Worker file_type = "file";
3029*2d543d20SAndroid Build Coastguard Worker } else if (strcmp(class_name, "dir") == 0) {
3030*2d543d20SAndroid Build Coastguard Worker file_type = "dir";
3031*2d543d20SAndroid Build Coastguard Worker } else if (strcmp(class_name, "chr_file") == 0) {
3032*2d543d20SAndroid Build Coastguard Worker file_type = "char";
3033*2d543d20SAndroid Build Coastguard Worker } else if (strcmp(class_name, "blk_file") == 0) {
3034*2d543d20SAndroid Build Coastguard Worker file_type = "block";
3035*2d543d20SAndroid Build Coastguard Worker } else if (strcmp(class_name, "sock_file") == 0) {
3036*2d543d20SAndroid Build Coastguard Worker file_type = "socket";
3037*2d543d20SAndroid Build Coastguard Worker } else if (strcmp(class_name, "fifo_file") == 0) {
3038*2d543d20SAndroid Build Coastguard Worker file_type = "pipe";
3039*2d543d20SAndroid Build Coastguard Worker } else if (strcmp(class_name, "lnk_file") == 0) {
3040*2d543d20SAndroid Build Coastguard Worker file_type = "symlink";
3041*2d543d20SAndroid Build Coastguard Worker } else {
3042*2d543d20SAndroid Build Coastguard Worker return -1;
3043*2d543d20SAndroid Build Coastguard Worker }
3044*2d543d20SAndroid Build Coastguard Worker cil_printf("(genfscon %s \"%s\" %s ", genfs->fstype, ocon->u.name, file_type);
3045*2d543d20SAndroid Build Coastguard Worker } else {
3046*2d543d20SAndroid Build Coastguard Worker cil_printf("(genfscon %s \"%s\" ", genfs->fstype, ocon->u.name);
3047*2d543d20SAndroid Build Coastguard Worker }
3048*2d543d20SAndroid Build Coastguard Worker context_to_cil(pdb, &ocon->context[0]);
3049*2d543d20SAndroid Build Coastguard Worker cil_printf(")\n");
3050*2d543d20SAndroid Build Coastguard Worker }
3051*2d543d20SAndroid Build Coastguard Worker }
3052*2d543d20SAndroid Build Coastguard Worker
3053*2d543d20SAndroid Build Coastguard Worker return 0;
3054*2d543d20SAndroid Build Coastguard Worker }
3055*2d543d20SAndroid Build Coastguard Worker
level_string_to_cil(char * levelstr)3056*2d543d20SAndroid Build Coastguard Worker static int level_string_to_cil(char *levelstr)
3057*2d543d20SAndroid Build Coastguard Worker {
3058*2d543d20SAndroid Build Coastguard Worker int rc = -1;
3059*2d543d20SAndroid Build Coastguard Worker char *sens = NULL;
3060*2d543d20SAndroid Build Coastguard Worker char *cats = NULL;
3061*2d543d20SAndroid Build Coastguard Worker int matched;
3062*2d543d20SAndroid Build Coastguard Worker char *saveptr = NULL;
3063*2d543d20SAndroid Build Coastguard Worker char *token = NULL;
3064*2d543d20SAndroid Build Coastguard Worker char *ranged = NULL;
3065*2d543d20SAndroid Build Coastguard Worker
3066*2d543d20SAndroid Build Coastguard Worker matched = tokenize(levelstr, ':', 2, &sens, &cats);
3067*2d543d20SAndroid Build Coastguard Worker if (matched < 1 || matched > 2) {
3068*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Invalid level: %s", levelstr);
3069*2d543d20SAndroid Build Coastguard Worker rc = -1;
3070*2d543d20SAndroid Build Coastguard Worker goto exit;
3071*2d543d20SAndroid Build Coastguard Worker }
3072*2d543d20SAndroid Build Coastguard Worker
3073*2d543d20SAndroid Build Coastguard Worker cil_printf("(%s", sens);
3074*2d543d20SAndroid Build Coastguard Worker
3075*2d543d20SAndroid Build Coastguard Worker if (matched == 2) {
3076*2d543d20SAndroid Build Coastguard Worker cil_printf("(");
3077*2d543d20SAndroid Build Coastguard Worker token = strtok_r(cats, ",", &saveptr);
3078*2d543d20SAndroid Build Coastguard Worker while (token != NULL) {
3079*2d543d20SAndroid Build Coastguard Worker ranged = strchr(token, '.');
3080*2d543d20SAndroid Build Coastguard Worker if (ranged == NULL) {
3081*2d543d20SAndroid Build Coastguard Worker cil_printf("%s ", token);
3082*2d543d20SAndroid Build Coastguard Worker } else {
3083*2d543d20SAndroid Build Coastguard Worker *ranged = '\0';
3084*2d543d20SAndroid Build Coastguard Worker cil_printf("(range %s %s) ", token, ranged + 1);
3085*2d543d20SAndroid Build Coastguard Worker }
3086*2d543d20SAndroid Build Coastguard Worker token = strtok_r(NULL, ",", &saveptr);
3087*2d543d20SAndroid Build Coastguard Worker }
3088*2d543d20SAndroid Build Coastguard Worker cil_printf(")");
3089*2d543d20SAndroid Build Coastguard Worker }
3090*2d543d20SAndroid Build Coastguard Worker
3091*2d543d20SAndroid Build Coastguard Worker cil_printf(")");
3092*2d543d20SAndroid Build Coastguard Worker
3093*2d543d20SAndroid Build Coastguard Worker rc = 0;
3094*2d543d20SAndroid Build Coastguard Worker exit:
3095*2d543d20SAndroid Build Coastguard Worker free(sens);
3096*2d543d20SAndroid Build Coastguard Worker free(cats);
3097*2d543d20SAndroid Build Coastguard Worker return rc;
3098*2d543d20SAndroid Build Coastguard Worker }
3099*2d543d20SAndroid Build Coastguard Worker
level_range_string_to_cil(char * levelrangestr)3100*2d543d20SAndroid Build Coastguard Worker static int level_range_string_to_cil(char *levelrangestr)
3101*2d543d20SAndroid Build Coastguard Worker {
3102*2d543d20SAndroid Build Coastguard Worker char *ranged = NULL;
3103*2d543d20SAndroid Build Coastguard Worker char *low;
3104*2d543d20SAndroid Build Coastguard Worker char *high;
3105*2d543d20SAndroid Build Coastguard Worker
3106*2d543d20SAndroid Build Coastguard Worker ranged = strchr(levelrangestr, '-');
3107*2d543d20SAndroid Build Coastguard Worker if (ranged == NULL) {
3108*2d543d20SAndroid Build Coastguard Worker low = high = levelrangestr;
3109*2d543d20SAndroid Build Coastguard Worker } else {
3110*2d543d20SAndroid Build Coastguard Worker *ranged = '\0';
3111*2d543d20SAndroid Build Coastguard Worker low = levelrangestr;
3112*2d543d20SAndroid Build Coastguard Worker high = ranged + 1;
3113*2d543d20SAndroid Build Coastguard Worker }
3114*2d543d20SAndroid Build Coastguard Worker
3115*2d543d20SAndroid Build Coastguard Worker level_string_to_cil(low);
3116*2d543d20SAndroid Build Coastguard Worker cil_printf(" ");
3117*2d543d20SAndroid Build Coastguard Worker level_string_to_cil(high);
3118*2d543d20SAndroid Build Coastguard Worker
3119*2d543d20SAndroid Build Coastguard Worker return 0;
3120*2d543d20SAndroid Build Coastguard Worker }
3121*2d543d20SAndroid Build Coastguard Worker
context_string_to_cil(char * contextstr)3122*2d543d20SAndroid Build Coastguard Worker static int context_string_to_cil(char *contextstr)
3123*2d543d20SAndroid Build Coastguard Worker {
3124*2d543d20SAndroid Build Coastguard Worker int rc = -1;
3125*2d543d20SAndroid Build Coastguard Worker int matched;
3126*2d543d20SAndroid Build Coastguard Worker char *user = NULL;
3127*2d543d20SAndroid Build Coastguard Worker char *role = NULL;
3128*2d543d20SAndroid Build Coastguard Worker char *type = NULL;
3129*2d543d20SAndroid Build Coastguard Worker char *level = NULL;
3130*2d543d20SAndroid Build Coastguard Worker
3131*2d543d20SAndroid Build Coastguard Worker matched = tokenize(contextstr, ':', 4, &user, &role, &type, &level);
3132*2d543d20SAndroid Build Coastguard Worker if (matched < 3 || matched > 4) {
3133*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Invalid context: %s", contextstr);
3134*2d543d20SAndroid Build Coastguard Worker rc = -1;
3135*2d543d20SAndroid Build Coastguard Worker goto exit;
3136*2d543d20SAndroid Build Coastguard Worker }
3137*2d543d20SAndroid Build Coastguard Worker
3138*2d543d20SAndroid Build Coastguard Worker cil_printf("(%s %s %s (", user, role, type);
3139*2d543d20SAndroid Build Coastguard Worker
3140*2d543d20SAndroid Build Coastguard Worker if (matched == 3) {
3141*2d543d20SAndroid Build Coastguard Worker cil_printf(DEFAULT_LEVEL);
3142*2d543d20SAndroid Build Coastguard Worker cil_printf(" ");
3143*2d543d20SAndroid Build Coastguard Worker cil_printf(DEFAULT_LEVEL);
3144*2d543d20SAndroid Build Coastguard Worker } else {
3145*2d543d20SAndroid Build Coastguard Worker level_range_string_to_cil(level);
3146*2d543d20SAndroid Build Coastguard Worker }
3147*2d543d20SAndroid Build Coastguard Worker
3148*2d543d20SAndroid Build Coastguard Worker cil_printf("))");
3149*2d543d20SAndroid Build Coastguard Worker
3150*2d543d20SAndroid Build Coastguard Worker rc = 0;
3151*2d543d20SAndroid Build Coastguard Worker
3152*2d543d20SAndroid Build Coastguard Worker exit:
3153*2d543d20SAndroid Build Coastguard Worker free(user);
3154*2d543d20SAndroid Build Coastguard Worker free(role);
3155*2d543d20SAndroid Build Coastguard Worker free(type);
3156*2d543d20SAndroid Build Coastguard Worker free(level);
3157*2d543d20SAndroid Build Coastguard Worker
3158*2d543d20SAndroid Build Coastguard Worker return rc;
3159*2d543d20SAndroid Build Coastguard Worker }
3160*2d543d20SAndroid Build Coastguard Worker
seusers_to_cil(struct sepol_module_package * mod_pkg)3161*2d543d20SAndroid Build Coastguard Worker static int seusers_to_cil(struct sepol_module_package *mod_pkg)
3162*2d543d20SAndroid Build Coastguard Worker {
3163*2d543d20SAndroid Build Coastguard Worker int rc = -1;
3164*2d543d20SAndroid Build Coastguard Worker char *seusers = sepol_module_package_get_seusers(mod_pkg);
3165*2d543d20SAndroid Build Coastguard Worker size_t seusers_len = sepol_module_package_get_seusers_len(mod_pkg);
3166*2d543d20SAndroid Build Coastguard Worker char *cur = seusers;
3167*2d543d20SAndroid Build Coastguard Worker char *end = seusers + seusers_len;
3168*2d543d20SAndroid Build Coastguard Worker char *line = NULL;
3169*2d543d20SAndroid Build Coastguard Worker char *user = NULL;
3170*2d543d20SAndroid Build Coastguard Worker char *seuser = NULL;
3171*2d543d20SAndroid Build Coastguard Worker char *level = NULL;
3172*2d543d20SAndroid Build Coastguard Worker char *tmp = NULL;
3173*2d543d20SAndroid Build Coastguard Worker int matched;
3174*2d543d20SAndroid Build Coastguard Worker
3175*2d543d20SAndroid Build Coastguard Worker if (seusers_len == 0) {
3176*2d543d20SAndroid Build Coastguard Worker return 0;
3177*2d543d20SAndroid Build Coastguard Worker }
3178*2d543d20SAndroid Build Coastguard Worker
3179*2d543d20SAndroid Build Coastguard Worker while ((rc = get_line(&cur, end, &line)) > 0) {
3180*2d543d20SAndroid Build Coastguard Worker tmp = line;
3181*2d543d20SAndroid Build Coastguard Worker while (isspace(*tmp)) {
3182*2d543d20SAndroid Build Coastguard Worker tmp++;
3183*2d543d20SAndroid Build Coastguard Worker }
3184*2d543d20SAndroid Build Coastguard Worker
3185*2d543d20SAndroid Build Coastguard Worker if (tmp[0] == '#' || tmp[0] == '\0') {
3186*2d543d20SAndroid Build Coastguard Worker free(line);
3187*2d543d20SAndroid Build Coastguard Worker line = NULL;
3188*2d543d20SAndroid Build Coastguard Worker continue;
3189*2d543d20SAndroid Build Coastguard Worker }
3190*2d543d20SAndroid Build Coastguard Worker
3191*2d543d20SAndroid Build Coastguard Worker matched = tokenize(tmp, ':', 3, &user, &seuser, &level);
3192*2d543d20SAndroid Build Coastguard Worker
3193*2d543d20SAndroid Build Coastguard Worker if (matched < 2 || matched > 3) {
3194*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Invalid seuser line: %s", line);
3195*2d543d20SAndroid Build Coastguard Worker rc = -1;
3196*2d543d20SAndroid Build Coastguard Worker goto exit;
3197*2d543d20SAndroid Build Coastguard Worker }
3198*2d543d20SAndroid Build Coastguard Worker
3199*2d543d20SAndroid Build Coastguard Worker if (!strcmp(user, "__default__")) {
3200*2d543d20SAndroid Build Coastguard Worker cil_printf("(selinuxuserdefault %s (", seuser);
3201*2d543d20SAndroid Build Coastguard Worker } else {
3202*2d543d20SAndroid Build Coastguard Worker cil_printf("(selinuxuser %s %s (", user, seuser);
3203*2d543d20SAndroid Build Coastguard Worker }
3204*2d543d20SAndroid Build Coastguard Worker
3205*2d543d20SAndroid Build Coastguard Worker switch (matched) {
3206*2d543d20SAndroid Build Coastguard Worker case 2:
3207*2d543d20SAndroid Build Coastguard Worker cil_printf("systemlow systemlow");
3208*2d543d20SAndroid Build Coastguard Worker break;
3209*2d543d20SAndroid Build Coastguard Worker case 3:
3210*2d543d20SAndroid Build Coastguard Worker level_range_string_to_cil(level);
3211*2d543d20SAndroid Build Coastguard Worker break;
3212*2d543d20SAndroid Build Coastguard Worker }
3213*2d543d20SAndroid Build Coastguard Worker
3214*2d543d20SAndroid Build Coastguard Worker cil_printf("))\n");
3215*2d543d20SAndroid Build Coastguard Worker
3216*2d543d20SAndroid Build Coastguard Worker free(user);
3217*2d543d20SAndroid Build Coastguard Worker free(seuser);
3218*2d543d20SAndroid Build Coastguard Worker free(level);
3219*2d543d20SAndroid Build Coastguard Worker free(line);
3220*2d543d20SAndroid Build Coastguard Worker user = seuser = level = NULL;
3221*2d543d20SAndroid Build Coastguard Worker }
3222*2d543d20SAndroid Build Coastguard Worker
3223*2d543d20SAndroid Build Coastguard Worker if (rc == -1) {
3224*2d543d20SAndroid Build Coastguard Worker cil_printf("Failed to read seusers\n");
3225*2d543d20SAndroid Build Coastguard Worker goto exit;
3226*2d543d20SAndroid Build Coastguard Worker }
3227*2d543d20SAndroid Build Coastguard Worker
3228*2d543d20SAndroid Build Coastguard Worker rc = 0;
3229*2d543d20SAndroid Build Coastguard Worker exit:
3230*2d543d20SAndroid Build Coastguard Worker free(line);
3231*2d543d20SAndroid Build Coastguard Worker free(user);
3232*2d543d20SAndroid Build Coastguard Worker free(seuser);
3233*2d543d20SAndroid Build Coastguard Worker free(level);
3234*2d543d20SAndroid Build Coastguard Worker
3235*2d543d20SAndroid Build Coastguard Worker return rc;
3236*2d543d20SAndroid Build Coastguard Worker }
3237*2d543d20SAndroid Build Coastguard Worker
netfilter_contexts_to_cil(struct sepol_module_package * mod_pkg)3238*2d543d20SAndroid Build Coastguard Worker static int netfilter_contexts_to_cil(struct sepol_module_package *mod_pkg)
3239*2d543d20SAndroid Build Coastguard Worker {
3240*2d543d20SAndroid Build Coastguard Worker size_t netcons_len = sepol_module_package_get_netfilter_contexts_len(mod_pkg);
3241*2d543d20SAndroid Build Coastguard Worker
3242*2d543d20SAndroid Build Coastguard Worker if (netcons_len > 0) {
3243*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Warning: netfilter_contexts are unsupported in CIL. Dropping from output.");
3244*2d543d20SAndroid Build Coastguard Worker }
3245*2d543d20SAndroid Build Coastguard Worker
3246*2d543d20SAndroid Build Coastguard Worker return 0;
3247*2d543d20SAndroid Build Coastguard Worker }
3248*2d543d20SAndroid Build Coastguard Worker
user_extra_to_cil(struct sepol_module_package * mod_pkg)3249*2d543d20SAndroid Build Coastguard Worker static int user_extra_to_cil(struct sepol_module_package *mod_pkg)
3250*2d543d20SAndroid Build Coastguard Worker {
3251*2d543d20SAndroid Build Coastguard Worker int rc = -1;
3252*2d543d20SAndroid Build Coastguard Worker char *userx = sepol_module_package_get_user_extra(mod_pkg);
3253*2d543d20SAndroid Build Coastguard Worker size_t userx_len = sepol_module_package_get_user_extra_len(mod_pkg);
3254*2d543d20SAndroid Build Coastguard Worker char *cur = userx;
3255*2d543d20SAndroid Build Coastguard Worker char *end = userx + userx_len;
3256*2d543d20SAndroid Build Coastguard Worker char *line;
3257*2d543d20SAndroid Build Coastguard Worker int matched;
3258*2d543d20SAndroid Build Coastguard Worker char *user = NULL;
3259*2d543d20SAndroid Build Coastguard Worker char *prefix = NULL;
3260*2d543d20SAndroid Build Coastguard Worker int prefix_len = 0;
3261*2d543d20SAndroid Build Coastguard Worker char *user_str = NULL;
3262*2d543d20SAndroid Build Coastguard Worker char *prefix_str = NULL;
3263*2d543d20SAndroid Build Coastguard Worker char *eol = NULL;
3264*2d543d20SAndroid Build Coastguard Worker char *tmp = NULL;
3265*2d543d20SAndroid Build Coastguard Worker
3266*2d543d20SAndroid Build Coastguard Worker if (userx_len == 0) {
3267*2d543d20SAndroid Build Coastguard Worker return 0;
3268*2d543d20SAndroid Build Coastguard Worker }
3269*2d543d20SAndroid Build Coastguard Worker
3270*2d543d20SAndroid Build Coastguard Worker while ((rc = get_line(&cur, end, &line)) > 0) {
3271*2d543d20SAndroid Build Coastguard Worker tmp = line;
3272*2d543d20SAndroid Build Coastguard Worker while (isspace(*tmp)) {
3273*2d543d20SAndroid Build Coastguard Worker tmp++;
3274*2d543d20SAndroid Build Coastguard Worker }
3275*2d543d20SAndroid Build Coastguard Worker
3276*2d543d20SAndroid Build Coastguard Worker if (tmp[0] == '#' || tmp[0] == '\0') {
3277*2d543d20SAndroid Build Coastguard Worker free(line);
3278*2d543d20SAndroid Build Coastguard Worker line = NULL;
3279*2d543d20SAndroid Build Coastguard Worker continue;
3280*2d543d20SAndroid Build Coastguard Worker }
3281*2d543d20SAndroid Build Coastguard Worker
3282*2d543d20SAndroid Build Coastguard Worker matched = tokenize(tmp, ' ', 4, &user_str, &user, &prefix_str, &prefix);
3283*2d543d20SAndroid Build Coastguard Worker if (matched != 4) {
3284*2d543d20SAndroid Build Coastguard Worker rc = -1;
3285*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Invalid user extra line: %s", line);
3286*2d543d20SAndroid Build Coastguard Worker goto exit;
3287*2d543d20SAndroid Build Coastguard Worker }
3288*2d543d20SAndroid Build Coastguard Worker
3289*2d543d20SAndroid Build Coastguard Worker prefix_len = strlen(prefix);
3290*2d543d20SAndroid Build Coastguard Worker eol = prefix + prefix_len - 1;
3291*2d543d20SAndroid Build Coastguard Worker if (*eol != ';' || strcmp(user_str, "user") || strcmp(prefix_str, "prefix")) {
3292*2d543d20SAndroid Build Coastguard Worker rc = -1;
3293*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Invalid user extra line: %s", line);
3294*2d543d20SAndroid Build Coastguard Worker goto exit;
3295*2d543d20SAndroid Build Coastguard Worker }
3296*2d543d20SAndroid Build Coastguard Worker *eol = '\0';
3297*2d543d20SAndroid Build Coastguard Worker
3298*2d543d20SAndroid Build Coastguard Worker cil_println(0, "(userprefix %s %s)", user, prefix);
3299*2d543d20SAndroid Build Coastguard Worker free(user);
3300*2d543d20SAndroid Build Coastguard Worker free(prefix);
3301*2d543d20SAndroid Build Coastguard Worker free(line);
3302*2d543d20SAndroid Build Coastguard Worker free(user_str);
3303*2d543d20SAndroid Build Coastguard Worker free(prefix_str);
3304*2d543d20SAndroid Build Coastguard Worker user = prefix = line = user_str = prefix_str = NULL;
3305*2d543d20SAndroid Build Coastguard Worker }
3306*2d543d20SAndroid Build Coastguard Worker
3307*2d543d20SAndroid Build Coastguard Worker if (rc == -1) {
3308*2d543d20SAndroid Build Coastguard Worker cil_printf("Failed to read user_extra\n");
3309*2d543d20SAndroid Build Coastguard Worker goto exit;
3310*2d543d20SAndroid Build Coastguard Worker }
3311*2d543d20SAndroid Build Coastguard Worker
3312*2d543d20SAndroid Build Coastguard Worker rc = 0;
3313*2d543d20SAndroid Build Coastguard Worker exit:
3314*2d543d20SAndroid Build Coastguard Worker free(line);
3315*2d543d20SAndroid Build Coastguard Worker free(user);
3316*2d543d20SAndroid Build Coastguard Worker free(prefix);
3317*2d543d20SAndroid Build Coastguard Worker
3318*2d543d20SAndroid Build Coastguard Worker return rc;
3319*2d543d20SAndroid Build Coastguard Worker }
3320*2d543d20SAndroid Build Coastguard Worker
file_contexts_to_cil(struct sepol_module_package * mod_pkg)3321*2d543d20SAndroid Build Coastguard Worker static int file_contexts_to_cil(struct sepol_module_package *mod_pkg)
3322*2d543d20SAndroid Build Coastguard Worker {
3323*2d543d20SAndroid Build Coastguard Worker int rc = -1;
3324*2d543d20SAndroid Build Coastguard Worker char *fc = sepol_module_package_get_file_contexts(mod_pkg);
3325*2d543d20SAndroid Build Coastguard Worker size_t fc_len = sepol_module_package_get_file_contexts_len(mod_pkg);
3326*2d543d20SAndroid Build Coastguard Worker char *cur = fc;
3327*2d543d20SAndroid Build Coastguard Worker char *end = fc + fc_len;
3328*2d543d20SAndroid Build Coastguard Worker char *line = NULL;
3329*2d543d20SAndroid Build Coastguard Worker int matched;
3330*2d543d20SAndroid Build Coastguard Worker char *regex = NULL;
3331*2d543d20SAndroid Build Coastguard Worker char *mode = NULL;
3332*2d543d20SAndroid Build Coastguard Worker char *context = NULL;
3333*2d543d20SAndroid Build Coastguard Worker const char *cilmode;
3334*2d543d20SAndroid Build Coastguard Worker char *tmp = NULL;
3335*2d543d20SAndroid Build Coastguard Worker
3336*2d543d20SAndroid Build Coastguard Worker if (fc_len == 0) {
3337*2d543d20SAndroid Build Coastguard Worker return 0;
3338*2d543d20SAndroid Build Coastguard Worker }
3339*2d543d20SAndroid Build Coastguard Worker
3340*2d543d20SAndroid Build Coastguard Worker while ((rc = get_line(&cur, end, &line)) > 0) {
3341*2d543d20SAndroid Build Coastguard Worker tmp = line;
3342*2d543d20SAndroid Build Coastguard Worker while (isspace(*tmp)) {
3343*2d543d20SAndroid Build Coastguard Worker tmp++;
3344*2d543d20SAndroid Build Coastguard Worker }
3345*2d543d20SAndroid Build Coastguard Worker
3346*2d543d20SAndroid Build Coastguard Worker if (tmp[0] == '#' || tmp[0] == '\0') {
3347*2d543d20SAndroid Build Coastguard Worker free(line);
3348*2d543d20SAndroid Build Coastguard Worker line = NULL;
3349*2d543d20SAndroid Build Coastguard Worker continue;
3350*2d543d20SAndroid Build Coastguard Worker }
3351*2d543d20SAndroid Build Coastguard Worker
3352*2d543d20SAndroid Build Coastguard Worker matched = tokenize(tmp, ' ', 3, ®ex, &mode, &context);
3353*2d543d20SAndroid Build Coastguard Worker if (matched < 2 || matched > 3) {
3354*2d543d20SAndroid Build Coastguard Worker rc = -1;
3355*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Invalid file context line: %s", line);
3356*2d543d20SAndroid Build Coastguard Worker goto exit;
3357*2d543d20SAndroid Build Coastguard Worker }
3358*2d543d20SAndroid Build Coastguard Worker
3359*2d543d20SAndroid Build Coastguard Worker if (matched == 2) {
3360*2d543d20SAndroid Build Coastguard Worker context = mode;
3361*2d543d20SAndroid Build Coastguard Worker mode = NULL;
3362*2d543d20SAndroid Build Coastguard Worker }
3363*2d543d20SAndroid Build Coastguard Worker
3364*2d543d20SAndroid Build Coastguard Worker if (mode == NULL) {
3365*2d543d20SAndroid Build Coastguard Worker cilmode = "any";
3366*2d543d20SAndroid Build Coastguard Worker } else if (!strcmp(mode, "--")) {
3367*2d543d20SAndroid Build Coastguard Worker cilmode = "file";
3368*2d543d20SAndroid Build Coastguard Worker } else if (!strcmp(mode, "-d")) {
3369*2d543d20SAndroid Build Coastguard Worker cilmode = "dir";
3370*2d543d20SAndroid Build Coastguard Worker } else if (!strcmp(mode, "-c")) {
3371*2d543d20SAndroid Build Coastguard Worker cilmode = "char";
3372*2d543d20SAndroid Build Coastguard Worker } else if (!strcmp(mode, "-b")) {
3373*2d543d20SAndroid Build Coastguard Worker cilmode = "block";
3374*2d543d20SAndroid Build Coastguard Worker } else if (!strcmp(mode, "-s")) {
3375*2d543d20SAndroid Build Coastguard Worker cilmode = "socket";
3376*2d543d20SAndroid Build Coastguard Worker } else if (!strcmp(mode, "-p")) {
3377*2d543d20SAndroid Build Coastguard Worker cilmode = "pipe";
3378*2d543d20SAndroid Build Coastguard Worker } else if (!strcmp(mode, "-l")) {
3379*2d543d20SAndroid Build Coastguard Worker cilmode = "symlink";
3380*2d543d20SAndroid Build Coastguard Worker } else {
3381*2d543d20SAndroid Build Coastguard Worker rc = -1;
3382*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Invalid mode in file context line: %s", line);
3383*2d543d20SAndroid Build Coastguard Worker goto exit;
3384*2d543d20SAndroid Build Coastguard Worker }
3385*2d543d20SAndroid Build Coastguard Worker
3386*2d543d20SAndroid Build Coastguard Worker cil_printf("(filecon \"%s\" %s ", regex, cilmode);
3387*2d543d20SAndroid Build Coastguard Worker
3388*2d543d20SAndroid Build Coastguard Worker if (!strcmp(context, "<<none>>")) {
3389*2d543d20SAndroid Build Coastguard Worker cil_printf("()");
3390*2d543d20SAndroid Build Coastguard Worker } else {
3391*2d543d20SAndroid Build Coastguard Worker context_string_to_cil(context);
3392*2d543d20SAndroid Build Coastguard Worker }
3393*2d543d20SAndroid Build Coastguard Worker
3394*2d543d20SAndroid Build Coastguard Worker cil_printf(")\n");
3395*2d543d20SAndroid Build Coastguard Worker
3396*2d543d20SAndroid Build Coastguard Worker free(regex);
3397*2d543d20SAndroid Build Coastguard Worker free(mode);
3398*2d543d20SAndroid Build Coastguard Worker free(context);
3399*2d543d20SAndroid Build Coastguard Worker free(line);
3400*2d543d20SAndroid Build Coastguard Worker regex = mode = context = line = NULL;
3401*2d543d20SAndroid Build Coastguard Worker }
3402*2d543d20SAndroid Build Coastguard Worker
3403*2d543d20SAndroid Build Coastguard Worker if (rc == -1) {
3404*2d543d20SAndroid Build Coastguard Worker cil_printf("Failed to read file_contexts_to_cil\n");
3405*2d543d20SAndroid Build Coastguard Worker goto exit;
3406*2d543d20SAndroid Build Coastguard Worker }
3407*2d543d20SAndroid Build Coastguard Worker
3408*2d543d20SAndroid Build Coastguard Worker rc = 0;
3409*2d543d20SAndroid Build Coastguard Worker exit:
3410*2d543d20SAndroid Build Coastguard Worker free(line);
3411*2d543d20SAndroid Build Coastguard Worker free(regex);
3412*2d543d20SAndroid Build Coastguard Worker free(mode);
3413*2d543d20SAndroid Build Coastguard Worker free(context);
3414*2d543d20SAndroid Build Coastguard Worker
3415*2d543d20SAndroid Build Coastguard Worker return rc;
3416*2d543d20SAndroid Build Coastguard Worker }
3417*2d543d20SAndroid Build Coastguard Worker
3418*2d543d20SAndroid Build Coastguard Worker
3419*2d543d20SAndroid Build Coastguard Worker static int (*const func_to_cil[SYM_NUM])(int indent, struct policydb *pdb, struct avrule_block *block, struct stack *decl_stack, char *key, void *datum, int scope) = {
3420*2d543d20SAndroid Build Coastguard Worker NULL, // commons, only stored in the global symtab, handled elsewhere
3421*2d543d20SAndroid Build Coastguard Worker class_to_cil,
3422*2d543d20SAndroid Build Coastguard Worker role_to_cil,
3423*2d543d20SAndroid Build Coastguard Worker type_to_cil,
3424*2d543d20SAndroid Build Coastguard Worker user_to_cil,
3425*2d543d20SAndroid Build Coastguard Worker boolean_to_cil,
3426*2d543d20SAndroid Build Coastguard Worker sens_to_cil,
3427*2d543d20SAndroid Build Coastguard Worker cat_to_cil
3428*2d543d20SAndroid Build Coastguard Worker };
3429*2d543d20SAndroid Build Coastguard Worker
typealiases_to_cil(int indent,struct policydb * pdb,struct avrule_block * UNUSED (block),struct stack * decl_stack)3430*2d543d20SAndroid Build Coastguard Worker static int typealiases_to_cil(int indent, struct policydb *pdb, struct avrule_block *UNUSED(block), struct stack *decl_stack)
3431*2d543d20SAndroid Build Coastguard Worker {
3432*2d543d20SAndroid Build Coastguard Worker struct type_datum *alias_datum;
3433*2d543d20SAndroid Build Coastguard Worker char *alias_name;
3434*2d543d20SAndroid Build Coastguard Worker char *type_name;
3435*2d543d20SAndroid Build Coastguard Worker struct list_node *curr;
3436*2d543d20SAndroid Build Coastguard Worker struct avrule_decl *decl = stack_peek(decl_stack);
3437*2d543d20SAndroid Build Coastguard Worker struct list *alias_list;
3438*2d543d20SAndroid Build Coastguard Worker int rc = -1;
3439*2d543d20SAndroid Build Coastguard Worker
3440*2d543d20SAndroid Build Coastguard Worker if (decl == NULL) {
3441*2d543d20SAndroid Build Coastguard Worker return -1;
3442*2d543d20SAndroid Build Coastguard Worker }
3443*2d543d20SAndroid Build Coastguard Worker
3444*2d543d20SAndroid Build Coastguard Worker alias_list = typealias_lists[decl->decl_id];
3445*2d543d20SAndroid Build Coastguard Worker if (alias_list == NULL) {
3446*2d543d20SAndroid Build Coastguard Worker return 0;
3447*2d543d20SAndroid Build Coastguard Worker }
3448*2d543d20SAndroid Build Coastguard Worker
3449*2d543d20SAndroid Build Coastguard Worker for (curr = alias_list->head; curr != NULL; curr = curr->next) {
3450*2d543d20SAndroid Build Coastguard Worker alias_name = curr->data;
3451*2d543d20SAndroid Build Coastguard Worker alias_datum = hashtab_search(pdb->p_types.table, alias_name);
3452*2d543d20SAndroid Build Coastguard Worker if (alias_datum == NULL) {
3453*2d543d20SAndroid Build Coastguard Worker rc = -1;
3454*2d543d20SAndroid Build Coastguard Worker goto exit;
3455*2d543d20SAndroid Build Coastguard Worker }
3456*2d543d20SAndroid Build Coastguard Worker if (alias_datum->flavor == TYPE_ALIAS) {
3457*2d543d20SAndroid Build Coastguard Worker type_name = pdb->p_type_val_to_name[alias_datum->primary - 1];
3458*2d543d20SAndroid Build Coastguard Worker } else {
3459*2d543d20SAndroid Build Coastguard Worker type_name = pdb->p_type_val_to_name[alias_datum->s.value - 1];
3460*2d543d20SAndroid Build Coastguard Worker }
3461*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(typealias %s)", alias_name);
3462*2d543d20SAndroid Build Coastguard Worker cil_println(indent, "(typealiasactual %s %s)", alias_name, type_name);
3463*2d543d20SAndroid Build Coastguard Worker }
3464*2d543d20SAndroid Build Coastguard Worker
3465*2d543d20SAndroid Build Coastguard Worker return 0;
3466*2d543d20SAndroid Build Coastguard Worker
3467*2d543d20SAndroid Build Coastguard Worker exit:
3468*2d543d20SAndroid Build Coastguard Worker return rc;
3469*2d543d20SAndroid Build Coastguard Worker }
3470*2d543d20SAndroid Build Coastguard Worker
declared_scopes_to_cil(int indent,struct policydb * pdb,struct avrule_block * block,struct stack * decl_stack)3471*2d543d20SAndroid Build Coastguard Worker static int declared_scopes_to_cil(int indent, struct policydb *pdb, struct avrule_block *block, struct stack *decl_stack)
3472*2d543d20SAndroid Build Coastguard Worker {
3473*2d543d20SAndroid Build Coastguard Worker int rc = -1;
3474*2d543d20SAndroid Build Coastguard Worker struct ebitmap map;
3475*2d543d20SAndroid Build Coastguard Worker struct ebitmap_node *node;
3476*2d543d20SAndroid Build Coastguard Worker unsigned int i;
3477*2d543d20SAndroid Build Coastguard Worker char * key;
3478*2d543d20SAndroid Build Coastguard Worker struct scope_datum *scope;
3479*2d543d20SAndroid Build Coastguard Worker int sym;
3480*2d543d20SAndroid Build Coastguard Worker void *datum;
3481*2d543d20SAndroid Build Coastguard Worker struct avrule_decl *decl = stack_peek(decl_stack);
3482*2d543d20SAndroid Build Coastguard Worker
3483*2d543d20SAndroid Build Coastguard Worker for (sym = 0; sym < SYM_NUM; sym++) {
3484*2d543d20SAndroid Build Coastguard Worker if (func_to_cil[sym] == NULL) {
3485*2d543d20SAndroid Build Coastguard Worker continue;
3486*2d543d20SAndroid Build Coastguard Worker }
3487*2d543d20SAndroid Build Coastguard Worker
3488*2d543d20SAndroid Build Coastguard Worker map = decl->declared.scope[sym];
3489*2d543d20SAndroid Build Coastguard Worker ebitmap_for_each_positive_bit(&map, node, i) {
3490*2d543d20SAndroid Build Coastguard Worker key = pdb->sym_val_to_name[sym][i];
3491*2d543d20SAndroid Build Coastguard Worker datum = hashtab_search(pdb->symtab[sym].table, key);
3492*2d543d20SAndroid Build Coastguard Worker if (datum == NULL) {
3493*2d543d20SAndroid Build Coastguard Worker rc = -1;
3494*2d543d20SAndroid Build Coastguard Worker goto exit;
3495*2d543d20SAndroid Build Coastguard Worker }
3496*2d543d20SAndroid Build Coastguard Worker scope = hashtab_search(pdb->scope[sym].table, key);
3497*2d543d20SAndroid Build Coastguard Worker if (scope == NULL) {
3498*2d543d20SAndroid Build Coastguard Worker rc = -1;
3499*2d543d20SAndroid Build Coastguard Worker goto exit;
3500*2d543d20SAndroid Build Coastguard Worker }
3501*2d543d20SAndroid Build Coastguard Worker rc = func_to_cil[sym](indent, pdb, block, decl_stack, key, datum, scope->scope);
3502*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
3503*2d543d20SAndroid Build Coastguard Worker goto exit;
3504*2d543d20SAndroid Build Coastguard Worker }
3505*2d543d20SAndroid Build Coastguard Worker }
3506*2d543d20SAndroid Build Coastguard Worker
3507*2d543d20SAndroid Build Coastguard Worker if (sym == SYM_CATS) {
3508*2d543d20SAndroid Build Coastguard Worker rc = cat_order_to_cil(indent, pdb, map);
3509*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
3510*2d543d20SAndroid Build Coastguard Worker goto exit;
3511*2d543d20SAndroid Build Coastguard Worker }
3512*2d543d20SAndroid Build Coastguard Worker }
3513*2d543d20SAndroid Build Coastguard Worker
3514*2d543d20SAndroid Build Coastguard Worker if (sym == SYM_LEVELS) {
3515*2d543d20SAndroid Build Coastguard Worker rc = sens_order_to_cil(indent, pdb, map);
3516*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
3517*2d543d20SAndroid Build Coastguard Worker goto exit;
3518*2d543d20SAndroid Build Coastguard Worker }
3519*2d543d20SAndroid Build Coastguard Worker }
3520*2d543d20SAndroid Build Coastguard Worker
3521*2d543d20SAndroid Build Coastguard Worker if (sym == SYM_CLASSES) {
3522*2d543d20SAndroid Build Coastguard Worker rc = class_order_to_cil(indent, pdb, map);
3523*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
3524*2d543d20SAndroid Build Coastguard Worker goto exit;
3525*2d543d20SAndroid Build Coastguard Worker }
3526*2d543d20SAndroid Build Coastguard Worker }
3527*2d543d20SAndroid Build Coastguard Worker }
3528*2d543d20SAndroid Build Coastguard Worker
3529*2d543d20SAndroid Build Coastguard Worker return 0;
3530*2d543d20SAndroid Build Coastguard Worker exit:
3531*2d543d20SAndroid Build Coastguard Worker return rc;
3532*2d543d20SAndroid Build Coastguard Worker }
3533*2d543d20SAndroid Build Coastguard Worker
required_scopes_to_cil(int indent,struct policydb * pdb,struct avrule_block * block,struct stack * decl_stack)3534*2d543d20SAndroid Build Coastguard Worker static int required_scopes_to_cil(int indent, struct policydb *pdb, struct avrule_block *block, struct stack *decl_stack)
3535*2d543d20SAndroid Build Coastguard Worker {
3536*2d543d20SAndroid Build Coastguard Worker int rc = -1;
3537*2d543d20SAndroid Build Coastguard Worker struct ebitmap map;
3538*2d543d20SAndroid Build Coastguard Worker struct ebitmap_node *node;
3539*2d543d20SAndroid Build Coastguard Worker unsigned int i;
3540*2d543d20SAndroid Build Coastguard Worker unsigned int j;
3541*2d543d20SAndroid Build Coastguard Worker char * key;
3542*2d543d20SAndroid Build Coastguard Worker int sym;
3543*2d543d20SAndroid Build Coastguard Worker void *datum;
3544*2d543d20SAndroid Build Coastguard Worker struct avrule_decl *decl = stack_peek(decl_stack);
3545*2d543d20SAndroid Build Coastguard Worker struct scope_datum *scope_datum;
3546*2d543d20SAndroid Build Coastguard Worker
3547*2d543d20SAndroid Build Coastguard Worker for (sym = 0; sym < SYM_NUM; sym++) {
3548*2d543d20SAndroid Build Coastguard Worker if (func_to_cil[sym] == NULL) {
3549*2d543d20SAndroid Build Coastguard Worker continue;
3550*2d543d20SAndroid Build Coastguard Worker }
3551*2d543d20SAndroid Build Coastguard Worker
3552*2d543d20SAndroid Build Coastguard Worker map = decl->required.scope[sym];
3553*2d543d20SAndroid Build Coastguard Worker ebitmap_for_each_positive_bit(&map, node, i) {
3554*2d543d20SAndroid Build Coastguard Worker key = pdb->sym_val_to_name[sym][i];
3555*2d543d20SAndroid Build Coastguard Worker
3556*2d543d20SAndroid Build Coastguard Worker scope_datum = hashtab_search(pdb->scope[sym].table, key);
3557*2d543d20SAndroid Build Coastguard Worker if (scope_datum == NULL) {
3558*2d543d20SAndroid Build Coastguard Worker rc = -1;
3559*2d543d20SAndroid Build Coastguard Worker goto exit;
3560*2d543d20SAndroid Build Coastguard Worker }
3561*2d543d20SAndroid Build Coastguard Worker for (j = 0; j < scope_datum->decl_ids_len; j++) {
3562*2d543d20SAndroid Build Coastguard Worker if (scope_datum->decl_ids[j] == decl->decl_id) {
3563*2d543d20SAndroid Build Coastguard Worker break;
3564*2d543d20SAndroid Build Coastguard Worker }
3565*2d543d20SAndroid Build Coastguard Worker }
3566*2d543d20SAndroid Build Coastguard Worker if (j >= scope_datum->decl_ids_len) {
3567*2d543d20SAndroid Build Coastguard Worker // Symbols required in the global scope are also in the
3568*2d543d20SAndroid Build Coastguard Worker // required scope ebitmap of all avrule decls (i.e. required
3569*2d543d20SAndroid Build Coastguard Worker // in all optionals). So we need to look at the scopes of each
3570*2d543d20SAndroid Build Coastguard Worker // symbol in this avrule_decl to determine if it actually is
3571*2d543d20SAndroid Build Coastguard Worker // required in this decl, or if it's just required in the
3572*2d543d20SAndroid Build Coastguard Worker // global scope. If we got here, then this symbol is not
3573*2d543d20SAndroid Build Coastguard Worker // actually required in this scope, so skip it.
3574*2d543d20SAndroid Build Coastguard Worker continue;
3575*2d543d20SAndroid Build Coastguard Worker }
3576*2d543d20SAndroid Build Coastguard Worker
3577*2d543d20SAndroid Build Coastguard Worker datum = hashtab_search(pdb->symtab[sym].table, key);
3578*2d543d20SAndroid Build Coastguard Worker if (datum == NULL) {
3579*2d543d20SAndroid Build Coastguard Worker rc = -1;
3580*2d543d20SAndroid Build Coastguard Worker goto exit;
3581*2d543d20SAndroid Build Coastguard Worker }
3582*2d543d20SAndroid Build Coastguard Worker rc = func_to_cil[sym](indent, pdb, block, decl_stack, key, datum, SCOPE_REQ);
3583*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
3584*2d543d20SAndroid Build Coastguard Worker goto exit;
3585*2d543d20SAndroid Build Coastguard Worker }
3586*2d543d20SAndroid Build Coastguard Worker }
3587*2d543d20SAndroid Build Coastguard Worker }
3588*2d543d20SAndroid Build Coastguard Worker
3589*2d543d20SAndroid Build Coastguard Worker return 0;
3590*2d543d20SAndroid Build Coastguard Worker exit:
3591*2d543d20SAndroid Build Coastguard Worker return rc;
3592*2d543d20SAndroid Build Coastguard Worker }
3593*2d543d20SAndroid Build Coastguard Worker
3594*2d543d20SAndroid Build Coastguard Worker
additive_scopes_to_cil_map(char * key,void * data,void * arg)3595*2d543d20SAndroid Build Coastguard Worker static int additive_scopes_to_cil_map(char *key, void *data, void *arg)
3596*2d543d20SAndroid Build Coastguard Worker {
3597*2d543d20SAndroid Build Coastguard Worker int rc = -1;
3598*2d543d20SAndroid Build Coastguard Worker struct map_args *args = arg;
3599*2d543d20SAndroid Build Coastguard Worker
3600*2d543d20SAndroid Build Coastguard Worker rc = func_to_cil[args->sym_index](args->indent, args->pdb, args->block, args->decl_stack, key, data, SCOPE_REQ);
3601*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
3602*2d543d20SAndroid Build Coastguard Worker goto exit;
3603*2d543d20SAndroid Build Coastguard Worker }
3604*2d543d20SAndroid Build Coastguard Worker
3605*2d543d20SAndroid Build Coastguard Worker return 0;
3606*2d543d20SAndroid Build Coastguard Worker
3607*2d543d20SAndroid Build Coastguard Worker exit:
3608*2d543d20SAndroid Build Coastguard Worker return rc;
3609*2d543d20SAndroid Build Coastguard Worker }
3610*2d543d20SAndroid Build Coastguard Worker
additive_scopes_to_cil(int indent,struct policydb * pdb,struct avrule_block * block,struct stack * decl_stack)3611*2d543d20SAndroid Build Coastguard Worker static int additive_scopes_to_cil(int indent, struct policydb *pdb, struct avrule_block *block, struct stack *decl_stack)
3612*2d543d20SAndroid Build Coastguard Worker {
3613*2d543d20SAndroid Build Coastguard Worker int rc = -1;
3614*2d543d20SAndroid Build Coastguard Worker struct avrule_decl *decl = stack_peek(decl_stack);
3615*2d543d20SAndroid Build Coastguard Worker struct map_args args;
3616*2d543d20SAndroid Build Coastguard Worker args.pdb = pdb;
3617*2d543d20SAndroid Build Coastguard Worker args.block = block;
3618*2d543d20SAndroid Build Coastguard Worker args.decl_stack = decl_stack;
3619*2d543d20SAndroid Build Coastguard Worker args.indent = indent;
3620*2d543d20SAndroid Build Coastguard Worker
3621*2d543d20SAndroid Build Coastguard Worker for (args.sym_index = 0; args.sym_index < SYM_NUM; args.sym_index++) {
3622*2d543d20SAndroid Build Coastguard Worker if (func_to_cil[args.sym_index] == NULL) {
3623*2d543d20SAndroid Build Coastguard Worker continue;
3624*2d543d20SAndroid Build Coastguard Worker }
3625*2d543d20SAndroid Build Coastguard Worker rc = hashtab_map(decl->symtab[args.sym_index].table, additive_scopes_to_cil_map, &args);
3626*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
3627*2d543d20SAndroid Build Coastguard Worker goto exit;
3628*2d543d20SAndroid Build Coastguard Worker }
3629*2d543d20SAndroid Build Coastguard Worker }
3630*2d543d20SAndroid Build Coastguard Worker
3631*2d543d20SAndroid Build Coastguard Worker return 0;
3632*2d543d20SAndroid Build Coastguard Worker
3633*2d543d20SAndroid Build Coastguard Worker exit:
3634*2d543d20SAndroid Build Coastguard Worker return rc;
3635*2d543d20SAndroid Build Coastguard Worker }
3636*2d543d20SAndroid Build Coastguard Worker
is_scope_superset(struct scope_index * sup,struct scope_index * sub)3637*2d543d20SAndroid Build Coastguard Worker static int is_scope_superset(struct scope_index *sup, struct scope_index *sub)
3638*2d543d20SAndroid Build Coastguard Worker {
3639*2d543d20SAndroid Build Coastguard Worker // returns 1 if sup is a superset of sub, returns 0 otherwise
3640*2d543d20SAndroid Build Coastguard Worker
3641*2d543d20SAndroid Build Coastguard Worker int rc = 0;
3642*2d543d20SAndroid Build Coastguard Worker
3643*2d543d20SAndroid Build Coastguard Worker uint32_t i;
3644*2d543d20SAndroid Build Coastguard Worker struct ebitmap sup_map;
3645*2d543d20SAndroid Build Coastguard Worker struct ebitmap sub_map;
3646*2d543d20SAndroid Build Coastguard Worker struct ebitmap res;
3647*2d543d20SAndroid Build Coastguard Worker
3648*2d543d20SAndroid Build Coastguard Worker ebitmap_init(&res);
3649*2d543d20SAndroid Build Coastguard Worker
3650*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < SYM_NUM; i++) {
3651*2d543d20SAndroid Build Coastguard Worker sup_map = sup->scope[i];
3652*2d543d20SAndroid Build Coastguard Worker sub_map = sub->scope[i];
3653*2d543d20SAndroid Build Coastguard Worker
3654*2d543d20SAndroid Build Coastguard Worker ebitmap_and(&res, &sup_map, &sub_map);
3655*2d543d20SAndroid Build Coastguard Worker if (!ebitmap_cmp(&res, &sub_map)) {
3656*2d543d20SAndroid Build Coastguard Worker goto exit;
3657*2d543d20SAndroid Build Coastguard Worker }
3658*2d543d20SAndroid Build Coastguard Worker ebitmap_destroy(&res);
3659*2d543d20SAndroid Build Coastguard Worker }
3660*2d543d20SAndroid Build Coastguard Worker
3661*2d543d20SAndroid Build Coastguard Worker if (sup->class_perms_len < sub->class_perms_len) {
3662*2d543d20SAndroid Build Coastguard Worker goto exit;
3663*2d543d20SAndroid Build Coastguard Worker }
3664*2d543d20SAndroid Build Coastguard Worker
3665*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < sub->class_perms_len; i++) {
3666*2d543d20SAndroid Build Coastguard Worker sup_map = sup->class_perms_map[i];
3667*2d543d20SAndroid Build Coastguard Worker sub_map = sub->class_perms_map[i];
3668*2d543d20SAndroid Build Coastguard Worker
3669*2d543d20SAndroid Build Coastguard Worker ebitmap_and(&res, &sup_map, &sub_map);
3670*2d543d20SAndroid Build Coastguard Worker if (!ebitmap_cmp(&res, &sub_map)) {
3671*2d543d20SAndroid Build Coastguard Worker goto exit;
3672*2d543d20SAndroid Build Coastguard Worker }
3673*2d543d20SAndroid Build Coastguard Worker ebitmap_destroy(&res);
3674*2d543d20SAndroid Build Coastguard Worker }
3675*2d543d20SAndroid Build Coastguard Worker
3676*2d543d20SAndroid Build Coastguard Worker rc = 1;
3677*2d543d20SAndroid Build Coastguard Worker
3678*2d543d20SAndroid Build Coastguard Worker exit:
3679*2d543d20SAndroid Build Coastguard Worker
3680*2d543d20SAndroid Build Coastguard Worker ebitmap_destroy(&res);
3681*2d543d20SAndroid Build Coastguard Worker return rc;
3682*2d543d20SAndroid Build Coastguard Worker }
3683*2d543d20SAndroid Build Coastguard Worker
block_to_cil(struct policydb * pdb,struct avrule_block * block,struct stack * stack,int indent)3684*2d543d20SAndroid Build Coastguard Worker static int block_to_cil(struct policydb *pdb, struct avrule_block *block, struct stack *stack, int indent)
3685*2d543d20SAndroid Build Coastguard Worker {
3686*2d543d20SAndroid Build Coastguard Worker int rc = -1;
3687*2d543d20SAndroid Build Coastguard Worker struct avrule_decl *decl;
3688*2d543d20SAndroid Build Coastguard Worker struct list *type_attr_list = NULL;
3689*2d543d20SAndroid Build Coastguard Worker struct list *role_attr_list = NULL;
3690*2d543d20SAndroid Build Coastguard Worker
3691*2d543d20SAndroid Build Coastguard Worker decl = block->branch_list;
3692*2d543d20SAndroid Build Coastguard Worker
3693*2d543d20SAndroid Build Coastguard Worker rc = list_init(&type_attr_list);
3694*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
3695*2d543d20SAndroid Build Coastguard Worker goto exit;
3696*2d543d20SAndroid Build Coastguard Worker }
3697*2d543d20SAndroid Build Coastguard Worker rc = list_init(&role_attr_list);
3698*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
3699*2d543d20SAndroid Build Coastguard Worker goto exit;
3700*2d543d20SAndroid Build Coastguard Worker }
3701*2d543d20SAndroid Build Coastguard Worker
3702*2d543d20SAndroid Build Coastguard Worker rc = typealiases_to_cil(indent, pdb, block, stack);
3703*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
3704*2d543d20SAndroid Build Coastguard Worker goto exit;
3705*2d543d20SAndroid Build Coastguard Worker }
3706*2d543d20SAndroid Build Coastguard Worker
3707*2d543d20SAndroid Build Coastguard Worker rc = declared_scopes_to_cil(indent, pdb, block, stack);
3708*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
3709*2d543d20SAndroid Build Coastguard Worker goto exit;
3710*2d543d20SAndroid Build Coastguard Worker }
3711*2d543d20SAndroid Build Coastguard Worker
3712*2d543d20SAndroid Build Coastguard Worker rc = required_scopes_to_cil(indent, pdb, block, stack);
3713*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
3714*2d543d20SAndroid Build Coastguard Worker goto exit;
3715*2d543d20SAndroid Build Coastguard Worker }
3716*2d543d20SAndroid Build Coastguard Worker
3717*2d543d20SAndroid Build Coastguard Worker rc = additive_scopes_to_cil(indent, pdb, block, stack);
3718*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
3719*2d543d20SAndroid Build Coastguard Worker goto exit;
3720*2d543d20SAndroid Build Coastguard Worker }
3721*2d543d20SAndroid Build Coastguard Worker
3722*2d543d20SAndroid Build Coastguard Worker rc = avrule_list_to_cil(indent, pdb, decl->avrules, type_attr_list);
3723*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
3724*2d543d20SAndroid Build Coastguard Worker goto exit;
3725*2d543d20SAndroid Build Coastguard Worker }
3726*2d543d20SAndroid Build Coastguard Worker
3727*2d543d20SAndroid Build Coastguard Worker rc = role_trans_to_cil(indent, pdb, decl->role_tr_rules, role_attr_list, type_attr_list);
3728*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
3729*2d543d20SAndroid Build Coastguard Worker goto exit;
3730*2d543d20SAndroid Build Coastguard Worker }
3731*2d543d20SAndroid Build Coastguard Worker
3732*2d543d20SAndroid Build Coastguard Worker rc = role_allows_to_cil(indent, pdb, decl->role_allow_rules, role_attr_list);
3733*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
3734*2d543d20SAndroid Build Coastguard Worker goto exit;
3735*2d543d20SAndroid Build Coastguard Worker }
3736*2d543d20SAndroid Build Coastguard Worker
3737*2d543d20SAndroid Build Coastguard Worker rc = range_trans_to_cil(indent, pdb, decl->range_tr_rules, type_attr_list);
3738*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
3739*2d543d20SAndroid Build Coastguard Worker goto exit;
3740*2d543d20SAndroid Build Coastguard Worker }
3741*2d543d20SAndroid Build Coastguard Worker
3742*2d543d20SAndroid Build Coastguard Worker rc = filename_trans_to_cil(indent, pdb, decl->filename_trans_rules, type_attr_list);
3743*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
3744*2d543d20SAndroid Build Coastguard Worker goto exit;
3745*2d543d20SAndroid Build Coastguard Worker }
3746*2d543d20SAndroid Build Coastguard Worker
3747*2d543d20SAndroid Build Coastguard Worker rc = cond_list_to_cil(indent, pdb, decl->cond_list, type_attr_list);
3748*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
3749*2d543d20SAndroid Build Coastguard Worker goto exit;
3750*2d543d20SAndroid Build Coastguard Worker }
3751*2d543d20SAndroid Build Coastguard Worker
3752*2d543d20SAndroid Build Coastguard Worker rc = cil_print_attr_list(indent, pdb, type_attr_list);
3753*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
3754*2d543d20SAndroid Build Coastguard Worker goto exit;
3755*2d543d20SAndroid Build Coastguard Worker }
3756*2d543d20SAndroid Build Coastguard Worker rc = cil_print_attr_list(indent, pdb, role_attr_list);
3757*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
3758*2d543d20SAndroid Build Coastguard Worker goto exit;
3759*2d543d20SAndroid Build Coastguard Worker }
3760*2d543d20SAndroid Build Coastguard Worker
3761*2d543d20SAndroid Build Coastguard Worker exit:
3762*2d543d20SAndroid Build Coastguard Worker attr_list_destroy(&type_attr_list);
3763*2d543d20SAndroid Build Coastguard Worker attr_list_destroy(&role_attr_list);
3764*2d543d20SAndroid Build Coastguard Worker
3765*2d543d20SAndroid Build Coastguard Worker return rc;
3766*2d543d20SAndroid Build Coastguard Worker }
3767*2d543d20SAndroid Build Coastguard Worker
module_block_to_cil(struct policydb * pdb,struct avrule_block * block,struct stack * stack,int * indent)3768*2d543d20SAndroid Build Coastguard Worker static int module_block_to_cil(struct policydb *pdb, struct avrule_block *block, struct stack *stack, int *indent)
3769*2d543d20SAndroid Build Coastguard Worker {
3770*2d543d20SAndroid Build Coastguard Worker int rc = 0;
3771*2d543d20SAndroid Build Coastguard Worker struct avrule_decl *decl;
3772*2d543d20SAndroid Build Coastguard Worker struct avrule_decl *decl_tmp;
3773*2d543d20SAndroid Build Coastguard Worker
3774*2d543d20SAndroid Build Coastguard Worker decl = block->branch_list;
3775*2d543d20SAndroid Build Coastguard Worker if (decl == NULL) {
3776*2d543d20SAndroid Build Coastguard Worker goto exit;
3777*2d543d20SAndroid Build Coastguard Worker }
3778*2d543d20SAndroid Build Coastguard Worker
3779*2d543d20SAndroid Build Coastguard Worker if (decl->next != NULL) {
3780*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Warning: 'else' blocks in optional statements are unsupported in CIL. Dropping from output.");
3781*2d543d20SAndroid Build Coastguard Worker }
3782*2d543d20SAndroid Build Coastguard Worker
3783*2d543d20SAndroid Build Coastguard Worker if (block->flags & AVRULE_OPTIONAL) {
3784*2d543d20SAndroid Build Coastguard Worker while (stack->pos > 0) {
3785*2d543d20SAndroid Build Coastguard Worker decl_tmp = stack_peek(stack);
3786*2d543d20SAndroid Build Coastguard Worker if (is_scope_superset(&decl->required, &decl_tmp->required)) {
3787*2d543d20SAndroid Build Coastguard Worker break;
3788*2d543d20SAndroid Build Coastguard Worker }
3789*2d543d20SAndroid Build Coastguard Worker
3790*2d543d20SAndroid Build Coastguard Worker stack_pop(stack);
3791*2d543d20SAndroid Build Coastguard Worker (*indent)--;
3792*2d543d20SAndroid Build Coastguard Worker cil_println(*indent, ")");
3793*2d543d20SAndroid Build Coastguard Worker }
3794*2d543d20SAndroid Build Coastguard Worker
3795*2d543d20SAndroid Build Coastguard Worker cil_println(*indent, "(optional %s_optional_%i", pdb->name, decl->decl_id);
3796*2d543d20SAndroid Build Coastguard Worker (*indent)++;
3797*2d543d20SAndroid Build Coastguard Worker }
3798*2d543d20SAndroid Build Coastguard Worker
3799*2d543d20SAndroid Build Coastguard Worker stack_push(stack, decl);
3800*2d543d20SAndroid Build Coastguard Worker
3801*2d543d20SAndroid Build Coastguard Worker rc = block_to_cil(pdb, block, stack, *indent);
3802*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
3803*2d543d20SAndroid Build Coastguard Worker goto exit;
3804*2d543d20SAndroid Build Coastguard Worker }
3805*2d543d20SAndroid Build Coastguard Worker
3806*2d543d20SAndroid Build Coastguard Worker exit:
3807*2d543d20SAndroid Build Coastguard Worker return rc;
3808*2d543d20SAndroid Build Coastguard Worker }
3809*2d543d20SAndroid Build Coastguard Worker
global_block_to_cil(struct policydb * pdb,struct avrule_block * block,struct stack * stack)3810*2d543d20SAndroid Build Coastguard Worker static int global_block_to_cil(struct policydb *pdb, struct avrule_block *block, struct stack *stack)
3811*2d543d20SAndroid Build Coastguard Worker {
3812*2d543d20SAndroid Build Coastguard Worker int rc = 0;
3813*2d543d20SAndroid Build Coastguard Worker struct avrule_decl *decl;
3814*2d543d20SAndroid Build Coastguard Worker
3815*2d543d20SAndroid Build Coastguard Worker decl = block->branch_list;
3816*2d543d20SAndroid Build Coastguard Worker if (decl == NULL) {
3817*2d543d20SAndroid Build Coastguard Worker goto exit;
3818*2d543d20SAndroid Build Coastguard Worker }
3819*2d543d20SAndroid Build Coastguard Worker
3820*2d543d20SAndroid Build Coastguard Worker if (decl->next != NULL) {
3821*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Warning: 'else' not allowed in global block. Dropping from output.");
3822*2d543d20SAndroid Build Coastguard Worker }
3823*2d543d20SAndroid Build Coastguard Worker
3824*2d543d20SAndroid Build Coastguard Worker stack_push(stack, decl);
3825*2d543d20SAndroid Build Coastguard Worker
3826*2d543d20SAndroid Build Coastguard Worker // type aliases and commons are only stored in the global symtab.
3827*2d543d20SAndroid Build Coastguard Worker // However, to get scoping correct, we assume they are in the
3828*2d543d20SAndroid Build Coastguard Worker // global block
3829*2d543d20SAndroid Build Coastguard Worker rc = hashtab_map(pdb->p_commons.table, common_to_cil, NULL);
3830*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
3831*2d543d20SAndroid Build Coastguard Worker goto exit;
3832*2d543d20SAndroid Build Coastguard Worker }
3833*2d543d20SAndroid Build Coastguard Worker
3834*2d543d20SAndroid Build Coastguard Worker rc = block_to_cil(pdb, block, stack, 0);
3835*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
3836*2d543d20SAndroid Build Coastguard Worker goto exit;
3837*2d543d20SAndroid Build Coastguard Worker }
3838*2d543d20SAndroid Build Coastguard Worker
3839*2d543d20SAndroid Build Coastguard Worker exit:
3840*2d543d20SAndroid Build Coastguard Worker return rc;
3841*2d543d20SAndroid Build Coastguard Worker }
3842*2d543d20SAndroid Build Coastguard Worker
blocks_to_cil(struct policydb * pdb)3843*2d543d20SAndroid Build Coastguard Worker static int blocks_to_cil(struct policydb *pdb)
3844*2d543d20SAndroid Build Coastguard Worker {
3845*2d543d20SAndroid Build Coastguard Worker int rc = -1;
3846*2d543d20SAndroid Build Coastguard Worker struct avrule_block *block;
3847*2d543d20SAndroid Build Coastguard Worker int indent = 0;
3848*2d543d20SAndroid Build Coastguard Worker struct stack *stack = NULL;
3849*2d543d20SAndroid Build Coastguard Worker
3850*2d543d20SAndroid Build Coastguard Worker rc = stack_init(&stack);
3851*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
3852*2d543d20SAndroid Build Coastguard Worker goto exit;
3853*2d543d20SAndroid Build Coastguard Worker }
3854*2d543d20SAndroid Build Coastguard Worker
3855*2d543d20SAndroid Build Coastguard Worker block = pdb->global;
3856*2d543d20SAndroid Build Coastguard Worker rc = global_block_to_cil(pdb, block, stack);
3857*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
3858*2d543d20SAndroid Build Coastguard Worker goto exit;
3859*2d543d20SAndroid Build Coastguard Worker }
3860*2d543d20SAndroid Build Coastguard Worker
3861*2d543d20SAndroid Build Coastguard Worker for (block = block->next; block != NULL; block = block->next) {
3862*2d543d20SAndroid Build Coastguard Worker rc = module_block_to_cil(pdb, block, stack, &indent);
3863*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
3864*2d543d20SAndroid Build Coastguard Worker goto exit;
3865*2d543d20SAndroid Build Coastguard Worker }
3866*2d543d20SAndroid Build Coastguard Worker }
3867*2d543d20SAndroid Build Coastguard Worker
3868*2d543d20SAndroid Build Coastguard Worker while (indent > 0) {
3869*2d543d20SAndroid Build Coastguard Worker indent--;
3870*2d543d20SAndroid Build Coastguard Worker cil_println(indent, ")");
3871*2d543d20SAndroid Build Coastguard Worker }
3872*2d543d20SAndroid Build Coastguard Worker
3873*2d543d20SAndroid Build Coastguard Worker exit:
3874*2d543d20SAndroid Build Coastguard Worker stack_destroy(&stack);
3875*2d543d20SAndroid Build Coastguard Worker
3876*2d543d20SAndroid Build Coastguard Worker return rc;
3877*2d543d20SAndroid Build Coastguard Worker }
3878*2d543d20SAndroid Build Coastguard Worker
linked_block_to_cil(struct policydb * pdb,struct avrule_block * block,struct stack * stack)3879*2d543d20SAndroid Build Coastguard Worker static int linked_block_to_cil(struct policydb *pdb, struct avrule_block *block, struct stack *stack)
3880*2d543d20SAndroid Build Coastguard Worker {
3881*2d543d20SAndroid Build Coastguard Worker int rc = 0;
3882*2d543d20SAndroid Build Coastguard Worker struct avrule_decl *decl;
3883*2d543d20SAndroid Build Coastguard Worker
3884*2d543d20SAndroid Build Coastguard Worker decl = block->branch_list;
3885*2d543d20SAndroid Build Coastguard Worker if (decl == NULL) {
3886*2d543d20SAndroid Build Coastguard Worker goto exit;
3887*2d543d20SAndroid Build Coastguard Worker }
3888*2d543d20SAndroid Build Coastguard Worker
3889*2d543d20SAndroid Build Coastguard Worker if (!decl->enabled) {
3890*2d543d20SAndroid Build Coastguard Worker if (decl->next != NULL) {
3891*2d543d20SAndroid Build Coastguard Worker decl = decl->next;
3892*2d543d20SAndroid Build Coastguard Worker } else {
3893*2d543d20SAndroid Build Coastguard Worker goto exit;
3894*2d543d20SAndroid Build Coastguard Worker }
3895*2d543d20SAndroid Build Coastguard Worker }
3896*2d543d20SAndroid Build Coastguard Worker
3897*2d543d20SAndroid Build Coastguard Worker stack_push(stack, decl);
3898*2d543d20SAndroid Build Coastguard Worker
3899*2d543d20SAndroid Build Coastguard Worker rc = block_to_cil(pdb, block, stack, 0);
3900*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
3901*2d543d20SAndroid Build Coastguard Worker goto exit;
3902*2d543d20SAndroid Build Coastguard Worker }
3903*2d543d20SAndroid Build Coastguard Worker
3904*2d543d20SAndroid Build Coastguard Worker stack_pop(stack);
3905*2d543d20SAndroid Build Coastguard Worker
3906*2d543d20SAndroid Build Coastguard Worker exit:
3907*2d543d20SAndroid Build Coastguard Worker return rc;
3908*2d543d20SAndroid Build Coastguard Worker }
3909*2d543d20SAndroid Build Coastguard Worker
linked_blocks_to_cil(struct policydb * pdb)3910*2d543d20SAndroid Build Coastguard Worker static int linked_blocks_to_cil(struct policydb *pdb)
3911*2d543d20SAndroid Build Coastguard Worker {
3912*2d543d20SAndroid Build Coastguard Worker // Convert base module that has been linked to CIL
3913*2d543d20SAndroid Build Coastguard Worker // Since it is linked, all optional blocks have been resolved
3914*2d543d20SAndroid Build Coastguard Worker int rc = -1;
3915*2d543d20SAndroid Build Coastguard Worker struct avrule_block *block;
3916*2d543d20SAndroid Build Coastguard Worker struct stack *stack = NULL;
3917*2d543d20SAndroid Build Coastguard Worker
3918*2d543d20SAndroid Build Coastguard Worker rc = stack_init(&stack);
3919*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
3920*2d543d20SAndroid Build Coastguard Worker goto exit;
3921*2d543d20SAndroid Build Coastguard Worker }
3922*2d543d20SAndroid Build Coastguard Worker
3923*2d543d20SAndroid Build Coastguard Worker block = pdb->global;
3924*2d543d20SAndroid Build Coastguard Worker rc = global_block_to_cil(pdb, block, stack);
3925*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
3926*2d543d20SAndroid Build Coastguard Worker goto exit;
3927*2d543d20SAndroid Build Coastguard Worker }
3928*2d543d20SAndroid Build Coastguard Worker
3929*2d543d20SAndroid Build Coastguard Worker for (block = block->next; block != NULL; block = block->next) {
3930*2d543d20SAndroid Build Coastguard Worker rc = linked_block_to_cil(pdb, block, stack);
3931*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
3932*2d543d20SAndroid Build Coastguard Worker goto exit;
3933*2d543d20SAndroid Build Coastguard Worker }
3934*2d543d20SAndroid Build Coastguard Worker }
3935*2d543d20SAndroid Build Coastguard Worker
3936*2d543d20SAndroid Build Coastguard Worker exit:
3937*2d543d20SAndroid Build Coastguard Worker stack_destroy(&stack);
3938*2d543d20SAndroid Build Coastguard Worker
3939*2d543d20SAndroid Build Coastguard Worker return rc;
3940*2d543d20SAndroid Build Coastguard Worker }
3941*2d543d20SAndroid Build Coastguard Worker
handle_unknown_to_cil(struct policydb * pdb)3942*2d543d20SAndroid Build Coastguard Worker static int handle_unknown_to_cil(struct policydb *pdb)
3943*2d543d20SAndroid Build Coastguard Worker {
3944*2d543d20SAndroid Build Coastguard Worker int rc = -1;
3945*2d543d20SAndroid Build Coastguard Worker const char *hu;
3946*2d543d20SAndroid Build Coastguard Worker
3947*2d543d20SAndroid Build Coastguard Worker switch (pdb->handle_unknown) {
3948*2d543d20SAndroid Build Coastguard Worker case SEPOL_DENY_UNKNOWN:
3949*2d543d20SAndroid Build Coastguard Worker hu = "deny";
3950*2d543d20SAndroid Build Coastguard Worker break;
3951*2d543d20SAndroid Build Coastguard Worker case SEPOL_REJECT_UNKNOWN:
3952*2d543d20SAndroid Build Coastguard Worker hu = "reject";
3953*2d543d20SAndroid Build Coastguard Worker break;
3954*2d543d20SAndroid Build Coastguard Worker case SEPOL_ALLOW_UNKNOWN:
3955*2d543d20SAndroid Build Coastguard Worker hu = "allow";
3956*2d543d20SAndroid Build Coastguard Worker break;
3957*2d543d20SAndroid Build Coastguard Worker default:
3958*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Unknown value for handle-unknown: %i", pdb->handle_unknown);
3959*2d543d20SAndroid Build Coastguard Worker rc = -1;
3960*2d543d20SAndroid Build Coastguard Worker goto exit;
3961*2d543d20SAndroid Build Coastguard Worker }
3962*2d543d20SAndroid Build Coastguard Worker
3963*2d543d20SAndroid Build Coastguard Worker cil_println(0, "(handleunknown %s)", hu);
3964*2d543d20SAndroid Build Coastguard Worker
3965*2d543d20SAndroid Build Coastguard Worker return 0;
3966*2d543d20SAndroid Build Coastguard Worker
3967*2d543d20SAndroid Build Coastguard Worker exit:
3968*2d543d20SAndroid Build Coastguard Worker return rc;
3969*2d543d20SAndroid Build Coastguard Worker }
3970*2d543d20SAndroid Build Coastguard Worker
generate_mls(struct policydb * pdb)3971*2d543d20SAndroid Build Coastguard Worker static int generate_mls(struct policydb *pdb)
3972*2d543d20SAndroid Build Coastguard Worker {
3973*2d543d20SAndroid Build Coastguard Worker const char *mls_str = pdb->mls ? "true" : "false";
3974*2d543d20SAndroid Build Coastguard Worker cil_println(0, "(mls %s)", mls_str);
3975*2d543d20SAndroid Build Coastguard Worker
3976*2d543d20SAndroid Build Coastguard Worker return 0;
3977*2d543d20SAndroid Build Coastguard Worker }
3978*2d543d20SAndroid Build Coastguard Worker
generate_default_level(void)3979*2d543d20SAndroid Build Coastguard Worker static int generate_default_level(void)
3980*2d543d20SAndroid Build Coastguard Worker {
3981*2d543d20SAndroid Build Coastguard Worker cil_println(0, "(sensitivity s0)");
3982*2d543d20SAndroid Build Coastguard Worker cil_println(0, "(sensitivityorder (s0))");
3983*2d543d20SAndroid Build Coastguard Worker cil_println(0, "(level " DEFAULT_LEVEL " (s0))");
3984*2d543d20SAndroid Build Coastguard Worker
3985*2d543d20SAndroid Build Coastguard Worker return 0;
3986*2d543d20SAndroid Build Coastguard Worker }
3987*2d543d20SAndroid Build Coastguard Worker
generate_default_object(void)3988*2d543d20SAndroid Build Coastguard Worker static int generate_default_object(void)
3989*2d543d20SAndroid Build Coastguard Worker {
3990*2d543d20SAndroid Build Coastguard Worker cil_println(0, "(role " DEFAULT_OBJECT ")");
3991*2d543d20SAndroid Build Coastguard Worker
3992*2d543d20SAndroid Build Coastguard Worker return 0;
3993*2d543d20SAndroid Build Coastguard Worker }
3994*2d543d20SAndroid Build Coastguard Worker
generate_builtin_roles(void)3995*2d543d20SAndroid Build Coastguard Worker static int generate_builtin_roles(void)
3996*2d543d20SAndroid Build Coastguard Worker {
3997*2d543d20SAndroid Build Coastguard Worker // due to inconsistentencies between policies and CIL not allowing
3998*2d543d20SAndroid Build Coastguard Worker // duplicate roles, some roles are always created, regardless of if they
3999*2d543d20SAndroid Build Coastguard Worker // are declared in modules or not
4000*2d543d20SAndroid Build Coastguard Worker cil_println(0, "(role auditadm_r)");
4001*2d543d20SAndroid Build Coastguard Worker cil_println(0, "(role secadm_r)");
4002*2d543d20SAndroid Build Coastguard Worker
4003*2d543d20SAndroid Build Coastguard Worker return 0;
4004*2d543d20SAndroid Build Coastguard Worker }
4005*2d543d20SAndroid Build Coastguard Worker
generate_gen_require_attribute(void)4006*2d543d20SAndroid Build Coastguard Worker static int generate_gen_require_attribute(void)
4007*2d543d20SAndroid Build Coastguard Worker {
4008*2d543d20SAndroid Build Coastguard Worker cil_println(0, "(typeattribute " GEN_REQUIRE_ATTR ")");
4009*2d543d20SAndroid Build Coastguard Worker cil_println(0, "(roleattribute " GEN_REQUIRE_ATTR ")");
4010*2d543d20SAndroid Build Coastguard Worker
4011*2d543d20SAndroid Build Coastguard Worker return 0;
4012*2d543d20SAndroid Build Coastguard Worker }
4013*2d543d20SAndroid Build Coastguard Worker
fix_module_name(struct policydb * pdb)4014*2d543d20SAndroid Build Coastguard Worker static int fix_module_name(struct policydb *pdb)
4015*2d543d20SAndroid Build Coastguard Worker {
4016*2d543d20SAndroid Build Coastguard Worker char *letter;
4017*2d543d20SAndroid Build Coastguard Worker int rc = -1;
4018*2d543d20SAndroid Build Coastguard Worker
4019*2d543d20SAndroid Build Coastguard Worker // The base module doesn't have its name set, but we use that for some
4020*2d543d20SAndroid Build Coastguard Worker // autogenerated names, like optionals and attributes, to prevent naming
4021*2d543d20SAndroid Build Coastguard Worker // collisions. However, they sometimes need to be fixed up.
4022*2d543d20SAndroid Build Coastguard Worker
4023*2d543d20SAndroid Build Coastguard Worker // the base module isn't given a name, so just call it "base"
4024*2d543d20SAndroid Build Coastguard Worker if (pdb->policy_type == POLICY_BASE) {
4025*2d543d20SAndroid Build Coastguard Worker pdb->name = strdup("base");
4026*2d543d20SAndroid Build Coastguard Worker if (pdb->name == NULL) {
4027*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Out of memory");
4028*2d543d20SAndroid Build Coastguard Worker rc = -1;
4029*2d543d20SAndroid Build Coastguard Worker goto exit;
4030*2d543d20SAndroid Build Coastguard Worker }
4031*2d543d20SAndroid Build Coastguard Worker }
4032*2d543d20SAndroid Build Coastguard Worker
4033*2d543d20SAndroid Build Coastguard Worker // CIL is more restrictive in module names than checkmodule. Convert bad
4034*2d543d20SAndroid Build Coastguard Worker // characters to underscores
4035*2d543d20SAndroid Build Coastguard Worker for (letter = pdb->name; *letter != '\0'; letter++) {
4036*2d543d20SAndroid Build Coastguard Worker if (isalnum(*letter)) {
4037*2d543d20SAndroid Build Coastguard Worker continue;
4038*2d543d20SAndroid Build Coastguard Worker }
4039*2d543d20SAndroid Build Coastguard Worker
4040*2d543d20SAndroid Build Coastguard Worker *letter = '_';
4041*2d543d20SAndroid Build Coastguard Worker }
4042*2d543d20SAndroid Build Coastguard Worker
4043*2d543d20SAndroid Build Coastguard Worker return 0;
4044*2d543d20SAndroid Build Coastguard Worker exit:
4045*2d543d20SAndroid Build Coastguard Worker return rc;
4046*2d543d20SAndroid Build Coastguard Worker }
4047*2d543d20SAndroid Build Coastguard Worker
sepol_module_policydb_to_cil(FILE * fp,struct policydb * pdb,int linked)4048*2d543d20SAndroid Build Coastguard Worker int sepol_module_policydb_to_cil(FILE *fp, struct policydb *pdb, int linked)
4049*2d543d20SAndroid Build Coastguard Worker {
4050*2d543d20SAndroid Build Coastguard Worker int rc = -1;
4051*2d543d20SAndroid Build Coastguard Worker
4052*2d543d20SAndroid Build Coastguard Worker out_file = fp;
4053*2d543d20SAndroid Build Coastguard Worker
4054*2d543d20SAndroid Build Coastguard Worker if (pdb == NULL) {
4055*2d543d20SAndroid Build Coastguard Worker rc = 0;
4056*2d543d20SAndroid Build Coastguard Worker goto exit;
4057*2d543d20SAndroid Build Coastguard Worker }
4058*2d543d20SAndroid Build Coastguard Worker
4059*2d543d20SAndroid Build Coastguard Worker if (pdb->policy_type != SEPOL_POLICY_BASE &&
4060*2d543d20SAndroid Build Coastguard Worker pdb->policy_type != SEPOL_POLICY_MOD) {
4061*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Policy package is not a base or module");
4062*2d543d20SAndroid Build Coastguard Worker rc = -1;
4063*2d543d20SAndroid Build Coastguard Worker goto exit;
4064*2d543d20SAndroid Build Coastguard Worker }
4065*2d543d20SAndroid Build Coastguard Worker
4066*2d543d20SAndroid Build Coastguard Worker rc = fix_module_name(pdb);
4067*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
4068*2d543d20SAndroid Build Coastguard Worker goto exit;
4069*2d543d20SAndroid Build Coastguard Worker }
4070*2d543d20SAndroid Build Coastguard Worker
4071*2d543d20SAndroid Build Coastguard Worker if (pdb->policy_type == SEPOL_POLICY_BASE && !pdb->mls) {
4072*2d543d20SAndroid Build Coastguard Worker // If this is a base non-mls policy, we need to define a default level
4073*2d543d20SAndroid Build Coastguard Worker // range that can be used for contexts by other non-mls modules, since
4074*2d543d20SAndroid Build Coastguard Worker // CIL requires that all contexts have a range, even if they are
4075*2d543d20SAndroid Build Coastguard Worker // ignored as in non-mls policies
4076*2d543d20SAndroid Build Coastguard Worker rc = generate_default_level();
4077*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
4078*2d543d20SAndroid Build Coastguard Worker goto exit;
4079*2d543d20SAndroid Build Coastguard Worker }
4080*2d543d20SAndroid Build Coastguard Worker }
4081*2d543d20SAndroid Build Coastguard Worker
4082*2d543d20SAndroid Build Coastguard Worker if (pdb->policy_type == SEPOL_POLICY_BASE) {
4083*2d543d20SAndroid Build Coastguard Worker // object_r is implicit in checkmodule, but not with CIL, create it
4084*2d543d20SAndroid Build Coastguard Worker // as part of base
4085*2d543d20SAndroid Build Coastguard Worker rc = generate_default_object();
4086*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
4087*2d543d20SAndroid Build Coastguard Worker goto exit;
4088*2d543d20SAndroid Build Coastguard Worker }
4089*2d543d20SAndroid Build Coastguard Worker
4090*2d543d20SAndroid Build Coastguard Worker rc = generate_builtin_roles();
4091*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
4092*2d543d20SAndroid Build Coastguard Worker goto exit;
4093*2d543d20SAndroid Build Coastguard Worker }
4094*2d543d20SAndroid Build Coastguard Worker
4095*2d543d20SAndroid Build Coastguard Worker // default attribute to be used to mimic gen_require in CIL
4096*2d543d20SAndroid Build Coastguard Worker rc = generate_gen_require_attribute();
4097*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
4098*2d543d20SAndroid Build Coastguard Worker goto exit;
4099*2d543d20SAndroid Build Coastguard Worker }
4100*2d543d20SAndroid Build Coastguard Worker
4101*2d543d20SAndroid Build Coastguard Worker // handle_unknown is used from only the base module
4102*2d543d20SAndroid Build Coastguard Worker rc = handle_unknown_to_cil(pdb);
4103*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
4104*2d543d20SAndroid Build Coastguard Worker goto exit;
4105*2d543d20SAndroid Build Coastguard Worker }
4106*2d543d20SAndroid Build Coastguard Worker
4107*2d543d20SAndroid Build Coastguard Worker // mls is used from only the base module
4108*2d543d20SAndroid Build Coastguard Worker rc = generate_mls(pdb);
4109*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
4110*2d543d20SAndroid Build Coastguard Worker goto exit;
4111*2d543d20SAndroid Build Coastguard Worker }
4112*2d543d20SAndroid Build Coastguard Worker }
4113*2d543d20SAndroid Build Coastguard Worker
4114*2d543d20SAndroid Build Coastguard Worker rc = role_list_create(pdb->p_roles.table);
4115*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
4116*2d543d20SAndroid Build Coastguard Worker goto exit;
4117*2d543d20SAndroid Build Coastguard Worker }
4118*2d543d20SAndroid Build Coastguard Worker
4119*2d543d20SAndroid Build Coastguard Worker rc = typealias_list_create(pdb);
4120*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
4121*2d543d20SAndroid Build Coastguard Worker goto exit;
4122*2d543d20SAndroid Build Coastguard Worker }
4123*2d543d20SAndroid Build Coastguard Worker
4124*2d543d20SAndroid Build Coastguard Worker rc = polcaps_to_cil(pdb);
4125*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
4126*2d543d20SAndroid Build Coastguard Worker goto exit;
4127*2d543d20SAndroid Build Coastguard Worker }
4128*2d543d20SAndroid Build Coastguard Worker
4129*2d543d20SAndroid Build Coastguard Worker rc = ocontexts_to_cil(pdb);
4130*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
4131*2d543d20SAndroid Build Coastguard Worker goto exit;
4132*2d543d20SAndroid Build Coastguard Worker }
4133*2d543d20SAndroid Build Coastguard Worker
4134*2d543d20SAndroid Build Coastguard Worker rc = genfscon_to_cil(pdb);
4135*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
4136*2d543d20SAndroid Build Coastguard Worker goto exit;
4137*2d543d20SAndroid Build Coastguard Worker }
4138*2d543d20SAndroid Build Coastguard Worker
4139*2d543d20SAndroid Build Coastguard Worker // now print everything that is scoped
4140*2d543d20SAndroid Build Coastguard Worker if (linked) {
4141*2d543d20SAndroid Build Coastguard Worker rc = linked_blocks_to_cil(pdb);
4142*2d543d20SAndroid Build Coastguard Worker } else {
4143*2d543d20SAndroid Build Coastguard Worker rc = blocks_to_cil(pdb);
4144*2d543d20SAndroid Build Coastguard Worker }
4145*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
4146*2d543d20SAndroid Build Coastguard Worker goto exit;
4147*2d543d20SAndroid Build Coastguard Worker }
4148*2d543d20SAndroid Build Coastguard Worker
4149*2d543d20SAndroid Build Coastguard Worker rc = 0;
4150*2d543d20SAndroid Build Coastguard Worker
4151*2d543d20SAndroid Build Coastguard Worker exit:
4152*2d543d20SAndroid Build Coastguard Worker role_list_destroy();
4153*2d543d20SAndroid Build Coastguard Worker typealias_list_destroy();
4154*2d543d20SAndroid Build Coastguard Worker
4155*2d543d20SAndroid Build Coastguard Worker return rc;
4156*2d543d20SAndroid Build Coastguard Worker }
4157*2d543d20SAndroid Build Coastguard Worker
sepol_module_package_to_cil(FILE * fp,struct sepol_module_package * mod_pkg)4158*2d543d20SAndroid Build Coastguard Worker int sepol_module_package_to_cil(FILE *fp, struct sepol_module_package *mod_pkg)
4159*2d543d20SAndroid Build Coastguard Worker {
4160*2d543d20SAndroid Build Coastguard Worker int rc = -1;
4161*2d543d20SAndroid Build Coastguard Worker struct sepol_policydb *pdb;
4162*2d543d20SAndroid Build Coastguard Worker
4163*2d543d20SAndroid Build Coastguard Worker out_file = fp;
4164*2d543d20SAndroid Build Coastguard Worker
4165*2d543d20SAndroid Build Coastguard Worker pdb = sepol_module_package_get_policy(mod_pkg);
4166*2d543d20SAndroid Build Coastguard Worker if (pdb == NULL) {
4167*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Failed to get policydb");
4168*2d543d20SAndroid Build Coastguard Worker rc = -1;
4169*2d543d20SAndroid Build Coastguard Worker goto exit;
4170*2d543d20SAndroid Build Coastguard Worker }
4171*2d543d20SAndroid Build Coastguard Worker
4172*2d543d20SAndroid Build Coastguard Worker rc = sepol_module_policydb_to_cil(fp, &pdb->p, 0);
4173*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
4174*2d543d20SAndroid Build Coastguard Worker goto exit;
4175*2d543d20SAndroid Build Coastguard Worker }
4176*2d543d20SAndroid Build Coastguard Worker
4177*2d543d20SAndroid Build Coastguard Worker rc = seusers_to_cil(mod_pkg);
4178*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
4179*2d543d20SAndroid Build Coastguard Worker goto exit;
4180*2d543d20SAndroid Build Coastguard Worker }
4181*2d543d20SAndroid Build Coastguard Worker
4182*2d543d20SAndroid Build Coastguard Worker rc = netfilter_contexts_to_cil(mod_pkg);
4183*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
4184*2d543d20SAndroid Build Coastguard Worker goto exit;
4185*2d543d20SAndroid Build Coastguard Worker }
4186*2d543d20SAndroid Build Coastguard Worker
4187*2d543d20SAndroid Build Coastguard Worker rc = user_extra_to_cil(mod_pkg);
4188*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
4189*2d543d20SAndroid Build Coastguard Worker goto exit;
4190*2d543d20SAndroid Build Coastguard Worker }
4191*2d543d20SAndroid Build Coastguard Worker
4192*2d543d20SAndroid Build Coastguard Worker rc = file_contexts_to_cil(mod_pkg);
4193*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
4194*2d543d20SAndroid Build Coastguard Worker goto exit;
4195*2d543d20SAndroid Build Coastguard Worker }
4196*2d543d20SAndroid Build Coastguard Worker
4197*2d543d20SAndroid Build Coastguard Worker rc = 0;
4198*2d543d20SAndroid Build Coastguard Worker
4199*2d543d20SAndroid Build Coastguard Worker exit:
4200*2d543d20SAndroid Build Coastguard Worker return rc;
4201*2d543d20SAndroid Build Coastguard Worker }
4202*2d543d20SAndroid Build Coastguard Worker
fp_to_buffer(FILE * fp,char ** data,size_t * data_len)4203*2d543d20SAndroid Build Coastguard Worker static int fp_to_buffer(FILE *fp, char **data, size_t *data_len)
4204*2d543d20SAndroid Build Coastguard Worker {
4205*2d543d20SAndroid Build Coastguard Worker int rc = -1;
4206*2d543d20SAndroid Build Coastguard Worker char *d = NULL, *d_tmp;
4207*2d543d20SAndroid Build Coastguard Worker size_t d_len = 0;
4208*2d543d20SAndroid Build Coastguard Worker size_t read_len = 0;
4209*2d543d20SAndroid Build Coastguard Worker size_t max_len = 1 << 17; // start at 128KB, this is enough to hold about half of all the existing pp files
4210*2d543d20SAndroid Build Coastguard Worker
4211*2d543d20SAndroid Build Coastguard Worker d = malloc(max_len);
4212*2d543d20SAndroid Build Coastguard Worker if (d == NULL) {
4213*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Out of memory");
4214*2d543d20SAndroid Build Coastguard Worker rc = -1;
4215*2d543d20SAndroid Build Coastguard Worker goto exit;
4216*2d543d20SAndroid Build Coastguard Worker }
4217*2d543d20SAndroid Build Coastguard Worker
4218*2d543d20SAndroid Build Coastguard Worker while ((read_len = fread(d + d_len, 1, max_len - d_len, fp)) > 0) {
4219*2d543d20SAndroid Build Coastguard Worker d_len += read_len;
4220*2d543d20SAndroid Build Coastguard Worker if (d_len == max_len) {
4221*2d543d20SAndroid Build Coastguard Worker max_len *= 2;
4222*2d543d20SAndroid Build Coastguard Worker d_tmp = realloc(d, max_len);
4223*2d543d20SAndroid Build Coastguard Worker if (d_tmp == NULL) {
4224*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Out of memory");
4225*2d543d20SAndroid Build Coastguard Worker rc = -1;
4226*2d543d20SAndroid Build Coastguard Worker goto exit;
4227*2d543d20SAndroid Build Coastguard Worker }
4228*2d543d20SAndroid Build Coastguard Worker d = d_tmp;
4229*2d543d20SAndroid Build Coastguard Worker }
4230*2d543d20SAndroid Build Coastguard Worker }
4231*2d543d20SAndroid Build Coastguard Worker
4232*2d543d20SAndroid Build Coastguard Worker if (ferror(fp) != 0) {
4233*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Failed to read pp file");
4234*2d543d20SAndroid Build Coastguard Worker rc = -1;
4235*2d543d20SAndroid Build Coastguard Worker goto exit;
4236*2d543d20SAndroid Build Coastguard Worker }
4237*2d543d20SAndroid Build Coastguard Worker
4238*2d543d20SAndroid Build Coastguard Worker *data = d;
4239*2d543d20SAndroid Build Coastguard Worker *data_len = d_len;
4240*2d543d20SAndroid Build Coastguard Worker
4241*2d543d20SAndroid Build Coastguard Worker return 0;
4242*2d543d20SAndroid Build Coastguard Worker
4243*2d543d20SAndroid Build Coastguard Worker exit:
4244*2d543d20SAndroid Build Coastguard Worker free(d);
4245*2d543d20SAndroid Build Coastguard Worker return rc;
4246*2d543d20SAndroid Build Coastguard Worker }
4247*2d543d20SAndroid Build Coastguard Worker
sepol_ppfile_to_module_package(FILE * fp,struct sepol_module_package ** mod_pkg)4248*2d543d20SAndroid Build Coastguard Worker int sepol_ppfile_to_module_package(FILE *fp, struct sepol_module_package **mod_pkg)
4249*2d543d20SAndroid Build Coastguard Worker {
4250*2d543d20SAndroid Build Coastguard Worker int rc = -1;
4251*2d543d20SAndroid Build Coastguard Worker struct sepol_policy_file *pf = NULL;
4252*2d543d20SAndroid Build Coastguard Worker struct sepol_module_package *pkg = NULL;
4253*2d543d20SAndroid Build Coastguard Worker char *data = NULL;
4254*2d543d20SAndroid Build Coastguard Worker size_t data_len;
4255*2d543d20SAndroid Build Coastguard Worker int fd;
4256*2d543d20SAndroid Build Coastguard Worker struct stat sb;
4257*2d543d20SAndroid Build Coastguard Worker
4258*2d543d20SAndroid Build Coastguard Worker rc = sepol_policy_file_create(&pf);
4259*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
4260*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Failed to create policy file");
4261*2d543d20SAndroid Build Coastguard Worker goto exit;
4262*2d543d20SAndroid Build Coastguard Worker }
4263*2d543d20SAndroid Build Coastguard Worker
4264*2d543d20SAndroid Build Coastguard Worker fd = fileno(fp);
4265*2d543d20SAndroid Build Coastguard Worker if (fstat(fd, &sb) == -1) {
4266*2d543d20SAndroid Build Coastguard Worker rc = -1;
4267*2d543d20SAndroid Build Coastguard Worker goto exit;
4268*2d543d20SAndroid Build Coastguard Worker }
4269*2d543d20SAndroid Build Coastguard Worker
4270*2d543d20SAndroid Build Coastguard Worker if (S_ISFIFO(sb.st_mode) || S_ISSOCK(sb.st_mode)) {
4271*2d543d20SAndroid Build Coastguard Worker // libsepol fails when trying to read a policy package from a pipe or a
4272*2d543d20SAndroid Build Coastguard Worker // socket due its use of lseek. In this case, read the data into a
4273*2d543d20SAndroid Build Coastguard Worker // buffer and provide that to libsepol
4274*2d543d20SAndroid Build Coastguard Worker rc = fp_to_buffer(fp, &data, &data_len);
4275*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
4276*2d543d20SAndroid Build Coastguard Worker goto exit;
4277*2d543d20SAndroid Build Coastguard Worker }
4278*2d543d20SAndroid Build Coastguard Worker
4279*2d543d20SAndroid Build Coastguard Worker sepol_policy_file_set_mem(pf, data, data_len);
4280*2d543d20SAndroid Build Coastguard Worker } else {
4281*2d543d20SAndroid Build Coastguard Worker sepol_policy_file_set_fp(pf, fp);
4282*2d543d20SAndroid Build Coastguard Worker }
4283*2d543d20SAndroid Build Coastguard Worker
4284*2d543d20SAndroid Build Coastguard Worker rc = sepol_module_package_create(&pkg);
4285*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
4286*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Failed to create module package");
4287*2d543d20SAndroid Build Coastguard Worker goto exit;
4288*2d543d20SAndroid Build Coastguard Worker }
4289*2d543d20SAndroid Build Coastguard Worker
4290*2d543d20SAndroid Build Coastguard Worker rc = sepol_module_package_read(pkg, pf, 0);
4291*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
4292*2d543d20SAndroid Build Coastguard Worker ERR(NULL, "Failed to read policy package");
4293*2d543d20SAndroid Build Coastguard Worker goto exit;
4294*2d543d20SAndroid Build Coastguard Worker }
4295*2d543d20SAndroid Build Coastguard Worker
4296*2d543d20SAndroid Build Coastguard Worker *mod_pkg = pkg;
4297*2d543d20SAndroid Build Coastguard Worker
4298*2d543d20SAndroid Build Coastguard Worker exit:
4299*2d543d20SAndroid Build Coastguard Worker free(data);
4300*2d543d20SAndroid Build Coastguard Worker
4301*2d543d20SAndroid Build Coastguard Worker sepol_policy_file_free(pf);
4302*2d543d20SAndroid Build Coastguard Worker
4303*2d543d20SAndroid Build Coastguard Worker if (rc != 0) {
4304*2d543d20SAndroid Build Coastguard Worker sepol_module_package_free(pkg);
4305*2d543d20SAndroid Build Coastguard Worker }
4306*2d543d20SAndroid Build Coastguard Worker
4307*2d543d20SAndroid Build Coastguard Worker return rc;
4308*2d543d20SAndroid Build Coastguard Worker }
4309