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