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