1*2d543d20SAndroid Build Coastguard Worker #include <cil/android.h>
2*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/hashtab.h>
3*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
4*2d543d20SAndroid Build Coastguard Worker #include <string.h>
5*2d543d20SAndroid Build Coastguard Worker
6*2d543d20SAndroid Build Coastguard Worker #include "cil_binary.h"
7*2d543d20SAndroid Build Coastguard Worker #include "cil_build_ast.h"
8*2d543d20SAndroid Build Coastguard Worker #include "cil_internal.h"
9*2d543d20SAndroid Build Coastguard Worker #include "cil_strpool.h"
10*2d543d20SAndroid Build Coastguard Worker #include "cil_symtab.h"
11*2d543d20SAndroid Build Coastguard Worker #include "cil_tree.h"
12*2d543d20SAndroid Build Coastguard Worker
13*2d543d20SAndroid Build Coastguard Worker #define VER_MAP_SZ (1 << 12)
14*2d543d20SAndroid Build Coastguard Worker
15*2d543d20SAndroid Build Coastguard Worker /* added to hashmap - currently unused as hashmap is used as a set */
16*2d543d20SAndroid Build Coastguard Worker struct version_datum {
17*2d543d20SAndroid Build Coastguard Worker struct cil_db *db;
18*2d543d20SAndroid Build Coastguard Worker struct cil_tree_node *ast_node;
19*2d543d20SAndroid Build Coastguard Worker char *orig_name;
20*2d543d20SAndroid Build Coastguard Worker };
21*2d543d20SAndroid Build Coastguard Worker
22*2d543d20SAndroid Build Coastguard Worker struct version_args {
23*2d543d20SAndroid Build Coastguard Worker struct cil_db *db;
24*2d543d20SAndroid Build Coastguard Worker hashtab_t vers_map;
25*2d543d20SAndroid Build Coastguard Worker const char *num;
26*2d543d20SAndroid Build Coastguard Worker };
27*2d543d20SAndroid Build Coastguard Worker
28*2d543d20SAndroid Build Coastguard Worker struct policydb_amend_args {
29*2d543d20SAndroid Build Coastguard Worker const struct cil_db *db;
30*2d543d20SAndroid Build Coastguard Worker policydb_t *pdb;
31*2d543d20SAndroid Build Coastguard Worker void **type_value_to_cil;
32*2d543d20SAndroid Build Coastguard Worker };
33*2d543d20SAndroid Build Coastguard Worker
34*2d543d20SAndroid Build Coastguard Worker enum plat_flavor {
35*2d543d20SAndroid Build Coastguard Worker PLAT_NONE = 0,
36*2d543d20SAndroid Build Coastguard Worker PLAT_TYPE,
37*2d543d20SAndroid Build Coastguard Worker PLAT_ATTRIB
38*2d543d20SAndroid Build Coastguard Worker };
39*2d543d20SAndroid Build Coastguard Worker
ver_map_hash_val(hashtab_t h,const_hashtab_key_t key)40*2d543d20SAndroid Build Coastguard Worker static unsigned int ver_map_hash_val(hashtab_t h, const_hashtab_key_t key)
41*2d543d20SAndroid Build Coastguard Worker {
42*2d543d20SAndroid Build Coastguard Worker /* from cil_stpool.c */
43*2d543d20SAndroid Build Coastguard Worker char *p, *keyp;
44*2d543d20SAndroid Build Coastguard Worker size_t size;
45*2d543d20SAndroid Build Coastguard Worker unsigned int val;
46*2d543d20SAndroid Build Coastguard Worker
47*2d543d20SAndroid Build Coastguard Worker val = 0;
48*2d543d20SAndroid Build Coastguard Worker keyp = (char*)key;
49*2d543d20SAndroid Build Coastguard Worker size = strlen(keyp);
50*2d543d20SAndroid Build Coastguard Worker for (p = keyp; ((size_t) (p - keyp)) < size; p++)
51*2d543d20SAndroid Build Coastguard Worker val =
52*2d543d20SAndroid Build Coastguard Worker (val << 4 | (val >> (8 * sizeof(unsigned int) - 4))) ^ (*p);
53*2d543d20SAndroid Build Coastguard Worker return val & (h->size - 1);
54*2d543d20SAndroid Build Coastguard Worker }
55*2d543d20SAndroid Build Coastguard Worker
56*2d543d20SAndroid Build Coastguard Worker
ver_map_key_cmp(hashtab_t h,const_hashtab_key_t key1,const_hashtab_key_t key2)57*2d543d20SAndroid Build Coastguard Worker static int ver_map_key_cmp(hashtab_t h __attribute__ ((unused)),
58*2d543d20SAndroid Build Coastguard Worker const_hashtab_key_t key1, const_hashtab_key_t key2)
59*2d543d20SAndroid Build Coastguard Worker {
60*2d543d20SAndroid Build Coastguard Worker /* hashtab_key_t is just a const char* underneath */
61*2d543d20SAndroid Build Coastguard Worker return strcmp(key1, key2);
62*2d543d20SAndroid Build Coastguard Worker }
63*2d543d20SAndroid Build Coastguard Worker
64*2d543d20SAndroid Build Coastguard Worker /*
65*2d543d20SAndroid Build Coastguard Worker * version_datum pointers all refer to memory owned elsewhere, so just free the
66*2d543d20SAndroid Build Coastguard Worker * datum itself.
67*2d543d20SAndroid Build Coastguard Worker */
ver_map_entry_destroy(hashtab_key_t k,hashtab_datum_t d,void * args)68*2d543d20SAndroid Build Coastguard Worker static int ver_map_entry_destroy(__attribute__ ((unused))hashtab_key_t k,
69*2d543d20SAndroid Build Coastguard Worker hashtab_datum_t d, __attribute__ ((unused))void *args)
70*2d543d20SAndroid Build Coastguard Worker {
71*2d543d20SAndroid Build Coastguard Worker free(d);
72*2d543d20SAndroid Build Coastguard Worker return 0;
73*2d543d20SAndroid Build Coastguard Worker }
74*2d543d20SAndroid Build Coastguard Worker
ver_map_destroy(hashtab_t h)75*2d543d20SAndroid Build Coastguard Worker static void ver_map_destroy(hashtab_t h)
76*2d543d20SAndroid Build Coastguard Worker {
77*2d543d20SAndroid Build Coastguard Worker hashtab_map(h, ver_map_entry_destroy, NULL);
78*2d543d20SAndroid Build Coastguard Worker hashtab_destroy(h);
79*2d543d20SAndroid Build Coastguard Worker }
80*2d543d20SAndroid Build Coastguard Worker
__extract_attributees_helper(struct cil_tree_node * node,uint32_t * finished,void * extra_args)81*2d543d20SAndroid Build Coastguard Worker static int __extract_attributees_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args)
82*2d543d20SAndroid Build Coastguard Worker {
83*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
84*2d543d20SAndroid Build Coastguard Worker struct version_args *args = (struct version_args *) extra_args;
85*2d543d20SAndroid Build Coastguard Worker char *key;
86*2d543d20SAndroid Build Coastguard Worker struct version_datum *datum;
87*2d543d20SAndroid Build Coastguard Worker
88*2d543d20SAndroid Build Coastguard Worker if (node == NULL || finished == NULL || extra_args == NULL) {
89*2d543d20SAndroid Build Coastguard Worker goto exit;
90*2d543d20SAndroid Build Coastguard Worker }
91*2d543d20SAndroid Build Coastguard Worker
92*2d543d20SAndroid Build Coastguard Worker switch (node->flavor) {
93*2d543d20SAndroid Build Coastguard Worker case CIL_ROLE:
94*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "%s unsupported statement in attributee policy (line %d)\n",
95*2d543d20SAndroid Build Coastguard Worker CIL_KEY_ROLE, node->line);
96*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_ERR;
97*2d543d20SAndroid Build Coastguard Worker break;
98*2d543d20SAndroid Build Coastguard Worker case CIL_TYPE:
99*2d543d20SAndroid Build Coastguard Worker case CIL_TYPEATTRIBUTE:
100*2d543d20SAndroid Build Coastguard Worker datum = cil_malloc(sizeof(*datum));
101*2d543d20SAndroid Build Coastguard Worker datum->db = args->db;
102*2d543d20SAndroid Build Coastguard Worker datum->ast_node = node;
103*2d543d20SAndroid Build Coastguard Worker datum->orig_name = DATUM(node->data)->name;
104*2d543d20SAndroid Build Coastguard Worker key = datum->orig_name;
105*2d543d20SAndroid Build Coastguard Worker if (!strncmp(key, "base_typeattr_", 14)) {
106*2d543d20SAndroid Build Coastguard Worker /* checkpolicy creates base attributes which are just typeattributesets,
107*2d543d20SAndroid Build Coastguard Worker of the existing types and attributes. These may be differnt in
108*2d543d20SAndroid Build Coastguard Worker every checkpolicy output, ignore them here, they'll be dealt with
109*2d543d20SAndroid Build Coastguard Worker as a special case when attributizing. */
110*2d543d20SAndroid Build Coastguard Worker free(datum);
111*2d543d20SAndroid Build Coastguard Worker } else {
112*2d543d20SAndroid Build Coastguard Worker rc = hashtab_insert(args->vers_map, (hashtab_key_t) key, (hashtab_datum_t) datum);
113*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
114*2d543d20SAndroid Build Coastguard Worker goto exit;
115*2d543d20SAndroid Build Coastguard Worker }
116*2d543d20SAndroid Build Coastguard Worker }
117*2d543d20SAndroid Build Coastguard Worker break;
118*2d543d20SAndroid Build Coastguard Worker case CIL_TYPEALIAS:
119*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "%s unsupported statement in attributee policy (line %d)\n",
120*2d543d20SAndroid Build Coastguard Worker CIL_KEY_TYPEALIAS, node->line);
121*2d543d20SAndroid Build Coastguard Worker goto exit;
122*2d543d20SAndroid Build Coastguard Worker break;
123*2d543d20SAndroid Build Coastguard Worker case CIL_TYPEPERMISSIVE:
124*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "%s unsupported statement in attributee policy (line %d)\n",
125*2d543d20SAndroid Build Coastguard Worker CIL_KEY_TYPEPERMISSIVE, node->line);
126*2d543d20SAndroid Build Coastguard Worker goto exit;
127*2d543d20SAndroid Build Coastguard Worker break;
128*2d543d20SAndroid Build Coastguard Worker case CIL_NAMETYPETRANSITION:
129*2d543d20SAndroid Build Coastguard Worker case CIL_TYPE_RULE:
130*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "%s unsupported statement in attributee policy (line %d)\n",
131*2d543d20SAndroid Build Coastguard Worker CIL_KEY_TYPETRANSITION, node->line);
132*2d543d20SAndroid Build Coastguard Worker goto exit;
133*2d543d20SAndroid Build Coastguard Worker break;
134*2d543d20SAndroid Build Coastguard Worker default:
135*2d543d20SAndroid Build Coastguard Worker break;
136*2d543d20SAndroid Build Coastguard Worker }
137*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
138*2d543d20SAndroid Build Coastguard Worker exit:
139*2d543d20SAndroid Build Coastguard Worker return rc;
140*2d543d20SAndroid Build Coastguard Worker }
141*2d543d20SAndroid Build Coastguard Worker
142*2d543d20SAndroid Build Coastguard Worker /*
143*2d543d20SAndroid Build Coastguard Worker * For the given db, with an already-built AST, fill the vers_map hash table
144*2d543d20SAndroid Build Coastguard Worker * with every encountered type and attribute. This could eventually be expanded
145*2d543d20SAndroid Build Coastguard Worker * to include other language constructs, such as users and roles, in which case
146*2d543d20SAndroid Build Coastguard Worker * multiple hash tables would be needed. These tables can then be used by
147*2d543d20SAndroid Build Coastguard Worker * attributize() to change all references to these types.
148*2d543d20SAndroid Build Coastguard Worker */
cil_extract_attributees(struct cil_db * db,hashtab_t vers_map)149*2d543d20SAndroid Build Coastguard Worker int cil_extract_attributees(struct cil_db *db, hashtab_t vers_map)
150*2d543d20SAndroid Build Coastguard Worker {
151*2d543d20SAndroid Build Coastguard Worker /* walk ast. */
152*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
153*2d543d20SAndroid Build Coastguard Worker struct version_args extra_args;
154*2d543d20SAndroid Build Coastguard Worker extra_args.db = db;
155*2d543d20SAndroid Build Coastguard Worker extra_args.vers_map = vers_map;
156*2d543d20SAndroid Build Coastguard Worker extra_args.num = NULL;
157*2d543d20SAndroid Build Coastguard Worker rc = cil_tree_walk(db->ast->root, __extract_attributees_helper, NULL, NULL, &extra_args);
158*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
159*2d543d20SAndroid Build Coastguard Worker goto exit;
160*2d543d20SAndroid Build Coastguard Worker }
161*2d543d20SAndroid Build Coastguard Worker
162*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
163*2d543d20SAndroid Build Coastguard Worker exit:
164*2d543d20SAndroid Build Coastguard Worker return rc;
165*2d543d20SAndroid Build Coastguard Worker }
166*2d543d20SAndroid Build Coastguard Worker
__cil_get_plat_flavor(hashtab_t vers_map,hashtab_key_t key)167*2d543d20SAndroid Build Coastguard Worker static enum plat_flavor __cil_get_plat_flavor(hashtab_t vers_map, hashtab_key_t key)
168*2d543d20SAndroid Build Coastguard Worker {
169*2d543d20SAndroid Build Coastguard Worker enum plat_flavor rc;
170*2d543d20SAndroid Build Coastguard Worker struct version_datum *vers_datum;
171*2d543d20SAndroid Build Coastguard Worker
172*2d543d20SAndroid Build Coastguard Worker vers_datum = (struct version_datum *)hashtab_search(vers_map, key);
173*2d543d20SAndroid Build Coastguard Worker if (vers_datum == NULL) {
174*2d543d20SAndroid Build Coastguard Worker return PLAT_NONE;
175*2d543d20SAndroid Build Coastguard Worker }
176*2d543d20SAndroid Build Coastguard Worker switch (vers_datum->ast_node->flavor) {
177*2d543d20SAndroid Build Coastguard Worker case CIL_TYPE:
178*2d543d20SAndroid Build Coastguard Worker rc = PLAT_TYPE;
179*2d543d20SAndroid Build Coastguard Worker break;
180*2d543d20SAndroid Build Coastguard Worker case CIL_TYPEATTRIBUTE:
181*2d543d20SAndroid Build Coastguard Worker rc = PLAT_ATTRIB;
182*2d543d20SAndroid Build Coastguard Worker break;
183*2d543d20SAndroid Build Coastguard Worker default:
184*2d543d20SAndroid Build Coastguard Worker rc = PLAT_NONE;
185*2d543d20SAndroid Build Coastguard Worker break;
186*2d543d20SAndroid Build Coastguard Worker }
187*2d543d20SAndroid Build Coastguard Worker return rc;
188*2d543d20SAndroid Build Coastguard Worker }
189*2d543d20SAndroid Build Coastguard Worker
190*2d543d20SAndroid Build Coastguard Worker /*
191*2d543d20SAndroid Build Coastguard Worker * Takes the old name and version string and creates a new strpool entry by
192*2d543d20SAndroid Build Coastguard Worker * combining them.
193*2d543d20SAndroid Build Coastguard Worker */
__cil_attrib_get_versname(char * old,const char * vers)194*2d543d20SAndroid Build Coastguard Worker static char *__cil_attrib_get_versname(char *old, const char *vers)
195*2d543d20SAndroid Build Coastguard Worker {
196*2d543d20SAndroid Build Coastguard Worker size_t len = 0;
197*2d543d20SAndroid Build Coastguard Worker char *tmp_new = NULL;
198*2d543d20SAndroid Build Coastguard Worker char *final;
199*2d543d20SAndroid Build Coastguard Worker
200*2d543d20SAndroid Build Coastguard Worker len += strlen(old) + strlen(vers) + 2;
201*2d543d20SAndroid Build Coastguard Worker tmp_new = cil_malloc(len);
202*2d543d20SAndroid Build Coastguard Worker snprintf(tmp_new, len, "%s_%s", old, vers);
203*2d543d20SAndroid Build Coastguard Worker final = cil_strpool_add(tmp_new);
204*2d543d20SAndroid Build Coastguard Worker free(tmp_new);
205*2d543d20SAndroid Build Coastguard Worker return final;
206*2d543d20SAndroid Build Coastguard Worker }
207*2d543d20SAndroid Build Coastguard Worker
208*2d543d20SAndroid Build Coastguard Worker /*
209*2d543d20SAndroid Build Coastguard Worker * Change type to attribute - create new versioned name based on old, create
210*2d543d20SAndroid Build Coastguard Worker * typeattribute node add to the existing type node.
211*2d543d20SAndroid Build Coastguard Worker */
__cil_attrib_convert_type(struct cil_tree_node * node,struct version_args * args)212*2d543d20SAndroid Build Coastguard Worker static int __cil_attrib_convert_type(struct cil_tree_node *node, struct version_args *args)
213*2d543d20SAndroid Build Coastguard Worker {
214*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
215*2d543d20SAndroid Build Coastguard Worker struct cil_type *type = (struct cil_type *)node->data;
216*2d543d20SAndroid Build Coastguard Worker struct cil_typeattribute *typeattr = NULL;
217*2d543d20SAndroid Build Coastguard Worker struct cil_tree_node *new_ast_node = NULL;
218*2d543d20SAndroid Build Coastguard Worker char *new_key;
219*2d543d20SAndroid Build Coastguard Worker
220*2d543d20SAndroid Build Coastguard Worker cil_typeattribute_init(&typeattr);
221*2d543d20SAndroid Build Coastguard Worker
222*2d543d20SAndroid Build Coastguard Worker new_key = __cil_attrib_get_versname(type->datum.name, args->num);
223*2d543d20SAndroid Build Coastguard Worker
224*2d543d20SAndroid Build Coastguard Worker /* create new tree node to contain typeattribute and add to tree */
225*2d543d20SAndroid Build Coastguard Worker cil_tree_node_init(&new_ast_node);
226*2d543d20SAndroid Build Coastguard Worker new_ast_node->parent = node->parent;
227*2d543d20SAndroid Build Coastguard Worker new_ast_node->next = node->next;
228*2d543d20SAndroid Build Coastguard Worker node->next = new_ast_node;
229*2d543d20SAndroid Build Coastguard Worker
230*2d543d20SAndroid Build Coastguard Worker rc = cil_gen_node(args->db, new_ast_node, (struct cil_symtab_datum *) typeattr,
231*2d543d20SAndroid Build Coastguard Worker new_key, CIL_SYM_TYPES, CIL_TYPEATTRIBUTE);
232*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
233*2d543d20SAndroid Build Coastguard Worker goto exit;
234*2d543d20SAndroid Build Coastguard Worker }
235*2d543d20SAndroid Build Coastguard Worker
236*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
237*2d543d20SAndroid Build Coastguard Worker exit:
238*2d543d20SAndroid Build Coastguard Worker return rc;
239*2d543d20SAndroid Build Coastguard Worker }
240*2d543d20SAndroid Build Coastguard Worker
241*2d543d20SAndroid Build Coastguard Worker /*
242*2d543d20SAndroid Build Coastguard Worker * Update datum - create new key, remove entry under old key,
243*2d543d20SAndroid Build Coastguard Worker * update entry, and insert under new key
244*2d543d20SAndroid Build Coastguard Worker */
__cil_attrib_swap_symtab_key(struct cil_tree_node * node,char * old_key,const char * num)245*2d543d20SAndroid Build Coastguard Worker static int __cil_attrib_swap_symtab_key(struct cil_tree_node *node, char *old_key,
246*2d543d20SAndroid Build Coastguard Worker const char *num)
247*2d543d20SAndroid Build Coastguard Worker {
248*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
249*2d543d20SAndroid Build Coastguard Worker char *new_key;
250*2d543d20SAndroid Build Coastguard Worker symtab_t *symtab;
251*2d543d20SAndroid Build Coastguard Worker struct cil_symtab_datum *datum = (struct cil_symtab_datum *) node->data;
252*2d543d20SAndroid Build Coastguard Worker
253*2d543d20SAndroid Build Coastguard Worker new_key = __cil_attrib_get_versname(old_key, num);
254*2d543d20SAndroid Build Coastguard Worker
255*2d543d20SAndroid Build Coastguard Worker symtab = datum->symtab;
256*2d543d20SAndroid Build Coastguard Worker
257*2d543d20SAndroid Build Coastguard Worker /* TODO: remove, but what happens to other nodes on this datum ?*/
258*2d543d20SAndroid Build Coastguard Worker cil_list_remove(datum->nodes, CIL_NODE, node, 0);
259*2d543d20SAndroid Build Coastguard Worker cil_symtab_remove_datum(datum);
260*2d543d20SAndroid Build Coastguard Worker
261*2d543d20SAndroid Build Coastguard Worker rc = cil_symtab_insert(symtab, new_key, datum, node);
262*2d543d20SAndroid Build Coastguard Worker
263*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
264*2d543d20SAndroid Build Coastguard Worker goto exit;
265*2d543d20SAndroid Build Coastguard Worker }
266*2d543d20SAndroid Build Coastguard Worker
267*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
268*2d543d20SAndroid Build Coastguard Worker exit:
269*2d543d20SAndroid Build Coastguard Worker return rc;
270*2d543d20SAndroid Build Coastguard Worker }
271*2d543d20SAndroid Build Coastguard Worker
272*2d543d20SAndroid Build Coastguard Worker /*
273*2d543d20SAndroid Build Coastguard Worker * expressions may contains strings which are not in the type-attribute
274*2d543d20SAndroid Build Coastguard Worker * namespace, so this is not a general cil_expr attributizer.
275*2d543d20SAndroid Build Coastguard Worker * TODO: add support for other types of expressions which may contain types.
276*2d543d20SAndroid Build Coastguard Worker */
cil_attrib_type_expr(struct cil_list * expr_str,struct version_args * args)277*2d543d20SAndroid Build Coastguard Worker static int cil_attrib_type_expr(struct cil_list *expr_str, struct version_args *args)
278*2d543d20SAndroid Build Coastguard Worker {
279*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
280*2d543d20SAndroid Build Coastguard Worker struct cil_list_item *curr = NULL;
281*2d543d20SAndroid Build Coastguard Worker char *new;
282*2d543d20SAndroid Build Coastguard Worker hashtab_key_t key;
283*2d543d20SAndroid Build Coastguard Worker
284*2d543d20SAndroid Build Coastguard Worker /* iterate through cil_list, replacing types */
285*2d543d20SAndroid Build Coastguard Worker cil_list_for_each(curr, expr_str) {
286*2d543d20SAndroid Build Coastguard Worker switch(curr->flavor) {
287*2d543d20SAndroid Build Coastguard Worker case CIL_LIST:
288*2d543d20SAndroid Build Coastguard Worker rc = cil_attrib_type_expr((struct cil_list *)curr->data, args);
289*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK)
290*2d543d20SAndroid Build Coastguard Worker goto exit;
291*2d543d20SAndroid Build Coastguard Worker break;
292*2d543d20SAndroid Build Coastguard Worker case CIL_STRING:
293*2d543d20SAndroid Build Coastguard Worker key = (hashtab_key_t) curr->data;
294*2d543d20SAndroid Build Coastguard Worker enum plat_flavor pf = __cil_get_plat_flavor(args->vers_map, key);
295*2d543d20SAndroid Build Coastguard Worker if (!strncmp(curr->data, "base_typeattr_", 14) || pf == PLAT_TYPE) {
296*2d543d20SAndroid Build Coastguard Worker new = __cil_attrib_get_versname((char *) curr->data, args->num);
297*2d543d20SAndroid Build Coastguard Worker curr->data = (void *) new;
298*2d543d20SAndroid Build Coastguard Worker }
299*2d543d20SAndroid Build Coastguard Worker break;
300*2d543d20SAndroid Build Coastguard Worker case CIL_DATUM:
301*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "AST already resolved. Not yet supported.\n");
302*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_ERR;
303*2d543d20SAndroid Build Coastguard Worker goto exit;
304*2d543d20SAndroid Build Coastguard Worker break;
305*2d543d20SAndroid Build Coastguard Worker default:
306*2d543d20SAndroid Build Coastguard Worker break;
307*2d543d20SAndroid Build Coastguard Worker }
308*2d543d20SAndroid Build Coastguard Worker }
309*2d543d20SAndroid Build Coastguard Worker
310*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
311*2d543d20SAndroid Build Coastguard Worker exit:
312*2d543d20SAndroid Build Coastguard Worker return rc;
313*2d543d20SAndroid Build Coastguard Worker }
314*2d543d20SAndroid Build Coastguard Worker
cil_attrib_check_context(struct cil_context * ctxt,struct version_args * args)315*2d543d20SAndroid Build Coastguard Worker static int cil_attrib_check_context(struct cil_context *ctxt, struct version_args *args)
316*2d543d20SAndroid Build Coastguard Worker {
317*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
318*2d543d20SAndroid Build Coastguard Worker hashtab_key_t key;
319*2d543d20SAndroid Build Coastguard Worker
320*2d543d20SAndroid Build Coastguard Worker if (ctxt->type != NULL) {
321*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "AST already resolved. Not yet supported.\n");
322*2d543d20SAndroid Build Coastguard Worker goto exit;
323*2d543d20SAndroid Build Coastguard Worker }
324*2d543d20SAndroid Build Coastguard Worker
325*2d543d20SAndroid Build Coastguard Worker key = (hashtab_key_t) ctxt->type_str;
326*2d543d20SAndroid Build Coastguard Worker if (__cil_get_plat_flavor(args->vers_map, key) != PLAT_NONE) {
327*2d543d20SAndroid Build Coastguard Worker /* TODO: reinstate check, but leave out for now
328*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "AST contains context with platform public type: %s\n",
329*2d543d20SAndroid Build Coastguard Worker ctxt->type_str);
330*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_ERR;
331*2d543d20SAndroid Build Coastguard Worker goto exit; */
332*2d543d20SAndroid Build Coastguard Worker }
333*2d543d20SAndroid Build Coastguard Worker
334*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
335*2d543d20SAndroid Build Coastguard Worker exit:
336*2d543d20SAndroid Build Coastguard Worker return rc;
337*2d543d20SAndroid Build Coastguard Worker }
338*2d543d20SAndroid Build Coastguard Worker
cil_attrib_sidcontext(struct cil_tree_node * node,struct version_args * args)339*2d543d20SAndroid Build Coastguard Worker static int cil_attrib_sidcontext(struct cil_tree_node *node, struct version_args *args)
340*2d543d20SAndroid Build Coastguard Worker {
341*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
342*2d543d20SAndroid Build Coastguard Worker struct cil_sidcontext *sidcon = (struct cil_sidcontext *)node->data;
343*2d543d20SAndroid Build Coastguard Worker
344*2d543d20SAndroid Build Coastguard Worker if (sidcon->context_str == NULL) {
345*2d543d20SAndroid Build Coastguard Worker /* sidcon contains an anon context, which needs to have type checked */
346*2d543d20SAndroid Build Coastguard Worker rc = cil_attrib_check_context(sidcon->context, args);
347*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
348*2d543d20SAndroid Build Coastguard Worker goto exit;
349*2d543d20SAndroid Build Coastguard Worker }
350*2d543d20SAndroid Build Coastguard Worker }
351*2d543d20SAndroid Build Coastguard Worker
352*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
353*2d543d20SAndroid Build Coastguard Worker exit:
354*2d543d20SAndroid Build Coastguard Worker return rc;
355*2d543d20SAndroid Build Coastguard Worker }
356*2d543d20SAndroid Build Coastguard Worker
cil_attrib_context(struct cil_tree_node * node,struct version_args * args)357*2d543d20SAndroid Build Coastguard Worker static int cil_attrib_context(struct cil_tree_node *node, struct version_args *args)
358*2d543d20SAndroid Build Coastguard Worker {
359*2d543d20SAndroid Build Coastguard Worker struct cil_context *ctxt = (struct cil_context *)node->data;
360*2d543d20SAndroid Build Coastguard Worker
361*2d543d20SAndroid Build Coastguard Worker return cil_attrib_check_context(ctxt, args);
362*2d543d20SAndroid Build Coastguard Worker }
363*2d543d20SAndroid Build Coastguard Worker
cil_attrib_roletype(struct cil_tree_node * node,struct version_args * args)364*2d543d20SAndroid Build Coastguard Worker static int cil_attrib_roletype(struct cil_tree_node *node,
365*2d543d20SAndroid Build Coastguard Worker __attribute__((unused)) struct version_args *args)
366*2d543d20SAndroid Build Coastguard Worker {
367*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
368*2d543d20SAndroid Build Coastguard Worker char *key;
369*2d543d20SAndroid Build Coastguard Worker struct cil_roletype *roletype = (struct cil_roletype *)node->data;
370*2d543d20SAndroid Build Coastguard Worker
371*2d543d20SAndroid Build Coastguard Worker if (roletype->role) {
372*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "AST already resolved. !!! Not yet supported.\n");
373*2d543d20SAndroid Build Coastguard Worker goto exit;
374*2d543d20SAndroid Build Coastguard Worker }
375*2d543d20SAndroid Build Coastguard Worker key = roletype->type_str;
376*2d543d20SAndroid Build Coastguard Worker if (__cil_get_plat_flavor(args->vers_map, (hashtab_key_t) key) == PLAT_TYPE) {
377*2d543d20SAndroid Build Coastguard Worker roletype->type_str = __cil_attrib_get_versname(key, args->num);
378*2d543d20SAndroid Build Coastguard Worker }
379*2d543d20SAndroid Build Coastguard Worker
380*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
381*2d543d20SAndroid Build Coastguard Worker exit:
382*2d543d20SAndroid Build Coastguard Worker return rc;
383*2d543d20SAndroid Build Coastguard Worker }
384*2d543d20SAndroid Build Coastguard Worker
cil_attrib_type(struct cil_tree_node * node,struct version_args * args)385*2d543d20SAndroid Build Coastguard Worker static int cil_attrib_type(struct cil_tree_node *node, struct version_args *args)
386*2d543d20SAndroid Build Coastguard Worker {
387*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
388*2d543d20SAndroid Build Coastguard Worker struct cil_type *type = (struct cil_type *)node->data;
389*2d543d20SAndroid Build Coastguard Worker char *key = type->datum.name;
390*2d543d20SAndroid Build Coastguard Worker
391*2d543d20SAndroid Build Coastguard Worker if (type->value) {
392*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "AST already resolved. !!! Not yet supported.\n");
393*2d543d20SAndroid Build Coastguard Worker goto exit;
394*2d543d20SAndroid Build Coastguard Worker }
395*2d543d20SAndroid Build Coastguard Worker if (__cil_get_plat_flavor(args->vers_map, (hashtab_key_t) key) == PLAT_TYPE) {
396*2d543d20SAndroid Build Coastguard Worker rc = __cil_attrib_convert_type(node, args);
397*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
398*2d543d20SAndroid Build Coastguard Worker goto exit;
399*2d543d20SAndroid Build Coastguard Worker }
400*2d543d20SAndroid Build Coastguard Worker }
401*2d543d20SAndroid Build Coastguard Worker
402*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
403*2d543d20SAndroid Build Coastguard Worker exit:
404*2d543d20SAndroid Build Coastguard Worker return rc;
405*2d543d20SAndroid Build Coastguard Worker }
406*2d543d20SAndroid Build Coastguard Worker
cil_attrib_typepermissive(struct cil_tree_node * node,struct version_args * args)407*2d543d20SAndroid Build Coastguard Worker static int cil_attrib_typepermissive(struct cil_tree_node *node,
408*2d543d20SAndroid Build Coastguard Worker struct version_args *args __attribute__ ((unused)))
409*2d543d20SAndroid Build Coastguard Worker {
410*2d543d20SAndroid Build Coastguard Worker struct cil_typepermissive *typeperm = (struct cil_typepermissive *)node->data;
411*2d543d20SAndroid Build Coastguard Worker
412*2d543d20SAndroid Build Coastguard Worker if (typeperm->type != NULL) {
413*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "AST already resolved. ### Not yet supported.\n");
414*2d543d20SAndroid Build Coastguard Worker return SEPOL_ERR;
415*2d543d20SAndroid Build Coastguard Worker }
416*2d543d20SAndroid Build Coastguard Worker
417*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
418*2d543d20SAndroid Build Coastguard Worker }
419*2d543d20SAndroid Build Coastguard Worker
cil_attrib_typeattribute(struct cil_tree_node * node,struct version_args * args)420*2d543d20SAndroid Build Coastguard Worker static int cil_attrib_typeattribute(struct cil_tree_node *node, struct version_args *args)
421*2d543d20SAndroid Build Coastguard Worker {
422*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
423*2d543d20SAndroid Build Coastguard Worker struct cil_typeattribute *typeattr = (struct cil_typeattribute *)node->data;
424*2d543d20SAndroid Build Coastguard Worker char *key = typeattr->datum.name;
425*2d543d20SAndroid Build Coastguard Worker
426*2d543d20SAndroid Build Coastguard Worker if (typeattr->types) {
427*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "AST already resolved. Not yet supported (line %d).\n",
428*2d543d20SAndroid Build Coastguard Worker node->line);
429*2d543d20SAndroid Build Coastguard Worker goto exit;
430*2d543d20SAndroid Build Coastguard Worker }
431*2d543d20SAndroid Build Coastguard Worker if (!strncmp(key, "base_typeattr_", 14)) {
432*2d543d20SAndroid Build Coastguard Worker rc = __cil_attrib_swap_symtab_key(node, key, args->num);
433*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
434*2d543d20SAndroid Build Coastguard Worker goto exit;
435*2d543d20SAndroid Build Coastguard Worker }
436*2d543d20SAndroid Build Coastguard Worker }
437*2d543d20SAndroid Build Coastguard Worker
438*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
439*2d543d20SAndroid Build Coastguard Worker exit:
440*2d543d20SAndroid Build Coastguard Worker return rc;
441*2d543d20SAndroid Build Coastguard Worker }
442*2d543d20SAndroid Build Coastguard Worker
cil_attrib_typeattributeset(struct cil_tree_node * node,struct version_args * args)443*2d543d20SAndroid Build Coastguard Worker static int cil_attrib_typeattributeset(struct cil_tree_node *node, struct version_args *args)
444*2d543d20SAndroid Build Coastguard Worker {
445*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
446*2d543d20SAndroid Build Coastguard Worker char *key;
447*2d543d20SAndroid Build Coastguard Worker struct cil_typeattributeset *typeattrset = (struct cil_typeattributeset *) node->data;
448*2d543d20SAndroid Build Coastguard Worker
449*2d543d20SAndroid Build Coastguard Worker if (typeattrset->datum_expr != NULL) {
450*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "AST already resolved. Not yet supported (line %d).\n",
451*2d543d20SAndroid Build Coastguard Worker node->line);
452*2d543d20SAndroid Build Coastguard Worker goto exit;
453*2d543d20SAndroid Build Coastguard Worker }
454*2d543d20SAndroid Build Coastguard Worker
455*2d543d20SAndroid Build Coastguard Worker key = typeattrset->attr_str;
456*2d543d20SAndroid Build Coastguard Worker /* first check to see if the attribute to which this set belongs is versioned */
457*2d543d20SAndroid Build Coastguard Worker if (!strncmp(key, "base_typeattr_", 14)) {
458*2d543d20SAndroid Build Coastguard Worker typeattrset->attr_str = __cil_attrib_get_versname(key, args->num);
459*2d543d20SAndroid Build Coastguard Worker }
460*2d543d20SAndroid Build Coastguard Worker
461*2d543d20SAndroid Build Coastguard Worker rc = cil_attrib_type_expr(typeattrset->str_expr, args);
462*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
463*2d543d20SAndroid Build Coastguard Worker goto exit;
464*2d543d20SAndroid Build Coastguard Worker }
465*2d543d20SAndroid Build Coastguard Worker
466*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
467*2d543d20SAndroid Build Coastguard Worker exit:
468*2d543d20SAndroid Build Coastguard Worker return rc;
469*2d543d20SAndroid Build Coastguard Worker }
470*2d543d20SAndroid Build Coastguard Worker
cil_attrib_typealiasactual(struct cil_tree_node * node,struct version_args * args)471*2d543d20SAndroid Build Coastguard Worker static int cil_attrib_typealiasactual(struct cil_tree_node *node, struct version_args *args)
472*2d543d20SAndroid Build Coastguard Worker {
473*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
474*2d543d20SAndroid Build Coastguard Worker char *key;
475*2d543d20SAndroid Build Coastguard Worker struct cil_aliasactual *aliasact = (struct cil_aliasactual *)node->data;
476*2d543d20SAndroid Build Coastguard Worker
477*2d543d20SAndroid Build Coastguard Worker key = aliasact->actual_str;
478*2d543d20SAndroid Build Coastguard Worker if (__cil_get_plat_flavor(args->vers_map, (hashtab_key_t) key) != PLAT_NONE) {
479*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "%s with platform public type not allowed (line %d)\n",
480*2d543d20SAndroid Build Coastguard Worker CIL_KEY_TYPEALIASACTUAL, node->line);
481*2d543d20SAndroid Build Coastguard Worker goto exit;
482*2d543d20SAndroid Build Coastguard Worker }
483*2d543d20SAndroid Build Coastguard Worker
484*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
485*2d543d20SAndroid Build Coastguard Worker exit:
486*2d543d20SAndroid Build Coastguard Worker return rc;
487*2d543d20SAndroid Build Coastguard Worker }
488*2d543d20SAndroid Build Coastguard Worker
cil_attrib_nametypetransition(struct cil_tree_node * node,struct version_args * args)489*2d543d20SAndroid Build Coastguard Worker static int cil_attrib_nametypetransition(struct cil_tree_node *node, struct version_args *args)
490*2d543d20SAndroid Build Coastguard Worker {
491*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
492*2d543d20SAndroid Build Coastguard Worker char *key;
493*2d543d20SAndroid Build Coastguard Worker struct cil_nametypetransition *namettrans = (struct cil_nametypetransition *)node->data;
494*2d543d20SAndroid Build Coastguard Worker
495*2d543d20SAndroid Build Coastguard Worker if (namettrans->src != NULL) {
496*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "AST already resolved. Not yet supported (line %d).\n",
497*2d543d20SAndroid Build Coastguard Worker node->line);
498*2d543d20SAndroid Build Coastguard Worker goto exit;
499*2d543d20SAndroid Build Coastguard Worker }
500*2d543d20SAndroid Build Coastguard Worker key = namettrans->src_str;
501*2d543d20SAndroid Build Coastguard Worker if (__cil_get_plat_flavor(args->vers_map, (hashtab_key_t) key) == PLAT_TYPE) {
502*2d543d20SAndroid Build Coastguard Worker namettrans->src_str = __cil_attrib_get_versname(key, args->num);
503*2d543d20SAndroid Build Coastguard Worker }
504*2d543d20SAndroid Build Coastguard Worker
505*2d543d20SAndroid Build Coastguard Worker key = namettrans->tgt_str;
506*2d543d20SAndroid Build Coastguard Worker if (__cil_get_plat_flavor(args->vers_map, (hashtab_key_t) key) == PLAT_TYPE) {
507*2d543d20SAndroid Build Coastguard Worker namettrans->tgt_str = __cil_attrib_get_versname(key, args->num);
508*2d543d20SAndroid Build Coastguard Worker }
509*2d543d20SAndroid Build Coastguard Worker
510*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
511*2d543d20SAndroid Build Coastguard Worker exit:
512*2d543d20SAndroid Build Coastguard Worker return rc;
513*2d543d20SAndroid Build Coastguard Worker }
514*2d543d20SAndroid Build Coastguard Worker
515*2d543d20SAndroid Build Coastguard Worker /*
516*2d543d20SAndroid Build Coastguard Worker * This is exactly the same as cil_attrib_nametypetransition, but the struct
517*2d543d20SAndroid Build Coastguard Worker * layouts differ, so we can't reuse it.
518*2d543d20SAndroid Build Coastguard Worker */
cil_attrib_type_rule(struct cil_tree_node * node,struct version_args * args)519*2d543d20SAndroid Build Coastguard Worker static int cil_attrib_type_rule(struct cil_tree_node *node, struct version_args *args)
520*2d543d20SAndroid Build Coastguard Worker {
521*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
522*2d543d20SAndroid Build Coastguard Worker char *key;
523*2d543d20SAndroid Build Coastguard Worker struct cil_type_rule *type_rule = (struct cil_type_rule *)node->data;
524*2d543d20SAndroid Build Coastguard Worker
525*2d543d20SAndroid Build Coastguard Worker if (type_rule->src != NULL) {
526*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "AST already resolved. Not yet supported (line %d).\n",
527*2d543d20SAndroid Build Coastguard Worker node->line);
528*2d543d20SAndroid Build Coastguard Worker goto exit;
529*2d543d20SAndroid Build Coastguard Worker }
530*2d543d20SAndroid Build Coastguard Worker key = type_rule->src_str;
531*2d543d20SAndroid Build Coastguard Worker if (__cil_get_plat_flavor(args->vers_map, (hashtab_key_t) key) == PLAT_TYPE) {
532*2d543d20SAndroid Build Coastguard Worker type_rule->src_str = __cil_attrib_get_versname(key, args->num);
533*2d543d20SAndroid Build Coastguard Worker }
534*2d543d20SAndroid Build Coastguard Worker
535*2d543d20SAndroid Build Coastguard Worker key = type_rule->tgt_str;
536*2d543d20SAndroid Build Coastguard Worker if (__cil_get_plat_flavor(args->vers_map, (hashtab_key_t) key) == PLAT_TYPE) {
537*2d543d20SAndroid Build Coastguard Worker type_rule->tgt_str = __cil_attrib_get_versname(key, args->num);
538*2d543d20SAndroid Build Coastguard Worker }
539*2d543d20SAndroid Build Coastguard Worker
540*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
541*2d543d20SAndroid Build Coastguard Worker exit:
542*2d543d20SAndroid Build Coastguard Worker return rc;
543*2d543d20SAndroid Build Coastguard Worker }
544*2d543d20SAndroid Build Coastguard Worker
cil_attrib_avrule(struct cil_tree_node * node,struct version_args * args)545*2d543d20SAndroid Build Coastguard Worker static int cil_attrib_avrule(struct cil_tree_node *node, struct version_args *args)
546*2d543d20SAndroid Build Coastguard Worker {
547*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
548*2d543d20SAndroid Build Coastguard Worker char *key;
549*2d543d20SAndroid Build Coastguard Worker struct cil_avrule *avrule = (struct cil_avrule *)node->data;
550*2d543d20SAndroid Build Coastguard Worker
551*2d543d20SAndroid Build Coastguard Worker if (avrule->src != NULL) {
552*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "AST already resolved. Not yet supported (line %d).\n",
553*2d543d20SAndroid Build Coastguard Worker node->line);
554*2d543d20SAndroid Build Coastguard Worker goto exit;
555*2d543d20SAndroid Build Coastguard Worker }
556*2d543d20SAndroid Build Coastguard Worker
557*2d543d20SAndroid Build Coastguard Worker key = avrule->src_str;
558*2d543d20SAndroid Build Coastguard Worker if (!strncmp(key, "base_typeattr_", 14) ||
559*2d543d20SAndroid Build Coastguard Worker __cil_get_plat_flavor(args->vers_map, (hashtab_key_t) key) == PLAT_TYPE) {
560*2d543d20SAndroid Build Coastguard Worker avrule->src_str = __cil_attrib_get_versname(key, args->num);
561*2d543d20SAndroid Build Coastguard Worker }
562*2d543d20SAndroid Build Coastguard Worker
563*2d543d20SAndroid Build Coastguard Worker key = avrule->tgt_str;
564*2d543d20SAndroid Build Coastguard Worker if (!strncmp(key, "base_typeattr_", 14) ||
565*2d543d20SAndroid Build Coastguard Worker __cil_get_plat_flavor(args->vers_map, (hashtab_key_t) key) == PLAT_TYPE) {
566*2d543d20SAndroid Build Coastguard Worker avrule->tgt_str = __cil_attrib_get_versname(key, args->num);
567*2d543d20SAndroid Build Coastguard Worker }
568*2d543d20SAndroid Build Coastguard Worker
569*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
570*2d543d20SAndroid Build Coastguard Worker exit:
571*2d543d20SAndroid Build Coastguard Worker return rc;
572*2d543d20SAndroid Build Coastguard Worker }
573*2d543d20SAndroid Build Coastguard Worker
cil_attrib_genfscon(struct cil_tree_node * node,struct version_args * args)574*2d543d20SAndroid Build Coastguard Worker static int cil_attrib_genfscon(struct cil_tree_node *node, struct version_args *args)
575*2d543d20SAndroid Build Coastguard Worker {
576*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
577*2d543d20SAndroid Build Coastguard Worker
578*2d543d20SAndroid Build Coastguard Worker struct cil_genfscon *genfscon = (struct cil_genfscon *)node->data;
579*2d543d20SAndroid Build Coastguard Worker
580*2d543d20SAndroid Build Coastguard Worker if (genfscon->context_str == NULL) {
581*2d543d20SAndroid Build Coastguard Worker /* genfscon contains an anon context, which needs to have type checked */
582*2d543d20SAndroid Build Coastguard Worker rc = cil_attrib_check_context(genfscon->context, args);
583*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
584*2d543d20SAndroid Build Coastguard Worker goto exit;
585*2d543d20SAndroid Build Coastguard Worker }
586*2d543d20SAndroid Build Coastguard Worker }
587*2d543d20SAndroid Build Coastguard Worker
588*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
589*2d543d20SAndroid Build Coastguard Worker exit:
590*2d543d20SAndroid Build Coastguard Worker return rc;
591*2d543d20SAndroid Build Coastguard Worker }
592*2d543d20SAndroid Build Coastguard Worker
cil_attrib_fsuse(struct cil_tree_node * node,struct version_args * args)593*2d543d20SAndroid Build Coastguard Worker static int cil_attrib_fsuse(struct cil_tree_node *node, struct version_args *args)
594*2d543d20SAndroid Build Coastguard Worker {
595*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
596*2d543d20SAndroid Build Coastguard Worker struct cil_fsuse *fsuse = (struct cil_fsuse *)node->data;
597*2d543d20SAndroid Build Coastguard Worker
598*2d543d20SAndroid Build Coastguard Worker if (fsuse->context_str == NULL) {
599*2d543d20SAndroid Build Coastguard Worker /* fsuse contains an anon context, which needs to have type checked */
600*2d543d20SAndroid Build Coastguard Worker rc = cil_attrib_check_context(fsuse->context, args);
601*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
602*2d543d20SAndroid Build Coastguard Worker goto exit;
603*2d543d20SAndroid Build Coastguard Worker }
604*2d543d20SAndroid Build Coastguard Worker }
605*2d543d20SAndroid Build Coastguard Worker
606*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
607*2d543d20SAndroid Build Coastguard Worker exit:
608*2d543d20SAndroid Build Coastguard Worker return rc;
609*2d543d20SAndroid Build Coastguard Worker }
610*2d543d20SAndroid Build Coastguard Worker
__attributize_helper(struct cil_tree_node * node,uint32_t * finished,void * extra_args)611*2d543d20SAndroid Build Coastguard Worker static int __attributize_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args)
612*2d543d20SAndroid Build Coastguard Worker {
613*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
614*2d543d20SAndroid Build Coastguard Worker struct version_args *args = (struct version_args *) extra_args;
615*2d543d20SAndroid Build Coastguard Worker
616*2d543d20SAndroid Build Coastguard Worker if (node == NULL || finished == NULL || extra_args == NULL) {
617*2d543d20SAndroid Build Coastguard Worker goto exit;
618*2d543d20SAndroid Build Coastguard Worker }
619*2d543d20SAndroid Build Coastguard Worker
620*2d543d20SAndroid Build Coastguard Worker switch (node->flavor) {
621*2d543d20SAndroid Build Coastguard Worker case CIL_SIDCONTEXT:
622*2d543d20SAndroid Build Coastguard Worker /* contains type, but shouldn't involve an attributized type, maybe add
623*2d543d20SAndroid Build Coastguard Worker a check on type and error if it conflicts */
624*2d543d20SAndroid Build Coastguard Worker rc = cil_attrib_sidcontext(node, args);
625*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
626*2d543d20SAndroid Build Coastguard Worker goto exit;
627*2d543d20SAndroid Build Coastguard Worker }
628*2d543d20SAndroid Build Coastguard Worker break;
629*2d543d20SAndroid Build Coastguard Worker case CIL_ROLE:
630*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "%s declaration illegal non-platform policy (line %d)\n",
631*2d543d20SAndroid Build Coastguard Worker CIL_KEY_ROLE, node->line);
632*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_ERR;
633*2d543d20SAndroid Build Coastguard Worker break;
634*2d543d20SAndroid Build Coastguard Worker case CIL_ROLETYPE:
635*2d543d20SAndroid Build Coastguard Worker /* Yes, this is needed if we support roletype in non-platform policy.
636*2d543d20SAndroid Build Coastguard Worker type_id can be type, typealias or typeattr */
637*2d543d20SAndroid Build Coastguard Worker rc = cil_attrib_roletype(node, args);
638*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
639*2d543d20SAndroid Build Coastguard Worker goto exit;
640*2d543d20SAndroid Build Coastguard Worker }
641*2d543d20SAndroid Build Coastguard Worker break;
642*2d543d20SAndroid Build Coastguard Worker case CIL_ROLEATTRIBUTE:
643*2d543d20SAndroid Build Coastguard Worker /* don't think this is needed, only used for cil_gen_req, and we aren't
644*2d543d20SAndroid Build Coastguard Worker yet supporting roles in non-platform policy. */
645*2d543d20SAndroid Build Coastguard Worker break;
646*2d543d20SAndroid Build Coastguard Worker case CIL_TYPE:
647*2d543d20SAndroid Build Coastguard Worker /* conver to attribute if in policy */
648*2d543d20SAndroid Build Coastguard Worker rc = cil_attrib_type(node, args);
649*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
650*2d543d20SAndroid Build Coastguard Worker goto exit;
651*2d543d20SAndroid Build Coastguard Worker }
652*2d543d20SAndroid Build Coastguard Worker break;
653*2d543d20SAndroid Build Coastguard Worker case CIL_TYPEPERMISSIVE:
654*2d543d20SAndroid Build Coastguard Worker rc = cil_attrib_typepermissive(node, args);
655*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
656*2d543d20SAndroid Build Coastguard Worker goto exit;
657*2d543d20SAndroid Build Coastguard Worker }
658*2d543d20SAndroid Build Coastguard Worker break;
659*2d543d20SAndroid Build Coastguard Worker case CIL_TYPEATTRIBUTE:
660*2d543d20SAndroid Build Coastguard Worker rc = cil_attrib_typeattribute(node, args);
661*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
662*2d543d20SAndroid Build Coastguard Worker goto exit;
663*2d543d20SAndroid Build Coastguard Worker }
664*2d543d20SAndroid Build Coastguard Worker break;
665*2d543d20SAndroid Build Coastguard Worker case CIL_TYPEATTRIBUTESET:
666*2d543d20SAndroid Build Coastguard Worker rc = cil_attrib_typeattributeset(node, args);
667*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
668*2d543d20SAndroid Build Coastguard Worker goto exit;
669*2d543d20SAndroid Build Coastguard Worker }
670*2d543d20SAndroid Build Coastguard Worker break;
671*2d543d20SAndroid Build Coastguard Worker case CIL_TYPEALIASACTUAL:
672*2d543d20SAndroid Build Coastguard Worker /* this will break on an attributized type - identify it and throw error */
673*2d543d20SAndroid Build Coastguard Worker rc = cil_attrib_typealiasactual(node, args);
674*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
675*2d543d20SAndroid Build Coastguard Worker goto exit;
676*2d543d20SAndroid Build Coastguard Worker }
677*2d543d20SAndroid Build Coastguard Worker break;
678*2d543d20SAndroid Build Coastguard Worker case CIL_NAMETYPETRANSITION:
679*2d543d20SAndroid Build Coastguard Worker /* not allowed in plat-policy. Types present, throw error if attributee */
680*2d543d20SAndroid Build Coastguard Worker rc = cil_attrib_nametypetransition(node, args);
681*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
682*2d543d20SAndroid Build Coastguard Worker goto exit;
683*2d543d20SAndroid Build Coastguard Worker }
684*2d543d20SAndroid Build Coastguard Worker break;
685*2d543d20SAndroid Build Coastguard Worker case CIL_TYPE_RULE:
686*2d543d20SAndroid Build Coastguard Worker /* not allowed in plat-policy. Types present, throw error if attributee */
687*2d543d20SAndroid Build Coastguard Worker rc = cil_attrib_type_rule(node, args);
688*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
689*2d543d20SAndroid Build Coastguard Worker goto exit;
690*2d543d20SAndroid Build Coastguard Worker }
691*2d543d20SAndroid Build Coastguard Worker break;
692*2d543d20SAndroid Build Coastguard Worker case CIL_AVRULE:
693*2d543d20SAndroid Build Coastguard Worker case CIL_AVRULEX:
694*2d543d20SAndroid Build Coastguard Worker rc = cil_attrib_avrule(node, args);
695*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
696*2d543d20SAndroid Build Coastguard Worker goto exit;
697*2d543d20SAndroid Build Coastguard Worker }
698*2d543d20SAndroid Build Coastguard Worker break;
699*2d543d20SAndroid Build Coastguard Worker case CIL_CONTEXT:
700*2d543d20SAndroid Build Coastguard Worker /* not currently found in AOSP policy, but if found would need to be
701*2d543d20SAndroid Build Coastguard Worker checked to not be attributee */
702*2d543d20SAndroid Build Coastguard Worker rc = cil_attrib_context(node, args);
703*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
704*2d543d20SAndroid Build Coastguard Worker goto exit;
705*2d543d20SAndroid Build Coastguard Worker }
706*2d543d20SAndroid Build Coastguard Worker break;
707*2d543d20SAndroid Build Coastguard Worker case CIL_GENFSCON:
708*2d543d20SAndroid Build Coastguard Worker /* not allowed in plat-policy, but types present, throw error if attributee */
709*2d543d20SAndroid Build Coastguard Worker rc = cil_attrib_genfscon(node, args);
710*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
711*2d543d20SAndroid Build Coastguard Worker goto exit;
712*2d543d20SAndroid Build Coastguard Worker }
713*2d543d20SAndroid Build Coastguard Worker break;
714*2d543d20SAndroid Build Coastguard Worker case CIL_FILECON:
715*2d543d20SAndroid Build Coastguard Worker case CIL_NODECON:
716*2d543d20SAndroid Build Coastguard Worker case CIL_PORTCON:
717*2d543d20SAndroid Build Coastguard Worker case CIL_PIRQCON:
718*2d543d20SAndroid Build Coastguard Worker case CIL_IOMEMCON:
719*2d543d20SAndroid Build Coastguard Worker case CIL_IOPORTCON:
720*2d543d20SAndroid Build Coastguard Worker case CIL_PCIDEVICECON:
721*2d543d20SAndroid Build Coastguard Worker case CIL_DEVICETREECON:
722*2d543d20SAndroid Build Coastguard Worker case CIL_VALIDATETRANS:
723*2d543d20SAndroid Build Coastguard Worker case CIL_MLSVALIDATETRANS:
724*2d543d20SAndroid Build Coastguard Worker case CIL_CALL:
725*2d543d20SAndroid Build Coastguard Worker case CIL_MACRO:
726*2d543d20SAndroid Build Coastguard Worker case CIL_OPTIONAL:
727*2d543d20SAndroid Build Coastguard Worker /* Not currently found in AOSP and not yet properly handled. Return err until support added. */
728*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "unsupported policy statement (line %d)\n", node->line);
729*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_ERR;
730*2d543d20SAndroid Build Coastguard Worker goto exit;
731*2d543d20SAndroid Build Coastguard Worker case CIL_FSUSE:
732*2d543d20SAndroid Build Coastguard Worker /* not allowed in plat-policy, but types present, throw error if attributee */
733*2d543d20SAndroid Build Coastguard Worker cil_attrib_fsuse(node, args);
734*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
735*2d543d20SAndroid Build Coastguard Worker goto exit;
736*2d543d20SAndroid Build Coastguard Worker }
737*2d543d20SAndroid Build Coastguard Worker break;
738*2d543d20SAndroid Build Coastguard Worker case CIL_CONSTRAIN:
739*2d543d20SAndroid Build Coastguard Worker case CIL_MLSCONSTRAIN:
740*2d543d20SAndroid Build Coastguard Worker /* there is type info here, but not sure if we'll allow non-platform code
741*2d543d20SAndroid Build Coastguard Worker to have this, or whether or not it's in platform policy. Currently
742*2d543d20SAndroid Build Coastguard Worker assuming that mlsconstrain is private-platform only, and that normal
743*2d543d20SAndroid Build Coastguard Worker constrain is verboten. */
744*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "unsupported policy statement (line %d)\n", node->line);
745*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_ERR;
746*2d543d20SAndroid Build Coastguard Worker goto exit;
747*2d543d20SAndroid Build Coastguard Worker default:
748*2d543d20SAndroid Build Coastguard Worker break;
749*2d543d20SAndroid Build Coastguard Worker }
750*2d543d20SAndroid Build Coastguard Worker
751*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
752*2d543d20SAndroid Build Coastguard Worker exit:
753*2d543d20SAndroid Build Coastguard Worker return rc;
754*2d543d20SAndroid Build Coastguard Worker }
755*2d543d20SAndroid Build Coastguard Worker
756*2d543d20SAndroid Build Coastguard Worker /*
757*2d543d20SAndroid Build Coastguard Worker * walk ast, replacing previously identified types and attributes with the
758*2d543d20SAndroid Build Coastguard Worker * attributized version. Also replace previous references to the attributees
759*2d543d20SAndroid Build Coastguard Worker * with the versioned type.
760*2d543d20SAndroid Build Coastguard Worker */
cil_attributize(struct cil_db * db,hashtab_t vers_map,const char * num)761*2d543d20SAndroid Build Coastguard Worker static int cil_attributize(struct cil_db *db, hashtab_t vers_map, const char *num)
762*2d543d20SAndroid Build Coastguard Worker {
763*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
764*2d543d20SAndroid Build Coastguard Worker struct version_args extra_args;
765*2d543d20SAndroid Build Coastguard Worker extra_args.db = db;
766*2d543d20SAndroid Build Coastguard Worker extra_args.vers_map = vers_map;
767*2d543d20SAndroid Build Coastguard Worker extra_args.num = num;
768*2d543d20SAndroid Build Coastguard Worker
769*2d543d20SAndroid Build Coastguard Worker rc = cil_tree_walk(db->ast->root, __attributize_helper, NULL, NULL, &extra_args);
770*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
771*2d543d20SAndroid Build Coastguard Worker goto exit;
772*2d543d20SAndroid Build Coastguard Worker }
773*2d543d20SAndroid Build Coastguard Worker
774*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
775*2d543d20SAndroid Build Coastguard Worker exit:
776*2d543d20SAndroid Build Coastguard Worker return rc;
777*2d543d20SAndroid Build Coastguard Worker }
778*2d543d20SAndroid Build Coastguard Worker
779*2d543d20SAndroid Build Coastguard Worker /*
780*2d543d20SAndroid Build Coastguard Worker * Create typeattributeset mappings from the attributes generated from the
781*2d543d20SAndroid Build Coastguard Worker * original types/attributes to the original values. This mapping will provide
782*2d543d20SAndroid Build Coastguard Worker * the basis for the platform policy's mapping to this public version.
783*2d543d20SAndroid Build Coastguard Worker *
784*2d543d20SAndroid Build Coastguard Worker * Add these new typeattributeset nodes to the given cil_db.
785*2d543d20SAndroid Build Coastguard Worker */
cil_build_mappings_tree(hashtab_key_t k,hashtab_datum_t d,void * args)786*2d543d20SAndroid Build Coastguard Worker static int cil_build_mappings_tree(hashtab_key_t k, hashtab_datum_t d, void *args)
787*2d543d20SAndroid Build Coastguard Worker {
788*2d543d20SAndroid Build Coastguard Worker struct cil_typeattributeset *attrset = NULL;
789*2d543d20SAndroid Build Coastguard Worker struct cil_typeattribute *typeattr = NULL;
790*2d543d20SAndroid Build Coastguard Worker struct cil_expandtypeattribute *expandattr = NULL;
791*2d543d20SAndroid Build Coastguard Worker struct cil_tree_node *ast_node = NULL;
792*2d543d20SAndroid Build Coastguard Worker struct version_args *verargs = (struct version_args *)args;
793*2d543d20SAndroid Build Coastguard Worker struct cil_tree_node *ast_parent = verargs->db->ast->root;
794*2d543d20SAndroid Build Coastguard Worker char *orig_type = (char *) k;
795*2d543d20SAndroid Build Coastguard Worker struct version_datum *vers_datum = (struct version_datum *) d;
796*2d543d20SAndroid Build Coastguard Worker char *new_key = __cil_attrib_get_versname(orig_type, verargs->num);
797*2d543d20SAndroid Build Coastguard Worker
798*2d543d20SAndroid Build Coastguard Worker if (vers_datum->ast_node->flavor == CIL_TYPEATTRIBUTE) {
799*2d543d20SAndroid Build Coastguard Worker // platform attributes are not versioned
800*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
801*2d543d20SAndroid Build Coastguard Worker }
802*2d543d20SAndroid Build Coastguard Worker /* create typeattributeset datum */
803*2d543d20SAndroid Build Coastguard Worker cil_typeattributeset_init(&attrset);
804*2d543d20SAndroid Build Coastguard Worker cil_list_init(&attrset->str_expr, CIL_TYPE);
805*2d543d20SAndroid Build Coastguard Worker attrset->attr_str = new_key;
806*2d543d20SAndroid Build Coastguard Worker cil_list_append(attrset->str_expr, CIL_STRING, orig_type);
807*2d543d20SAndroid Build Coastguard Worker
808*2d543d20SAndroid Build Coastguard Worker /* create containing tree node */
809*2d543d20SAndroid Build Coastguard Worker cil_tree_node_init(&ast_node);
810*2d543d20SAndroid Build Coastguard Worker ast_node->data = attrset;
811*2d543d20SAndroid Build Coastguard Worker ast_node->flavor = CIL_TYPEATTRIBUTESET;
812*2d543d20SAndroid Build Coastguard Worker
813*2d543d20SAndroid Build Coastguard Worker /* add to tree */
814*2d543d20SAndroid Build Coastguard Worker ast_node->parent = ast_parent;
815*2d543d20SAndroid Build Coastguard Worker if (ast_parent->cl_head == NULL)
816*2d543d20SAndroid Build Coastguard Worker ast_parent->cl_head = ast_node;
817*2d543d20SAndroid Build Coastguard Worker else
818*2d543d20SAndroid Build Coastguard Worker ast_parent->cl_tail->next = ast_node;
819*2d543d20SAndroid Build Coastguard Worker ast_parent->cl_tail = ast_node;
820*2d543d20SAndroid Build Coastguard Worker
821*2d543d20SAndroid Build Coastguard Worker /* create expandtypeattribute datum */
822*2d543d20SAndroid Build Coastguard Worker cil_expandtypeattribute_init(&expandattr);
823*2d543d20SAndroid Build Coastguard Worker cil_list_init(&expandattr->attr_strs, CIL_TYPE);
824*2d543d20SAndroid Build Coastguard Worker cil_list_append(expandattr->attr_strs, CIL_STRING, new_key);
825*2d543d20SAndroid Build Coastguard Worker expandattr->expand = CIL_TRUE;
826*2d543d20SAndroid Build Coastguard Worker
827*2d543d20SAndroid Build Coastguard Worker /* create containing tree node */
828*2d543d20SAndroid Build Coastguard Worker cil_tree_node_init(&ast_node);
829*2d543d20SAndroid Build Coastguard Worker ast_node->data = expandattr;
830*2d543d20SAndroid Build Coastguard Worker ast_node->flavor = CIL_EXPANDTYPEATTRIBUTE;
831*2d543d20SAndroid Build Coastguard Worker /* add to tree */
832*2d543d20SAndroid Build Coastguard Worker ast_node->parent = ast_parent;
833*2d543d20SAndroid Build Coastguard Worker ast_parent->cl_tail->next = ast_node;
834*2d543d20SAndroid Build Coastguard Worker ast_parent->cl_tail = ast_node;
835*2d543d20SAndroid Build Coastguard Worker
836*2d543d20SAndroid Build Coastguard Worker /* re)declare typeattribute. */
837*2d543d20SAndroid Build Coastguard Worker cil_typeattribute_init(&typeattr);
838*2d543d20SAndroid Build Coastguard Worker typeattr->datum.name = new_key;
839*2d543d20SAndroid Build Coastguard Worker typeattr->datum.fqn = new_key;
840*2d543d20SAndroid Build Coastguard Worker cil_tree_node_init(&ast_node);
841*2d543d20SAndroid Build Coastguard Worker ast_node->data = typeattr;
842*2d543d20SAndroid Build Coastguard Worker ast_node->flavor = CIL_TYPEATTRIBUTE;
843*2d543d20SAndroid Build Coastguard Worker ast_node->parent = ast_parent;
844*2d543d20SAndroid Build Coastguard Worker ast_parent->cl_tail->next = ast_node;
845*2d543d20SAndroid Build Coastguard Worker ast_parent->cl_tail = ast_node;
846*2d543d20SAndroid Build Coastguard Worker
847*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
848*2d543d20SAndroid Build Coastguard Worker }
849*2d543d20SAndroid Build Coastguard Worker
850*2d543d20SAndroid Build Coastguard Worker /*
851*2d543d20SAndroid Build Coastguard Worker * Initializes the given db and uses the version mapping generated by
852*2d543d20SAndroid Build Coastguard Worker * cil_extract_attributees() to fill it with the glue policy required to
853*2d543d20SAndroid Build Coastguard Worker * connect the attributized policy created by cil_attributize() to the policy
854*2d543d20SAndroid Build Coastguard Worker * declaring the concrete types.
855*2d543d20SAndroid Build Coastguard Worker */
cil_attrib_mapping(struct cil_db ** db,hashtab_t vers_map,const char * num)856*2d543d20SAndroid Build Coastguard Worker static int cil_attrib_mapping(struct cil_db **db, hashtab_t vers_map, const char *num)
857*2d543d20SAndroid Build Coastguard Worker {
858*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
859*2d543d20SAndroid Build Coastguard Worker struct version_args extra_args;
860*2d543d20SAndroid Build Coastguard Worker
861*2d543d20SAndroid Build Coastguard Worker cil_db_init(db);
862*2d543d20SAndroid Build Coastguard Worker
863*2d543d20SAndroid Build Coastguard Worker /* foreach entry in vers_map, create typeattributeset node and attach to tree */
864*2d543d20SAndroid Build Coastguard Worker extra_args.db = *db;
865*2d543d20SAndroid Build Coastguard Worker extra_args.vers_map = NULL;
866*2d543d20SAndroid Build Coastguard Worker extra_args.num = num;
867*2d543d20SAndroid Build Coastguard Worker rc = hashtab_map(vers_map, cil_build_mappings_tree, &extra_args);
868*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
869*2d543d20SAndroid Build Coastguard Worker goto exit;
870*2d543d20SAndroid Build Coastguard Worker }
871*2d543d20SAndroid Build Coastguard Worker
872*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
873*2d543d20SAndroid Build Coastguard Worker exit:
874*2d543d20SAndroid Build Coastguard Worker return rc;
875*2d543d20SAndroid Build Coastguard Worker }
876*2d543d20SAndroid Build Coastguard Worker
cil_android_attrib_mapping(struct cil_db ** mdb,struct cil_db * srcdb,const char * num)877*2d543d20SAndroid Build Coastguard Worker int cil_android_attrib_mapping(struct cil_db **mdb, struct cil_db *srcdb, const char *num)
878*2d543d20SAndroid Build Coastguard Worker {
879*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
880*2d543d20SAndroid Build Coastguard Worker hashtab_t ver_map_tab = NULL;
881*2d543d20SAndroid Build Coastguard Worker
882*2d543d20SAndroid Build Coastguard Worker ver_map_tab = hashtab_create(ver_map_hash_val, ver_map_key_cmp, VER_MAP_SZ);
883*2d543d20SAndroid Build Coastguard Worker if (!ver_map_tab) {
884*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Unable to create version mapping table.\n");
885*2d543d20SAndroid Build Coastguard Worker goto exit;
886*2d543d20SAndroid Build Coastguard Worker }
887*2d543d20SAndroid Build Coastguard Worker rc = cil_build_ast(srcdb, srcdb->parse->root, srcdb->ast->root);
888*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
889*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Unable to build source db AST.\n");
890*2d543d20SAndroid Build Coastguard Worker goto exit;
891*2d543d20SAndroid Build Coastguard Worker }
892*2d543d20SAndroid Build Coastguard Worker rc = cil_extract_attributees(srcdb, ver_map_tab);
893*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
894*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Unable to extract attributizable elements from source db.\n");
895*2d543d20SAndroid Build Coastguard Worker goto exit;
896*2d543d20SAndroid Build Coastguard Worker }
897*2d543d20SAndroid Build Coastguard Worker rc = cil_attrib_mapping(mdb, ver_map_tab, num);
898*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
899*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Unable to create mapping db from source db.\n");
900*2d543d20SAndroid Build Coastguard Worker goto exit;
901*2d543d20SAndroid Build Coastguard Worker }
902*2d543d20SAndroid Build Coastguard Worker exit:
903*2d543d20SAndroid Build Coastguard Worker ver_map_destroy(ver_map_tab);
904*2d543d20SAndroid Build Coastguard Worker return rc;
905*2d543d20SAndroid Build Coastguard Worker }
906*2d543d20SAndroid Build Coastguard Worker
cil_android_attributize(struct cil_db * tgtdb,struct cil_db * srcdb,const char * num)907*2d543d20SAndroid Build Coastguard Worker int cil_android_attributize(struct cil_db *tgtdb, struct cil_db *srcdb, const char *num)
908*2d543d20SAndroid Build Coastguard Worker {
909*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
910*2d543d20SAndroid Build Coastguard Worker hashtab_t ver_map_tab = NULL;
911*2d543d20SAndroid Build Coastguard Worker
912*2d543d20SAndroid Build Coastguard Worker ver_map_tab = hashtab_create(ver_map_hash_val, ver_map_key_cmp, VER_MAP_SZ);
913*2d543d20SAndroid Build Coastguard Worker if (!ver_map_tab) {
914*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Unable to create version mapping table.\n");
915*2d543d20SAndroid Build Coastguard Worker goto exit;
916*2d543d20SAndroid Build Coastguard Worker }
917*2d543d20SAndroid Build Coastguard Worker rc = cil_build_ast(srcdb, srcdb->parse->root, srcdb->ast->root);
918*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
919*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Unable to build source db AST.\n");
920*2d543d20SAndroid Build Coastguard Worker goto exit;
921*2d543d20SAndroid Build Coastguard Worker }
922*2d543d20SAndroid Build Coastguard Worker rc = cil_extract_attributees(srcdb, ver_map_tab);
923*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
924*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Unable to extract attributizable elements from source db.\n");
925*2d543d20SAndroid Build Coastguard Worker goto exit;
926*2d543d20SAndroid Build Coastguard Worker }
927*2d543d20SAndroid Build Coastguard Worker rc = cil_build_ast(tgtdb, tgtdb->parse->root, tgtdb->ast->root);
928*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
929*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Unable to build target db AST.\n");
930*2d543d20SAndroid Build Coastguard Worker goto exit;
931*2d543d20SAndroid Build Coastguard Worker }
932*2d543d20SAndroid Build Coastguard Worker rc = cil_attributize(tgtdb, ver_map_tab, num);
933*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
934*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Unable to attributize target db.\n");
935*2d543d20SAndroid Build Coastguard Worker goto exit;
936*2d543d20SAndroid Build Coastguard Worker }
937*2d543d20SAndroid Build Coastguard Worker exit:
938*2d543d20SAndroid Build Coastguard Worker ver_map_destroy(ver_map_tab);
939*2d543d20SAndroid Build Coastguard Worker return rc;
940*2d543d20SAndroid Build Coastguard Worker }
941*2d543d20SAndroid Build Coastguard Worker
define_symbols(struct cil_tree_node * node,uint32_t * finished,void * extra_args)942*2d543d20SAndroid Build Coastguard Worker static int define_symbols(struct cil_tree_node *node, uint32_t *finished __attribute__((unused)), void *extra_args)
943*2d543d20SAndroid Build Coastguard Worker {
944*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_OK;
945*2d543d20SAndroid Build Coastguard Worker struct cil_type *type = NULL;
946*2d543d20SAndroid Build Coastguard Worker struct cil_typeattribute *typeattribute = NULL;
947*2d543d20SAndroid Build Coastguard Worker struct policydb_amend_args *args = extra_args;
948*2d543d20SAndroid Build Coastguard Worker policydb_t *pdb = args->pdb;
949*2d543d20SAndroid Build Coastguard Worker void **type_value_to_cil = args->type_value_to_cil;
950*2d543d20SAndroid Build Coastguard Worker
951*2d543d20SAndroid Build Coastguard Worker switch (node->flavor) {
952*2d543d20SAndroid Build Coastguard Worker case CIL_TYPE:
953*2d543d20SAndroid Build Coastguard Worker rc = cil_type_to_policydb(pdb, node->data, type_value_to_cil);
954*2d543d20SAndroid Build Coastguard Worker // symtab_insert returns 1 when the symbol already exists
955*2d543d20SAndroid Build Coastguard Worker if (rc == 1) {
956*2d543d20SAndroid Build Coastguard Worker type = node->data;
957*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_WARN, "Type with symbol \"%s\" already exists.\n", type->datum.fqn);
958*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_OK;
959*2d543d20SAndroid Build Coastguard Worker }
960*2d543d20SAndroid Build Coastguard Worker break;
961*2d543d20SAndroid Build Coastguard Worker case CIL_TYPEATTRIBUTE:
962*2d543d20SAndroid Build Coastguard Worker rc = cil_typeattribute_to_policydb(pdb, node->data, type_value_to_cil);
963*2d543d20SAndroid Build Coastguard Worker // symtab_insert returns 1 when the symbol already exists
964*2d543d20SAndroid Build Coastguard Worker if (rc == 1) {
965*2d543d20SAndroid Build Coastguard Worker typeattribute = node->data;
966*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_WARN, "Typeattribute with symbol \"%s\" already exists.\n", typeattribute->datum.fqn);
967*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_OK;
968*2d543d20SAndroid Build Coastguard Worker }
969*2d543d20SAndroid Build Coastguard Worker break;
970*2d543d20SAndroid Build Coastguard Worker case CIL_ROLE:
971*2d543d20SAndroid Build Coastguard Worker case CIL_POLICYCAP:
972*2d543d20SAndroid Build Coastguard Worker case CIL_USER:
973*2d543d20SAndroid Build Coastguard Worker case CIL_BOOL:
974*2d543d20SAndroid Build Coastguard Worker case CIL_CATALIAS:
975*2d543d20SAndroid Build Coastguard Worker case CIL_SENS: // Unsupported symbol statements.
976*2d543d20SAndroid Build Coastguard Worker default:
977*2d543d20SAndroid Build Coastguard Worker break;
978*2d543d20SAndroid Build Coastguard Worker }
979*2d543d20SAndroid Build Coastguard Worker
980*2d543d20SAndroid Build Coastguard Worker return rc;
981*2d543d20SAndroid Build Coastguard Worker }
982*2d543d20SAndroid Build Coastguard Worker
expand_symbols(struct cil_tree_node * node,uint32_t * finished,void * extra_args)983*2d543d20SAndroid Build Coastguard Worker static int expand_symbols(struct cil_tree_node *node, uint32_t *finished __attribute__((unused)), void *extra_args)
984*2d543d20SAndroid Build Coastguard Worker {
985*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_OK;
986*2d543d20SAndroid Build Coastguard Worker struct policydb_amend_args *args = extra_args;
987*2d543d20SAndroid Build Coastguard Worker const struct cil_db *db = args->db;
988*2d543d20SAndroid Build Coastguard Worker policydb_t *pdb = args->pdb;
989*2d543d20SAndroid Build Coastguard Worker
990*2d543d20SAndroid Build Coastguard Worker switch (node->flavor) {
991*2d543d20SAndroid Build Coastguard Worker case CIL_TYPEATTRIBUTE:
992*2d543d20SAndroid Build Coastguard Worker rc = cil_typeattribute_to_bitmap(pdb, db, node->data);
993*2d543d20SAndroid Build Coastguard Worker break;
994*2d543d20SAndroid Build Coastguard Worker case CIL_ROLE:
995*2d543d20SAndroid Build Coastguard Worker case CIL_AVRULE:
996*2d543d20SAndroid Build Coastguard Worker case CIL_AVRULEX:
997*2d543d20SAndroid Build Coastguard Worker case CIL_TYPE:
998*2d543d20SAndroid Build Coastguard Worker case CIL_TYPEALIAS:
999*2d543d20SAndroid Build Coastguard Worker case CIL_TYPEPERMISSIVE:
1000*2d543d20SAndroid Build Coastguard Worker case CIL_SENSALIAS:
1001*2d543d20SAndroid Build Coastguard Worker case CIL_USER:
1002*2d543d20SAndroid Build Coastguard Worker case CIL_TYPE_RULE:
1003*2d543d20SAndroid Build Coastguard Worker case CIL_ROLETRANSITION:
1004*2d543d20SAndroid Build Coastguard Worker case CIL_ROLEATTRIBUTESET:
1005*2d543d20SAndroid Build Coastguard Worker case CIL_NAMETYPETRANSITION:
1006*2d543d20SAndroid Build Coastguard Worker case CIL_CONSTRAIN:
1007*2d543d20SAndroid Build Coastguard Worker case CIL_MLSCONSTRAIN:
1008*2d543d20SAndroid Build Coastguard Worker case CIL_VALIDATETRANS:
1009*2d543d20SAndroid Build Coastguard Worker case CIL_MLSVALIDATETRANS:
1010*2d543d20SAndroid Build Coastguard Worker case CIL_RANGETRANSITION:
1011*2d543d20SAndroid Build Coastguard Worker case CIL_DEFAULTUSER:
1012*2d543d20SAndroid Build Coastguard Worker case CIL_DEFAULTROLE:
1013*2d543d20SAndroid Build Coastguard Worker case CIL_DEFAULTTYPE:
1014*2d543d20SAndroid Build Coastguard Worker case CIL_DEFAULTRANGE: // Unsupported symbol statements.
1015*2d543d20SAndroid Build Coastguard Worker default:
1016*2d543d20SAndroid Build Coastguard Worker break;
1017*2d543d20SAndroid Build Coastguard Worker }
1018*2d543d20SAndroid Build Coastguard Worker
1019*2d543d20SAndroid Build Coastguard Worker return rc;
1020*2d543d20SAndroid Build Coastguard Worker }
1021*2d543d20SAndroid Build Coastguard Worker
apply_rules(struct cil_tree_node * node,uint32_t * finished,void * extra_args)1022*2d543d20SAndroid Build Coastguard Worker static int apply_rules(struct cil_tree_node *node, uint32_t *finished __attribute__((unused)), void *extra_args)
1023*2d543d20SAndroid Build Coastguard Worker {
1024*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_OK;
1025*2d543d20SAndroid Build Coastguard Worker struct cil_avrule *rule = NULL;
1026*2d543d20SAndroid Build Coastguard Worker struct policydb_amend_args *args = extra_args;
1027*2d543d20SAndroid Build Coastguard Worker const struct cil_db *db = args->db;
1028*2d543d20SAndroid Build Coastguard Worker policydb_t *pdb = args->pdb;
1029*2d543d20SAndroid Build Coastguard Worker
1030*2d543d20SAndroid Build Coastguard Worker switch (node->flavor) {
1031*2d543d20SAndroid Build Coastguard Worker case CIL_AVRULE:
1032*2d543d20SAndroid Build Coastguard Worker rule = node->data;
1033*2d543d20SAndroid Build Coastguard Worker if (rule->rule_kind != CIL_AVRULE_NEVERALLOW) {
1034*2d543d20SAndroid Build Coastguard Worker rc = cil_avrule_to_policydb(pdb, db, node->data);
1035*2d543d20SAndroid Build Coastguard Worker }
1036*2d543d20SAndroid Build Coastguard Worker else {
1037*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_WARN, "Found a neverallow rule.\n");
1038*2d543d20SAndroid Build Coastguard Worker }
1039*2d543d20SAndroid Build Coastguard Worker break;
1040*2d543d20SAndroid Build Coastguard Worker case CIL_BOOLEANIF:
1041*2d543d20SAndroid Build Coastguard Worker case CIL_AVRULEX:
1042*2d543d20SAndroid Build Coastguard Worker case CIL_ROLEALLOW: // Unsupported rule statement.
1043*2d543d20SAndroid Build Coastguard Worker default:
1044*2d543d20SAndroid Build Coastguard Worker break;
1045*2d543d20SAndroid Build Coastguard Worker }
1046*2d543d20SAndroid Build Coastguard Worker
1047*2d543d20SAndroid Build Coastguard Worker return rc;
1048*2d543d20SAndroid Build Coastguard Worker }
1049*2d543d20SAndroid Build Coastguard Worker
cil_amend_policydb(struct cil_db * db,sepol_policydb_t * policydb)1050*2d543d20SAndroid Build Coastguard Worker int cil_amend_policydb(struct cil_db *db, sepol_policydb_t *policydb)
1051*2d543d20SAndroid Build Coastguard Worker {
1052*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
1053*2d543d20SAndroid Build Coastguard Worker policydb_t *pdb = &policydb->p;
1054*2d543d20SAndroid Build Coastguard Worker
1055*2d543d20SAndroid Build Coastguard Worker if (db == NULL || policydb == NULL) {
1056*2d543d20SAndroid Build Coastguard Worker if (db == NULL) {
1057*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "db == NULL\n");
1058*2d543d20SAndroid Build Coastguard Worker }
1059*2d543d20SAndroid Build Coastguard Worker else if (policydb == NULL) {
1060*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "policydb == NULL\n");
1061*2d543d20SAndroid Build Coastguard Worker }
1062*2d543d20SAndroid Build Coastguard Worker return rc;
1063*2d543d20SAndroid Build Coastguard Worker }
1064*2d543d20SAndroid Build Coastguard Worker
1065*2d543d20SAndroid Build Coastguard Worker // type_value_to_cil should be able to map the new types in the cil_db, the
1066*2d543d20SAndroid Build Coastguard Worker // existing types in the pdb, and the redefinitions from the cil_db.
1067*2d543d20SAndroid Build Coastguard Worker // Since libsepol values start at 1, we allocate extra memory instead of shifting every value.
1068*2d543d20SAndroid Build Coastguard Worker void **type_value_to_cil = calloc(db->num_types_and_attrs + pdb->p_types.nprim + 1,
1069*2d543d20SAndroid Build Coastguard Worker sizeof(*type_value_to_cil));
1070*2d543d20SAndroid Build Coastguard Worker if (!type_value_to_cil)
1071*2d543d20SAndroid Build Coastguard Worker goto exit;
1072*2d543d20SAndroid Build Coastguard Worker
1073*2d543d20SAndroid Build Coastguard Worker struct policydb_amend_args extra_args;
1074*2d543d20SAndroid Build Coastguard Worker extra_args.db = db;
1075*2d543d20SAndroid Build Coastguard Worker extra_args.pdb = pdb;
1076*2d543d20SAndroid Build Coastguard Worker extra_args.type_value_to_cil = type_value_to_cil;
1077*2d543d20SAndroid Build Coastguard Worker
1078*2d543d20SAndroid Build Coastguard Worker // 1) Add types and attributes symbols to policy_db.
1079*2d543d20SAndroid Build Coastguard Worker unsigned int types_size = pdb->p_types.nprim;
1080*2d543d20SAndroid Build Coastguard Worker rc = cil_tree_walk(db->ast->root, define_symbols, NULL, NULL, &extra_args);
1081*2d543d20SAndroid Build Coastguard Worker if(rc != SEPOL_OK) {
1082*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Error adding symbols to policydb.\n");
1083*2d543d20SAndroid Build Coastguard Worker goto exit;
1084*2d543d20SAndroid Build Coastguard Worker }
1085*2d543d20SAndroid Build Coastguard Worker if (pdb->p_types.nprim > types_size) {
1086*2d543d20SAndroid Build Coastguard Worker // We introduced new types, we need to expand the type<->attr maps.
1087*2d543d20SAndroid Build Coastguard Worker pdb->type_attr_map = cil_realloc(pdb->type_attr_map, pdb->p_types.nprim * sizeof(ebitmap_t));
1088*2d543d20SAndroid Build Coastguard Worker pdb->attr_type_map = cil_realloc(pdb->attr_type_map, pdb->p_types.nprim * sizeof(ebitmap_t));
1089*2d543d20SAndroid Build Coastguard Worker for (unsigned int i = types_size; i < pdb->p_types.nprim; i++) {
1090*2d543d20SAndroid Build Coastguard Worker ebitmap_init(&pdb->type_attr_map[i]);
1091*2d543d20SAndroid Build Coastguard Worker ebitmap_init(&pdb->attr_type_map[i]);
1092*2d543d20SAndroid Build Coastguard Worker }
1093*2d543d20SAndroid Build Coastguard Worker }
1094*2d543d20SAndroid Build Coastguard Worker
1095*2d543d20SAndroid Build Coastguard Worker // 2) Expand typeattribute symbols.
1096*2d543d20SAndroid Build Coastguard Worker rc = cil_tree_walk(db->ast->root, expand_symbols, NULL, NULL, &extra_args);
1097*2d543d20SAndroid Build Coastguard Worker if(rc != SEPOL_OK) {
1098*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Error expanding symbols.\n");
1099*2d543d20SAndroid Build Coastguard Worker goto exit;
1100*2d543d20SAndroid Build Coastguard Worker }
1101*2d543d20SAndroid Build Coastguard Worker
1102*2d543d20SAndroid Build Coastguard Worker // 3) Apply rule statements.
1103*2d543d20SAndroid Build Coastguard Worker rc = cil_tree_walk(db->ast->root, apply_rules, NULL, NULL, &extra_args);
1104*2d543d20SAndroid Build Coastguard Worker if(rc != SEPOL_OK) {
1105*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Error applying rules.\n");
1106*2d543d20SAndroid Build Coastguard Worker goto exit;
1107*2d543d20SAndroid Build Coastguard Worker }
1108*2d543d20SAndroid Build Coastguard Worker
1109*2d543d20SAndroid Build Coastguard Worker exit:
1110*2d543d20SAndroid Build Coastguard Worker free(type_value_to_cil);
1111*2d543d20SAndroid Build Coastguard Worker return rc;
1112*2d543d20SAndroid Build Coastguard Worker }
1113