xref: /aosp_15_r20/external/selinux/libsepol/cil/src/cil_copy_ast.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1 /*
2  * Copyright 2011 Tresys Technology, LLC. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  *    1. Redistributions of source code must retain the above copyright notice,
8  *       this list of conditions and the following disclaimer.
9  *
10  *    2. Redistributions in binary form must reproduce the above copyright notice,
11  *       this list of conditions and the following disclaimer in the documentation
12  *       and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS
15  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17  * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
18  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
22  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
23  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  * The views and conclusions contained in the software and documentation are those
26  * of the authors and should not be interpreted as representing official policies,
27  * either expressed or implied, of Tresys Technology, LLC.
28  */
29 
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <string.h>
33 
34 #include "cil_internal.h"
35 #include "cil_log.h"
36 #include "cil_mem.h"
37 #include "cil_tree.h"
38 #include "cil_list.h"
39 #include "cil_symtab.h"
40 #include "cil_copy_ast.h"
41 #include "cil_build_ast.h"
42 #include "cil_strpool.h"
43 #include "cil_verify.h"
44 
45 struct cil_args_copy {
46 	struct cil_tree_node *orig_dest;
47 	struct cil_tree_node *dest;
48 	struct cil_db *db;
49 };
50 
cil_copy_list(struct cil_list * data,struct cil_list ** copy)51 void cil_copy_list(struct cil_list *data, struct cil_list **copy)
52 {
53 	struct cil_list *new;
54 	struct cil_list_item *orig_item;
55 
56 	cil_list_init(&new, data->flavor);
57 
58 	cil_list_for_each(orig_item, data) {
59 		switch (orig_item->flavor) {
60 		case CIL_STRING:
61 			cil_list_append(new, CIL_STRING, orig_item->data);
62 			break;
63 		case CIL_LIST: {
64 			struct cil_list *new_sub = NULL;
65 			cil_copy_list((struct cil_list*)orig_item->data, &new_sub);
66 			cil_list_append(new, CIL_LIST, new_sub);
67 			break;
68 		}
69 		case CIL_PARAM: {
70 			struct cil_param *po = orig_item->data;
71 			struct cil_param *pn;
72 			cil_param_init(&pn);
73 			pn->str = po->str;
74 			pn->flavor = po->flavor;
75 			cil_list_append(new, CIL_PARAM, pn);
76 		}
77 			break;
78 
79 		default:
80 			cil_list_append(new, orig_item->flavor, orig_item->data);
81 			break;
82 		}
83 	}
84 
85 	*copy = new;
86 }
87 
cil_copy_node(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)88 static int cil_copy_node(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
89 {
90 	char *new = NULL;
91 
92 	if (data != NULL) {
93 		new = data;
94 	}
95 	*copy = new;
96 
97 	return SEPOL_OK;
98 }
99 
cil_copy_ordered(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)100 int cil_copy_ordered(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
101 {
102 	struct cil_ordered *orig = data;
103 	struct cil_ordered *new = NULL;
104 
105 	cil_ordered_init(&new);
106 	if (orig->strs != NULL) {
107 		cil_copy_list(orig->strs, &new->strs);
108 	}
109 	if (orig->datums != NULL) {
110 		cil_copy_list(orig->datums, &new->datums);
111 	}
112 
113 	*copy = new;
114 
115 	return SEPOL_OK;
116 }
117 
cil_copy_block(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)118 int cil_copy_block(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
119 {
120 	struct cil_block *orig = data;
121 	char *key = orig->datum.name;
122 	struct cil_symtab_datum *datum = NULL;
123 
124 	cil_symtab_get_datum(symtab, key, &datum);
125 	if (datum != NULL) {
126 		if (FLAVOR(datum) != CIL_BLOCK) {
127 			cil_tree_log(NODE(orig), CIL_ERR, "Block %s being copied", key);
128 			cil_tree_log(NODE(datum), CIL_ERR, "  Conflicts with %s already declared", cil_node_to_string(NODE(datum)));
129 			return SEPOL_ERR;
130 		}
131 		cil_tree_log(NODE(orig), CIL_WARN, "Block %s being copied", key);
132 		cil_tree_log(NODE(datum), CIL_WARN, "  Previously declared");
133 		*copy = datum;
134 	} else {
135 		struct cil_block *new;
136 		cil_block_init(&new);
137 		*copy = new;
138 	}
139 
140 	return SEPOL_OK;
141 }
142 
cil_copy_blockabstract(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)143 int cil_copy_blockabstract(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
144 {
145 	struct cil_blockabstract *orig = data;
146 	struct cil_blockabstract *new = NULL;
147 
148 	cil_blockabstract_init(&new);
149 
150 	new->block_str = orig->block_str;
151 	new->block = orig->block;
152 
153 	*copy = new;
154 
155 	return SEPOL_OK;
156 }
157 
cil_copy_blockinherit(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)158 int cil_copy_blockinherit(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
159 {
160 	struct cil_blockinherit *orig = data;
161 	struct cil_blockinherit *new = NULL;
162 
163 	cil_blockinherit_init(&new);
164 
165 	new->block_str = orig->block_str;
166 	new->block = orig->block;
167 
168 	*copy = new;
169 
170 	return SEPOL_OK;
171 }
172 
cil_copy_policycap(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)173 static int cil_copy_policycap(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
174 {
175 	struct cil_policycap *orig = data;
176 	char *key = orig->datum.name;
177 	struct cil_symtab_datum *datum = NULL;
178 
179 	cil_symtab_get_datum(symtab, key, &datum);
180 	if (datum == NULL) {
181 		struct cil_policycap *new;
182 		cil_policycap_init(&new);
183 		*copy = new;
184 	} else {
185 		*copy = datum;
186 	}
187 
188 	return SEPOL_OK;
189 }
190 
cil_copy_perm(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)191 int cil_copy_perm(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
192 {
193 	struct cil_perm *orig = data;
194 	char *key = orig->datum.name;
195 	struct cil_symtab_datum *datum = NULL;
196 
197 	cil_symtab_get_datum(symtab, key, &datum);
198 	if (datum == NULL) {
199 		struct cil_perm *new;
200 		cil_perm_init(&new);
201 		*copy = new;
202 	} else {
203 		*copy = datum;
204 	}
205 
206 	return SEPOL_OK;
207 }
208 
cil_copy_classperms(struct cil_classperms * orig,struct cil_classperms ** new)209 void cil_copy_classperms(struct cil_classperms *orig, struct cil_classperms **new)
210 {
211 	cil_classperms_init(new);
212 	(*new)->class_str = orig->class_str;
213 	cil_copy_list(orig->perm_strs, &((*new)->perm_strs));
214 }
215 
cil_copy_classperms_set(struct cil_classperms_set * orig,struct cil_classperms_set ** new)216 void cil_copy_classperms_set(struct cil_classperms_set *orig, struct cil_classperms_set **new)
217 {
218 	cil_classperms_set_init(new);
219 	(*new)->set_str = orig->set_str;
220 }
221 
cil_copy_classperms_list(struct cil_list * orig,struct cil_list ** new)222 void cil_copy_classperms_list(struct cil_list *orig, struct cil_list **new)
223 {
224 	struct cil_list_item *orig_item;
225 
226 	if (orig == NULL) {
227 		return;
228 	}
229 
230 	cil_list_init(new, CIL_LIST_ITEM);
231 	cil_list_for_each(orig_item, orig) {
232 		if (orig_item->flavor == CIL_CLASSPERMS) {
233 			struct cil_classperms *cp;
234 			cil_copy_classperms(orig_item->data, &cp);
235 			cil_list_append(*new, CIL_CLASSPERMS, cp);
236 		} else {
237 			struct cil_classperms_set *cp_set;
238 			cil_copy_classperms_set(orig_item->data, &cp_set);
239 			cil_list_append(*new, CIL_CLASSPERMS_SET, cp_set);
240 		}
241 	}
242 }
243 
cil_copy_classmapping(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)244 int cil_copy_classmapping(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
245 {
246 	struct cil_classmapping *orig = data;
247 	struct cil_classmapping *new = NULL;
248 
249 	cil_classmapping_init(&new);
250 
251 	new->map_class_str = orig->map_class_str;
252 	new->map_class = orig->map_class;
253 	new->map_perm_str = orig->map_perm_str;
254 	new->map_perm = orig->map_perm;
255 
256 	cil_copy_classperms_list(orig->classperms, &new->classperms);
257 
258 	*copy = new;
259 
260 	return SEPOL_OK;
261 }
262 
cil_copy_class(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)263 int cil_copy_class(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
264 {
265 	struct cil_class *orig = data;
266 	struct cil_class *new = NULL;
267 	char *key = orig->datum.name;
268 	struct cil_symtab_datum *datum = NULL;
269 
270 	cil_symtab_get_datum(symtab, key, &datum);
271 	if (datum != NULL) {
272 		cil_log(CIL_INFO, "cil_copy_class: class cannot be redefined\n");
273 		return SEPOL_ERR;
274 	}
275 
276 	cil_class_init(&new);
277 
278 	new->common = NULL;
279 
280 	*copy = new;
281 
282 	return SEPOL_OK;
283 }
284 
cil_copy_classpermission(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)285 int cil_copy_classpermission(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
286 {
287 	struct cil_classpermission *orig = data;
288 	struct cil_classpermission *new = NULL;
289 	char *key = orig->datum.name;
290 	struct cil_symtab_datum *datum = NULL;
291 
292 	if (key != NULL) {
293 		cil_symtab_get_datum(symtab, key, &datum);
294 		if (datum != NULL) {
295 			cil_log(CIL_INFO, "classpermission cannot be redefined\n");
296 			return SEPOL_ERR;
297 		}
298 	}
299 
300 	cil_classpermission_init(&new);
301 
302 	cil_copy_classperms_list(orig->classperms, &new->classperms);
303 
304 	*copy = new;
305 
306 	return SEPOL_OK;
307 }
308 
cil_copy_classpermissionset(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)309 int cil_copy_classpermissionset(__attribute__((unused)) struct cil_db *db, void *data, void **copy,  __attribute__((unused)) symtab_t *symtab)
310 {
311 	struct cil_classpermissionset *orig = data;
312 	struct cil_classpermissionset *new = NULL;
313 
314 	cil_classpermissionset_init(&new);
315 
316 	new->set_str = orig->set_str;
317 	new->set = orig->set;
318 
319 	cil_copy_classperms_list(orig->classperms, &new->classperms);
320 
321 	*copy = new;
322 
323 	return SEPOL_OK;
324 }
325 
cil_copy_classcommon(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)326 int cil_copy_classcommon(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
327 {
328 	struct cil_classcommon *orig = data;
329 	struct cil_classcommon *new = NULL;
330 
331 	cil_classcommon_init(&new);
332 
333 	new->class_str = orig->class_str;
334 	new->class = orig->class;
335 	new->common_str = orig->common_str;
336 	new->common = orig->common;
337 
338 	*copy = new;
339 
340 	return SEPOL_OK;
341 }
342 
cil_copy_sid(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)343 int cil_copy_sid(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
344 {
345 	struct cil_sid *orig = data;
346 	char *key = orig->datum.name;
347 	struct cil_symtab_datum *datum = NULL;
348 
349 	cil_symtab_get_datum(symtab, key, &datum);
350 	if (datum == NULL) {
351 		struct cil_sid *new;
352 		cil_sid_init(&new);
353 		*copy = new;
354 	} else {
355 		*copy = datum;
356 	}
357 
358 	return SEPOL_OK;
359 }
360 
cil_copy_sidcontext(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)361 int cil_copy_sidcontext(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
362 {
363 	struct cil_sidcontext *orig = data;
364 	struct cil_sidcontext *new = NULL;
365 
366 	cil_sidcontext_init(&new);
367 
368 	if (orig->context_str != NULL) {
369 		new->context_str = orig->context_str;
370 	} else {
371 		cil_context_init(&new->context);
372 		cil_copy_fill_context(db, orig->context, new->context);
373 	}
374 
375 	*copy = new;
376 
377 	return SEPOL_OK;
378 }
379 
cil_copy_user(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)380 int cil_copy_user(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
381 {
382 	struct cil_user *orig = data;
383 	char *key = orig->datum.name;
384 	struct cil_symtab_datum *datum = NULL;
385 
386 	cil_symtab_get_datum(symtab, key, &datum);
387 	if (datum == NULL) {
388 		struct cil_user *new;
389 		cil_user_init(&new);
390 		*copy = new;
391 	} else {
392 		*copy = datum;
393 	}
394 
395 	return SEPOL_OK;
396 }
397 
cil_copy_userattribute(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)398 int cil_copy_userattribute(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
399 {
400 	struct cil_userattribute *orig = data;
401 	struct cil_userattribute *new = NULL;
402 	char *key = orig->datum.name;
403 	struct cil_symtab_datum *datum = NULL;
404 
405 	cil_symtab_get_datum(symtab, key, &datum);
406 	if (datum == NULL) {
407 		cil_userattribute_init(&new);
408 		*copy = new;
409 	} else {
410 		*copy = datum;
411 	}
412 
413 	return SEPOL_OK;
414 }
415 
cil_copy_userattributeset(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)416 int cil_copy_userattributeset(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
417 {
418 	struct cil_userattributeset *orig = data;
419 	struct cil_userattributeset *new = NULL;
420 
421 	cil_userattributeset_init(&new);
422 
423 	new->attr_str = orig->attr_str;
424 
425 	cil_copy_expr(db, orig->str_expr, &new->str_expr);
426 	cil_copy_expr(db, orig->datum_expr, &new->datum_expr);
427 
428 	*copy = new;
429 
430 	return SEPOL_OK;
431 }
432 
cil_copy_userrole(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)433 int cil_copy_userrole(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
434 {
435 	struct cil_userrole *orig = data;
436 	struct cil_userrole *new = NULL;
437 
438 	cil_userrole_init(&new);
439 
440 	new->user_str = orig->user_str;
441 	new->role_str = orig->role_str;
442 
443 	*copy = new;
444 
445 	return SEPOL_OK;
446 }
447 
cil_copy_userlevel(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)448 int cil_copy_userlevel(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
449 {
450 	struct cil_userlevel *orig = data;
451 	struct cil_userlevel *new = NULL;
452 
453 	cil_userlevel_init(&new);
454 
455 	new->user_str = orig->user_str;
456 
457 	if (orig->level_str != NULL) {
458 		new->level_str = orig->level_str;
459 	} else {
460 		cil_copy_fill_level(db, orig->level, &new->level);
461 	}
462 
463 	*copy = new;
464 
465 	return SEPOL_OK;
466 }
467 
cil_copy_userrange(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)468 int cil_copy_userrange(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
469 {
470 	struct cil_userrange *orig = data;
471 	struct cil_userrange *new = NULL;
472 
473 	cil_userrange_init(&new);
474 
475 	new->user_str = orig->user_str;
476 
477 	if (orig->range_str != NULL) {
478 		new->range_str = orig->range_str;
479 	} else {
480 		cil_levelrange_init(&new->range);
481 		cil_copy_fill_levelrange(db, orig->range, new->range);
482 	}
483 
484 	*copy = new;
485 
486 	return SEPOL_OK;
487 }
488 
cil_copy_userprefix(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)489 int cil_copy_userprefix(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
490 {
491 	struct cil_userprefix *orig = data;
492 	struct cil_userprefix *new = NULL;
493 
494 	cil_userprefix_init(&new);
495 
496 	new->user_str = orig->user_str;
497 	new->prefix_str = orig->prefix_str;
498 
499 	*copy = new;
500 
501 	return SEPOL_OK;
502 }
503 
cil_copy_role(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)504 int cil_copy_role(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
505 {
506 	struct cil_role *orig = data;
507 	char *key = orig->datum.name;
508 	struct cil_symtab_datum *datum = NULL;
509 
510 	cil_symtab_get_datum(symtab, key, &datum);
511 	if (datum == NULL) {
512 		struct cil_role *new;
513 		cil_role_init(&new);
514 		*copy = new;
515 	} else {
516 		*copy = datum;
517 	}
518 
519 	return SEPOL_OK;
520 }
521 
cil_copy_roletype(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)522 int cil_copy_roletype(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
523 {
524 	struct cil_roletype *orig = data;
525 	struct cil_roletype *new = NULL;
526 
527 	cil_roletype_init(&new);
528 
529 	new->role_str = orig->role_str;
530 	new->type_str = orig->type_str;
531 
532 	*copy = new;
533 
534 	return SEPOL_OK;
535 }
536 
cil_copy_roleattribute(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)537 int cil_copy_roleattribute(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
538 {
539 	struct cil_roleattribute *orig = data;
540 	char *key = orig->datum.name;
541 	struct cil_symtab_datum *datum = NULL;
542 
543 	cil_symtab_get_datum(symtab, key, &datum);
544 	if (datum == NULL) {
545 		struct cil_roleattribute *new;
546 		cil_roleattribute_init(&new);
547 		*copy = new;
548 	} else {
549 		*copy = datum;
550 	}
551 
552 	return SEPOL_OK;
553 }
554 
cil_copy_roleattributeset(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)555 int cil_copy_roleattributeset(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
556 {
557 	struct cil_roleattributeset *orig = data;
558 	struct cil_roleattributeset *new = NULL;
559 
560 	cil_roleattributeset_init(&new);
561 
562 	new->attr_str = orig->attr_str;
563 
564 	cil_copy_expr(db, orig->str_expr, &new->str_expr);
565 	cil_copy_expr(db, orig->datum_expr, &new->datum_expr);
566 
567 	*copy = new;
568 
569 	return SEPOL_OK;
570 }
571 
cil_copy_roleallow(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)572 int cil_copy_roleallow(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
573 {
574 	struct cil_roleallow *orig = data;
575 	struct cil_roleallow *new = NULL;
576 
577 	cil_roleallow_init(&new);
578 
579 	new->src_str = orig->src_str;
580 	new->tgt_str = orig->tgt_str;
581 
582 	*copy = new;
583 
584 	return SEPOL_OK;
585 }
586 
cil_copy_type(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)587 int cil_copy_type(__attribute__((unused)) struct cil_db *db, __attribute__((unused)) void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
588 {
589 	struct cil_type *new;
590 
591 	cil_type_init(&new);
592 	*copy = new;
593 
594 	return SEPOL_OK;
595 }
596 
cil_copy_typepermissive(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)597 int cil_copy_typepermissive(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
598 {
599 	struct cil_typepermissive *orig = data;
600 	struct cil_typepermissive *new = NULL;
601 
602 	cil_typepermissive_init(&new);
603 
604 	new->type_str = orig->type_str;
605 
606 	*copy = new;
607 
608 	return SEPOL_OK;
609 }
610 
cil_copy_typeattribute(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)611 int cil_copy_typeattribute(__attribute__((unused)) struct cil_db *db, __attribute__((unused)) void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
612 {
613 	struct cil_typeattribute *new;
614 
615 	cil_typeattribute_init(&new);
616 	*copy = new;
617 
618 	return SEPOL_OK;
619 }
620 
cil_copy_typeattributeset(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)621 int cil_copy_typeattributeset(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
622 {
623 	struct cil_typeattributeset *orig = data;
624 	struct cil_typeattributeset *new = NULL;
625 
626 	cil_typeattributeset_init(&new);
627 
628 	new->attr_str = orig->attr_str;
629 
630 	cil_copy_expr(db, orig->str_expr, &new->str_expr);
631 	cil_copy_expr(db, orig->datum_expr, &new->datum_expr);
632 
633 	*copy = new;
634 
635 	return SEPOL_OK;
636 }
637 
cil_copy_expandtypeattribute(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)638 static int cil_copy_expandtypeattribute(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
639 {
640 	struct cil_expandtypeattribute *orig = data;
641 	struct cil_expandtypeattribute *new = NULL;
642 
643 	cil_expandtypeattribute_init(&new);
644 
645 	if (orig->attr_strs != NULL) {
646 		cil_copy_list(orig->attr_strs, &new->attr_strs);
647 	}
648 
649 	if (orig->attr_datums != NULL) {
650 		cil_copy_list(orig->attr_datums, &new->attr_datums);
651 	}
652 
653 	new->expand = orig->expand;
654 
655 	*copy = new;
656 
657 	return SEPOL_OK;
658 }
659 
cil_copy_alias(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)660 static int cil_copy_alias(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
661 {
662 	struct cil_alias *orig = data;
663 	struct cil_alias *new = NULL;
664 	char *key = orig->datum.name;
665 	struct cil_symtab_datum *datum = NULL;
666 
667 	cil_symtab_get_datum(symtab, key, &datum);
668 	if (datum != NULL) {
669 		cil_log(CIL_INFO, "cil_copy_alias: alias cannot be redefined\n");
670 		return SEPOL_ERR;
671 	}
672 
673 	cil_alias_init(&new);
674 
675 	*copy = new;
676 
677 	return SEPOL_OK;
678 }
679 
cil_copy_aliasactual(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)680 static int cil_copy_aliasactual(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused))symtab_t *symtab)
681 {
682 	struct cil_aliasactual *orig = data;
683 	struct cil_aliasactual *new = NULL;
684 
685 	cil_aliasactual_init(&new);
686 
687 	new->alias_str = orig->alias_str;
688 	new->alias = orig->alias;
689 	new->actual_str = orig->actual_str;
690 	new->actual = orig->actual;
691 
692 	*copy = new;
693 
694 	return SEPOL_OK;
695 }
696 
cil_copy_roletransition(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)697 static int cil_copy_roletransition(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
698 {
699 	struct cil_roletransition *orig = data;
700 	struct cil_roletransition *new = NULL;
701 
702 	cil_roletransition_init(&new);
703 
704 	new->src_str = orig->src_str;
705 	new->tgt_str = orig->tgt_str;
706 	new->obj_str = orig->obj_str;
707 	new->result_str = orig->result_str;
708 
709 	*copy = new;
710 
711 	return SEPOL_OK;
712 }
713 
cil_copy_nametypetransition(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)714 int cil_copy_nametypetransition(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
715 {
716 	struct cil_nametypetransition *orig = data;
717 	struct cil_nametypetransition *new = NULL;
718 
719 	cil_nametypetransition_init(&new);
720 
721 	new->src_str = orig->src_str;
722 	new->tgt_str = orig->tgt_str;
723 	new->obj_str = orig->obj_str;
724 	new->name_str = orig->name_str;
725 	new->name = orig->name;
726 	new->result_str = orig->result_str;
727 
728 
729 	*copy = new;
730 
731 	return SEPOL_OK;
732 }
733 
cil_copy_rangetransition(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)734 int cil_copy_rangetransition(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
735 {
736 	struct cil_rangetransition *orig = data;
737 	struct cil_rangetransition *new = NULL;
738 
739 	cil_rangetransition_init(&new);
740 
741 	new->src_str = orig->src_str;
742 	new->exec_str = orig->exec_str;
743 	new->obj_str = orig->obj_str;
744 
745 	if (orig->range_str != NULL) {
746 		new->range_str = orig->range_str;
747 	} else {
748 		cil_levelrange_init(&new->range);
749 		cil_copy_fill_levelrange(db, orig->range, new->range);
750 	}
751 
752 	*copy = new;
753 
754 	return SEPOL_OK;
755 }
756 
cil_copy_bool(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)757 int cil_copy_bool(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
758 {
759 	struct cil_bool *orig = data;
760 	struct cil_bool *new = NULL;
761 	char *key = orig->datum.name;
762 	struct cil_symtab_datum *datum = NULL;
763 
764 	cil_symtab_get_datum(symtab, key, &datum);
765 	if (datum != NULL) {
766 		cil_log(CIL_INFO, "cil_copy_bool: boolean cannot be redefined\n");
767 		return SEPOL_ERR;
768 	}
769 
770 	cil_bool_init(&new);
771 	new->value = orig->value;
772 	*copy = new;
773 
774 	return SEPOL_OK;
775 }
776 
cil_copy_tunable(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)777 static int cil_copy_tunable(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
778 {
779 	struct cil_tunable *orig = data;
780 	struct cil_tunable *new = NULL;
781 	char *key = orig->datum.name;
782 	struct cil_symtab_datum *datum = NULL;
783 
784 	cil_symtab_get_datum(symtab, key, &datum);
785 	if (datum != NULL) {
786 		cil_log(CIL_INFO, "cil_copy_tunable: tunable cannot be redefined\n");
787 		return SEPOL_ERR;
788 	}
789 
790 	cil_tunable_init(&new);
791 	new->value = orig->value;
792 	*copy = new;
793 
794 	return SEPOL_OK;
795 }
796 
cil_copy_fill_permissionx(struct cil_db * db,struct cil_permissionx * orig,struct cil_permissionx * new)797 static void cil_copy_fill_permissionx(struct cil_db *db, struct cil_permissionx *orig, struct cil_permissionx *new)
798 {
799 	new->kind = orig->kind;
800 	new->obj_str = orig->obj_str;
801 	cil_copy_expr(db, orig->expr_str, &new->expr_str);
802 }
803 
cil_copy_avrule(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)804 int cil_copy_avrule(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
805 {
806 	struct cil_avrule *orig = data;
807 	struct cil_avrule *new = NULL;
808 
809 	cil_avrule_init(&new);
810 
811 	new->is_extended = orig->is_extended;
812 	new->rule_kind = orig->rule_kind;
813 	new->src_str = orig->src_str;
814 	new->tgt_str = orig->tgt_str;
815 
816 	if (!new->is_extended) {
817 		cil_copy_classperms_list(orig->perms.classperms, &new->perms.classperms);
818 	} else {
819 		if (orig->perms.x.permx_str != NULL) {
820 			new->perms.x.permx_str = orig->perms.x.permx_str;
821 		} else {
822 			cil_permissionx_init(&new->perms.x.permx);
823 			cil_copy_fill_permissionx(db, orig->perms.x.permx, new->perms.x.permx);
824 		}
825 	}
826 
827 	*copy = new;
828 
829 	return SEPOL_OK;
830 }
831 
cil_copy_permissionx(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)832 static int cil_copy_permissionx(struct cil_db *db, void *data, void **copy, symtab_t *symtab)
833 {
834 	struct cil_permissionx *orig = data;
835 	struct cil_permissionx *new = NULL;
836 	char *key = orig->datum.name;
837 	struct cil_symtab_datum *datum = NULL;
838 
839 
840 	cil_symtab_get_datum(symtab, key, &datum);
841 	if (datum != NULL) {
842 		cil_log(CIL_INFO, "cil_copy_permissionx: permissionx cannot be redefined\n");
843 		return SEPOL_ERR;
844 	}
845 
846 	cil_permissionx_init(&new);
847 	cil_copy_fill_permissionx(db, orig, new);
848 
849 	*copy = new;
850 
851 	return SEPOL_OK;
852 }
853 
cil_copy_deny_rule(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)854 int cil_copy_deny_rule(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
855 {
856 	struct cil_deny_rule *orig = data;
857 	struct cil_deny_rule *new = NULL;
858 
859 	cil_deny_rule_init(&new);
860 
861 	new->src_str = orig->src_str;
862 	new->tgt_str = orig->tgt_str;
863 	cil_copy_classperms_list(orig->classperms, &new->classperms);
864 
865 	*copy = new;
866 
867 	return SEPOL_OK;
868 }
869 
cil_copy_type_rule(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)870 int cil_copy_type_rule(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
871 {
872 	struct cil_type_rule  *orig = data;
873 	struct cil_type_rule *new = NULL;
874 
875 	cil_type_rule_init(&new);
876 
877 	new->rule_kind = orig->rule_kind;
878 	new->src_str = orig->src_str;
879 	new->tgt_str = orig->tgt_str;
880 	new->obj_str = orig->obj_str;
881 	new->result_str = orig->result_str;
882 
883 	*copy = new;
884 
885 	return SEPOL_OK;
886 }
887 
cil_copy_sens(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)888 int cil_copy_sens(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
889 {
890 	struct cil_sens *orig = data;
891 	char *key = orig->datum.name;
892 	struct cil_symtab_datum *datum = NULL;
893 
894 	cil_symtab_get_datum(symtab, key, &datum);
895 	if (datum == NULL) {
896 		struct cil_sens *new;
897 		cil_sens_init(&new);
898 		*copy = new;
899 	} else {
900 		*copy = datum;
901 	}
902 
903 	return SEPOL_OK;
904 }
905 
cil_copy_cat(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)906 int cil_copy_cat(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
907 {
908 	struct cil_cat *orig = data;
909 	char *key = orig->datum.name;
910 	struct cil_symtab_datum *datum = NULL;
911 
912 	cil_symtab_get_datum(symtab, key, &datum);
913 	if (datum == NULL) {
914 		struct cil_cat *new;
915 		cil_cat_init(&new);
916 		*copy = new;
917 	} else {
918 		*copy = datum;
919 	}
920 
921 	return SEPOL_OK;
922 }
923 
cil_copy_cats(struct cil_db * db,struct cil_cats * orig,struct cil_cats ** new)924 static void cil_copy_cats(struct cil_db *db, struct cil_cats *orig, struct cil_cats **new)
925 {
926 	cil_cats_init(new);
927 	cil_copy_expr(db, orig->str_expr, &(*new)->str_expr);
928 	cil_copy_expr(db, orig->datum_expr, &(*new)->datum_expr);
929 }
930 
cil_copy_catset(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)931 int cil_copy_catset(struct cil_db *db, void *data, void **copy, symtab_t *symtab)
932 {
933 	struct cil_catset *orig = data;
934 	struct cil_catset *new = NULL;
935 	char *key = orig->datum.name;
936 	struct cil_symtab_datum *datum = NULL;
937 
938 	cil_symtab_get_datum(symtab, key, &datum);
939 	if (datum != NULL) {
940 		cil_log(CIL_INFO, "cil_copy_catset: categoryset cannot be redefined\n");
941 		return SEPOL_ERR;
942 	}
943 
944 	cil_catset_init(&new);
945 
946 	cil_copy_cats(db, orig->cats, &new->cats);
947 
948 	*copy = new;
949 
950 	return SEPOL_OK;
951 }
952 
cil_copy_senscat(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)953 int cil_copy_senscat(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
954 {
955 	struct cil_senscat *orig = data;
956 	struct cil_senscat *new = NULL;
957 
958 	cil_senscat_init(&new);
959 
960 	new->sens_str = orig->sens_str;
961 
962 	cil_copy_cats(db, orig->cats, &new->cats);
963 
964 	*copy = new;
965 
966 	return SEPOL_OK;
967 }
968 
cil_copy_fill_level(struct cil_db * db,struct cil_level * orig,struct cil_level ** new)969 void cil_copy_fill_level(struct cil_db *db, struct cil_level *orig, struct cil_level **new)
970 {
971 	cil_level_init(new);
972 
973 	(*new)->sens_str = orig->sens_str;
974 
975 	if (orig->cats != NULL) {
976 		cil_copy_cats(db, orig->cats, &(*new)->cats);
977 	}
978 }
979 
cil_copy_level(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)980 int cil_copy_level(struct cil_db *db, void *data, void **copy, symtab_t *symtab)
981 {
982 	struct cil_level *orig = data;
983 	struct cil_level *new = NULL;
984 	char *key = orig->datum.name;
985 	struct cil_symtab_datum *datum = NULL;
986 
987 	if (key != NULL) {
988 		cil_symtab_get_datum(symtab, key, &datum);
989 		if (datum != NULL) {
990 			cil_log(CIL_INFO, "cil_copy_level: level cannot be redefined\n");
991 			return SEPOL_ERR;
992 		}
993 	}
994 
995 	cil_copy_fill_level(db, orig, &new);
996 
997 	*copy = new;
998 
999 	return SEPOL_OK;
1000 }
1001 
cil_copy_fill_levelrange(struct cil_db * db,struct cil_levelrange * data,struct cil_levelrange * new)1002 void cil_copy_fill_levelrange(struct cil_db *db, struct cil_levelrange *data, struct cil_levelrange *new)
1003 {
1004 	if (data->low_str != NULL) {
1005 		new->low_str = data->low_str;
1006 	} else {
1007 		cil_copy_fill_level(db, data->low, &new->low);
1008 	}
1009 
1010 	if (data->high_str != NULL) {
1011 		new->high_str = data->high_str;
1012 	} else {
1013 		cil_copy_fill_level(db, data->high, &new->high);
1014 	}
1015 }
1016 
cil_copy_levelrange(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1017 int cil_copy_levelrange(struct cil_db *db, void *data, void **copy, symtab_t *symtab)
1018 {
1019 	struct cil_levelrange *orig = data;
1020 	struct cil_levelrange *new = NULL;
1021 	char *key = orig->datum.name;
1022 	struct cil_symtab_datum *datum = NULL;
1023 
1024 	if (key != NULL) {
1025 		cil_symtab_get_datum(symtab, key, &datum);
1026 		if (datum != NULL) {
1027 			cil_log(CIL_INFO, "cil_copy_levelrange: levelrange cannot be redefined\n");
1028 			return SEPOL_ERR;
1029 		}
1030 	}
1031 
1032 	cil_levelrange_init(&new);
1033 	cil_copy_fill_levelrange(db, orig, new);
1034 
1035 	*copy = new;
1036 
1037 	return SEPOL_OK;
1038 }
1039 
cil_copy_fill_context(struct cil_db * db,struct cil_context * data,struct cil_context * new)1040 void cil_copy_fill_context(struct cil_db *db, struct cil_context *data, struct cil_context *new)
1041 {
1042 	new->user_str = data->user_str;
1043 	new->role_str = data->role_str;
1044 	new->type_str = data->type_str;
1045 
1046 	if (data->range_str != NULL) {
1047 		new->range_str = data->range_str;
1048 	} else {
1049 		cil_levelrange_init(&new->range);
1050 		cil_copy_fill_levelrange(db, data->range, new->range);
1051 	}
1052 }
1053 
cil_copy_context(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1054 int cil_copy_context(struct cil_db *db, void *data, void **copy, symtab_t *symtab)
1055 {
1056 	struct cil_context *orig = data;
1057 	struct cil_context *new = NULL;
1058 	char *key = orig->datum.name;
1059 	struct cil_symtab_datum *datum = NULL;
1060 
1061 	if (key != NULL) {
1062 		cil_symtab_get_datum(symtab, key, &datum);
1063 		if (datum != NULL) {
1064 			cil_log(CIL_INFO, "cil_copy_context: context cannot be redefined\n");
1065 			return SEPOL_ERR;
1066 		}
1067 	}
1068 
1069 	cil_context_init(&new);
1070 	cil_copy_fill_context(db, orig, new);
1071 
1072 	*copy = new;
1073 
1074 	return SEPOL_OK;
1075 }
1076 
cil_copy_netifcon(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1077 int cil_copy_netifcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1078 {
1079 	struct cil_netifcon *orig = data;
1080 	struct cil_netifcon *new = NULL;
1081 
1082 	cil_netifcon_init(&new);
1083 
1084 	new->interface_str = orig->interface_str;
1085 
1086 	if (orig->if_context_str != NULL) {
1087 		new->if_context_str = orig->if_context_str;
1088 	} else {
1089 		cil_context_init(&new->if_context);
1090 		cil_copy_fill_context(db, orig->if_context, new->if_context);
1091 	}
1092 
1093 	if (orig->packet_context_str != NULL) {
1094 		new->packet_context_str = orig->packet_context_str;
1095 	} else {
1096 		cil_context_init(&new->packet_context);
1097 		cil_copy_fill_context(db, orig->packet_context, new->packet_context);
1098 	}
1099 
1100 	*copy = new;
1101 
1102 	return SEPOL_OK;
1103 }
1104 
cil_copy_genfscon(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1105 int cil_copy_genfscon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1106 {
1107 	struct cil_genfscon *orig = data;
1108 	struct cil_genfscon *new = NULL;
1109 
1110 	cil_genfscon_init(&new);
1111 
1112 	new->fs_str = orig->fs_str;
1113 	new->path_str = orig->path_str;
1114 
1115 	if (orig->context_str != NULL) {
1116 		new->context_str = orig->context_str;
1117 	} else {
1118 		cil_context_init(&new->context);
1119 		cil_copy_fill_context(db, orig->context, new->context);
1120 	}
1121 
1122 	*copy = new;
1123 
1124 	return SEPOL_OK;
1125 }
1126 
cil_copy_filecon(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1127 int cil_copy_filecon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1128 {
1129 	struct cil_filecon *orig = data;
1130 	struct cil_filecon *new = NULL;
1131 
1132 	cil_filecon_init(&new);
1133 
1134 	new->path_str = orig->path_str;
1135 	new->path = orig->path;
1136 	new->type = orig->type;
1137 
1138 	if (orig->context_str != NULL) {
1139 		new->context_str = orig->context_str;
1140 	} else if (orig->context != NULL) {
1141 		cil_context_init(&new->context);
1142 		cil_copy_fill_context(db, orig->context, new->context);
1143 	}
1144 
1145 	*copy = new;
1146 
1147 	return SEPOL_OK;
1148 }
1149 
cil_copy_nodecon(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1150 int cil_copy_nodecon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1151 {
1152 	struct cil_nodecon *orig = data;
1153 	struct cil_nodecon *new = NULL;
1154 
1155 	cil_nodecon_init(&new);
1156 
1157 	if (orig->addr_str != NULL) {
1158 		new->addr_str = orig->addr_str;
1159 	} else {
1160 		cil_ipaddr_init(&new->addr);
1161 		cil_copy_fill_ipaddr(orig->addr, new->addr);
1162 	}
1163 
1164 	if (orig->mask_str != NULL) {
1165 		new->mask_str = orig->mask_str;
1166 	} else {
1167 		cil_ipaddr_init(&new->mask);
1168 		cil_copy_fill_ipaddr(orig->mask, new->mask);
1169 	}
1170 
1171 	if (orig->context_str != NULL) {
1172 		new->context_str = orig->context_str;
1173 	} else {
1174 		cil_context_init(&new->context);
1175 		cil_copy_fill_context(db, orig->context, new->context);
1176 	}
1177 
1178 	*copy = new;
1179 
1180 	return SEPOL_OK;
1181 }
1182 
cil_copy_ibpkeycon(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1183 int cil_copy_ibpkeycon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1184 {
1185 	struct cil_ibpkeycon *orig = data;
1186 	struct cil_ibpkeycon *new = NULL;
1187 
1188 	cil_ibpkeycon_init(&new);
1189 
1190 	new->subnet_prefix_str = orig->subnet_prefix_str;
1191 	new->pkey_low = orig->pkey_low;
1192 	new->pkey_high = orig->pkey_high;
1193 
1194 	if (orig->context_str) {
1195 		new->context_str = orig->context_str;
1196 	} else {
1197 		cil_context_init(&new->context);
1198 		cil_copy_fill_context(db, orig->context, new->context);
1199 	}
1200 
1201 	*copy = new;
1202 
1203 	return SEPOL_OK;
1204 }
1205 
cil_copy_ibendportcon(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1206 static int cil_copy_ibendportcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1207 {
1208 	struct cil_ibendportcon *orig = data;
1209 	struct cil_ibendportcon *new = NULL;
1210 
1211 	cil_ibendportcon_init(&new);
1212 
1213 	new->dev_name_str = orig->dev_name_str;
1214 	new->port = orig->port;
1215 
1216 	if (orig->context_str) {
1217 		new->context_str = orig->context_str;
1218 	} else {
1219 		cil_context_init(&new->context);
1220 		cil_copy_fill_context(db, orig->context, new->context);
1221 	}
1222 
1223 	*copy = new;
1224 
1225 	return SEPOL_OK;
1226 }
1227 
cil_copy_portcon(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1228 int cil_copy_portcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1229 {
1230 	struct cil_portcon *orig = data;
1231 	struct cil_portcon *new = NULL;
1232 
1233 	cil_portcon_init(&new);
1234 
1235 	new->proto = orig->proto;
1236 	new->port_low = orig->port_low;
1237 	new->port_high = orig->port_high;
1238 
1239 	if (orig->context_str != NULL) {
1240 		new->context_str = orig->context_str;
1241 	} else {
1242 		cil_context_init(&new->context);
1243 		cil_copy_fill_context(db, orig->context, new->context);
1244 	}
1245 
1246 	*copy = new;
1247 
1248 	return SEPOL_OK;
1249 }
1250 
cil_copy_pirqcon(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1251 int cil_copy_pirqcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1252 {
1253 	struct cil_pirqcon *orig = data;
1254 	struct cil_pirqcon *new = NULL;
1255 
1256 	cil_pirqcon_init(&new);
1257 
1258 	new->pirq = orig->pirq;
1259 
1260 	if (orig->context_str != NULL) {
1261 		new->context_str = orig->context_str;
1262 	} else {
1263 		cil_context_init(&new->context);
1264 		cil_copy_fill_context(db, orig->context, new->context);
1265 	}
1266 
1267 	*copy = new;
1268 
1269 	return SEPOL_OK;
1270 }
1271 
cil_copy_iomemcon(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1272 int cil_copy_iomemcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1273 {
1274 	struct cil_iomemcon *orig = data;
1275 	struct cil_iomemcon *new = NULL;
1276 
1277 	cil_iomemcon_init(&new);
1278 
1279 	new->iomem_low = orig->iomem_low;
1280 	new->iomem_high = orig->iomem_high;
1281 
1282 	if (orig->context_str != NULL) {
1283 		new->context_str = orig->context_str;
1284 	} else {
1285 		cil_context_init(&new->context);
1286 		cil_copy_fill_context(db, orig->context, new->context);
1287 	}
1288 
1289 	*copy = new;
1290 
1291 	return SEPOL_OK;
1292 }
1293 
cil_copy_ioportcon(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1294 int cil_copy_ioportcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1295 {
1296 	struct cil_ioportcon *orig = data;
1297 	struct cil_ioportcon *new = NULL;
1298 
1299 	cil_ioportcon_init(&new);
1300 
1301 	new->ioport_low = orig->ioport_low;
1302 	new->ioport_high = orig->ioport_high;
1303 
1304 	if (orig->context_str != NULL) {
1305 		new->context_str = orig->context_str;
1306 	} else {
1307 		cil_context_init(&new->context);
1308 		cil_copy_fill_context(db, orig->context, new->context);
1309 	}
1310 
1311 	*copy = new;
1312 
1313 	return SEPOL_OK;
1314 }
1315 
cil_copy_pcidevicecon(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1316 int cil_copy_pcidevicecon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1317 {
1318 	struct cil_pcidevicecon *orig = data;
1319 	struct cil_pcidevicecon *new = NULL;
1320 
1321 	cil_pcidevicecon_init(&new);
1322 
1323 	new->dev = orig->dev;
1324 
1325 	if (orig->context_str != NULL) {
1326 		new->context_str = orig->context_str;
1327 	} else {
1328 		cil_context_init(&new->context);
1329 		cil_copy_fill_context(db, orig->context, new->context);
1330 	}
1331 
1332 	*copy = new;
1333 
1334 	return SEPOL_OK;
1335 }
1336 
cil_copy_devicetreecon(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1337 static int cil_copy_devicetreecon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1338 {
1339 	struct cil_devicetreecon *orig = data;
1340 	struct cil_devicetreecon *new = NULL;
1341 
1342 	cil_devicetreecon_init(&new);
1343 
1344 	new->path = orig->path;
1345 
1346 	if (orig->context_str != NULL) {
1347 		new->context_str = orig->context_str;
1348 	} else {
1349 		cil_context_init(&new->context);
1350 		cil_copy_fill_context(db, orig->context, new->context);
1351 	}
1352 
1353 	*copy = new;
1354 
1355 	return SEPOL_OK;
1356 }
1357 
cil_copy_fsuse(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1358 int cil_copy_fsuse(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1359 {
1360 	struct cil_fsuse *orig = data;
1361 	struct cil_fsuse *new = NULL;
1362 
1363 	cil_fsuse_init(&new);
1364 
1365 	new->type = orig->type;
1366 	new->fs_str = orig->fs_str;
1367 
1368 	if (orig->context_str != NULL) {
1369 		new->context_str = orig->context_str;
1370 	} else {
1371 		cil_context_init(&new->context);
1372 		cil_copy_fill_context(db, orig->context, new->context);
1373 	}
1374 
1375 	*copy = new;
1376 
1377 	return SEPOL_OK;
1378 }
1379 
cil_copy_expr(struct cil_db * db,struct cil_list * orig,struct cil_list ** new)1380 int cil_copy_expr(struct cil_db *db, struct cil_list *orig, struct cil_list **new)
1381 {
1382 	struct cil_list_item *curr;
1383 
1384 	if (orig == NULL) {
1385 		*new = NULL;
1386 		return SEPOL_OK;
1387 	}
1388 
1389 	cil_list_init(new, orig->flavor);
1390 
1391 	cil_list_for_each(curr, orig) {
1392 		switch (curr->flavor) {
1393 		case CIL_LIST: {
1394 			struct cil_list *sub_list;
1395 			cil_copy_expr(db, curr->data, &sub_list);
1396 			cil_list_append(*new, CIL_LIST, sub_list);
1397 			break;
1398 		}
1399 		case CIL_STRING:
1400 			cil_list_append(*new, CIL_STRING, curr->data);
1401 			break;
1402 		case CIL_DATUM:
1403 			cil_list_append(*new, curr->flavor, curr->data);
1404 			break;
1405 		case CIL_OP:
1406 			cil_list_append(*new, curr->flavor, curr->data);
1407 			break;
1408 		case CIL_CONS_OPERAND:
1409 			cil_list_append(*new, curr->flavor, curr->data);
1410 			break;
1411 		default:
1412 			cil_log(CIL_INFO, "Unknown flavor %d in expression being copied\n",curr->flavor);
1413 			cil_list_append(*new, curr->flavor, curr->data);
1414 			break;
1415 		}
1416 	}
1417 
1418 	return SEPOL_OK;
1419 }
1420 
cil_copy_constrain(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1421 int cil_copy_constrain(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1422 {
1423 	struct cil_constrain *orig = data;
1424 	struct cil_constrain *new = NULL;
1425 
1426 	cil_constrain_init(&new);
1427 	cil_copy_classperms_list(orig->classperms, &new->classperms);
1428 
1429 	cil_copy_expr(db, orig->str_expr, &new->str_expr);
1430 	cil_copy_expr(db, orig->datum_expr, &new->datum_expr);
1431 
1432 	*copy = new;
1433 
1434 	return SEPOL_OK;
1435 }
1436 
cil_copy_validatetrans(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1437 int cil_copy_validatetrans(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1438 {
1439 	struct cil_validatetrans *orig = data;
1440 	struct cil_validatetrans *new = NULL;
1441 
1442 	cil_validatetrans_init(&new);
1443 
1444 	new->class_str = orig->class_str;
1445 
1446 	cil_copy_expr(db, orig->str_expr, &new->str_expr);
1447 	cil_copy_expr(db, orig->datum_expr, &new->datum_expr);
1448 
1449 	*copy = new;
1450 
1451 	return SEPOL_OK;
1452 }
1453 
cil_copy_call(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1454 int cil_copy_call(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1455 {
1456 	struct cil_call *orig = data;
1457 	struct cil_call *new = NULL;
1458 	int rc = SEPOL_ERR;
1459 
1460 	cil_call_init(&new);
1461 
1462 	new->macro_str = orig->macro_str;
1463 	new->macro = orig->macro;
1464 
1465 	if (orig->args_tree != NULL) {
1466 		cil_tree_init(&new->args_tree);
1467 		rc = cil_copy_ast(db, orig->args_tree->root, new->args_tree->root);
1468 		if (rc != SEPOL_OK) {
1469 			goto exit;
1470 		}
1471 	}
1472 
1473 	new->copied = orig->copied;
1474 
1475 	*copy = new;
1476 
1477 	return SEPOL_OK;
1478 
1479 exit:
1480 	cil_destroy_call(new);
1481 	return rc;
1482 }
1483 
cil_copy_macro(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1484 static int cil_copy_macro(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
1485 {
1486 	struct cil_macro *orig = data;
1487 	char *key = orig->datum.name;
1488 	struct cil_symtab_datum *datum = NULL;
1489 
1490 	cil_symtab_get_datum(symtab, key, &datum);
1491 	if (datum != NULL) {
1492 		if (FLAVOR(datum) != CIL_MACRO) {
1493 			cil_tree_log(NODE(orig), CIL_ERR, "Macro %s being copied", key);
1494 			cil_tree_log(NODE(datum), CIL_ERR, "  Conflicts with %s already declared", cil_node_to_string(NODE(datum)));
1495 			return SEPOL_ERR;
1496 		}
1497 		cil_tree_log(NODE(orig), CIL_WARN, "Skipping macro %s", key);
1498 		cil_tree_log(NODE(datum), CIL_WARN, "  Previously declared");
1499 		*copy = NULL;
1500 	} else {
1501 		struct cil_macro *new;
1502 		cil_macro_init(&new);
1503 		if (orig->params != NULL) {
1504 			cil_copy_list(orig->params, &new->params);
1505 		}
1506 		*copy = new;
1507 	}
1508 
1509 	return SEPOL_OK;
1510 }
1511 
cil_copy_optional(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1512 int cil_copy_optional(__attribute__((unused)) struct cil_db *db, __attribute__((unused)) void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1513 {
1514 	struct cil_optional *new;
1515 
1516 	cil_optional_init(&new);
1517 	*copy = new;
1518 
1519 	return SEPOL_OK;
1520 }
1521 
cil_copy_fill_ipaddr(struct cil_ipaddr * data,struct cil_ipaddr * new)1522 void cil_copy_fill_ipaddr(struct cil_ipaddr *data, struct cil_ipaddr *new)
1523 {
1524 	new->family = data->family;
1525 	memcpy(&new->ip, &data->ip, sizeof(data->ip));
1526 }
1527 
cil_copy_ipaddr(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1528 int cil_copy_ipaddr(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
1529 {
1530 	struct cil_ipaddr *orig = data;
1531 	struct cil_ipaddr *new = NULL;
1532 	char * key = orig->datum.name;
1533 	struct cil_symtab_datum *datum = NULL;
1534 
1535 	cil_symtab_get_datum(symtab, key, &datum);
1536 	if (datum != NULL) {
1537 		cil_log(CIL_INFO, "cil_copy_ipaddr: ipaddress cannot be redefined\n");
1538 		return SEPOL_ERR;
1539 	}
1540 
1541 	cil_ipaddr_init(&new);
1542 	cil_copy_fill_ipaddr(orig, new);
1543 
1544 	*copy = new;
1545 
1546 	return SEPOL_OK;
1547 }
1548 
cil_copy_condblock(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1549 static int cil_copy_condblock(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1550 {
1551 	struct cil_condblock *orig = data;
1552 	struct cil_condblock *new = *copy;
1553 	cil_condblock_init(&new);
1554 	new->flavor = orig->flavor;
1555 	*copy = new;
1556 
1557 	return SEPOL_OK;
1558 }
1559 
cil_copy_boolif(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1560 int cil_copy_boolif(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1561 {
1562 	struct cil_booleanif *orig = data;
1563 	struct cil_booleanif *new = NULL;
1564 
1565 	cil_boolif_init(&new);
1566 
1567 	cil_copy_expr(db, orig->str_expr, &new->str_expr);
1568 	cil_copy_expr(db, orig->datum_expr, &new->datum_expr);
1569 	new->preserved_tunable = orig->preserved_tunable;
1570 
1571 	*copy = new;
1572 
1573 	return SEPOL_OK;
1574 }
1575 
cil_copy_tunif(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1576 static int cil_copy_tunif(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1577 {
1578 	struct cil_tunableif *orig = data;
1579 	struct cil_tunableif *new = NULL;
1580 
1581 	cil_tunif_init(&new);
1582 
1583 	cil_copy_expr(db, orig->str_expr, &new->str_expr);
1584 	cil_copy_expr(db, orig->datum_expr, &new->datum_expr);
1585 
1586 	*copy = new;
1587 
1588 	return SEPOL_OK;
1589 }
1590 
cil_copy_default(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1591 static int cil_copy_default(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1592 {
1593 	struct cil_default *orig = data;
1594 	struct cil_default *new = NULL;
1595 
1596 	cil_default_init(&new);
1597 
1598 	new->flavor = orig->flavor;
1599 
1600 	if (orig->class_strs != NULL) {
1601 		cil_copy_list(orig->class_strs, &new->class_strs);
1602 	}
1603 
1604 	new->object = orig->object;
1605 
1606 	*copy = new;
1607 
1608 	return SEPOL_OK;
1609 }
1610 
cil_copy_defaultrange(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1611 static int cil_copy_defaultrange(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1612 {
1613 	struct cil_defaultrange *orig = data;
1614 	struct cil_defaultrange *new = NULL;
1615 
1616 	cil_defaultrange_init(&new);
1617 
1618 	if (orig->class_strs != NULL) {
1619 		cil_copy_list(orig->class_strs, &new->class_strs);
1620 	}
1621 
1622 	new->object_range = orig->object_range;
1623 
1624 	*copy = new;
1625 
1626 	return SEPOL_OK;
1627 }
1628 
cil_copy_handleunknown(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1629 static int cil_copy_handleunknown(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1630 {
1631 	struct cil_handleunknown *orig = data;
1632 	struct cil_handleunknown *new = NULL;
1633 
1634 	cil_handleunknown_init(&new);
1635 	new->handle_unknown = orig->handle_unknown;
1636 	*copy = new;
1637 
1638 	return SEPOL_OK;
1639 }
1640 
cil_copy_mls(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1641 static int cil_copy_mls(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1642 {
1643 	struct cil_mls *orig = data;
1644 	struct cil_mls *new = NULL;
1645 
1646 	cil_mls_init(&new);
1647 	new->value = orig->value;
1648 	*copy = new;
1649 
1650 	return SEPOL_OK;
1651 }
1652 
cil_copy_bounds(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1653 static int cil_copy_bounds(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1654 {
1655 	struct cil_bounds *orig = data;
1656 	struct cil_bounds *new = NULL;
1657 
1658 	cil_bounds_init(&new);
1659 
1660 	new->parent_str = orig->parent_str;
1661 	new->child_str = orig->child_str;
1662 
1663 	*copy = new;
1664 
1665 	return SEPOL_OK;
1666 }
1667 
cil_copy_src_info(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1668 static int cil_copy_src_info(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1669 {
1670 	struct cil_src_info *orig = data;
1671 	struct cil_src_info *new = NULL;
1672 
1673 	cil_src_info_init(&new);
1674 
1675 	new->kind = orig->kind;
1676 	new->hll_line = orig->hll_line;
1677 	new->path = orig->path;
1678 
1679 	*copy = new;
1680 
1681 	return SEPOL_OK;
1682 }
1683 
__cil_copy_node_helper(struct cil_tree_node * orig,uint32_t * finished,void * extra_args)1684 static int __cil_copy_node_helper(struct cil_tree_node *orig, uint32_t *finished, void *extra_args)
1685 {
1686 	int rc = SEPOL_ERR;
1687 	struct cil_tree_node *parent = NULL;
1688 	struct cil_tree_node *new = NULL;
1689 	struct cil_db *db = NULL;
1690 	struct cil_args_copy *args = NULL;
1691 	struct cil_tree_node *namespace = NULL;
1692 	enum cil_sym_index sym_index = CIL_SYM_UNKNOWN;
1693 	symtab_t *symtab = NULL;
1694 	void *data = NULL;
1695 	int (*copy_func)(struct cil_db *db, void *data, void **copy, symtab_t *symtab) = NULL;
1696 	struct cil_blockinherit *blockinherit = NULL;
1697 
1698 	if (orig == NULL || extra_args == NULL) {
1699 		goto exit;
1700 	}
1701 
1702 	args = extra_args;
1703 	parent = args->dest;
1704 	db = args->db;
1705 
1706 
1707 	switch (orig->flavor) {
1708 	case CIL_BLOCK:
1709 		copy_func = &cil_copy_block;
1710 		break;
1711 	case CIL_BLOCKABSTRACT:
1712 		if (args->orig_dest->flavor == CIL_BLOCKINHERIT) {
1713 			/* When inheriting a block, don't copy any blockabstract
1714 			 * statements. Inheriting a block from a block that was
1715 			 * just inherited never worked. */
1716 			return SEPOL_OK;
1717 		}
1718 		copy_func = &cil_copy_blockabstract;
1719 		break;
1720 	case CIL_BLOCKINHERIT:
1721 		copy_func = &cil_copy_blockinherit;
1722 		break;
1723 	case CIL_POLICYCAP:
1724 		copy_func = &cil_copy_policycap;
1725 		break;
1726 	case CIL_PERM:
1727 	case CIL_MAP_PERM:
1728 		copy_func = &cil_copy_perm;
1729 		break;
1730 	case CIL_CLASSMAPPING:
1731 		copy_func = &cil_copy_classmapping;
1732 		break;
1733 	case CIL_CLASS:
1734 	case CIL_COMMON:
1735 	case CIL_MAP_CLASS:
1736 		copy_func = &cil_copy_class;
1737 		break;
1738 	case CIL_CLASSORDER:
1739 		copy_func = &cil_copy_ordered;
1740 		break;
1741 	case CIL_CLASSPERMISSION:
1742 		copy_func = &cil_copy_classpermission;
1743 		break;
1744 	case CIL_CLASSPERMISSIONSET:
1745 		copy_func = &cil_copy_classpermissionset;
1746 		break;
1747 	case CIL_CLASSCOMMON:
1748 		copy_func = &cil_copy_classcommon;
1749 		break;
1750 	case CIL_SID:
1751 		copy_func = &cil_copy_sid;
1752 		break;
1753 	case CIL_SIDCONTEXT:
1754 		copy_func = &cil_copy_sidcontext;
1755 		break;
1756 	case CIL_SIDORDER:
1757 		copy_func = &cil_copy_ordered;
1758 		break;
1759 	case CIL_USER:
1760 		copy_func = &cil_copy_user;
1761 		break;
1762 	case CIL_USERATTRIBUTE:
1763 		copy_func = &cil_copy_userattribute;
1764 		break;
1765 	case CIL_USERATTRIBUTESET:
1766 		copy_func = &cil_copy_userattributeset;
1767 		break;
1768 	case CIL_USERROLE:
1769 		copy_func = &cil_copy_userrole;
1770 		break;
1771 	case CIL_USERLEVEL:
1772 		copy_func = &cil_copy_userlevel;
1773 		break;
1774 	case CIL_USERRANGE:
1775 		copy_func = &cil_copy_userrange;
1776 		break;
1777 	case CIL_USERBOUNDS:
1778 		copy_func = &cil_copy_bounds;
1779 		break;
1780 	case CIL_USERPREFIX:
1781 		copy_func = &cil_copy_userprefix;
1782 		break;
1783 	case CIL_ROLE:
1784 		copy_func = &cil_copy_role;
1785 		break;
1786 	case CIL_ROLETYPE:
1787 		copy_func = &cil_copy_roletype;
1788 		break;
1789 	case CIL_ROLEBOUNDS:
1790 		copy_func = &cil_copy_bounds;
1791 		break;
1792 	case CIL_ROLEATTRIBUTE:
1793 		copy_func = &cil_copy_roleattribute;
1794 		break;
1795 	case CIL_ROLEATTRIBUTESET:
1796 		copy_func = &cil_copy_roleattributeset;
1797 		break;
1798 	case CIL_ROLEALLOW:
1799 		copy_func = &cil_copy_roleallow;
1800 		break;
1801 	case CIL_TYPE:
1802 		copy_func = &cil_copy_type;
1803 		break;
1804 	case CIL_TYPEBOUNDS:
1805 		copy_func = &cil_copy_bounds;
1806 		break;
1807 	case CIL_TYPEPERMISSIVE:
1808 		copy_func = cil_copy_typepermissive;
1809 		break;
1810 	case CIL_TYPEATTRIBUTE:
1811 		copy_func = &cil_copy_typeattribute;
1812 		break;
1813 	case CIL_TYPEATTRIBUTESET:
1814 		copy_func = &cil_copy_typeattributeset;
1815 		break;
1816 	case CIL_EXPANDTYPEATTRIBUTE:
1817 		copy_func = &cil_copy_expandtypeattribute;
1818 		break;
1819 	case CIL_TYPEALIAS:
1820 		copy_func = &cil_copy_alias;
1821 		break;
1822 	case CIL_TYPEALIASACTUAL:
1823 		copy_func = &cil_copy_aliasactual;
1824 		break;
1825 	case CIL_ROLETRANSITION:
1826 		copy_func = &cil_copy_roletransition;
1827 		break;
1828 	case CIL_NAMETYPETRANSITION:
1829 		copy_func = &cil_copy_nametypetransition;
1830 		break;
1831 	case CIL_RANGETRANSITION:
1832 		copy_func = &cil_copy_rangetransition;
1833 		break;
1834 	case CIL_TUNABLE:
1835 		copy_func = &cil_copy_tunable;
1836 		break;
1837 	case CIL_BOOL:
1838 		copy_func = &cil_copy_bool;
1839 		break;
1840 	case CIL_AVRULE:
1841 	case CIL_AVRULEX:
1842 		copy_func = &cil_copy_avrule;
1843 		break;
1844 	case CIL_PERMISSIONX:
1845 		copy_func = &cil_copy_permissionx;
1846 		break;
1847 	case CIL_DENY_RULE:
1848 		copy_func = &cil_copy_deny_rule;
1849 		break;
1850 	case CIL_TYPE_RULE:
1851 		copy_func = &cil_copy_type_rule;
1852 		break;
1853 	case CIL_SENS:
1854 		copy_func = &cil_copy_sens;
1855 		break;
1856 	case CIL_SENSALIAS:
1857 		copy_func = &cil_copy_alias;
1858 		break;
1859 	case CIL_SENSALIASACTUAL:
1860 		copy_func = &cil_copy_aliasactual;
1861 		break;
1862 	case CIL_CAT:
1863 		copy_func = &cil_copy_cat;
1864 		break;
1865 	case CIL_CATALIAS:
1866 		copy_func = &cil_copy_alias;
1867 		break;
1868 	case CIL_CATALIASACTUAL:
1869 		copy_func = &cil_copy_aliasactual;
1870 		break;
1871 	case CIL_CATSET:
1872 		copy_func = &cil_copy_catset;
1873 		break;
1874 	case CIL_SENSCAT:
1875 		copy_func = &cil_copy_senscat;
1876 		break;
1877 	case CIL_CATORDER:
1878 		copy_func = &cil_copy_ordered;
1879 		break;
1880 	case CIL_SENSITIVITYORDER:
1881 		copy_func = &cil_copy_ordered;
1882 		break;
1883 	case CIL_LEVEL:
1884 		copy_func = &cil_copy_level;
1885 		break;
1886 	case CIL_LEVELRANGE:
1887 		copy_func = &cil_copy_levelrange;
1888 		break;
1889 	case CIL_CONTEXT:
1890 		copy_func = &cil_copy_context;
1891 		break;
1892 	case CIL_NETIFCON:
1893 		copy_func = &cil_copy_netifcon;
1894 		break;
1895 	case CIL_GENFSCON:
1896 		copy_func = &cil_copy_genfscon;
1897 		break;
1898 	case CIL_FILECON:
1899 		copy_func = &cil_copy_filecon;
1900 		break;
1901 	case CIL_NODECON:
1902 		copy_func = &cil_copy_nodecon;
1903 		break;
1904 	case CIL_IBPKEYCON:
1905 		copy_func = &cil_copy_ibpkeycon;
1906 		break;
1907 	case CIL_IBENDPORTCON:
1908 		copy_func = &cil_copy_ibendportcon;
1909 		break;
1910 	case CIL_PORTCON:
1911 		copy_func = &cil_copy_portcon;
1912 		break;
1913 	case CIL_PIRQCON:
1914 		copy_func = &cil_copy_pirqcon;
1915 		break;
1916 	case CIL_IOMEMCON:
1917 		copy_func = &cil_copy_iomemcon;
1918 		break;
1919 	case CIL_IOPORTCON:
1920 		copy_func = &cil_copy_ioportcon;
1921 		break;
1922 	case CIL_PCIDEVICECON:
1923 		copy_func = &cil_copy_pcidevicecon;
1924 		break;
1925 	case CIL_DEVICETREECON:
1926 		copy_func = &cil_copy_devicetreecon;
1927 		break;
1928 	case CIL_FSUSE:
1929 		copy_func = &cil_copy_fsuse;
1930 		break;
1931 	case CIL_CONSTRAIN:
1932 	case CIL_MLSCONSTRAIN:
1933 		copy_func = &cil_copy_constrain;
1934 		break;
1935 	case CIL_VALIDATETRANS:
1936 	case CIL_MLSVALIDATETRANS:
1937 		copy_func = &cil_copy_validatetrans;
1938 		break;
1939 	case CIL_CALL:
1940 		copy_func = &cil_copy_call;
1941 		break;
1942 	case CIL_MACRO:
1943 		copy_func = &cil_copy_macro;
1944 		break;
1945 	case CIL_NODE:
1946 		copy_func = &cil_copy_node;
1947 		break;
1948 	case CIL_OPTIONAL:
1949 		copy_func = &cil_copy_optional;
1950 		break;
1951 	case CIL_IPADDR:
1952 		copy_func = &cil_copy_ipaddr;
1953 		break;
1954 	case CIL_CONDBLOCK:
1955 		copy_func = &cil_copy_condblock;
1956 		break;
1957 	case CIL_BOOLEANIF:
1958 		copy_func = &cil_copy_boolif;
1959 		break;
1960 	case CIL_TUNABLEIF:
1961 		copy_func = &cil_copy_tunif;
1962 		break;
1963 	case CIL_DEFAULTUSER:
1964 	case CIL_DEFAULTROLE:
1965 	case CIL_DEFAULTTYPE:
1966 		copy_func = &cil_copy_default;
1967 		break;
1968 	case CIL_DEFAULTRANGE:
1969 		copy_func = &cil_copy_defaultrange;
1970 		break;
1971 	case CIL_HANDLEUNKNOWN:
1972 		copy_func = &cil_copy_handleunknown;
1973 		break;
1974 	case CIL_MLS:
1975 		copy_func = &cil_copy_mls;
1976 		break;
1977 	case CIL_SRC_INFO:
1978 		copy_func = &cil_copy_src_info;
1979 		break;
1980 	default:
1981 		goto exit;
1982 	}
1983 
1984 	if (orig->flavor >= CIL_MIN_DECLARATIVE) {
1985 		rc = cil_flavor_to_symtab_index(orig->flavor, &sym_index);
1986 		if (rc != SEPOL_OK) {
1987 			goto exit;
1988 		}
1989 
1990 		rc = cil_get_symtab(parent, &symtab, sym_index);
1991 		if (rc != SEPOL_OK) {
1992 			goto exit;
1993 		}
1994 	}
1995 
1996 	rc = (*copy_func)(db, orig->data, &data, symtab);
1997 	if (rc == SEPOL_OK) {
1998 		if (orig->flavor == CIL_MACRO && data == NULL) {
1999 			/* Skipping macro re-declaration */
2000 			if (args->orig_dest->flavor != CIL_BLOCKINHERIT) {
2001 				cil_log(CIL_ERR, "  Re-declaration of macro is only allowed when inheriting a block\n");
2002 				return SEPOL_ERR;
2003 			}
2004 			*finished = CIL_TREE_SKIP_HEAD;
2005 			return SEPOL_OK;
2006 		}
2007 
2008 		cil_tree_node_init(&new);
2009 
2010 		new->parent = parent;
2011 		new->line = orig->line;
2012 		new->hll_offset = orig->hll_offset;
2013 		new->flavor = orig->flavor;
2014 		new->data = data;
2015 
2016 		if (orig->flavor == CIL_BLOCK && DATUM(data)->nodes->head != NULL) {
2017 			/* Duplicate block */
2018 			if (args->orig_dest->flavor != CIL_BLOCKINHERIT) {
2019 				cil_log(CIL_ERR, "  Re-declaration of block is only allowed when inheriting a block\n");
2020 				rc = SEPOL_ERR;
2021 				goto exit;
2022 			}
2023 			cil_list_append(DATUM(new->data)->nodes, CIL_NODE, new);
2024 		} else if (orig->flavor >= CIL_MIN_DECLARATIVE) {
2025 			/* Check the flavor of data if was found in the destination symtab */
2026 			if (DATUM(data)->nodes->head && FLAVOR(data) != orig->flavor) {
2027 				cil_tree_log(orig, CIL_ERR, "Incompatible flavor when trying to copy %s", DATUM(data)->name);
2028 				cil_tree_log(NODE(data), CIL_ERR, "Note: conflicting declaration");
2029 				new->flavor = FLAVOR(data);
2030 				rc = SEPOL_ERR;
2031 				goto exit;
2032 			}
2033 
2034 			rc = cil_add_decl_to_symtab(db, symtab, DATUM(orig->data)->name, DATUM(data), new);
2035 			if (rc != SEPOL_OK) {
2036 				if (rc == SEPOL_EEXIST) {
2037 					cil_symtab_datum_destroy(data);
2038 					free(data);
2039 					data = NULL;
2040 					rc = SEPOL_OK;
2041 				} else {
2042 					goto exit;
2043 				}
2044 			}
2045 
2046 			namespace = new;
2047 			while (namespace->flavor != CIL_MACRO && namespace->flavor != CIL_BLOCK && namespace->flavor != CIL_ROOT) {
2048 				namespace = namespace->parent;
2049 			}
2050 
2051 			if (namespace->flavor == CIL_MACRO) {
2052 				rc = cil_verify_decl_does_not_shadow_macro_parameter(namespace->data, orig, DATUM(orig->data)->name);
2053 				if (rc != SEPOL_OK) {
2054 					goto exit;
2055 				}
2056 			}
2057 		}
2058 
2059 		if (new->flavor == CIL_BLOCKINHERIT) {
2060 			blockinherit = new->data;
2061 			// if a blockinherit statement is copied before blockinherit are
2062 			// resolved (like in an in-statement), the block will not have been
2063 			// resolved yet, so there's nothing to append yet. This is fine,
2064 			// the copied blockinherit statement will be handled later, as if
2065 			// it wasn't in an in-statement
2066 			if (blockinherit->block != NULL) {
2067 				cil_list_append(blockinherit->block->bi_nodes, CIL_NODE, new);
2068 			}
2069 		}
2070 
2071 		if (parent->cl_head == NULL) {
2072 			parent->cl_head = new;
2073 			parent->cl_tail = new;
2074 		} else {
2075 			parent->cl_tail->next = new;
2076 			parent->cl_tail = new;
2077 		}
2078 
2079 		if (orig->cl_head != NULL) {
2080 			args->dest = new;
2081 		}
2082 	} else {
2083 		cil_tree_log(orig, CIL_ERR, "Problem copying %s node", cil_node_to_string(orig));
2084 		goto exit;
2085 	}
2086 
2087 	return SEPOL_OK;
2088 
2089 exit:
2090 	cil_tree_node_destroy(&new);
2091 	return rc;
2092 }
2093 
__cil_copy_last_child_helper(struct cil_tree_node * orig,void * extra_args)2094 static int __cil_copy_last_child_helper(__attribute__((unused)) struct cil_tree_node *orig, void *extra_args)
2095 {
2096 	struct cil_tree_node *node = NULL;
2097 	struct cil_args_copy *args = NULL;
2098 
2099 	args = extra_args;
2100 	node = args->dest;
2101 
2102 	if (node->flavor != CIL_ROOT) {
2103 		args->dest = node->parent;
2104 	}
2105 
2106 	return SEPOL_OK;
2107 }
2108 
2109 // dest is the parent node to copy into
2110 // if the copy is for a call to a macro, dest should be a pointer to the call
cil_copy_ast(struct cil_db * db,struct cil_tree_node * orig,struct cil_tree_node * dest)2111 int cil_copy_ast(struct cil_db *db, struct cil_tree_node *orig, struct cil_tree_node *dest)
2112 {
2113 	int rc = SEPOL_ERR;
2114 	struct cil_args_copy extra_args;
2115 
2116 	extra_args.orig_dest = dest;
2117 	extra_args.dest = dest;
2118 	extra_args.db = db;
2119 
2120 	rc = cil_tree_walk(orig, __cil_copy_node_helper, NULL,  __cil_copy_last_child_helper, &extra_args);
2121 	if (rc != SEPOL_OK) {
2122 		cil_tree_log(dest, CIL_ERR, "Failed to copy %s to %s", cil_node_to_string(orig), cil_node_to_string(dest));
2123 		goto exit;
2124 	}
2125 
2126 	return SEPOL_OK;
2127 
2128 exit:
2129 	return rc;
2130 }
2131 
2132