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