Coverage Report

Created: 2025-09-17 06:24

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/selinux/libsepol/cil/src/cil_resolve_ast.c
Line
Count
Source
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 <sepol/policydb/conditional.h>
35
36
#include "cil_internal.h"
37
#include "cil_flavor.h"
38
#include "cil_log.h"
39
#include "cil_mem.h"
40
#include "cil_tree.h"
41
#include "cil_list.h"
42
#include "cil_build_ast.h"
43
#include "cil_resolve_ast.h"
44
#include "cil_reset_ast.h"
45
#include "cil_copy_ast.h"
46
#include "cil_verify.h"
47
#include "cil_strpool.h"
48
#include "cil_symtab.h"
49
#include "cil_stack.h"
50
51
struct cil_args_resolve {
52
  struct cil_db *db;
53
  enum cil_pass pass;
54
  uint32_t *changed;
55
  struct cil_list *to_destroy;
56
  struct cil_tree_node *block;
57
  struct cil_tree_node *macro;
58
  struct cil_tree_node *optional;
59
  struct cil_tree_node *disabled_optional;
60
  struct cil_tree_node *boolif;
61
  struct cil_list *sidorder_lists;
62
  struct cil_list *classorder_lists;
63
  struct cil_list *unordered_classorder_lists;
64
  struct cil_list *catorder_lists;
65
  struct cil_list *sensitivityorder_lists;
66
  struct cil_list *in_list_before;
67
  struct cil_list *in_list_after;
68
  struct cil_list *abstract_blocks;
69
};
70
71
static int __cil_resolve_perms(symtab_t *class_symtab, symtab_t *common_symtab, struct cil_list *perm_strs, struct cil_list **perm_datums, enum cil_flavor class_flavor)
72
1.10M
{
73
1.10M
  int rc = SEPOL_ERR;
74
1.10M
  struct cil_list_item *curr;
75
76
1.10M
  cil_list_init(perm_datums, perm_strs->flavor);
77
78
1.33M
  cil_list_for_each(curr, perm_strs) {
79
1.33M
    if (curr->flavor == CIL_LIST) {
80
1.96k
      struct cil_list *sub_list;
81
1.96k
      rc = __cil_resolve_perms(class_symtab, common_symtab, curr->data, &sub_list, class_flavor);
82
1.96k
      if (rc != SEPOL_OK) {
83
222
        cil_log(CIL_ERR, "Failed to resolve permission list\n");
84
222
        goto exit;
85
222
      }
86
1.74k
      cil_list_append(*perm_datums, CIL_LIST, sub_list);
87
1.32M
    } else if (curr->flavor == CIL_STRING) {
88
1.32M
      struct cil_symtab_datum *perm_datum = NULL;
89
1.32M
      rc = cil_symtab_get_datum(class_symtab, curr->data, &perm_datum);
90
1.32M
      if (rc == SEPOL_ENOENT) {
91
564k
        if (common_symtab) {
92
564k
          rc = cil_symtab_get_datum(common_symtab, curr->data, &perm_datum);
93
564k
        }
94
564k
      }
95
1.32M
      if (rc != SEPOL_OK) {
96
2.94k
        if (class_flavor == CIL_MAP_CLASS) {
97
228
          cil_log(CIL_ERR, "Failed to resolve permission %s for map class\n", (char*)curr->data);
98
2.72k
        } else {
99
2.72k
          cil_log(CIL_ERR, "Failed to resolve permission %s\n", (char*)curr->data);
100
2.72k
        }
101
2.94k
        goto exit;
102
2.94k
      }
103
1.31M
      cil_list_append(*perm_datums, CIL_DATUM, perm_datum);
104
1.31M
    } else {
105
9.70k
      cil_list_append(*perm_datums, curr->flavor, curr->data);
106
9.70k
    }
107
1.33M
  }
108
109
1.10M
  return SEPOL_OK;
110
111
3.17k
exit:
112
3.17k
  cil_list_destroy(perm_datums, CIL_FALSE);
113
3.17k
  return rc;
114
1.10M
}
115
116
int cil_resolve_classperms(struct cil_tree_node *current, struct cil_classperms *cp, struct cil_db *db)
117
1.12M
{
118
1.12M
  int rc = SEPOL_ERR;
119
1.12M
  struct cil_symtab_datum *datum = NULL;
120
1.12M
  symtab_t *common_symtab = NULL;
121
1.12M
  struct cil_class *class;
122
123
1.12M
  if (cp->class) {
124
127
    return SEPOL_OK;
125
127
  }
126
127
1.12M
  rc = cil_resolve_name(current, cp->class_str, CIL_SYM_CLASSES, db, &datum);
128
1.12M
  if (rc != SEPOL_OK) {
129
12.4k
    goto exit;
130
12.4k
  }
131
132
1.10M
  class = (struct cil_class *)datum;
133
134
1.10M
  if (class->common != NULL) {
135
507k
    common_symtab = &class->common->perms;
136
507k
  }
137
138
1.10M
  cp->class = class;
139
140
1.10M
  rc = __cil_resolve_perms(&class->perms, common_symtab, cp->perm_strs, &cp->perms, FLAVOR(datum));
141
1.10M
  if (rc != SEPOL_OK) {
142
2.94k
    goto exit;
143
2.94k
  }
144
145
1.10M
  return SEPOL_OK;
146
147
15.4k
exit:
148
15.4k
  return rc;
149
1.10M
}
150
151
static int cil_resolve_classperms_set(struct cil_tree_node *current, struct cil_classperms_set *cp_set, struct cil_db *db)
152
80.0k
{
153
80.0k
  int rc = SEPOL_ERR;
154
80.0k
  struct cil_symtab_datum *datum = NULL;
155
156
80.0k
  rc = cil_resolve_name(current, cp_set->set_str, CIL_SYM_CLASSPERMSETS, db, &datum);
157
80.0k
  if (rc != SEPOL_OK) {
158
12.2k
    goto exit;
159
12.2k
  }
160
67.7k
  cp_set->set = (struct cil_classpermission*)datum;
161
162
  /* This could be an anonymous classpermission */
163
67.7k
  if (datum->name == NULL) {
164
21.8k
    rc = cil_resolve_classperms_list(current, cp_set->set->classperms, db);
165
21.8k
    if (rc != SEPOL_OK) {
166
5
      goto exit;
167
5
    }
168
21.8k
  }
169
170
67.7k
  return SEPOL_OK;
171
172
12.2k
exit:
173
12.2k
  return rc;
174
67.7k
}
175
176
int cil_resolve_classperms_list(struct cil_tree_node *current, struct cil_list *cp_list, struct cil_db *db)
177
1.20M
{
178
1.20M
  int rc = SEPOL_ERR;
179
1.20M
  struct cil_list_item *curr;
180
181
1.20M
  cil_list_for_each(curr, cp_list) {
182
1.20M
    if (curr->flavor == CIL_CLASSPERMS) {
183
1.12M
      rc = cil_resolve_classperms(current, curr->data, db);
184
1.12M
      if (rc != SEPOL_OK) {
185
15.4k
        goto exit;
186
15.4k
      }
187
1.12M
    } else {
188
80.0k
      rc = cil_resolve_classperms_set(current, curr->data, db);
189
80.0k
      if (rc != SEPOL_OK) {
190
12.2k
        goto exit;
191
12.2k
      }
192
80.0k
    }
193
1.20M
  }
194
195
1.17M
  return SEPOL_OK;
196
197
27.6k
exit:
198
27.6k
  return rc;
199
1.20M
}
200
201
int cil_resolve_classpermissionset(struct cil_tree_node *current, struct cil_classpermissionset *cps, struct cil_db *db)
202
8.74k
{
203
8.74k
  int rc = SEPOL_ERR;
204
8.74k
  struct cil_list_item *curr;
205
8.74k
  struct cil_symtab_datum *datum;
206
8.74k
  struct cil_classpermission *cp;
207
208
8.74k
  rc = cil_resolve_name(current, cps->set_str, CIL_SYM_CLASSPERMSETS, db, &datum);
209
8.74k
  if (rc != SEPOL_OK) {
210
365
    goto exit;
211
365
  }
212
213
8.37k
  if (!datum->fqn) {
214
4
    cil_tree_log(current, CIL_ERR, "Anonymous classpermission used in a classpermissionset");
215
4
    rc = SEPOL_ERR;
216
4
    goto exit;
217
4
  }
218
219
8.37k
  rc = cil_resolve_classperms_list(current, cps->classperms, db);
220
8.37k
  if (rc != SEPOL_OK) {
221
120
    goto exit;
222
120
  }
223
224
8.25k
  cp = (struct cil_classpermission *)datum;
225
8.25k
  cps->set = cp;
226
227
8.25k
  if (cp->classperms == NULL) {
228
4.19k
    cil_list_init(&cp->classperms, CIL_CLASSPERMS);
229
4.19k
  }
230
231
8.25k
  cil_list_for_each(curr, cps->classperms) {
232
8.25k
    cil_list_append(cp->classperms, curr->flavor, curr->data);
233
8.25k
  }
234
235
8.25k
  return SEPOL_OK;
236
237
489
exit:
238
489
  return rc;
239
8.37k
}
240
241
static void cil_type_used(struct cil_symtab_datum *datum, int used)
242
1.47M
{
243
1.47M
  struct cil_typeattribute *attr = NULL;
244
245
1.47M
  if (FLAVOR(datum) == CIL_TYPEATTRIBUTE) {
246
247k
    attr = (struct cil_typeattribute*)datum;
247
247k
    attr->used |= used;
248
247k
    if ((attr->used & CIL_ATTR_EXPAND_TRUE) &&
249
1.34k
        (attr->used & CIL_ATTR_EXPAND_FALSE)) {
250
0
      cil_log(CIL_WARN, "Conflicting use of expandtypeattribute. "
251
0
          "Expandtypeattribute was set to both true or false for %s. "
252
0
          "Resolving to false. \n", attr->datum.name);
253
0
      attr->used &= ~CIL_ATTR_EXPAND_TRUE;
254
0
    }
255
247k
  }
256
1.47M
}
257
258
static int cil_resolve_permissionx(struct cil_tree_node *current, struct cil_permissionx *permx, struct cil_db *db)
259
25.1k
{
260
25.1k
  struct cil_symtab_datum *obj_datum = NULL;
261
25.1k
  int rc = SEPOL_ERR;
262
263
25.1k
  rc = cil_resolve_name(current, permx->obj_str, CIL_SYM_CLASSES, db, &obj_datum);
264
25.1k
  if (rc != SEPOL_OK) {
265
1.92k
    goto exit;
266
1.92k
  }
267
23.2k
  permx->obj = (struct cil_class*)obj_datum;
268
269
23.2k
  return SEPOL_OK;
270
271
1.92k
exit:
272
1.92k
  return rc;
273
25.1k
}
274
275
int cil_resolve_avrule(struct cil_tree_node *current, struct cil_db *db)
276
972k
{
277
972k
  struct cil_avrule *rule = current->data;
278
972k
  struct cil_symtab_datum *src_datum = NULL;
279
972k
  struct cil_symtab_datum *tgt_datum = NULL;
280
972k
  struct cil_symtab_datum *permx_datum = NULL;
281
972k
  int used;
282
972k
  int rc = SEPOL_ERR;
283
284
972k
  rc = cil_resolve_name(current, rule->src_str, CIL_SYM_TYPES, db, &src_datum);
285
972k
  if (rc != SEPOL_OK) {
286
16.4k
    goto exit;
287
16.4k
  }
288
956k
  rule->src = src_datum;
289
    
290
956k
  if (rule->tgt_str == CIL_KEY_SELF) {
291
233k
    rule->tgt = db->selftype;
292
722k
  } else if (rule->tgt_str == CIL_KEY_NOTSELF) {
293
19.7k
    rule->tgt = db->notselftype;
294
702k
  } else if (rule->tgt_str == CIL_KEY_OTHER) {
295
11.3k
    rule->tgt = db->othertype;
296
691k
  } else {
297
691k
    rc = cil_resolve_name(current, rule->tgt_str, CIL_SYM_TYPES, db, &tgt_datum);
298
691k
    if (rc != SEPOL_OK) {
299
518
      goto exit;
300
518
    }
301
690k
    rule->tgt = tgt_datum;
302
690k
    used = (rule->rule_kind == CIL_AVRULE_NEVERALLOW) ?
303
641k
      CIL_ATTR_NEVERALLOW : CIL_ATTR_AVRULE;
304
690k
    cil_type_used(src_datum, used); /* src not used if tgt is self */
305
690k
    cil_type_used(tgt_datum, used);
306
690k
  }
307
308
955k
  if (!rule->is_extended) {
309
935k
    rc = cil_resolve_classperms_list(current, rule->perms.classperms, db);
310
935k
    if (rc != SEPOL_OK) {
311
2.96k
      goto exit;
312
2.96k
    }
313
935k
  } else {
314
19.8k
    if (rule->perms.x.permx_str != NULL) {
315
1.08k
      rc = cil_resolve_name(current, rule->perms.x.permx_str, CIL_SYM_PERMX, db, &permx_datum);
316
1.08k
      if (rc != SEPOL_OK) {
317
50
        goto exit;
318
50
      }
319
1.03k
      rule->perms.x.permx = (struct cil_permissionx*)permx_datum;
320
18.7k
    } else {
321
18.7k
      rc = cil_resolve_permissionx(current, rule->perms.x.permx, db);
322
18.7k
      if (rc != SEPOL_OK) {
323
377
        goto exit;
324
377
      }
325
18.7k
    }
326
19.8k
  }
327
328
952k
  return SEPOL_OK;
329
330
20.3k
exit:
331
20.3k
  return rc;
332
955k
}
333
334
int cil_resolve_deny_rule(struct cil_tree_node *current, struct cil_db *db)
335
31.6k
{
336
31.6k
  struct cil_deny_rule *rule = current->data;
337
31.6k
  struct cil_symtab_datum *src_datum = NULL;
338
31.6k
  struct cil_symtab_datum *tgt_datum = NULL;
339
31.6k
  int rc = SEPOL_ERR;
340
341
31.6k
  rc = cil_resolve_name(current, rule->src_str, CIL_SYM_TYPES, db, &src_datum);
342
31.6k
  if (rc != SEPOL_OK) {
343
609
    goto exit;
344
609
  }
345
31.0k
  rule->src = src_datum;
346
347
31.0k
  if (rule->tgt_str == CIL_KEY_SELF) {
348
3.07k
    rule->tgt = db->selftype;
349
27.9k
  } else if (rule->tgt_str == CIL_KEY_NOTSELF) {
350
5.64k
    rule->tgt = db->notselftype;
351
22.3k
  } else if (rule->tgt_str == CIL_KEY_OTHER) {
352
3.07k
    rule->tgt = db->othertype;
353
19.2k
  } else {
354
19.2k
    rc = cil_resolve_name(current, rule->tgt_str, CIL_SYM_TYPES, db, &tgt_datum);
355
19.2k
    if (rc != SEPOL_OK) {
356
77
      goto exit;
357
77
    }
358
19.1k
    rule->tgt = tgt_datum;
359
19.1k
  }
360
361
30.9k
  rc = cil_resolve_classperms_list(current, rule->classperms, db);
362
30.9k
  if (rc != SEPOL_OK) {
363
654
    goto exit;
364
654
  }
365
366
30.3k
  return SEPOL_OK;
367
368
1.34k
exit:
369
1.34k
  return rc;
370
30.9k
}
371
372
int cil_resolve_type_rule(struct cil_tree_node *current, struct cil_db *db)
373
73.3k
{
374
73.3k
  struct cil_type_rule *rule = current->data;
375
73.3k
  struct cil_symtab_datum *src_datum = NULL;
376
73.3k
  struct cil_symtab_datum *tgt_datum = NULL;
377
73.3k
  struct cil_symtab_datum *obj_datum = NULL;
378
73.3k
  struct cil_symtab_datum *result_datum = NULL;
379
73.3k
  struct cil_tree_node *result_node = NULL;
380
73.3k
  int rc = SEPOL_ERR;
381
382
73.3k
  rc = cil_resolve_name(current, rule->src_str, CIL_SYM_TYPES, db, &src_datum);
383
73.3k
  if (rc != SEPOL_OK) {
384
4.00k
    goto exit;
385
4.00k
  }
386
69.3k
  rule->src = src_datum;
387
388
69.3k
  if (rule->tgt_str == CIL_KEY_SELF) {
389
3.34k
    rule->tgt = db->selftype;
390
65.9k
  } else {
391
65.9k
    rc = cil_resolve_name(current, rule->tgt_str, CIL_SYM_TYPES, db, &tgt_datum);
392
65.9k
    if (rc != SEPOL_OK) {
393
333
      goto exit;
394
333
    }
395
65.6k
    rule->tgt = tgt_datum;
396
65.6k
  }
397
398
69.0k
  rc = cil_resolve_name(current, rule->obj_str, CIL_SYM_CLASSES, db, &obj_datum);
399
69.0k
  if (rc != SEPOL_OK) {
400
536
    goto exit;
401
536
  }
402
68.4k
  rule->obj = (struct cil_class*)obj_datum;
403
404
68.4k
  rc = cil_resolve_name(current, rule->result_str, CIL_SYM_TYPES, db, &result_datum);
405
68.4k
  if (rc != SEPOL_OK) {
406
1.29k
    goto exit;
407
1.29k
  }
408
409
67.1k
  result_node = NODE(result_datum);
410
411
67.1k
  if (result_node->flavor != CIL_TYPE) {
412
1
    cil_log(CIL_ERR, "Type rule result must be a type [%d]\n",result_node->flavor);
413
1
    rc = SEPOL_ERR;
414
1
    goto exit;
415
1
  }
416
67.1k
  rule->result = result_datum;
417
418
67.1k
  return SEPOL_OK;
419
420
6.17k
exit:
421
6.17k
  return rc;
422
67.1k
}
423
424
int cil_resolve_typeattributeset(struct cil_tree_node *current, struct cil_db *db)
425
118k
{
426
118k
  struct cil_typeattributeset *attrtypes = current->data;
427
118k
  struct cil_symtab_datum *attr_datum = NULL;
428
118k
  struct cil_tree_node *attr_node = NULL;
429
118k
  struct cil_typeattribute *attr = NULL;
430
118k
  int rc = SEPOL_ERR;
431
432
118k
  rc = cil_resolve_name(current, attrtypes->attr_str, CIL_SYM_TYPES, db, &attr_datum);
433
118k
  if (rc != SEPOL_OK) {
434
1.02k
    goto exit;
435
1.02k
  }
436
437
117k
  attr_node = NODE(attr_datum);
438
439
117k
  if (attr_node->flavor != CIL_TYPEATTRIBUTE) {
440
1
    rc = SEPOL_ERR;
441
1
    cil_log(CIL_ERR, "Attribute type not an attribute\n");
442
1
    goto exit;
443
1
  }
444
445
117k
  attr = (struct cil_typeattribute*)attr_datum;
446
447
117k
  rc = cil_resolve_expr(CIL_TYPEATTRIBUTESET, attrtypes->str_expr, &attrtypes->datum_expr, current, db);
448
117k
  if (rc != SEPOL_OK) {
449
178
    goto exit;
450
178
  }
451
452
116k
  if (attr->expr_list == NULL) {
453
49.1k
    cil_list_init(&attr->expr_list, CIL_TYPEATTRIBUTE);
454
49.1k
  }
455
456
116k
  cil_list_append(attr->expr_list, CIL_LIST, attrtypes->datum_expr);
457
458
116k
  return SEPOL_OK;
459
460
1.20k
exit:
461
1.20k
  return rc;
462
117k
}
463
464
static int cil_resolve_expandtypeattribute(struct cil_tree_node *current, struct cil_db *db)
465
3.39k
{
466
3.39k
  struct cil_expandtypeattribute *expandattr = current->data;
467
3.39k
  struct cil_symtab_datum *attr_datum = NULL;
468
3.39k
  struct cil_tree_node *attr_node = NULL;
469
3.39k
  struct cil_list_item *curr;
470
3.39k
  int used;
471
3.39k
  int rc = SEPOL_ERR;
472
473
3.39k
  cil_list_init(&expandattr->attr_datums, CIL_TYPE);
474
475
4.20k
  cil_list_for_each(curr, expandattr->attr_strs) {
476
4.20k
    rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_TYPES, db, &attr_datum);
477
4.20k
    if (rc != SEPOL_OK) {
478
2.87k
      goto exit;
479
2.87k
    }
480
481
1.33k
    attr_node = NODE(attr_datum);
482
483
1.33k
    if (attr_node->flavor != CIL_TYPEATTRIBUTE) {
484
1
      rc = SEPOL_ERR;
485
1
      cil_log(CIL_ERR, "Attribute type not an attribute\n");
486
1
      goto exit;
487
1
    }
488
1.33k
    used = expandattr->expand ? CIL_ATTR_EXPAND_TRUE : CIL_ATTR_EXPAND_FALSE;
489
1.33k
    cil_type_used(attr_datum, used);
490
1.33k
    cil_list_append(expandattr->attr_datums, CIL_TYPE, attr_datum);
491
1.33k
  }
492
493
525
  return SEPOL_OK;
494
2.87k
exit:
495
2.87k
  return rc;
496
3.39k
}
497
498
static int cil_resolve_aliasactual(struct cil_tree_node *current, struct cil_db *db, enum cil_flavor flavor, enum cil_flavor alias_flavor)
499
13.9k
{
500
13.9k
  int rc = SEPOL_ERR;
501
13.9k
  enum cil_sym_index sym_index;
502
13.9k
  struct cil_aliasactual *aliasactual = current->data;
503
13.9k
  struct cil_symtab_datum *alias_datum = NULL;
504
13.9k
  struct cil_symtab_datum *actual_datum = NULL;
505
13.9k
  struct cil_alias *alias;
506
507
13.9k
  rc = cil_flavor_to_symtab_index(flavor, &sym_index);
508
13.9k
  if (rc != SEPOL_OK) {
509
0
    goto exit;
510
0
  }
511
512
13.9k
  rc = cil_resolve_name_keep_aliases(current, aliasactual->alias_str, sym_index, db, &alias_datum);
513
13.9k
  if (rc != SEPOL_OK) {
514
7.36k
    goto exit;
515
7.36k
  }
516
6.58k
  if (FLAVOR(alias_datum) != alias_flavor) {
517
1
    cil_log(CIL_ERR, "%s is not an alias\n",alias_datum->name);
518
1
    rc = SEPOL_ERR;
519
1
    goto exit;
520
1
  }
521
522
6.58k
  rc = cil_resolve_name(current, aliasactual->actual_str, sym_index, db, &actual_datum);
523
6.58k
  if (rc != SEPOL_OK) {
524
260
    goto exit;
525
260
  }
526
527
6.32k
  if (FLAVOR(actual_datum) != flavor && FLAVOR(actual_datum) != alias_flavor) {
528
2
    cil_log(CIL_ERR, "%s is a %s, but aliases a %s\n", alias_datum->name, cil_node_to_string(NODE(alias_datum)), cil_node_to_string(NODE(actual_datum)));
529
2
    rc = SEPOL_ERR;
530
2
    goto exit;
531
2
  }
532
533
6.31k
  alias = (struct cil_alias *)alias_datum;
534
6.31k
  aliasactual->alias = alias_datum;
535
536
6.31k
  if (alias->actual != NULL) {
537
5
    cil_log(CIL_ERR, "%s %s cannot bind more than one value\n", cil_node_to_string(NODE(alias_datum)), alias_datum->name);
538
5
    rc = SEPOL_ERR;
539
5
    goto exit;
540
5
  }
541
542
6.31k
  alias->actual = actual_datum;
543
6.31k
  aliasactual->actual = actual_datum;
544
545
6.31k
  return SEPOL_OK;
546
547
7.63k
exit:
548
7.63k
  return rc;
549
6.31k
}
550
551
static int cil_resolve_alias_to_actual(struct cil_tree_node *current, enum cil_flavor flavor)
552
6.00k
{
553
6.00k
  struct cil_alias *alias = current->data;
554
6.00k
  struct cil_alias *a1 = current->data;
555
6.00k
  struct cil_alias *a2 = current->data;
556
6.00k
  struct cil_tree_node *a1_node = NULL;
557
6.00k
  int steps = 0;
558
6.00k
  int limit = 2;
559
560
6.00k
  if (alias->actual == NULL) {
561
18
    cil_tree_log(current, CIL_ERR, "Alias declared but not used");
562
18
    return SEPOL_ERR;
563
18
  }
564
565
5.98k
  a1_node = a1->datum.nodes->head->data;
566
567
11.9k
  while (flavor != a1_node->flavor) {
568
5.99k
    if (a1->actual == NULL) {
569
2
      cil_tree_log(current, CIL_ERR, "Alias %s references an unused alias %s", alias->datum.name, a1->datum.name);
570
2
      return SEPOL_ERR;
571
2
    }
572
5.99k
    a1 = a1->actual;
573
5.99k
    a1_node = a1->datum.nodes->head->data;
574
5.99k
    steps += 1;
575
576
5.99k
    if (a1 == a2) {
577
14
      cil_log(CIL_ERR, "Circular alias found: %s ", a1->datum.name);
578
14
      a1 = a1->actual;
579
14
      while (a1 != a2) {
580
0
        cil_log(CIL_ERR, "%s ", a1->datum.name);
581
0
        a1 = a1->actual;
582
0
      }
583
14
      cil_log(CIL_ERR,"\n");
584
14
      return SEPOL_ERR;
585
14
    }
586
587
5.97k
    if (steps == limit) {
588
5
      steps = 0;
589
5
      limit *= 2;
590
5
      a2 = a1;
591
5
    }
592
5.97k
  }
593
594
5.96k
  alias->actual = a1;
595
596
5.96k
  return SEPOL_OK;
597
5.98k
}
598
599
int cil_resolve_typepermissive(struct cil_tree_node *current, struct cil_db *db)
600
2.47k
{
601
2.47k
  struct cil_typepermissive *typeperm = current->data;
602
2.47k
  struct cil_symtab_datum *type_datum = NULL;
603
2.47k
  struct cil_tree_node *type_node = NULL;
604
2.47k
  int rc = SEPOL_ERR;
605
606
2.47k
  rc = cil_resolve_name(current, typeperm->type_str, CIL_SYM_TYPES, db, &type_datum);
607
2.47k
  if (rc != SEPOL_OK) {
608
315
    goto exit;
609
315
  }
610
611
2.16k
  type_node = NODE(type_datum);
612
613
2.16k
  if (type_node->flavor != CIL_TYPE && type_node->flavor != CIL_TYPEALIAS) {
614
1
    cil_log(CIL_ERR, "Typepermissive must be a type or type alias\n");
615
1
    rc = SEPOL_ERR;
616
1
    goto exit;
617
1
  }
618
619
2.16k
  typeperm->type = type_datum;
620
621
2.16k
  return SEPOL_OK;
622
623
316
exit:
624
316
  return rc;
625
2.16k
}
626
627
int cil_resolve_typeneveraudit(struct cil_tree_node *current, struct cil_db *db)
628
1.87k
{
629
1.87k
  struct cil_typeneveraudit *typeperm = current->data;
630
1.87k
  struct cil_symtab_datum *type_datum = NULL;
631
1.87k
  struct cil_tree_node *type_node = NULL;
632
1.87k
  int rc = SEPOL_ERR;
633
634
1.87k
  rc = cil_resolve_name(current, typeperm->type_str, CIL_SYM_TYPES, db, &type_datum);
635
1.87k
  if (rc != SEPOL_OK) {
636
796
    goto exit;
637
796
  }
638
639
1.08k
  type_node = NODE(type_datum);
640
641
1.08k
  if (type_node->flavor != CIL_TYPE && type_node->flavor != CIL_TYPEALIAS) {
642
0
    cil_log(CIL_ERR, "Typeneveraudit must be a type or type alias\n");
643
0
    rc = SEPOL_ERR;
644
0
    goto exit;
645
0
  }
646
647
1.08k
  typeperm->type = type_datum;
648
649
1.08k
  return SEPOL_OK;
650
651
796
exit:
652
796
  return rc;
653
1.08k
}
654
655
int cil_resolve_nametypetransition(struct cil_tree_node *current, struct cil_db *db)
656
46.4k
{
657
46.4k
  struct cil_nametypetransition *nametypetrans = current->data;
658
46.4k
  struct cil_symtab_datum *src_datum = NULL;
659
46.4k
  struct cil_symtab_datum *tgt_datum = NULL;
660
46.4k
  struct cil_symtab_datum *obj_datum = NULL;
661
46.4k
  struct cil_symtab_datum *name_datum = NULL;
662
46.4k
  struct cil_symtab_datum *result_datum = NULL;
663
46.4k
  struct cil_tree_node *result_node = NULL;
664
46.4k
  int rc = SEPOL_ERR;
665
666
46.4k
  rc = cil_resolve_name(current, nametypetrans->src_str, CIL_SYM_TYPES, db, &src_datum);
667
46.4k
  if (rc != SEPOL_OK) {
668
922
    goto exit;
669
922
  }
670
45.5k
  nametypetrans->src = src_datum;
671
672
45.5k
  if (nametypetrans->tgt_str == CIL_KEY_SELF) {
673
6.84k
    nametypetrans->tgt = db->selftype;
674
38.7k
  } else {
675
38.7k
    rc = cil_resolve_name(current, nametypetrans->tgt_str, CIL_SYM_TYPES, db, &tgt_datum);
676
38.7k
    if (rc != SEPOL_OK) {
677
538
      goto exit;
678
538
    }
679
38.1k
    nametypetrans->tgt = tgt_datum;
680
38.1k
  }
681
682
45.0k
  rc = cil_resolve_name(current, nametypetrans->obj_str, CIL_SYM_CLASSES, db, &obj_datum);
683
45.0k
  if (rc != SEPOL_OK) {
684
398
    goto exit;
685
398
  }
686
44.6k
  nametypetrans->obj = (struct cil_class*)obj_datum;
687
688
44.6k
  if (!nametypetrans->name) {
689
0
    rc = cil_resolve_name(current, nametypetrans->name_str, CIL_SYM_STRINGS, db, &name_datum);
690
0
    if (rc != SEPOL_OK) {
691
0
      goto exit;
692
0
    }
693
0
    nametypetrans->name = name_datum;
694
0
  }
695
696
44.6k
  rc = cil_resolve_name(current, nametypetrans->result_str, CIL_SYM_TYPES, db, &result_datum);
697
44.6k
  if (rc != SEPOL_OK) {
698
296
    goto exit;
699
296
  }
700
701
44.3k
  result_node = NODE(result_datum);
702
703
44.3k
  if (result_node->flavor != CIL_TYPE && result_node->flavor != CIL_TYPEALIAS) {
704
1
    cil_log(CIL_ERR, "typetransition result is not a type or type alias\n");
705
1
    rc = SEPOL_ERR;
706
1
    goto exit;
707
1
  }
708
44.3k
  nametypetrans->result = result_datum;
709
710
44.3k
  return SEPOL_OK;
711
712
2.15k
exit:
713
2.15k
  return rc;
714
44.3k
}
715
716
int cil_resolve_rangetransition(struct cil_tree_node *current, struct cil_db *db)
717
35.3k
{
718
35.3k
  struct cil_rangetransition *rangetrans = current->data;
719
35.3k
  struct cil_symtab_datum *src_datum = NULL;
720
35.3k
  struct cil_symtab_datum *exec_datum = NULL;
721
35.3k
  struct cil_symtab_datum *obj_datum = NULL;
722
35.3k
  struct cil_symtab_datum *range_datum = NULL;
723
35.3k
  int rc = SEPOL_ERR;
724
725
35.3k
  rc = cil_resolve_name(current, rangetrans->src_str, CIL_SYM_TYPES, db, &src_datum);
726
35.3k
  if (rc != SEPOL_OK) {
727
1.73k
    goto exit;
728
1.73k
  }
729
33.5k
  rangetrans->src = src_datum;
730
731
33.5k
  rc = cil_resolve_name(current, rangetrans->exec_str, CIL_SYM_TYPES, db, &exec_datum);
732
33.5k
  if (rc != SEPOL_OK) {
733
372
    goto exit;
734
372
  }
735
33.2k
  rangetrans->exec = exec_datum;
736
737
33.2k
  rc = cil_resolve_name(current, rangetrans->obj_str, CIL_SYM_CLASSES, db, &obj_datum);
738
33.2k
  if (rc != SEPOL_OK) {
739
202
    goto exit;
740
202
  }
741
33.0k
  rangetrans->obj = (struct cil_class*)obj_datum;
742
743
33.0k
  if (rangetrans->range_str != NULL) {
744
2.60k
    rc = cil_resolve_name(current, rangetrans->range_str, CIL_SYM_LEVELRANGES, db, &range_datum);
745
2.60k
    if (rc != SEPOL_OK) {
746
408
      goto exit;
747
408
    }
748
2.19k
    rangetrans->range = (struct cil_levelrange*)range_datum;
749
750
    /* This could still be an anonymous levelrange even if range_str is set, if range_str is a param_str*/
751
2.19k
    if (rangetrans->range->datum.name == NULL) {
752
0
      rc = cil_resolve_levelrange(current, rangetrans->range, db);
753
0
      if (rc != SEPOL_OK) {
754
0
        goto exit;
755
0
      }
756
0
    }
757
30.4k
  } else {
758
30.4k
    rc = cil_resolve_levelrange(current, rangetrans->range, db);
759
30.4k
    if (rc != SEPOL_OK) {
760
704
      goto exit;
761
704
    }
762
30.4k
  }
763
764
31.8k
  return SEPOL_OK;
765
766
3.42k
exit:
767
3.42k
  return rc;
768
33.0k
}
769
770
static int __class_update_perm_values(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
771
14.0k
{
772
14.0k
  struct cil_perm *perm = (struct cil_perm *)d;
773
774
14.0k
  perm->value += *((int *)args);
775
776
14.0k
  return SEPOL_OK;
777
14.0k
}
778
779
int cil_resolve_classcommon(struct cil_tree_node *current, struct cil_db *db)
780
10.9k
{
781
10.9k
  struct cil_class *class = NULL;
782
10.9k
  struct cil_class *common = NULL;
783
10.9k
  struct cil_classcommon *clscom = current->data;
784
10.9k
  struct cil_symtab_datum *class_datum = NULL;
785
10.9k
  struct cil_symtab_datum *common_datum = NULL;
786
10.9k
  int rc = SEPOL_ERR;
787
788
10.9k
  rc = cil_resolve_name(current, clscom->class_str, CIL_SYM_CLASSES, db, &class_datum);
789
10.9k
  if (rc != SEPOL_OK) {
790
6.58k
    goto exit;
791
6.58k
  }
792
4.31k
  if (NODE(class_datum)->flavor != CIL_CLASS) {
793
2
    cil_log(CIL_ERR, "Class %s is not a kernel class and cannot be associated with common %s\n", clscom->class_str, clscom->common_str);
794
2
    rc = SEPOL_ERR;
795
2
    goto exit;
796
2
  }
797
798
4.31k
  rc = cil_resolve_name(current, clscom->common_str, CIL_SYM_COMMONS, db, &common_datum);
799
4.31k
  if (rc != SEPOL_OK) {
800
341
    goto exit;
801
341
  }
802
803
3.96k
  class = (struct cil_class *)class_datum;
804
3.96k
  common = (struct cil_class *)common_datum;
805
3.96k
  if (class->common != NULL) {
806
1
    cil_log(CIL_ERR, "class cannot be associated with more than one common\n");
807
1
    rc = SEPOL_ERR;
808
1
    goto exit;
809
1
  }
810
811
3.96k
  class->common = common;
812
813
3.96k
  clscom->class = class;
814
3.96k
  clscom->common = common;
815
816
3.96k
  cil_symtab_map(&class->perms, __class_update_perm_values, &common->num_perms);
817
818
3.96k
  class->num_perms += common->num_perms;
819
3.96k
  if (class->num_perms > CIL_PERMS_PER_CLASS) {
820
5
    cil_tree_log(current, CIL_ERR, "Too many permissions in class '%s' when including common permissions", class->datum.name);
821
5
    rc = SEPOL_ERR;
822
5
    goto exit;
823
5
  }
824
825
3.96k
  return SEPOL_OK;
826
827
6.93k
exit:
828
6.93k
  return rc;
829
3.96k
}
830
831
int cil_resolve_classmapping(struct cil_tree_node *current, struct cil_db *db)
832
72.5k
{
833
72.5k
  int rc = SEPOL_ERR;
834
72.5k
  struct cil_classmapping *mapping = current->data;
835
72.5k
  struct cil_class *map = NULL;
836
72.5k
  struct cil_perm *mp = NULL;
837
72.5k
  struct cil_symtab_datum *datum = NULL;
838
72.5k
  struct cil_list_item *curr;
839
840
72.5k
  rc = cil_resolve_name(current, mapping->map_class_str, CIL_SYM_CLASSES, db, &datum);
841
72.5k
  if (rc != SEPOL_OK) {
842
462
    goto exit;
843
462
  }
844
72.0k
  map = (struct cil_class*)datum;
845
72.0k
  mapping->map_class = map;
846
847
72.0k
  rc = cil_symtab_get_datum(&map->perms, mapping->map_perm_str, &datum);
848
72.0k
  if (rc != SEPOL_OK) {
849
219
    goto exit;
850
219
  }
851
852
71.8k
  mp = (struct cil_perm*)datum;
853
71.8k
  mapping->map_perm = mp;
854
855
71.8k
  rc = cil_resolve_classperms_list(current, mapping->classperms, db);
856
71.8k
  if (rc != SEPOL_OK) {
857
88
    goto exit;
858
88
  }
859
860
71.7k
  if (mp->classperms == NULL) {
861
5.55k
    cil_list_init(&mp->classperms, CIL_CLASSPERMS);
862
5.55k
  }
863
864
71.7k
  cil_list_for_each(curr, mapping->classperms) {
865
71.7k
    cil_list_append(mp->classperms, curr->flavor, curr->data);
866
71.7k
  }
867
868
71.7k
  return SEPOL_OK;
869
870
769
exit:
871
769
  return rc;
872
71.8k
}
873
874
int cil_resolve_userrole(struct cil_tree_node *current, struct cil_db *db)
875
42.0k
{
876
42.0k
  struct cil_userrole *userrole = current->data;
877
42.0k
  struct cil_symtab_datum *user_datum = NULL;
878
42.0k
  struct cil_symtab_datum *role_datum = NULL;
879
42.0k
  int rc = SEPOL_ERR;
880
881
42.0k
  rc = cil_resolve_name(current, userrole->user_str, CIL_SYM_USERS, db, &user_datum);
882
42.0k
  if (rc != SEPOL_OK) {
883
7.22k
    goto exit;
884
7.22k
  }
885
34.8k
  userrole->user = (struct cil_user*)user_datum;
886
887
34.8k
  rc = cil_resolve_name(current, userrole->role_str, CIL_SYM_ROLES, db, &role_datum);
888
34.8k
  if (rc != SEPOL_OK) {
889
198
    goto exit;
890
198
  }
891
34.6k
  userrole->role = role_datum;
892
893
34.6k
  return SEPOL_OK;
894
895
7.42k
exit:
896
7.42k
  return rc;
897
34.8k
}
898
899
int cil_resolve_userlevel(struct cil_tree_node *current, struct cil_db *db)
900
31.1k
{
901
31.1k
  struct cil_userlevel *usrlvl = current->data;
902
31.1k
  struct cil_symtab_datum *user_datum = NULL;
903
31.1k
  struct cil_symtab_datum *lvl_datum = NULL;
904
31.1k
  struct cil_user *user = NULL;
905
31.1k
  struct cil_tree_node *user_node = NULL;
906
31.1k
  int rc = SEPOL_ERR;
907
908
31.1k
  rc = cil_resolve_name(current, usrlvl->user_str, CIL_SYM_USERS, db, &user_datum);
909
31.1k
  if (rc != SEPOL_OK) {
910
780
    goto exit;
911
780
  }
912
913
30.3k
  user_node = NODE(user_datum);
914
915
30.3k
  if (user_node->flavor != CIL_USER) {
916
1
    cil_log(CIL_ERR, "Userlevel must be a user\n");
917
1
    rc = SEPOL_ERR;
918
1
    goto exit;
919
1
  }
920
921
30.3k
  user = (struct cil_user*)user_datum;
922
30.3k
  usrlvl->user = user;
923
924
30.3k
  if (usrlvl->level_str != NULL) {
925
22.4k
    rc = cil_resolve_name(current, usrlvl->level_str, CIL_SYM_LEVELS, db, &lvl_datum);
926
22.4k
    if (rc != SEPOL_OK) {
927
185
      goto exit;
928
185
    }
929
22.2k
    usrlvl->level = (struct cil_level*)lvl_datum;
930
22.2k
    user->dftlevel = usrlvl->level;
931
932
    /* This could still be an anonymous level even if level_str is set, if level_str is a param_str*/
933
22.2k
    if (user->dftlevel->datum.name == NULL) {
934
892
      rc = cil_resolve_level(current, user->dftlevel, db);
935
892
      if (rc != SEPOL_OK) {
936
70
        goto exit;
937
70
      }
938
892
    }
939
22.2k
  } else if (usrlvl->level != NULL) {
940
7.94k
    rc = cil_resolve_level(current, usrlvl->level, db);
941
7.94k
    if (rc != SEPOL_OK) {
942
392
      goto exit;
943
392
    }
944
7.55k
    user->dftlevel = usrlvl->level;
945
7.55k
  }
946
947
29.7k
  return SEPOL_OK;
948
949
1.42k
exit:
950
1.42k
  return rc;
951
30.3k
}
952
953
int cil_resolve_userrange(struct cil_tree_node *current, struct cil_db *db)
954
447k
{
955
447k
  struct cil_userrange *userrange = current->data;
956
447k
  struct cil_symtab_datum *user_datum = NULL;
957
447k
  struct cil_symtab_datum *range_datum = NULL;
958
447k
  struct cil_user *user = NULL;
959
447k
  struct cil_tree_node *user_node = NULL;
960
447k
  int rc = SEPOL_ERR;
961
962
447k
  rc = cil_resolve_name(current, userrange->user_str, CIL_SYM_USERS, db, &user_datum);
963
447k
  if (rc != SEPOL_OK) {
964
1.27k
    goto exit;
965
1.27k
  }
966
967
446k
  user_node = NODE(user_datum);
968
969
446k
  if (user_node->flavor != CIL_USER) {
970
1
    cil_log(CIL_ERR, "Userrange must be a user: %s\n", user_datum->fqn);
971
1
    rc = SEPOL_ERR;
972
1
    goto exit;
973
1
  }
974
975
446k
  user = (struct cil_user*)user_datum;
976
446k
  userrange->user = user;
977
978
446k
  if (userrange->range_str != NULL) {
979
17.4k
    rc = cil_resolve_name(current, userrange->range_str, CIL_SYM_LEVELRANGES, db, &range_datum);
980
17.4k
    if (rc != SEPOL_OK) {
981
224
      goto exit;
982
224
    }
983
17.2k
    userrange->range = (struct cil_levelrange*)range_datum;
984
17.2k
    user->range = userrange->range;
985
986
    /* This could still be an anonymous levelrange even if levelrange_str is set, if levelrange_str is a param_str*/
987
17.2k
    if (user->range->datum.name == NULL) {
988
565
      rc = cil_resolve_levelrange(current, user->range, db);
989
565
      if (rc != SEPOL_OK) {
990
378
        goto exit;
991
378
      }
992
565
    }
993
429k
  } else if (userrange->range != NULL) {
994
429k
    rc = cil_resolve_levelrange(current, userrange->range, db);
995
429k
    if (rc != SEPOL_OK) {
996
880
      goto exit;
997
880
    }
998
428k
    user->range = userrange->range;
999
428k
  }
1000
1001
445k
  return SEPOL_OK;
1002
1003
2.75k
exit:
1004
2.75k
  return rc;
1005
446k
}
1006
1007
int cil_resolve_userprefix(struct cil_tree_node *current, struct cil_db *db)
1008
2.29k
{
1009
2.29k
  struct cil_userprefix *userprefix = current->data;
1010
2.29k
  struct cil_symtab_datum *user_datum = NULL;
1011
2.29k
  struct cil_tree_node *user_node = NULL;
1012
2.29k
  int rc = SEPOL_ERR;
1013
1014
2.29k
  rc = cil_resolve_name(current, userprefix->user_str, CIL_SYM_USERS, db, &user_datum);
1015
2.29k
  if (rc != SEPOL_OK) {
1016
246
    goto exit;
1017
246
  }
1018
1019
2.05k
  user_node = NODE(user_datum);
1020
1021
2.05k
  if (user_node->flavor != CIL_USER) {
1022
0
    cil_log(CIL_ERR, "Userprefix must be a user: %s\n", user_datum->fqn);
1023
0
    rc = SEPOL_ERR;
1024
0
    goto exit;
1025
0
  }
1026
1027
2.05k
  userprefix->user = (struct cil_user*)user_datum;
1028
1029
2.29k
exit:
1030
2.29k
  return rc;
1031
2.05k
}
1032
1033
int cil_resolve_selinuxuser(struct cil_tree_node *current, struct cil_db *db)
1034
3.85k
{
1035
3.85k
  struct cil_selinuxuser *selinuxuser = current->data;
1036
3.85k
  struct cil_symtab_datum *user_datum = NULL;
1037
3.85k
  struct cil_symtab_datum *lvlrange_datum = NULL;
1038
3.85k
  struct cil_tree_node *user_node = NULL;
1039
3.85k
  int rc = SEPOL_ERR;
1040
1041
3.85k
  rc = cil_resolve_name(current, selinuxuser->user_str, CIL_SYM_USERS, db, &user_datum);
1042
3.85k
  if (rc != SEPOL_OK) {
1043
955
    goto exit;
1044
955
  }
1045
1046
2.89k
  user_node = NODE(user_datum);
1047
1048
2.89k
  if (user_node->flavor != CIL_USER) {
1049
0
    cil_log(CIL_ERR, "Selinuxuser must be a user: %s\n", user_datum->fqn);
1050
0
    rc = SEPOL_ERR;
1051
0
    goto exit;
1052
0
  }
1053
1054
2.89k
  selinuxuser->user = (struct cil_user*)user_datum;
1055
1056
2.89k
  if (selinuxuser->range_str != NULL) {
1057
941
    rc = cil_resolve_name(current, selinuxuser->range_str, CIL_SYM_LEVELRANGES, db, &lvlrange_datum);
1058
941
    if (rc != SEPOL_OK) {
1059
307
      goto exit;
1060
307
    }
1061
634
    selinuxuser->range = (struct cil_levelrange*)lvlrange_datum;
1062
1063
    /* This could still be an anonymous levelrange even if range_str is set, if range_str is a param_str*/
1064
634
    if (selinuxuser->range->datum.name == NULL) {
1065
0
      rc = cil_resolve_levelrange(current, selinuxuser->range, db);
1066
0
      if (rc != SEPOL_OK) {
1067
0
        goto exit;
1068
0
      }
1069
0
    }
1070
1.95k
  } else if (selinuxuser->range != NULL) {
1071
1.95k
    rc = cil_resolve_levelrange(current, selinuxuser->range, db);
1072
1.95k
    if (rc != SEPOL_OK) {
1073
211
      goto exit;
1074
211
    }
1075
1.95k
  }
1076
1077
2.37k
  rc = SEPOL_OK;
1078
3.85k
exit:
1079
3.85k
  return rc;
1080
2.37k
}
1081
1082
int cil_resolve_roletype(struct cil_tree_node *current, struct cil_db *db)
1083
193k
{
1084
193k
  struct cil_roletype *roletype = current->data;
1085
193k
  struct cil_symtab_datum *role_datum = NULL;
1086
193k
  struct cil_symtab_datum *type_datum = NULL;
1087
193k
  int rc = SEPOL_ERR;
1088
1089
193k
  rc = cil_resolve_name(current, roletype->role_str, CIL_SYM_ROLES, db, &role_datum);
1090
193k
  if (rc != SEPOL_OK) {
1091
458
    goto exit;
1092
458
  }
1093
192k
  roletype->role = (struct cil_role*)role_datum;
1094
1095
192k
  rc = cil_resolve_name(current, roletype->type_str, CIL_SYM_TYPES, db, &type_datum);
1096
192k
  if (rc != SEPOL_OK) {
1097
304
    goto exit;
1098
304
  }
1099
192k
  roletype->type = (struct cil_type*)type_datum;
1100
1101
192k
  return SEPOL_OK;
1102
1103
762
exit:
1104
762
  return rc;
1105
192k
}
1106
1107
int cil_resolve_roletransition(struct cil_tree_node *current, struct cil_db *db)
1108
27.4k
{
1109
27.4k
  struct cil_roletransition *roletrans = current->data;
1110
27.4k
  struct cil_symtab_datum *src_datum = NULL;
1111
27.4k
  struct cil_symtab_datum *tgt_datum = NULL;
1112
27.4k
  struct cil_symtab_datum *obj_datum = NULL;
1113
27.4k
  struct cil_symtab_datum *result_datum = NULL;
1114
27.4k
  struct cil_tree_node *node = NULL;
1115
27.4k
  int rc = SEPOL_ERR;
1116
1117
27.4k
  rc = cil_resolve_name(current, roletrans->src_str, CIL_SYM_ROLES, db, &src_datum);
1118
27.4k
  if (rc != SEPOL_OK) {
1119
3.17k
    goto exit;
1120
3.17k
  }
1121
24.2k
  roletrans->src = (struct cil_role*)src_datum;
1122
1123
24.2k
  rc = cil_resolve_name(current, roletrans->tgt_str, CIL_SYM_TYPES, db, &tgt_datum);
1124
24.2k
  if (rc != SEPOL_OK) {
1125
6.20k
    goto exit;
1126
6.20k
  }
1127
18.0k
  roletrans->tgt = tgt_datum;
1128
1129
18.0k
  rc = cil_resolve_name(current, roletrans->obj_str, CIL_SYM_CLASSES, db, &obj_datum);
1130
18.0k
  if (rc != SEPOL_OK) {
1131
410
    goto exit;
1132
410
  }
1133
17.6k
  roletrans->obj = (struct cil_class*)obj_datum;
1134
1135
17.6k
  rc = cil_resolve_name(current, roletrans->result_str, CIL_SYM_ROLES, db, &result_datum);
1136
17.6k
  if (rc != SEPOL_OK) {
1137
1.08k
    goto exit;
1138
1.08k
  }
1139
16.5k
  node = NODE(result_datum);
1140
16.5k
  if (node->flavor != CIL_ROLE) {
1141
1
    rc = SEPOL_ERR;
1142
1
    cil_log(CIL_ERR, "roletransition must result in a role, but %s is a %s\n", roletrans->result_str, cil_node_to_string(node));
1143
1
    goto exit;
1144
1
  }
1145
16.5k
  roletrans->result = (struct cil_role*)result_datum;
1146
1147
16.5k
  return SEPOL_OK;
1148
1149
10.8k
exit:
1150
10.8k
  return rc;
1151
16.5k
}
1152
1153
int cil_resolve_roleallow(struct cil_tree_node *current, struct cil_db *db)
1154
8.06k
{
1155
8.06k
  struct cil_roleallow *roleallow = current->data;
1156
8.06k
  struct cil_symtab_datum *src_datum = NULL;
1157
8.06k
  struct cil_symtab_datum *tgt_datum = NULL;
1158
8.06k
  int rc = SEPOL_ERR;
1159
1160
8.06k
  rc = cil_resolve_name(current, roleallow->src_str, CIL_SYM_ROLES, db, &src_datum);
1161
8.06k
  if (rc != SEPOL_OK) {
1162
534
    goto exit;
1163
534
  }
1164
7.53k
  roleallow->src = (struct cil_role*)src_datum;
1165
1166
7.53k
  rc = cil_resolve_name(current, roleallow->tgt_str, CIL_SYM_ROLES, db, &tgt_datum);
1167
7.53k
  if (rc != SEPOL_OK) {
1168
368
    goto exit;
1169
368
  }
1170
7.16k
  roleallow->tgt = (struct cil_role*)tgt_datum;
1171
1172
7.16k
  return SEPOL_OK;
1173
1174
902
exit:
1175
902
  return rc;
1176
7.53k
}
1177
1178
int cil_resolve_roleattributeset(struct cil_tree_node *current, struct cil_db *db)
1179
11.8k
{
1180
11.8k
  int rc = SEPOL_ERR;
1181
11.8k
  struct cil_roleattributeset *attrroles = current->data;
1182
11.8k
  struct cil_symtab_datum *attr_datum = NULL;
1183
11.8k
  struct cil_tree_node *attr_node = NULL;
1184
11.8k
  struct cil_roleattribute *attr = NULL;
1185
1186
11.8k
  rc = cil_resolve_name(current, attrroles->attr_str, CIL_SYM_ROLES, db, &attr_datum);
1187
11.8k
  if (rc != SEPOL_OK) {
1188
1.48k
    goto exit;
1189
1.48k
  }
1190
10.3k
  attr_node = NODE(attr_datum);
1191
1192
10.3k
  if (attr_node->flavor != CIL_ROLEATTRIBUTE) {
1193
1
    rc = SEPOL_ERR;
1194
1
    cil_log(CIL_ERR, "Attribute role not an attribute\n");
1195
1
    goto exit;
1196
1
  }
1197
10.3k
  attr = (struct cil_roleattribute*)attr_datum;
1198
1199
10.3k
  rc = cil_resolve_expr(CIL_ROLEATTRIBUTESET, attrroles->str_expr, &attrroles->datum_expr, current, db);
1200
10.3k
  if (rc != SEPOL_OK) {
1201
378
    goto exit;
1202
378
  }
1203
1204
10.0k
  if (attr->expr_list == NULL) {
1205
6.89k
    cil_list_init(&attr->expr_list, CIL_ROLEATTRIBUTE);
1206
6.89k
  }
1207
1208
10.0k
  cil_list_append(attr->expr_list, CIL_LIST, attrroles->datum_expr);
1209
1210
10.0k
  return SEPOL_OK;
1211
1212
1.86k
exit:
1213
1.86k
  return rc;
1214
10.3k
}
1215
1216
static struct cil_list_item *__cil_ordered_item_insert(struct cil_list *old, struct cil_list_item *curr, struct cil_list_item *item)
1217
62.4k
{
1218
62.4k
  if (item->flavor == CIL_SID) {
1219
12.0k
    struct cil_sid *sid = item->data;
1220
12.0k
    if (sid->ordered == CIL_TRUE) {
1221
249
      cil_log(CIL_ERR, "SID %s has already been merged into the ordered list\n", sid->datum.name);
1222
249
      return NULL;
1223
249
    }
1224
11.8k
    sid->ordered = CIL_TRUE;
1225
50.4k
  } else if (item->flavor == CIL_CLASS) {
1226
30.6k
    struct cil_class *class = item->data;
1227
30.6k
    if (class->ordered == CIL_TRUE) {
1228
1.75k
      cil_log(CIL_ERR, "Class %s has already been merged into the ordered list\n", class->datum.name);
1229
1.75k
      return NULL;
1230
1.75k
    }
1231
28.8k
    class->ordered = CIL_TRUE;
1232
28.8k
  } else if (item->flavor == CIL_CAT) {
1233
11.1k
    struct cil_cat *cat = item->data;
1234
11.1k
    if (cat->ordered == CIL_TRUE) {
1235
1.40k
      cil_log(CIL_ERR, "Category %s has already been merged into the ordered list\n", cat->datum.name);
1236
1.40k
      return NULL;
1237
1.40k
    }
1238
9.72k
    cat->ordered = CIL_TRUE;
1239
9.72k
  } else if (item->flavor == CIL_SENS) {
1240
8.64k
    struct cil_sens *sens = item->data;
1241
8.64k
    if (sens->ordered == CIL_TRUE) {
1242
732
      cil_log(CIL_ERR, "Sensitivity %s has already been merged into the ordered list\n", sens->datum.name);
1243
732
      return NULL;
1244
732
    }
1245
7.91k
    sens->ordered = CIL_TRUE;
1246
7.91k
  }
1247
1248
58.3k
  return cil_list_insert(old, curr, item->flavor, item->data);
1249
62.4k
}
1250
1251
static int __cil_ordered_list_insert(struct cil_list *old, struct cil_list_item *ocurr, struct cil_list_item *nstart, struct cil_list_item *nstop)
1252
29.0k
{
1253
29.0k
  struct cil_list_item *ncurr = NULL;
1254
1255
79.5k
  for (ncurr = nstart; ncurr != nstop; ncurr = ncurr->next) {
1256
54.6k
    ocurr = __cil_ordered_item_insert(old, ocurr, ncurr);
1257
54.6k
    if (ocurr == NULL) {
1258
4.14k
      return SEPOL_ERR;
1259
4.14k
    }
1260
54.6k
  }
1261
24.9k
  return SEPOL_OK;
1262
29.0k
}
1263
1264
static void __cil_ordered_find_next_match(struct cil_list_item **i, struct cil_list_item **j, struct cil_list_item **p)
1265
103k
{
1266
103k
  struct cil_list_item *pstart = *p;
1267
103k
  struct cil_list_item *jstart = *j;
1268
1269
109k
  while (*i) {
1270
106k
    *p = pstart;
1271
106k
    *j = jstart;
1272
311k
    while (*j) {
1273
305k
      if ((*i)->data == (*j)->data) {
1274
101k
        return;
1275
101k
      }
1276
204k
      *p = *j;
1277
204k
      *j = (*j)->next;
1278
204k
    }
1279
5.81k
    *i = (*i)->next;
1280
5.81k
  }
1281
103k
}
1282
1283
static int __cil_ordered_lists_merge(struct cil_list *old, struct cil_list *new)
1284
75.7k
{
1285
75.7k
  struct cil_list_item *ofirst = old->head;
1286
75.7k
  struct cil_list_item *ocurr = NULL;
1287
75.7k
  struct cil_list_item *oprev = NULL;
1288
75.7k
  struct cil_list_item *nfirst = new->head;
1289
75.7k
  struct cil_list_item *ncurr = NULL;
1290
75.7k
  int rc = SEPOL_ERR;
1291
1292
75.7k
  if (nfirst == NULL) {
1293
0
    return SEPOL_OK;
1294
0
  }
1295
1296
75.7k
  if (ofirst == NULL) {
1297
    /* First list added */
1298
19.9k
    return __cil_ordered_list_insert(old, NULL, nfirst, NULL);
1299
19.9k
  }
1300
1301
55.8k
  ncurr = nfirst;
1302
55.8k
  ocurr = ofirst;
1303
55.8k
  oprev = NULL;
1304
155k
  while (ncurr && ocurr) {
1305
103k
    __cil_ordered_find_next_match(&ncurr, &ocurr, &oprev);
1306
103k
    if (!ncurr || !ocurr) {
1307
2.19k
      break;
1308
2.19k
    }
1309
101k
    if (ncurr != nfirst) {
1310
2.23k
      rc = __cil_ordered_list_insert(old, oprev, nfirst, ncurr);
1311
2.23k
      if (rc != SEPOL_OK) {
1312
1.41k
        return rc;
1313
1.41k
      }
1314
2.23k
    }
1315
99.6k
    ncurr = ncurr->next;
1316
99.6k
    nfirst = ncurr;
1317
99.6k
    oprev = ocurr;
1318
99.6k
    ocurr = ocurr->next;
1319
99.6k
  }
1320
1321
54.3k
  if (!ncurr) {
1322
47.4k
    if (!nfirst) {
1323
      /* Done */
1324
45.2k
      return SEPOL_OK;
1325
45.2k
    } else {
1326
      /* Can't merge yet */
1327
2.19k
      return SEPOL_ERR;
1328
2.19k
    }
1329
47.4k
  }
1330
1331
6.90k
  if (ncurr && !ocurr) { /* some remaining */
1332
6.90k
    rc = __cil_ordered_list_insert(old, oprev, ncurr, NULL);
1333
6.90k
    if (rc != SEPOL_OK) {
1334
2.63k
      return rc;
1335
2.63k
    }
1336
6.90k
  }
1337
1338
4.27k
  return SEPOL_OK;
1339
6.90k
}
1340
1341
static int insert_unordered(struct cil_list *merged, struct cil_list *unordered_list)
1342
13.5k
{
1343
13.5k
  struct cil_tree_node *node;
1344
13.5k
  struct cil_ordered *unordered;
1345
13.5k
  struct cil_list_item *curr = NULL;
1346
13.5k
  struct cil_list_item *item = NULL;
1347
13.5k
  struct cil_list_item *ret = NULL;
1348
13.5k
  int rc = SEPOL_ERR;
1349
1350
13.5k
  cil_list_for_each(curr, unordered_list) {
1351
10.7k
    node = curr->data;
1352
10.7k
    unordered = node->data;
1353
33.7k
    cil_list_for_each(item, unordered->datums) {
1354
33.7k
      if (cil_list_contains(merged, item->data)) {
1355
        /* item was declared in an ordered statement, which supersedes
1356
         * all unordered statements */
1357
25.9k
        if (item->flavor == CIL_CLASS) {
1358
25.9k
          cil_log(CIL_WARN, "Ignoring '%s' as it has already been declared in classorder.\n", ((struct cil_class*)(item->data))->datum.name);
1359
25.9k
        }
1360
25.9k
        continue;
1361
25.9k
      }
1362
1363
7.86k
      ret = __cil_ordered_item_insert(merged, merged->tail, item);
1364
7.86k
      if (ret == NULL) {
1365
0
        rc = SEPOL_ERR;
1366
0
        goto exit;
1367
0
      }
1368
7.86k
    }
1369
10.7k
  }
1370
1371
13.5k
  rc = SEPOL_OK;
1372
1373
13.5k
exit:
1374
13.5k
  return rc;
1375
13.5k
}
1376
1377
static struct cil_list *__cil_ordered_lists_merge_all(struct cil_list **ordered_lists, struct cil_list **unordered_lists)
1378
54.2k
{
1379
54.2k
  struct cil_list *composite = NULL;
1380
54.2k
  struct cil_tree_node *node;
1381
54.2k
  struct cil_ordered *ordered;
1382
54.2k
  struct cil_list_item *curr = NULL;
1383
54.2k
  int changed = CIL_TRUE;
1384
54.2k
  int waiting = 1;
1385
54.2k
  int rc = SEPOL_ERR;
1386
1387
54.2k
  cil_list_init(&composite, (*ordered_lists)->flavor);
1388
1389
108k
  while (waiting && changed == CIL_TRUE) {
1390
54.3k
    changed = CIL_FALSE;
1391
54.3k
    waiting = 0;
1392
84.0k
    cil_list_for_each(curr, *ordered_lists) {
1393
84.0k
      node = curr->data;
1394
84.0k
      ordered = node->data;
1395
84.0k
      if (ordered->merged == CIL_FALSE) {
1396
75.7k
        rc = __cil_ordered_lists_merge(composite, ordered->datums);
1397
75.7k
        if (rc != SEPOL_OK) {
1398
          /* Can't merge yet */
1399
6.33k
          waiting++;
1400
69.3k
        } else {
1401
69.3k
          ordered->merged = CIL_TRUE;
1402
69.3k
          changed = CIL_TRUE;
1403
69.3k
        }
1404
75.7k
      }
1405
84.0k
    }
1406
54.3k
    if (waiting > 0 && changed == CIL_FALSE) {
1407
6.32k
      cil_list_for_each(curr, *ordered_lists) {
1408
6.32k
        node = curr->data;
1409
6.32k
        ordered = node->data;
1410
6.32k
        if (ordered->merged == CIL_FALSE) {
1411
2.96k
          cil_tree_log(node, CIL_ERR, "Unable to merge ordered list");
1412
2.96k
        }
1413
6.32k
      }
1414
149
      goto exit;
1415
149
    }
1416
54.3k
  }
1417
1418
54.0k
  rc = cil_verify_completed_ordered_list(composite, *ordered_lists);
1419
54.0k
  if (rc != SEPOL_OK) {
1420
52
    cil_log(CIL_ERR, "Unable to validate ordering\n");
1421
52
    goto exit;
1422
52
  }
1423
1424
54.0k
  if (unordered_lists != NULL) {
1425
13.5k
    rc = insert_unordered(composite, *unordered_lists);
1426
13.5k
    if (rc != SEPOL_OK) {
1427
0
      goto exit;
1428
0
    }
1429
13.5k
  }
1430
1431
54.0k
  return composite;
1432
1433
201
exit:
1434
201
  cil_list_destroy(&composite, CIL_FALSE);
1435
201
  return NULL;
1436
54.0k
}
1437
1438
int cil_resolve_classorder(struct cil_tree_node *current, struct cil_db *db, struct cil_list *classorder_list, struct cil_list *unordered_classorder_list)
1439
43.7k
{
1440
43.7k
  struct cil_ordered *ordered = current->data;
1441
43.7k
  struct cil_list_item *curr = NULL;
1442
43.7k
  struct cil_symtab_datum *datum = NULL;
1443
43.7k
  int rc = SEPOL_ERR;
1444
43.7k
  int unordered = CIL_FALSE;
1445
1446
43.7k
  cil_list_init(&ordered->datums, CIL_DATUM);
1447
1448
132k
  cil_list_for_each(curr, ordered->strs) {
1449
132k
    if (curr->data == CIL_KEY_UNORDERED) {
1450
10.8k
      unordered = CIL_TRUE;
1451
10.8k
      continue;
1452
10.8k
    }
1453
1454
121k
    rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_CLASSES, db, &datum);
1455
121k
    if (rc != SEPOL_OK) {
1456
44
      cil_log(CIL_ERR, "Failed to resolve class %s in classorder\n", (char *)curr->data);
1457
44
      rc = SEPOL_ERR;
1458
44
      goto exit;
1459
44
    }
1460
121k
    if (FLAVOR(datum) != CIL_CLASS) {
1461
1
      cil_log(CIL_ERR, "%s is not a class. Only classes are allowed in classorder statements\n", datum->name);
1462
1
      rc = SEPOL_ERR;
1463
1
      goto exit;
1464
1
    }
1465
121k
    cil_list_append(ordered->datums, CIL_CLASS, datum);
1466
121k
  }
1467
1468
43.6k
  if (unordered) {
1469
10.8k
    cil_list_append(unordered_classorder_list, CIL_CLASSORDER, current);
1470
32.8k
  } else {
1471
32.8k
    cil_list_append(classorder_list, CIL_CLASSORDER, current);
1472
32.8k
  }
1473
1474
43.6k
  return SEPOL_OK;
1475
1476
45
exit:
1477
45
  cil_list_destroy(&ordered->datums, CIL_FALSE);
1478
45
  return rc;
1479
43.7k
}
1480
1481
int cil_resolve_sidorder(struct cil_tree_node *current, struct cil_db *db, struct cil_list *sidorder_list)
1482
23.2k
{
1483
23.2k
  struct cil_ordered *ordered = current->data;
1484
23.2k
  struct cil_list_item *curr = NULL;
1485
23.2k
  struct cil_symtab_datum *datum = NULL;
1486
23.2k
  int rc = SEPOL_ERR;
1487
1488
23.2k
  cil_list_init(&ordered->datums, CIL_DATUM);
1489
1490
27.7k
  cil_list_for_each(curr, ordered->strs) {
1491
27.7k
    rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_SIDS, db, &datum);
1492
27.7k
    if (rc != SEPOL_OK) {
1493
487
      cil_log(CIL_ERR, "Failed to resolve sid %s in sidorder\n", (char *)curr->data);
1494
487
      goto exit;
1495
487
    }
1496
27.2k
    if (FLAVOR(datum) != CIL_SID) {
1497
0
      cil_log(CIL_ERR, "%s is not a sid. Only sids are allowed in sidorder statements\n", datum->name);
1498
0
      rc = SEPOL_ERR;
1499
0
      goto exit;
1500
0
    }
1501
1502
27.2k
    cil_list_append(ordered->datums, CIL_SID, datum);
1503
27.2k
  }
1504
1505
22.7k
  cil_list_append(sidorder_list, CIL_SIDORDER, current);
1506
1507
22.7k
  return SEPOL_OK;
1508
1509
487
exit:
1510
487
  cil_list_destroy(&ordered->datums, CIL_FALSE);
1511
487
  return rc;
1512
23.2k
}
1513
1514
static void cil_set_cat_values(struct cil_list *ordered_cats, struct cil_db *db)
1515
13.4k
{
1516
13.4k
  struct cil_list_item *curr;
1517
13.4k
  int v = 0;
1518
1519
13.4k
  cil_list_for_each(curr, ordered_cats) {
1520
9.50k
    struct cil_cat *cat = curr->data;
1521
9.50k
    cat->value = v;
1522
9.50k
    v++;
1523
9.50k
  }
1524
1525
13.4k
  db->num_cats = v;
1526
13.4k
}
1527
1528
int cil_resolve_catorder(struct cil_tree_node *current, struct cil_db *db, struct cil_list *catorder_list)
1529
16.4k
{
1530
16.4k
  struct cil_ordered *ordered = current->data;
1531
16.4k
  struct cil_list_item *curr = NULL;
1532
16.4k
  struct cil_symtab_datum *datum;
1533
16.4k
  int rc = SEPOL_ERR;
1534
1535
16.4k
  cil_list_init(&ordered->datums, CIL_DATUM);
1536
1537
32.9k
  cil_list_for_each(curr, ordered->strs) {
1538
32.9k
    rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_CATS, db, &datum);
1539
32.9k
    if (rc != SEPOL_OK) {
1540
4.31k
      cil_log(CIL_ERR, "Failed to resolve category %s in categoryorder\n", (char *)curr->data);
1541
4.31k
      goto exit;
1542
4.31k
    }
1543
28.6k
    if (FLAVOR(datum) != CIL_CAT) {
1544
1
      cil_log(CIL_ERR, "%s is not a category. Only categories are allowed in categoryorder statements\n", datum->name);
1545
1
      rc = SEPOL_ERR;
1546
1
      goto exit;
1547
1
    }
1548
1549
28.6k
    cil_list_append(ordered->datums, CIL_CAT, datum);
1550
28.6k
  }
1551
1552
12.1k
  cil_list_append(catorder_list, CIL_CATORDER, current);
1553
1554
12.1k
  return SEPOL_OK;
1555
1556
4.31k
exit:
1557
4.31k
  cil_list_destroy(&ordered->datums, CIL_FALSE);
1558
4.31k
  return rc;
1559
16.4k
}
1560
1561
int cil_resolve_sensitivityorder(struct cil_tree_node *current, struct cil_db *db, struct cil_list *sensitivityorder_list)
1562
5.24k
{
1563
5.24k
  struct cil_ordered *ordered = current->data;
1564
5.24k
  struct cil_list_item *curr = NULL;
1565
5.24k
  struct cil_symtab_datum *datum = NULL;
1566
5.24k
  int rc = SEPOL_ERR;
1567
1568
5.24k
  cil_list_init(&ordered->datums, CIL_DATUM);
1569
1570
11.3k
  cil_list_for_each(curr, ordered->strs) {
1571
11.3k
    rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_SENS, db, &datum);
1572
11.3k
    if (rc != SEPOL_OK) {
1573
337
      cil_log(CIL_ERR, "Failed to resolve sensitivity %s in sensitivityorder\n", (char *)curr->data);
1574
337
      goto exit;
1575
337
    }
1576
11.0k
    if (FLAVOR(datum) != CIL_SENS) {
1577
0
      cil_log(CIL_ERR, "%s is not a sensitivity. Only sensitivities are allowed in sensitivityorder statements\n", datum->name);
1578
0
      rc = SEPOL_ERR;
1579
0
      goto exit;
1580
0
    }
1581
11.0k
    cil_list_append(ordered->datums, CIL_SENS, datum);
1582
11.0k
  }
1583
1584
4.90k
  cil_list_append(sensitivityorder_list, CIL_SENSITIVITYORDER, current);
1585
1586
4.90k
  return SEPOL_OK;
1587
1588
337
exit:
1589
337
  cil_list_destroy(&ordered->datums, CIL_FALSE);
1590
337
  return rc;
1591
5.24k
}
1592
1593
static int cil_resolve_cats(struct cil_tree_node *current, struct cil_cats *cats, struct cil_db *db)
1594
638k
{
1595
638k
  int rc = SEPOL_ERR;
1596
1597
638k
  rc = cil_resolve_expr(CIL_CATSET, cats->str_expr, &cats->datum_expr, current, db);
1598
638k
  if (rc != SEPOL_OK) {
1599
3.03k
    goto exit;
1600
3.03k
  }
1601
  
1602
635k
  return SEPOL_OK;
1603
1604
3.03k
exit:
1605
3.03k
  return rc;
1606
638k
}
1607
1608
1609
int cil_resolve_catset(struct cil_tree_node *current, struct cil_catset *catset, struct cil_db *db)
1610
5.57k
{
1611
5.57k
  return cil_resolve_cats(current, catset->cats, db);
1612
5.57k
}
1613
1614
int cil_resolve_senscat(struct cil_tree_node *current, struct cil_db *db)
1615
30.3k
{
1616
30.3k
  int rc = SEPOL_ERR;
1617
30.3k
  struct cil_senscat *senscat = current->data;
1618
30.3k
  struct cil_symtab_datum *sens_datum;
1619
30.3k
  struct cil_sens *sens = NULL;
1620
1621
30.3k
  rc = cil_resolve_name(current, (char*)senscat->sens_str, CIL_SYM_SENS, db, &sens_datum);
1622
30.3k
  if (rc != SEPOL_OK) {
1623
397
    cil_log(CIL_ERR, "Failed to find sensitivity\n");
1624
397
    goto exit;
1625
397
  }
1626
1627
29.9k
  rc = cil_resolve_cats(current, senscat->cats, db);
1628
29.9k
  if (rc != SEPOL_OK) {
1629
531
    goto exit;
1630
531
  }
1631
1632
29.4k
  sens = (struct cil_sens *)sens_datum;
1633
1634
29.4k
  if (sens->cats_list == NULL ) {
1635
5.10k
    cil_list_init(&sens->cats_list, CIL_CAT);
1636
5.10k
  }
1637
1638
29.4k
  cil_list_append(sens->cats_list, CIL_CAT, senscat->cats);
1639
1640
29.4k
  return SEPOL_OK;
1641
1642
928
exit:
1643
928
  return rc;
1644
29.9k
}
1645
1646
int cil_resolve_level(struct cil_tree_node *current, struct cil_level *level, struct cil_db *db)
1647
5.68M
{
1648
5.68M
  struct cil_symtab_datum *sens_datum = NULL;
1649
5.68M
  int rc = SEPOL_ERR;
1650
1651
5.68M
  if (level->sens) {
1652
429
    return SEPOL_OK;
1653
429
  }
1654
1655
5.67M
  rc = cil_resolve_name(current, (char*)level->sens_str, CIL_SYM_SENS, db, &sens_datum);
1656
5.67M
  if (rc != SEPOL_OK) {
1657
3.94k
    cil_log(CIL_ERR, "Failed to find sensitivity\n");
1658
3.94k
    goto exit;
1659
3.94k
  }
1660
1661
5.67M
  level->sens = (struct cil_sens *)sens_datum;
1662
1663
5.67M
  if (level->cats != NULL) {
1664
603k
    rc = cil_resolve_cats(current, level->cats, db);
1665
603k
    if (rc != SEPOL_OK) {
1666
2.23k
      goto exit;
1667
2.23k
    }
1668
603k
  }
1669
1670
5.67M
  return SEPOL_OK;
1671
1672
6.17k
exit:
1673
6.17k
  return rc;
1674
5.67M
}
1675
1676
int cil_resolve_levelrange(struct cil_tree_node *current, struct cil_levelrange *lvlrange, struct cil_db *db)
1677
2.84M
{
1678
2.84M
  struct cil_symtab_datum *low_datum = NULL;
1679
2.84M
  struct cil_symtab_datum *high_datum = NULL;
1680
2.84M
  int rc = SEPOL_ERR;
1681
1682
2.84M
  if (lvlrange->low_str != NULL) {
1683
15.4k
    rc = cil_resolve_name(current, lvlrange->low_str, CIL_SYM_LEVELS, db, &low_datum);
1684
15.4k
    if (rc != SEPOL_OK) {
1685
456
      goto exit;
1686
456
    }
1687
14.9k
    lvlrange->low = (struct cil_level*)low_datum;
1688
1689
    /* This could still be an anonymous level even if low_str is set, if low_str is a param_str */
1690
14.9k
    if (lvlrange->low->datum.name == NULL) {
1691
0
      rc = cil_resolve_level(current, lvlrange->low, db);
1692
0
      if (rc != SEPOL_OK) {
1693
0
        goto exit;
1694
0
      }
1695
0
    }
1696
2.83M
  } else if (lvlrange->low != NULL) {
1697
2.83M
    rc = cil_resolve_level(current, lvlrange->low, db);
1698
2.83M
    if (rc != SEPOL_OK) {
1699
2.90k
      goto exit;
1700
2.90k
    }
1701
2.83M
  }
1702
1703
2.84M
  if (lvlrange->high_str != NULL) {
1704
13.7k
    rc = cil_resolve_name(current, lvlrange->high_str, CIL_SYM_LEVELS, db, &high_datum);
1705
13.7k
    if (rc != SEPOL_OK) {
1706
349
      goto exit;
1707
349
    }
1708
13.4k
    lvlrange->high = (struct cil_level*)high_datum;
1709
1710
    /* This could still be an anonymous level even if high_str is set, if high_str is a param_str */
1711
13.4k
    if (lvlrange->high->datum.name == NULL) {
1712
0
      rc = cil_resolve_level(current, lvlrange->high, db);
1713
0
      if (rc != SEPOL_OK) {
1714
0
        goto exit;
1715
0
      }
1716
0
    }
1717
2.82M
  } else if (lvlrange->high != NULL) {
1718
2.82M
    rc = cil_resolve_level(current, lvlrange->high, db);
1719
2.82M
    if (rc != SEPOL_OK) {
1720
1.21k
      goto exit;
1721
1.21k
    }
1722
2.82M
  }
1723
1724
2.84M
  return SEPOL_OK;
1725
1726
4.92k
exit:
1727
4.92k
  return rc;
1728
2.84M
}
1729
1730
int cil_resolve_constrain(struct cil_tree_node *current, struct cil_db *db)
1731
131k
{
1732
131k
  struct cil_constrain *cons = current->data;
1733
131k
  int rc = SEPOL_ERR;
1734
1735
131k
  rc = cil_resolve_classperms_list(current, cons->classperms, db);
1736
131k
  if (rc != SEPOL_OK) {
1737
23.8k
    goto exit;
1738
23.8k
  }
1739
1740
107k
  rc = cil_resolve_expr(CIL_CONSTRAIN, cons->str_expr, &cons->datum_expr, current, db);
1741
107k
  if (rc != SEPOL_OK) {
1742
281
    goto exit;
1743
281
  }
1744
1745
107k
  return SEPOL_OK;
1746
1747
24.1k
exit:
1748
24.1k
  return rc;
1749
107k
}
1750
1751
int cil_resolve_validatetrans(struct cil_tree_node *current, struct cil_db *db)
1752
140k
{
1753
140k
  struct cil_validatetrans *validtrans = current->data;
1754
140k
  struct cil_symtab_datum *class_datum = NULL;
1755
140k
  int rc = SEPOL_ERR;
1756
1757
140k
  rc = cil_resolve_name(current, validtrans->class_str, CIL_SYM_CLASSES, db, &class_datum);
1758
140k
  if (rc != SEPOL_OK) {
1759
22.2k
    goto exit;
1760
22.2k
  }
1761
117k
  validtrans->class = (struct cil_class*)class_datum;
1762
1763
117k
  rc = cil_resolve_expr(CIL_VALIDATETRANS, validtrans->str_expr, &validtrans->datum_expr, current, db);
1764
117k
  if (rc != SEPOL_OK) {
1765
293
    goto exit;
1766
293
  }
1767
1768
117k
  return SEPOL_OK;
1769
1770
22.5k
exit:
1771
22.5k
  return rc;
1772
117k
}
1773
1774
int cil_resolve_context(struct cil_tree_node *current, struct cil_context *context, struct cil_db *db)
1775
2.41M
{
1776
2.41M
  struct cil_symtab_datum *user_datum = NULL;
1777
2.41M
  struct cil_symtab_datum *role_datum = NULL;
1778
2.41M
  struct cil_symtab_datum *type_datum = NULL;
1779
2.41M
  struct cil_tree_node *node = NULL;
1780
2.41M
  struct cil_symtab_datum *lvlrange_datum = NULL;
1781
1782
2.41M
  int rc = SEPOL_ERR;
1783
1784
2.41M
  rc = cil_resolve_name(current, context->user_str, CIL_SYM_USERS, db, &user_datum);
1785
2.41M
  if (rc != SEPOL_OK) {
1786
38.0k
    goto exit;
1787
38.0k
  }
1788
1789
2.38M
  node = NODE(user_datum);
1790
1791
2.38M
  if (node->flavor != CIL_USER) {
1792
0
    cil_log(CIL_ERR, "Context user must be a user: %s\n", user_datum->fqn);
1793
0
    rc = SEPOL_ERR;
1794
0
    goto exit;
1795
0
  }
1796
1797
2.38M
  context->user = (struct cil_user*)user_datum;
1798
1799
2.38M
  rc = cil_resolve_name(current, context->role_str, CIL_SYM_ROLES, db, &role_datum);
1800
2.38M
  if (rc != SEPOL_OK) {
1801
2.36k
    goto exit;
1802
2.36k
  }
1803
1804
2.37M
  node = NODE(role_datum);
1805
2.37M
  if (node->flavor != CIL_ROLE) {
1806
0
    rc = SEPOL_ERR;
1807
0
    cil_log(CIL_ERR, "Context role not a role: %s\n", role_datum->fqn);
1808
0
    goto exit;
1809
0
  }
1810
1811
2.37M
  context->role = (struct cil_role*)role_datum;
1812
1813
2.37M
  rc = cil_resolve_name(current, context->type_str, CIL_SYM_TYPES, db, &type_datum);
1814
2.37M
  if (rc != SEPOL_OK) {
1815
1.16k
    goto exit;
1816
1.16k
  }
1817
1818
2.37M
  node = NODE(type_datum);
1819
1820
2.37M
  if (node->flavor != CIL_TYPE && node->flavor != CIL_TYPEALIAS) {
1821
0
    rc = SEPOL_ERR;
1822
0
    cil_log(CIL_ERR, "Type not a type or type alias\n");
1823
0
    goto exit;
1824
0
  }
1825
2.37M
  context->type = type_datum;
1826
1827
2.37M
  if (context->range_str != NULL) {
1828
208
    rc = cil_resolve_name(current, context->range_str, CIL_SYM_LEVELRANGES, db, &lvlrange_datum);
1829
208
    if (rc != SEPOL_OK) {
1830
208
      goto exit;
1831
208
    }
1832
0
    context->range = (struct cil_levelrange*)lvlrange_datum;
1833
1834
    /* This could still be an anonymous levelrange even if levelrange_str is set, if levelrange_str is a param_str*/
1835
0
    if (context->range->datum.name == NULL) {
1836
0
      rc = cil_resolve_levelrange(current, context->range, db);
1837
0
      if (rc != SEPOL_OK) {
1838
0
        goto exit;
1839
0
      }
1840
0
    }
1841
2.37M
  } else if (context->range != NULL) {
1842
2.37M
    rc = cil_resolve_levelrange(current, context->range, db);
1843
2.37M
    if (rc != SEPOL_OK) {
1844
1.01k
      goto exit;
1845
1.01k
    }
1846
2.37M
  }
1847
1848
2.37M
  return SEPOL_OK;
1849
1850
42.7k
exit:
1851
42.7k
  return rc;
1852
2.37M
}
1853
1854
int cil_resolve_filecon(struct cil_tree_node *current, struct cil_db *db)
1855
530k
{
1856
530k
  struct cil_filecon *filecon = current->data;
1857
530k
  struct cil_symtab_datum *context_datum = NULL;
1858
530k
  struct cil_symtab_datum *path_datum = NULL;
1859
530k
  int rc = SEPOL_ERR;
1860
1861
530k
  if (!filecon->path) {
1862
0
    rc = cil_resolve_name(current, filecon->path_str, CIL_SYM_STRINGS, db, &path_datum);
1863
0
    if (rc != SEPOL_OK) {
1864
0
      return rc;
1865
0
    }
1866
0
    filecon->path = path_datum;
1867
0
  }
1868
1869
530k
  if (filecon->context_str != NULL) {
1870
909
    rc = cil_resolve_name(current, filecon->context_str, CIL_SYM_CONTEXTS, db, &context_datum);
1871
909
    if (rc != SEPOL_OK) {
1872
293
      return rc;
1873
293
    }
1874
616
    filecon->context = (struct cil_context*)context_datum;
1875
529k
  } else if (filecon->context != NULL) {
1876
6.27k
    rc = cil_resolve_context(current, filecon->context, db);
1877
6.27k
    if (rc != SEPOL_OK) {
1878
2.02k
      return rc;
1879
2.02k
    }
1880
6.27k
  }
1881
1882
528k
  return SEPOL_OK;
1883
530k
}
1884
1885
int cil_resolve_ibpkeycon(struct cil_tree_node *current, struct cil_db *db)
1886
1.23M
{
1887
1.23M
  struct cil_ibpkeycon *ibpkeycon = current->data;
1888
1.23M
  struct cil_symtab_datum *context_datum = NULL;
1889
1.23M
  int rc = SEPOL_ERR;
1890
1891
1.23M
  if (ibpkeycon->context_str) {
1892
951
    rc = cil_resolve_name(current, ibpkeycon->context_str, CIL_SYM_CONTEXTS, db, &context_datum);
1893
951
    if (rc != SEPOL_OK)
1894
784
      goto exit;
1895
1896
167
    ibpkeycon->context = (struct cil_context *)context_datum;
1897
1.23M
  } else {
1898
1.23M
    rc = cil_resolve_context(current, ibpkeycon->context, db);
1899
1.23M
    if (rc != SEPOL_OK)
1900
1.81k
      goto exit;
1901
1.23M
  }
1902
1903
1.23M
  return SEPOL_OK;
1904
1905
2.59k
exit:
1906
2.59k
  return rc;
1907
1.23M
}
1908
1909
int cil_resolve_portcon(struct cil_tree_node *current, struct cil_db *db)
1910
83.8k
{
1911
83.8k
  struct cil_portcon *portcon = current->data;
1912
83.8k
  struct cil_symtab_datum *context_datum = NULL;
1913
83.8k
  int rc = SEPOL_ERR;
1914
1915
83.8k
  if (portcon->context_str != NULL) {
1916
10.4k
    rc = cil_resolve_name(current, portcon->context_str, CIL_SYM_CONTEXTS, db, &context_datum);
1917
10.4k
    if (rc != SEPOL_OK) {
1918
7.44k
      goto exit;
1919
7.44k
    }
1920
2.96k
    portcon->context = (struct cil_context*)context_datum;
1921
73.4k
  } else {
1922
73.4k
    rc = cil_resolve_context(current, portcon->context, db);
1923
73.4k
    if (rc != SEPOL_OK) {
1924
2.85k
      goto exit;
1925
2.85k
    }
1926
73.4k
  }
1927
1928
73.5k
  return SEPOL_OK;
1929
1930
10.2k
exit:
1931
10.2k
  return rc;
1932
83.8k
}
1933
1934
int cil_resolve_genfscon(struct cil_tree_node *current, struct cil_db *db)
1935
14.7k
{
1936
14.7k
  struct cil_genfscon *genfscon = current->data;
1937
14.7k
  struct cil_symtab_datum *context_datum = NULL;
1938
14.7k
  int rc = SEPOL_ERR;
1939
1940
14.7k
  if (genfscon->context_str != NULL) {
1941
4.62k
    rc = cil_resolve_name(current, genfscon->context_str, CIL_SYM_CONTEXTS, db, &context_datum);
1942
4.62k
    if (rc != SEPOL_OK) {
1943
3.26k
      goto exit;
1944
3.26k
    }
1945
1.36k
    genfscon->context = (struct cil_context*)context_datum;
1946
10.1k
  } else {
1947
10.1k
    rc = cil_resolve_context(current, genfscon->context, db);
1948
10.1k
    if (rc != SEPOL_OK) {
1949
1.36k
      goto exit;
1950
1.36k
    }
1951
10.1k
  }
1952
1953
10.1k
  return SEPOL_OK;
1954
1955
4.62k
exit:
1956
4.62k
  return rc;
1957
14.7k
}
1958
1959
int cil_resolve_nodecon(struct cil_tree_node *current, struct cil_db *db)
1960
39.0k
{
1961
39.0k
  struct cil_nodecon *nodecon = current->data;
1962
39.0k
  struct cil_symtab_datum *addr_datum = NULL;
1963
39.0k
  struct cil_symtab_datum *mask_datum = NULL;
1964
39.0k
  struct cil_symtab_datum *context_datum = NULL;
1965
39.0k
  int rc = SEPOL_ERR;
1966
1967
39.0k
  if (nodecon->addr_str != NULL) {
1968
8.61k
    rc = cil_resolve_name(current, nodecon->addr_str, CIL_SYM_IPADDRS, db, &addr_datum);
1969
8.61k
    if (rc != SEPOL_OK) {
1970
6.15k
      goto exit;
1971
6.15k
    }
1972
2.46k
    nodecon->addr = (struct cil_ipaddr*)addr_datum;
1973
2.46k
  }
1974
1975
32.9k
  if (nodecon->mask_str != NULL) {
1976
2.81k
    rc = cil_resolve_name(current, nodecon->mask_str, CIL_SYM_IPADDRS, db, &mask_datum);
1977
2.81k
    if (rc != SEPOL_OK) {
1978
744
      goto exit;
1979
744
    }
1980
2.07k
    nodecon->mask = (struct cil_ipaddr*)mask_datum;
1981
2.07k
  }
1982
1983
32.1k
  if (nodecon->context_str != NULL) {
1984
1.89k
    rc = cil_resolve_name(current, nodecon->context_str, CIL_SYM_CONTEXTS, db, &context_datum);
1985
1.89k
    if (rc != SEPOL_OK) {
1986
482
      goto exit;
1987
482
    }
1988
1.40k
    nodecon->context = (struct cil_context*)context_datum;
1989
30.3k
  } else {
1990
30.3k
    rc = cil_resolve_context(current, nodecon->context, db);
1991
30.3k
    if (rc != SEPOL_OK) {
1992
1.39k
      goto exit;
1993
1.39k
    }
1994
30.3k
  }
1995
1996
30.3k
  if (nodecon->addr->family != nodecon->mask->family) {
1997
2
    cil_log(CIL_ERR, "Nodecon ip address not in the same family\n");
1998
2
    rc = SEPOL_ERR;
1999
2
    goto exit;
2000
2
  }
2001
2002
2003
30.3k
  return SEPOL_OK;
2004
2005
8.76k
exit:
2006
8.76k
  return rc;
2007
30.3k
}
2008
2009
int cil_resolve_netifcon(struct cil_tree_node *current, struct cil_db *db)
2010
16.6k
{
2011
16.6k
  struct cil_netifcon *netifcon = current->data;
2012
16.6k
  struct cil_symtab_datum *ifcon_datum = NULL;
2013
16.6k
  struct cil_symtab_datum *packcon_datum = NULL;
2014
2015
16.6k
  int rc = SEPOL_ERR;
2016
2017
16.6k
  if (netifcon->if_context_str != NULL) {
2018
13.4k
    rc = cil_resolve_name(current, netifcon->if_context_str, CIL_SYM_CONTEXTS, db, &ifcon_datum);
2019
13.4k
    if (rc != SEPOL_OK) {
2020
10.9k
      goto exit;
2021
10.9k
    }
2022
2.57k
    netifcon->if_context = (struct cil_context*)ifcon_datum;
2023
3.15k
  } else {
2024
3.15k
    rc = cil_resolve_context(current, netifcon->if_context, db);
2025
3.15k
    if (rc != SEPOL_OK) {
2026
598
      goto exit;
2027
598
    }
2028
3.15k
  }
2029
2030
5.13k
  if (netifcon->packet_context_str != NULL) {
2031
2.13k
    rc = cil_resolve_name(current, netifcon->packet_context_str, CIL_SYM_CONTEXTS, db, &packcon_datum);
2032
2.13k
    if (rc != SEPOL_OK) {
2033
760
      goto exit;
2034
760
    }
2035
1.37k
    netifcon->packet_context = (struct cil_context*)packcon_datum;
2036
2.99k
  } else {
2037
2.99k
    rc = cil_resolve_context(current, netifcon->packet_context, db);
2038
2.99k
    if (rc != SEPOL_OK) {
2039
488
      goto exit;
2040
488
    }
2041
2.99k
  }
2042
3.88k
  return SEPOL_OK;
2043
2044
12.7k
exit:
2045
12.7k
  return rc;
2046
5.13k
}
2047
2048
int cil_resolve_ibendportcon(struct cil_tree_node *current, struct cil_db *db)
2049
611k
{
2050
611k
  struct cil_ibendportcon *ibendportcon = current->data;
2051
611k
  struct cil_symtab_datum *con_datum = NULL;
2052
2053
611k
  int rc = SEPOL_ERR;
2054
2055
611k
  if (ibendportcon->context_str) {
2056
4.74k
    rc = cil_resolve_name(current, ibendportcon->context_str, CIL_SYM_CONTEXTS, db, &con_datum);
2057
4.74k
    if (rc != SEPOL_OK)
2058
534
      goto exit;
2059
2060
4.20k
    ibendportcon->context = (struct cil_context *)con_datum;
2061
607k
  } else {
2062
607k
    rc = cil_resolve_context(current, ibendportcon->context, db);
2063
607k
    if (rc != SEPOL_OK)
2064
1.01k
      goto exit;
2065
607k
  }
2066
2067
610k
  return SEPOL_OK;
2068
2069
1.54k
exit:
2070
1.54k
  return rc;
2071
611k
}
2072
2073
int cil_resolve_pirqcon(struct cil_tree_node *current, struct cil_db *db)
2074
210k
{
2075
210k
  struct cil_pirqcon *pirqcon = current->data;
2076
210k
  struct cil_symtab_datum *context_datum = NULL;
2077
210k
  int rc = SEPOL_ERR;
2078
2079
210k
  if (pirqcon->context_str != NULL) {
2080
1.85k
    rc = cil_resolve_name(current, pirqcon->context_str, CIL_SYM_CONTEXTS, db, &context_datum);
2081
1.85k
    if (rc != SEPOL_OK) {
2082
1.15k
      goto exit;
2083
1.15k
    }
2084
700
    pirqcon->context = (struct cil_context*)context_datum;
2085
208k
  } else {
2086
208k
    rc = cil_resolve_context(current, pirqcon->context, db);
2087
208k
    if (rc != SEPOL_OK) {
2088
2.14k
      goto exit;
2089
2.14k
    }
2090
208k
  }
2091
2092
207k
  return SEPOL_OK;
2093
2094
3.29k
exit:
2095
3.29k
  return rc;
2096
210k
}
2097
2098
int cil_resolve_iomemcon(struct cil_tree_node *current, struct cil_db *db)
2099
130k
{
2100
130k
  struct cil_iomemcon *iomemcon = current->data;
2101
130k
  struct cil_symtab_datum *context_datum = NULL;
2102
130k
  int rc = SEPOL_ERR;
2103
2104
130k
  if (iomemcon->context_str != NULL) {
2105
2.25k
    rc = cil_resolve_name(current, iomemcon->context_str, CIL_SYM_CONTEXTS, db, &context_datum);
2106
2.25k
    if (rc != SEPOL_OK) {
2107
1.60k
      goto exit;
2108
1.60k
    }
2109
653
    iomemcon->context = (struct cil_context*)context_datum;
2110
127k
  } else {
2111
127k
    rc = cil_resolve_context(current, iomemcon->context, db);
2112
127k
    if (rc != SEPOL_OK) {
2113
5.01k
      goto exit;
2114
5.01k
    }
2115
127k
  }
2116
2117
123k
  return SEPOL_OK;
2118
2119
6.61k
exit:
2120
6.61k
  return rc;
2121
130k
}
2122
2123
int cil_resolve_ioportcon(struct cil_tree_node *current, struct cil_db *db)
2124
8.55k
{
2125
8.55k
  struct cil_ioportcon *ioportcon = current->data;
2126
8.55k
  struct cil_symtab_datum *context_datum = NULL;
2127
8.55k
  int rc = SEPOL_ERR;
2128
2129
8.55k
  if (ioportcon->context_str != NULL) {
2130
2.90k
    rc = cil_resolve_name(current, ioportcon->context_str, CIL_SYM_CONTEXTS, db, &context_datum);
2131
2.90k
    if (rc != SEPOL_OK) {
2132
2.18k
      goto exit;
2133
2.18k
    }
2134
712
    ioportcon->context = (struct cil_context*)context_datum;
2135
5.65k
  } else {
2136
5.65k
    rc = cil_resolve_context(current, ioportcon->context, db);
2137
5.65k
    if (rc != SEPOL_OK) {
2138
2.89k
      goto exit;
2139
2.89k
    }
2140
5.65k
  }
2141
2142
3.47k
  return SEPOL_OK;
2143
2144
5.08k
exit:
2145
5.08k
  return rc;
2146
8.55k
}
2147
2148
int cil_resolve_pcidevicecon(struct cil_tree_node *current, struct cil_db *db)
2149
20.8k
{
2150
20.8k
  struct cil_pcidevicecon *pcidevicecon = current->data;
2151
20.8k
  struct cil_symtab_datum *context_datum = NULL;
2152
20.8k
  int rc = SEPOL_ERR;
2153
2154
20.8k
  if (pcidevicecon->context_str != NULL) {
2155
3.19k
    rc = cil_resolve_name(current, pcidevicecon->context_str, CIL_SYM_CONTEXTS, db, &context_datum);
2156
3.19k
    if (rc != SEPOL_OK) {
2157
2.38k
      goto exit;
2158
2.38k
    }
2159
813
    pcidevicecon->context = (struct cil_context*)context_datum;
2160
17.6k
  } else {
2161
17.6k
    rc = cil_resolve_context(current, pcidevicecon->context, db);
2162
17.6k
    if (rc != SEPOL_OK) {
2163
15.6k
      goto exit;
2164
15.6k
    }
2165
17.6k
  }
2166
2167
2.77k
  return SEPOL_OK;
2168
2169
18.0k
exit:
2170
18.0k
  return rc;
2171
20.8k
}
2172
2173
static int cil_resolve_devicetreecon(struct cil_tree_node *current, struct cil_db *db)
2174
3.31k
{
2175
3.31k
  struct cil_devicetreecon *devicetreecon = current->data;
2176
3.31k
  struct cil_symtab_datum *context_datum = NULL;
2177
3.31k
  int rc = SEPOL_ERR;
2178
2179
3.31k
  if (devicetreecon->context_str != NULL) {
2180
1.39k
    rc = cil_resolve_name(current, devicetreecon->context_str, CIL_SYM_CONTEXTS, db, &context_datum);
2181
1.39k
    if (rc != SEPOL_OK) {
2182
763
      goto exit;
2183
763
    }
2184
634
    devicetreecon->context = (struct cil_context*)context_datum;
2185
1.91k
  } else {
2186
1.91k
    rc = cil_resolve_context(current, devicetreecon->context, db);
2187
1.91k
    if (rc != SEPOL_OK) {
2188
551
      goto exit;
2189
551
    }
2190
1.91k
  }
2191
2192
2.00k
  return SEPOL_OK;
2193
2194
1.31k
exit:
2195
1.31k
  return rc;
2196
3.31k
}
2197
2198
int cil_resolve_fsuse(struct cil_tree_node *current, struct cil_db *db)
2199
85.5k
{
2200
85.5k
  struct cil_fsuse *fsuse = current->data;
2201
85.5k
  struct cil_symtab_datum *context_datum = NULL;
2202
85.5k
  int rc = SEPOL_ERR;
2203
2204
85.5k
  if (fsuse->context_str != NULL) {
2205
4.98k
    rc = cil_resolve_name(current, fsuse->context_str, CIL_SYM_CONTEXTS, db, &context_datum);
2206
4.98k
    if (rc != SEPOL_OK) {
2207
4.24k
      goto exit;
2208
4.24k
    }
2209
746
    fsuse->context = (struct cil_context*)context_datum;
2210
80.5k
  } else {
2211
80.5k
    rc = cil_resolve_context(current, fsuse->context, db);
2212
80.5k
    if (rc != SEPOL_OK) {
2213
1.83k
      goto exit;
2214
1.83k
    }
2215
80.5k
  }
2216
2217
79.4k
  return SEPOL_OK;
2218
2219
6.07k
exit:
2220
6.07k
  return rc;
2221
85.5k
}
2222
2223
int cil_resolve_sidcontext(struct cil_tree_node *current, struct cil_db *db)
2224
3.18k
{
2225
3.18k
  struct cil_sidcontext *sidcon = current->data;
2226
3.18k
  struct cil_symtab_datum *sid_datum = NULL;
2227
3.18k
  struct cil_symtab_datum *context_datum = NULL;
2228
3.18k
  struct cil_sid *sid = NULL;
2229
2230
3.18k
  int rc = SEPOL_ERR;
2231
2232
3.18k
  rc = cil_resolve_name(current, sidcon->sid_str, CIL_SYM_SIDS, db, &sid_datum);
2233
3.18k
  if (rc != SEPOL_OK) {
2234
335
    goto exit;
2235
335
  }
2236
2.84k
  sid = (struct cil_sid*)sid_datum;
2237
2.84k
  sidcon->sid = sid;
2238
2239
2.84k
  if (sidcon->context_str != NULL) {
2240
219
    rc = cil_resolve_name(current, sidcon->context_str, CIL_SYM_CONTEXTS, db, &context_datum);
2241
219
    if (rc != SEPOL_OK) {
2242
216
      goto exit;
2243
216
    }
2244
3
    sidcon->context = (struct cil_context*)context_datum;
2245
2.62k
  } else if (sidcon->context != NULL) {
2246
2.62k
    rc = cil_resolve_context(current, sidcon->context, db);
2247
2.62k
    if (rc != SEPOL_OK) {
2248
471
      goto exit;
2249
471
    }
2250
2.62k
  }
2251
2252
2.16k
  if (sid->context != NULL) {
2253
1
    cil_log(CIL_ERR, "sid's cannot be associated with more than one context\n");
2254
1
    rc = SEPOL_ERR;
2255
1
    goto exit;
2256
1
  }
2257
2258
2.15k
  sid->context = sidcon->context;
2259
2260
2.15k
  return SEPOL_OK;
2261
2262
1.02k
exit:
2263
1.02k
  return rc;
2264
2.16k
}
2265
2266
static int cil_resolve_blockinherit_link(struct cil_tree_node *current, struct cil_db *db)
2267
16.7k
{
2268
16.7k
  struct cil_blockinherit *inherit = current->data;
2269
16.7k
  struct cil_symtab_datum *block_datum = NULL;
2270
16.7k
  struct cil_tree_node *node = NULL;
2271
16.7k
  int rc = SEPOL_ERR;
2272
2273
16.7k
  rc = cil_resolve_name(current, inherit->block_str, CIL_SYM_BLOCKS, db, &block_datum);
2274
16.7k
  if (rc != SEPOL_OK) {
2275
427
    goto exit;
2276
427
  }
2277
2278
16.2k
  node = NODE(block_datum);
2279
2280
16.2k
  if (node->flavor != CIL_BLOCK) {
2281
2
    cil_log(CIL_ERR, "%s is not a block\n", cil_node_to_string(node));
2282
2
    rc = SEPOL_ERR;
2283
2
    goto exit;
2284
2
  }
2285
2286
16.2k
  inherit->block = (struct cil_block *)block_datum;
2287
2288
16.2k
  if (inherit->block->bi_nodes == NULL) {
2289
12.9k
    cil_list_init(&inherit->block->bi_nodes, CIL_NODE);
2290
12.9k
  }
2291
16.2k
  cil_list_append(inherit->block->bi_nodes, CIL_NODE, current);
2292
2293
16.2k
  return SEPOL_OK;
2294
2295
429
exit:
2296
429
  return rc;
2297
16.2k
}
2298
2299
static int cil_resolve_blockinherit_copy(struct cil_tree_node *current, struct cil_db *db)
2300
355k
{
2301
355k
  struct cil_block *block = current->data;
2302
355k
  struct cil_list_item *item = NULL;
2303
355k
  int rc = SEPOL_ERR;
2304
2305
  // This block is not inherited
2306
355k
  if (block->bi_nodes == NULL) {
2307
344k
    rc = SEPOL_OK;
2308
344k
    goto exit;
2309
344k
  }
2310
2311
  // Make sure this is the original block and not a merged block from a blockinherit
2312
10.8k
  if (current != block->datum.nodes->head->data) {
2313
1.62k
    rc = SEPOL_OK;
2314
1.62k
    goto exit;
2315
1.62k
  }
2316
2317
147k
  cil_list_for_each(item, block->bi_nodes) {
2318
147k
    rc = cil_copy_ast(db, current, item->data);
2319
147k
    if (rc != SEPOL_OK) {
2320
15
      cil_log(CIL_ERR, "Failed to copy block contents into blockinherit\n");
2321
15
      goto exit;
2322
15
    }
2323
147k
  }
2324
2325
9.20k
  return SEPOL_OK;
2326
2327
346k
exit:
2328
346k
  return rc;
2329
9.21k
}
2330
2331
static void cil_mark_subtree_abstract(struct cil_tree_node *node)
2332
1.90k
{
2333
1.90k
  struct cil_block *block = node->data;
2334
2335
1.90k
  block->is_abstract = CIL_TRUE;
2336
2337
21.1k
  for (node = node->cl_head; node; node = node->next) {
2338
19.2k
    if (node->flavor == CIL_BLOCK) {
2339
943
      cil_mark_subtree_abstract(node);
2340
943
    }
2341
19.2k
  }
2342
1.90k
}
2343
2344
static int cil_resolve_blockabstract(struct cil_tree_node *current, struct cil_db *db, struct cil_list *abstract_blocks)
2345
971
{
2346
971
  struct cil_blockabstract *abstract = current->data;
2347
971
  struct cil_symtab_datum *block_datum = NULL;
2348
971
  struct cil_tree_node *block_node = NULL;
2349
971
  int rc = SEPOL_ERR;
2350
2351
971
  rc = cil_resolve_name(current, abstract->block_str, CIL_SYM_BLOCKS, db, &block_datum);
2352
971
  if (rc != SEPOL_OK) {
2353
10
    goto exit;
2354
10
  }
2355
2356
961
  block_node = NODE(block_datum);
2357
961
  if (block_node->flavor != CIL_BLOCK) {
2358
2
    cil_log(CIL_ERR, "Failed to resolve blockabstract to a block, rc: %d\n", rc);
2359
2
    rc = SEPOL_ERR;
2360
2
    goto exit;
2361
2
  }
2362
2363
959
  abstract->block = (struct cil_block *)block_datum;
2364
2365
959
  cil_list_append(abstract_blocks, CIL_NODE, block_node);
2366
2367
959
  return SEPOL_OK;
2368
2369
12
exit:
2370
12
  return rc;
2371
961
}
2372
2373
int cil_resolve_in(struct cil_tree_node *current, struct cil_db *db)
2374
10.9k
{
2375
10.9k
  struct cil_in *in = current->data;
2376
10.9k
  struct cil_symtab_datum *block_datum = NULL;
2377
10.9k
  struct cil_tree_node *block_node = NULL;
2378
10.9k
  int rc = SEPOL_ERR;
2379
2380
10.9k
  rc = cil_resolve_name(current, in->block_str, CIL_SYM_BLOCKS, db, &block_datum);
2381
10.9k
  if (rc != SEPOL_OK) {
2382
0
    goto exit;
2383
0
  }
2384
2385
10.9k
  in->block = (struct cil_block *)block_datum;
2386
2387
10.9k
  block_node = NODE(block_datum);
2388
2389
10.9k
  if (block_node->flavor == CIL_OPTIONAL) {
2390
5.46k
    if (block_datum->nodes && block_datum->nodes->head != block_datum->nodes->tail) {
2391
11
      cil_tree_log(current, CIL_ERR, "Multiple optional blocks referred to by in-statement");
2392
11
      cil_tree_log(block_node, CIL_ERR, "First optional block");
2393
11
      rc = SEPOL_ERR;
2394
11
      goto exit;
2395
11
    }
2396
5.46k
  }
2397
2398
10.9k
  rc = cil_copy_ast(db, current, block_node);
2399
10.9k
  if (rc != SEPOL_OK) {
2400
54
    cil_tree_log(current, CIL_ERR, "Failed to copy in-statement");
2401
54
    goto exit;
2402
54
  }
2403
2404
10.9k
  cil_tree_children_destroy(current);
2405
2406
10.9k
  return SEPOL_OK;
2407
2408
65
exit:
2409
65
  return rc;
2410
10.9k
}
2411
2412
static int cil_resolve_in_list(struct cil_list *in_list, struct cil_db *db)
2413
23.8k
{
2414
23.8k
  struct cil_list_item *curr = NULL;
2415
23.8k
  struct cil_tree_node *node = NULL;
2416
23.8k
  struct cil_tree_node *last_failed_node = NULL;
2417
23.8k
  struct cil_in *in = NULL;
2418
23.8k
  struct cil_symtab_datum *block_datum = NULL;
2419
23.8k
  int resolved = 0;
2420
23.8k
  int unresolved = 0;
2421
23.8k
  int rc = SEPOL_ERR;
2422
2423
23.9k
  do {
2424
23.9k
    resolved = 0;
2425
23.9k
    unresolved = 0;
2426
2427
23.9k
    cil_list_for_each(curr, in_list) {
2428
15.7k
      if (curr->flavor != CIL_NODE) {
2429
1.00k
        continue;
2430
1.00k
      }
2431
2432
14.7k
      node = curr->data;
2433
14.7k
      in = node->data;
2434
2435
14.7k
      rc = cil_resolve_name(node, in->block_str, CIL_SYM_BLOCKS, db, &block_datum);
2436
14.7k
      if (rc != SEPOL_OK) {
2437
3.75k
        unresolved++;
2438
3.75k
        last_failed_node = node;
2439
10.9k
      } else {
2440
10.9k
        rc = cil_resolve_in(node, db);
2441
10.9k
        if (rc != SEPOL_OK) {
2442
65
          goto exit;
2443
65
        }
2444
        
2445
10.9k
        resolved++;
2446
10.9k
        curr->data = NULL;
2447
10.9k
        curr->flavor = CIL_NONE;
2448
10.9k
      }
2449
14.7k
    }
2450
2451
23.8k
    if (unresolved > 0 && resolved == 0) {
2452
405
      cil_tree_log(last_failed_node, CIL_ERR, "Failed to resolve in-statement");
2453
405
      rc = SEPOL_ERR;
2454
405
      goto exit;
2455
405
    }
2456
2457
23.8k
  } while (unresolved > 0);
2458
2459
23.3k
  rc = SEPOL_OK;
2460
2461
23.8k
exit:
2462
23.8k
  return rc;
2463
23.3k
}
2464
2465
2466
static int cil_resolve_bounds(struct cil_tree_node *current, struct cil_db *db, enum cil_flavor flavor, enum cil_flavor attr_flavor)
2467
18.8k
{
2468
18.8k
  int rc = SEPOL_ERR;
2469
18.8k
  struct cil_bounds *bounds = current->data;
2470
18.8k
  enum cil_sym_index index;
2471
18.8k
  struct cil_symtab_datum *parent_datum = NULL;
2472
18.8k
  struct cil_symtab_datum *child_datum = NULL;
2473
2474
18.8k
  rc = cil_flavor_to_symtab_index(flavor, &index);
2475
18.8k
  if (rc != SEPOL_OK) {
2476
0
    goto exit;
2477
0
  }
2478
2479
18.8k
  rc = cil_resolve_name(current, bounds->parent_str, index, db, &parent_datum);
2480
18.8k
  if (rc != SEPOL_OK) {
2481
9.86k
    goto exit;
2482
9.86k
  }
2483
8.99k
  if (FLAVOR(parent_datum) == attr_flavor) {
2484
1
    cil_log(CIL_ERR, "Bounds parent %s is an attribute\n", bounds->parent_str);
2485
1
    rc = SEPOL_ERR;
2486
1
    goto exit;
2487
1
  }
2488
2489
2490
8.99k
  rc = cil_resolve_name(current, bounds->child_str, index, db, &child_datum);
2491
8.99k
  if (rc != SEPOL_OK) {
2492
523
    goto exit;
2493
523
  }
2494
8.47k
  if (FLAVOR(child_datum) == attr_flavor) {
2495
1
    cil_log(CIL_ERR, "Bounds child %s is an attribute\n", bounds->child_str);
2496
1
    rc = SEPOL_ERR;
2497
1
    goto exit;
2498
1
  }
2499
2500
8.47k
  switch (flavor) {
2501
134
  case CIL_USER: {
2502
134
    struct cil_user *user = (struct cil_user *)child_datum;
2503
2504
134
    if (user->bounds != NULL) {
2505
1
      cil_tree_log(NODE(user->bounds), CIL_ERR, "User %s already bound by parent", bounds->child_str);
2506
1
      rc = SEPOL_ERR;
2507
1
      goto exit;
2508
1
    }
2509
2510
133
    user->bounds = (struct cil_user *)parent_datum;
2511
133
    break;
2512
134
  }
2513
1
  case CIL_ROLE: {
2514
1
    struct cil_role *role = (struct cil_role *)child_datum;
2515
2516
1
    if (role->bounds != NULL) {
2517
0
      cil_tree_log(NODE(role->bounds), CIL_ERR, "Role %s already bound by parent", bounds->child_str);
2518
0
      rc = SEPOL_ERR;
2519
0
      goto exit;
2520
0
    }
2521
2522
1
    role->bounds = (struct cil_role *)parent_datum;
2523
1
    break;
2524
1
  }
2525
8.33k
  case CIL_TYPE: {
2526
8.33k
    struct cil_type *type = (struct cil_type *)child_datum;
2527
2528
8.33k
    if (type->bounds != NULL) {
2529
2
      cil_tree_log(NODE(type->bounds), CIL_ERR, "Type %s already bound by parent", bounds->child_str);
2530
2
      rc = SEPOL_ERR;
2531
2
      goto exit;
2532
2
    }
2533
2534
8.33k
    type->bounds = (struct cil_type *)parent_datum;
2535
8.33k
    break;
2536
8.33k
  }
2537
0
  default:
2538
0
    break;
2539
8.47k
  }
2540
2541
8.47k
  return SEPOL_OK;
2542
2543
10.3k
exit:
2544
10.3k
  cil_tree_log(current, CIL_ERR, "Bad bounds statement");
2545
10.3k
  return rc;
2546
8.47k
}
2547
2548
static int cil_resolve_default(struct cil_tree_node *current, struct cil_db *db)
2549
52.7k
{
2550
52.7k
  int rc = SEPOL_ERR;
2551
52.7k
  struct cil_default *def = current->data;
2552
52.7k
  struct cil_list_item *curr;
2553
52.7k
  struct cil_symtab_datum *datum;
2554
2555
52.7k
  cil_list_init(&def->class_datums, def->flavor);
2556
2557
63.9k
  cil_list_for_each(curr, def->class_strs) {
2558
63.9k
    rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_CLASSES, db, &datum);
2559
63.9k
    if (rc != SEPOL_OK) {
2560
4.16k
      goto exit;
2561
4.16k
    }
2562
59.7k
    cil_list_append(def->class_datums, CIL_CLASS, datum);
2563
59.7k
  }
2564
2565
48.5k
  return SEPOL_OK;
2566
2567
4.16k
exit:
2568
4.16k
  return rc;
2569
52.7k
}
2570
2571
static int cil_resolve_defaultrange(struct cil_tree_node *current, struct cil_db *db)
2572
61.5k
{
2573
61.5k
  int rc = SEPOL_ERR;
2574
61.5k
  struct cil_defaultrange *def = current->data;
2575
61.5k
  struct cil_list_item *curr;
2576
61.5k
  struct cil_symtab_datum *datum;
2577
2578
61.5k
  cil_list_init(&def->class_datums, CIL_DEFAULTRANGE);
2579
2580
84.5k
  cil_list_for_each(curr, def->class_strs) {
2581
84.5k
    rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_CLASSES, db, &datum);
2582
84.5k
    if (rc != SEPOL_OK) {
2583
327
      goto exit;
2584
327
    }
2585
84.1k
    cil_list_append(def->class_datums, CIL_CLASS, datum);
2586
84.1k
  }
2587
2588
61.1k
  return SEPOL_OK;
2589
2590
327
exit:
2591
327
  return rc;
2592
61.5k
}
2593
2594
static void cil_print_recursive_call(struct cil_tree_node *call_node, struct cil_tree_node *terminating_node)
2595
9
{
2596
9
  struct cil_list *trace = NULL;
2597
9
  struct cil_list_item * item = NULL;
2598
9
  struct cil_tree_node *curr = NULL;
2599
2600
9
  cil_list_init(&trace, CIL_NODE);
2601
2602
54
  for (curr = call_node; curr != terminating_node; curr = curr->parent) {
2603
45
    if (curr->flavor == CIL_CALL) {
2604
11
      if (curr != call_node) {
2605
2
        cil_list_prepend(trace, CIL_NODE, NODE(((struct cil_call *)curr->data)->macro));
2606
2
      }
2607
11
      cil_list_prepend(trace, CIL_NODE, curr);
2608
11
    }
2609
45
  }
2610
2611
9
  if (terminating_node->flavor == CIL_MACRO) {
2612
0
    cil_list_prepend(trace, CIL_NODE, terminating_node);
2613
9
  } else {
2614
9
    cil_list_prepend(trace, CIL_NODE, NODE(((struct cil_call *)terminating_node->data)->macro));
2615
9
  }
2616
2617
22
  cil_list_for_each(item, trace) {
2618
22
    curr = item->data;
2619
22
    if (curr->flavor == CIL_MACRO) {
2620
11
      cil_tree_log(curr, CIL_ERR, "macro %s", DATUM(curr->data)->name);
2621
11
    } else {
2622
11
      cil_tree_log(curr, CIL_ERR, "call %s", ((struct cil_call *)curr->data)->macro_str);
2623
11
    }
2624
22
  }
2625
2626
9
  cil_list_destroy(&trace, CIL_FALSE);
2627
9
}
2628
2629
static int cil_check_recursive_call(struct cil_tree_node *call_node, struct cil_tree_node *macro_node)
2630
80.6k
{
2631
80.6k
  struct cil_tree_node *curr = NULL;
2632
80.6k
  struct cil_call * call = NULL;
2633
80.6k
  int rc = SEPOL_ERR;
2634
2635
923k
  for (curr = call_node; curr != NULL; curr = curr->parent) {
2636
843k
    if (curr->flavor == CIL_CALL) {
2637
97.0k
      if (curr == call_node) {
2638
80.6k
        continue;
2639
80.6k
      }
2640
2641
16.3k
      call = curr->data;
2642
16.3k
      if (call->macro != macro_node->data) {
2643
16.3k
        continue;
2644
16.3k
      }
2645
746k
    } else if (curr->flavor == CIL_MACRO) {
2646
0
      if (curr != macro_node) {
2647
0
        rc = SEPOL_OK;
2648
0
        goto exit;
2649
0
      }
2650
746k
    } else {
2651
746k
      continue;
2652
746k
    }
2653
2654
9
    cil_log(CIL_ERR, "Recursive macro call found:\n");
2655
9
    cil_print_recursive_call(call_node, curr);
2656
2657
9
    rc = SEPOL_ERR;
2658
9
    goto exit;
2659
843k
  }
2660
2661
80.6k
  rc = SEPOL_OK;
2662
80.6k
exit:
2663
80.6k
  return rc;
2664
80.6k
}
2665
2666
static int cil_build_call_args(struct cil_tree_node *call_node, struct cil_call *call, struct cil_macro *macro, struct cil_db *db)
2667
80.7k
{
2668
80.7k
  struct cil_list_item *item;
2669
80.7k
  struct cil_args *arg = NULL;
2670
80.7k
  struct cil_tree_node *arg_node = NULL;
2671
80.7k
  int rc = SEPOL_ERR;
2672
2673
80.7k
  if (macro->params == NULL) {
2674
39.5k
    if (call->args_tree == NULL) {
2675
39.5k
      return SEPOL_OK;
2676
39.5k
    } else {
2677
6
      cil_tree_log(call_node, CIL_ERR, "Unexpected arguments");
2678
6
      return SEPOL_ERR;
2679
6
    }
2680
39.5k
  }
2681
41.2k
  if (call->args_tree == NULL) {
2682
5
    cil_tree_log(call_node, CIL_ERR, "Missing arguments");
2683
5
    return SEPOL_ERR;
2684
5
  }
2685
2686
41.2k
  arg_node = call->args_tree->root->cl_head;
2687
2688
41.2k
  cil_list_init(&call->args, CIL_LIST_ITEM);
2689
2690
50.8k
  cil_list_for_each(item, macro->params) {
2691
50.8k
    enum cil_flavor flavor = ((struct cil_param*)item->data)->flavor;
2692
2693
50.8k
    if (arg_node == NULL) {
2694
2
      cil_tree_log(call_node, CIL_ERR, "Missing arguments");
2695
2
      rc = SEPOL_ERR;
2696
2
      goto exit;
2697
2
    }
2698
50.8k
    if (item->flavor != CIL_PARAM) {
2699
0
      rc = SEPOL_ERR;
2700
0
      goto exit;
2701
0
    }
2702
2703
50.8k
    cil_args_init(&arg);
2704
2705
50.8k
    switch (flavor) {
2706
1.97k
    case CIL_DECLARED_STRING: {
2707
1.97k
      struct cil_symtab_datum *string;
2708
1.97k
      if (arg_node->data == NULL) {
2709
2
        cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
2710
2
        cil_destroy_args(arg);
2711
2
        rc = SEPOL_ERR;
2712
2
        goto exit;
2713
2
      }
2714
1.97k
      string = cil_gen_declared_string(db, arg_node->data, call_node);
2715
1.97k
      if (string) {
2716
1.34k
        arg->arg = string;
2717
1.34k
      } else {
2718
629
        arg->arg_str = arg_node->data;
2719
629
      }
2720
1.97k
    }
2721
0
      break;
2722
18.2k
    case CIL_TYPE:
2723
18.2k
      if (arg_node->data == NULL) {
2724
1
        cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
2725
1
        cil_destroy_args(arg);
2726
1
        rc = SEPOL_ERR;
2727
1
        goto exit;
2728
1
      }
2729
18.2k
      arg->arg_str = arg_node->data;
2730
18.2k
      break;
2731
531
    case CIL_ROLE:
2732
531
      if (arg_node->data == NULL) {
2733
1
        cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
2734
1
        cil_destroy_args(arg);
2735
1
        rc = SEPOL_ERR;
2736
1
        goto exit;
2737
1
      }
2738
530
      arg->arg_str = arg_node->data;
2739
530
      break;
2740
6.70k
    case CIL_USER:
2741
6.70k
      if (arg_node->data == NULL) {
2742
1
        cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
2743
1
        cil_destroy_args(arg);
2744
1
        rc = SEPOL_ERR;
2745
1
        goto exit;
2746
1
      }
2747
6.70k
      arg->arg_str = arg_node->data;
2748
6.70k
      break;
2749
1.11k
    case CIL_SENS:
2750
1.11k
      if (arg_node->data == NULL) {
2751
2
        cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
2752
2
        cil_destroy_args(arg);
2753
2
        rc = SEPOL_ERR;
2754
2
        goto exit;
2755
2
      }
2756
1.11k
      arg->arg_str = arg_node->data;
2757
1.11k
      break;
2758
360
    case CIL_CAT:
2759
360
      if (arg_node->data == NULL) {
2760
1
        cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
2761
1
        cil_destroy_args(arg);
2762
1
        rc = SEPOL_ERR;
2763
1
        goto exit;
2764
1
      }
2765
359
      arg->arg_str = arg_node->data;
2766
359
      break;
2767
1.16k
    case CIL_BOOL:
2768
1.16k
      if (arg_node->data == NULL) {
2769
1
        cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
2770
1
        cil_destroy_args(arg);
2771
1
        rc = SEPOL_ERR;
2772
1
        goto exit;
2773
1
      }
2774
1.16k
      arg->arg_str = arg_node->data;
2775
1.16k
      break;
2776
1.12k
    case CIL_CATSET: {
2777
1.12k
      if (arg_node->cl_head != NULL) {
2778
788
        struct cil_catset *catset = NULL;
2779
788
        struct cil_tree_node *cat_node = NULL;
2780
788
        cil_catset_init(&catset);
2781
788
        rc = cil_fill_cats(arg_node, &catset->cats);
2782
788
        if (rc != SEPOL_OK) {
2783
1
          cil_destroy_catset(catset);
2784
1
          cil_destroy_args(arg);
2785
1
          goto exit;
2786
1
        }
2787
787
        cil_tree_node_init(&cat_node);
2788
787
        cat_node->flavor = CIL_CATSET;
2789
787
        cat_node->data = catset;
2790
787
        cil_list_append(((struct cil_symtab_datum*)catset)->nodes,
2791
787
                CIL_LIST_ITEM, cat_node);
2792
787
        arg->arg = (struct cil_symtab_datum*)catset;
2793
787
      } else if (arg_node->data == NULL) {
2794
2
        cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
2795
2
        cil_destroy_args(arg);
2796
2
        rc = SEPOL_ERR;
2797
2
        goto exit;
2798
333
      } else {
2799
333
        arg->arg_str = arg_node->data;
2800
333
      }
2801
2802
1.12k
      break;
2803
1.12k
    }
2804
2.49k
    case CIL_LEVEL: {
2805
2.49k
      if (arg_node->cl_head != NULL) {
2806
1.41k
        struct cil_level *level = NULL;
2807
1.41k
        struct cil_tree_node *lvl_node = NULL;
2808
1.41k
        cil_level_init(&level);
2809
2810
1.41k
        rc = cil_fill_level(arg_node->cl_head, level);
2811
1.41k
        if (rc != SEPOL_OK) {
2812
2
          cil_log(CIL_ERR, "Failed to create anonymous level, rc: %d\n", rc);
2813
2
          cil_destroy_level(level);
2814
2
          cil_destroy_args(arg);
2815
2
          goto exit;
2816
2
        }
2817
1.40k
        cil_tree_node_init(&lvl_node);
2818
1.40k
        lvl_node->flavor = CIL_LEVEL;
2819
1.40k
        lvl_node->data = level;
2820
1.40k
        cil_list_append(((struct cil_symtab_datum*)level)->nodes,
2821
1.40k
                CIL_LIST_ITEM, lvl_node);
2822
1.40k
        arg->arg = (struct cil_symtab_datum*)level;
2823
1.40k
      } else if (arg_node->data == NULL) {
2824
1
        cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
2825
1
        cil_destroy_args(arg);
2826
1
        rc = SEPOL_ERR;
2827
1
        goto exit;
2828
1.08k
      } else {
2829
1.08k
        arg->arg_str = arg_node->data;
2830
1.08k
      }
2831
2832
2.49k
      break;
2833
2.49k
    }
2834
2.63k
    case CIL_LEVELRANGE: {
2835
2.63k
      if (arg_node->cl_head != NULL) {
2836
1.08k
        struct cil_levelrange *range = NULL;
2837
1.08k
        struct cil_tree_node *range_node = NULL;
2838
1.08k
        cil_levelrange_init(&range);
2839
2840
1.08k
        rc = cil_fill_levelrange(arg_node->cl_head, range);
2841
1.08k
        if (rc != SEPOL_OK) {
2842
1
          cil_log(CIL_ERR, "Failed to create anonymous levelrange, rc: %d\n", rc);
2843
1
          cil_destroy_levelrange(range);
2844
1
          cil_destroy_args(arg);
2845
1
          goto exit;
2846
1
        }
2847
1.08k
        cil_tree_node_init(&range_node);
2848
1.08k
        range_node->flavor = CIL_LEVELRANGE;
2849
1.08k
        range_node->data = range;
2850
1.08k
        cil_list_append(((struct cil_symtab_datum*)range)->nodes,
2851
1.08k
                CIL_LIST_ITEM, range_node);
2852
1.08k
        arg->arg = (struct cil_symtab_datum*)range;
2853
1.54k
      } else if (arg_node->data == NULL) {
2854
2
        cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
2855
2
        cil_destroy_args(arg);
2856
2
        rc = SEPOL_ERR;
2857
2
        goto exit;
2858
1.54k
      } else {
2859
1.54k
        arg->arg_str = arg_node->data;
2860
1.54k
      }
2861
2862
2.62k
      break;
2863
2.63k
    }
2864
2.62k
    case CIL_IPADDR: {
2865
1.14k
      if (arg_node->data == NULL) {
2866
1
        cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
2867
1
        cil_destroy_args(arg);
2868
1
        rc = SEPOL_ERR;
2869
1
        goto exit;
2870
1.14k
      } else if (strchr(arg_node->data, '.') || strchr(arg_node->data, ':')) {
2871
608
        struct cil_ipaddr *ipaddr = NULL;
2872
608
        struct cil_tree_node *addr_node = NULL;
2873
608
        cil_ipaddr_init(&ipaddr);
2874
608
        rc = cil_fill_ipaddr(arg_node, ipaddr);
2875
608
        if (rc != SEPOL_OK) {
2876
6
          cil_tree_log(call_node, CIL_ERR, "Failed to create anonymous ip address");
2877
6
          cil_destroy_ipaddr(ipaddr);
2878
6
          cil_destroy_args(arg);
2879
6
          goto exit;
2880
6
        }
2881
602
        cil_tree_node_init(&addr_node);
2882
602
        addr_node->flavor = CIL_IPADDR;
2883
602
        addr_node->data = ipaddr;
2884
602
        cil_list_append(DATUM(ipaddr)->nodes, CIL_LIST_ITEM, addr_node);
2885
602
        arg->arg = DATUM(ipaddr);
2886
602
      } else {
2887
533
        arg->arg_str = arg_node->data;
2888
533
      }
2889
1.13k
      break;
2890
1.14k
    }
2891
1.13k
    case CIL_CLASS:
2892
414
      if (arg_node->data == NULL) {
2893
1
        cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
2894
1
        cil_destroy_args(arg);
2895
1
        rc = SEPOL_ERR;
2896
1
        goto exit;
2897
1
      }
2898
413
      arg->arg_str = arg_node->data;
2899
413
      break;
2900
35
    case CIL_MAP_CLASS:
2901
35
      if (arg_node->data == NULL) {
2902
1
        cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
2903
1
        cil_destroy_args(arg);
2904
1
        rc = SEPOL_ERR;
2905
1
        goto exit;
2906
1
      }
2907
34
      arg->arg_str = arg_node->data;
2908
34
      break;
2909
12.9k
    case CIL_CLASSPERMISSION: {
2910
12.9k
      if (arg_node->cl_head != NULL) {
2911
12.0k
        struct cil_classpermission *cp = NULL;
2912
12.0k
        struct cil_tree_node *cp_node = NULL;
2913
2914
12.0k
        cil_classpermission_init(&cp);
2915
12.0k
        rc = cil_fill_classperms_list(arg_node, &cp->classperms);
2916
12.0k
        if (rc != SEPOL_OK) {
2917
3
          cil_log(CIL_ERR, "Failed to create anonymous classpermission\n");
2918
3
          cil_destroy_classpermission(cp);
2919
3
          cil_destroy_args(arg);
2920
3
          goto exit;
2921
3
        }
2922
12.0k
        cil_tree_node_init(&cp_node);
2923
12.0k
        cp_node->flavor = CIL_CLASSPERMISSION;
2924
12.0k
        cp_node->data = cp;
2925
12.0k
        cil_list_append(cp->datum.nodes, CIL_LIST_ITEM, cp_node);
2926
12.0k
        arg->arg = (struct cil_symtab_datum*)cp;
2927
12.0k
      } else if (arg_node->data == NULL) {
2928
0
        cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
2929
0
        cil_destroy_args(arg);
2930
0
        rc = SEPOL_ERR;
2931
0
        goto exit;
2932
862
      } else {
2933
862
        arg->arg_str = arg_node->data;
2934
862
      }
2935
12.9k
      break;
2936
12.9k
    }
2937
12.9k
    default:
2938
0
      cil_log(CIL_ERR, "Unexpected flavor: %d\n",
2939
0
          (((struct cil_param*)item->data)->flavor));
2940
0
      cil_destroy_args(arg);
2941
0
      rc = SEPOL_ERR;
2942
0
      goto exit;
2943
50.8k
    }
2944
50.8k
    arg->param_str = ((struct cil_param*)item->data)->str;
2945
50.8k
    arg->flavor = flavor;
2946
2947
50.8k
    cil_list_append(call->args, CIL_ARGS, arg);
2948
2949
50.8k
    arg_node = arg_node->next;
2950
50.8k
  }
2951
2952
41.1k
  if (arg_node != NULL) {
2953
8
    cil_tree_log(call_node, CIL_ERR, "Unexpected arguments");
2954
8
    rc = SEPOL_ERR;
2955
8
    goto exit;
2956
8
  }
2957
2958
41.1k
  return SEPOL_OK;
2959
2960
40
exit:
2961
40
  return rc;
2962
41.1k
}
2963
2964
static int cil_resolve_call(struct cil_tree_node *current, struct cil_db *db)
2965
82.7k
{
2966
82.7k
  struct cil_call *call = current->data;
2967
82.7k
  struct cil_tree_node *macro_node = NULL;
2968
82.7k
  struct cil_symtab_datum *macro_datum = NULL;
2969
82.7k
  int rc = SEPOL_ERR;
2970
2971
82.7k
  if (call->copied) {
2972
0
    return SEPOL_OK;
2973
0
  }
2974
2975
82.7k
  rc = cil_resolve_name(current, call->macro_str, CIL_SYM_BLOCKS, db, &macro_datum);
2976
82.7k
  if (rc != SEPOL_OK) {
2977
2.02k
    goto exit;
2978
2.02k
  }
2979
2980
80.7k
  macro_node = NODE(macro_datum);
2981
2982
80.7k
  if (macro_node->flavor != CIL_MACRO) {
2983
22
    cil_tree_log(current, CIL_ERR, "Failed to resolve %s to a macro", call->macro_str);
2984
22
    rc = SEPOL_ERR;
2985
22
    goto exit;
2986
22
  }
2987
80.7k
  call->macro = (struct cil_macro*)macro_datum;
2988
2989
80.7k
  rc = cil_build_call_args(current, call, call->macro, db);
2990
80.7k
  if (rc != SEPOL_OK) {
2991
51
    goto exit;
2992
51
  }
2993
2994
80.6k
  rc = cil_check_recursive_call(current, macro_node);
2995
80.6k
  if (rc != SEPOL_OK) {
2996
9
    goto exit;
2997
9
  }
2998
2999
80.6k
  rc = cil_copy_ast(db, macro_node, current);
3000
80.6k
  if (rc != SEPOL_OK) {
3001
35
    cil_tree_log(current, CIL_ERR, "Failed to copy macro %s to call", macro_datum->name);
3002
35
    goto exit;
3003
35
  }
3004
3005
80.6k
  call->copied = 1;
3006
3007
80.6k
  return SEPOL_OK;
3008
3009
2.14k
exit:
3010
2.14k
  return rc;
3011
80.6k
}
3012
3013
static int cil_resolve_call_args(struct cil_tree_node *current, struct cil_db *db)
3014
122k
{
3015
122k
  struct cil_call *call = current->data;
3016
122k
  int rc = SEPOL_ERR;
3017
122k
  enum cil_sym_index sym_index = CIL_SYM_UNKNOWN;
3018
122k
  struct cil_list_item *item;
3019
3020
122k
  if (call->args == NULL) {
3021
61.9k
    rc = SEPOL_OK;
3022
61.9k
    goto exit;
3023
61.9k
  }
3024
3025
68.8k
  cil_list_for_each(item, call->args) {
3026
68.8k
    struct cil_args *arg = item->data;
3027
68.8k
    if (arg->arg == NULL && arg->arg_str == NULL) {
3028
0
      cil_log(CIL_ERR, "Arguments not created correctly\n");
3029
0
      rc = SEPOL_ERR;
3030
0
      goto exit;
3031
0
    }
3032
3033
68.8k
    switch (arg->flavor) {
3034
1.55k
    case CIL_DECLARED_STRING:
3035
1.55k
      if (arg->arg != NULL) {
3036
990
        continue; /* No need to resolve */
3037
990
      } else {
3038
562
        sym_index = CIL_SYM_STRINGS;
3039
562
      }
3040
562
      break;
3041
2.04k
    case CIL_LEVEL:
3042
2.04k
      if (arg->arg_str == NULL && arg->arg != NULL) {
3043
1.35k
        continue; // anonymous, no need to resolve
3044
1.35k
      } else {
3045
691
        sym_index = CIL_SYM_LEVELS;
3046
691
      }
3047
691
      break;
3048
2.17k
    case CIL_LEVELRANGE:
3049
2.17k
      if (arg->arg_str == NULL && arg->arg != NULL) {
3050
867
        continue; // anonymous, no need to resolve
3051
1.30k
      } else {
3052
1.30k
        sym_index = CIL_SYM_LEVELRANGES;
3053
1.30k
      }
3054
1.30k
      break;
3055
1.30k
    case CIL_CATSET:
3056
1.16k
      if (arg->arg_str == NULL && arg->arg != NULL) {
3057
1.05k
        continue; // anonymous, no need to resolve
3058
1.05k
      } else {
3059
101
        sym_index = CIL_SYM_CATS;
3060
101
      }
3061
101
      break;
3062
1.06k
    case CIL_IPADDR:
3063
1.06k
      if (arg->arg_str == NULL && arg->arg != NULL) {
3064
572
        continue; // anonymous, no need to resolve
3065
572
      } else {
3066
496
        sym_index = CIL_SYM_IPADDRS;
3067
496
      }
3068
496
      break;
3069
24.6k
    case CIL_CLASSPERMISSION:
3070
24.6k
      if (arg->arg_str == NULL && arg->arg != NULL) {
3071
23.6k
        continue;
3072
23.6k
      } else {
3073
998
        sym_index = CIL_SYM_CLASSPERMSETS;
3074
998
      }
3075
998
      break;
3076
25.9k
    case CIL_TYPE:
3077
25.9k
      if (arg->arg_str == NULL && arg->arg != NULL) {
3078
0
        continue; // anonymous, no need to resolve
3079
25.9k
      } else {
3080
25.9k
        sym_index = CIL_SYM_TYPES;
3081
25.9k
      }
3082
25.9k
      break;
3083
25.9k
    case CIL_ROLE:
3084
457
      sym_index = CIL_SYM_ROLES;
3085
457
      break;
3086
6.51k
    case CIL_USER:
3087
6.51k
      sym_index = CIL_SYM_USERS;
3088
6.51k
      break;
3089
1.19k
    case CIL_SENS:
3090
1.19k
      sym_index = CIL_SYM_SENS;
3091
1.19k
      break;
3092
341
    case CIL_CAT:
3093
341
      sym_index = CIL_SYM_CATS;
3094
341
      break;
3095
356
    case CIL_CLASS:
3096
390
    case CIL_MAP_CLASS:
3097
390
      sym_index = CIL_SYM_CLASSES;
3098
390
      break;
3099
1.27k
    case CIL_BOOL:
3100
1.27k
      sym_index = CIL_SYM_BOOLS;
3101
1.27k
      break;
3102
0
    default:
3103
0
      rc = SEPOL_ERR;
3104
0
      goto exit;
3105
68.8k
    }
3106
3107
40.2k
    if (sym_index != CIL_SYM_UNKNOWN) {
3108
40.2k
      struct cil_symtab_datum *datum;
3109
40.2k
      struct cil_tree_node *n;
3110
40.2k
      rc = cil_resolve_name(current, arg->arg_str, sym_index, db, &datum);
3111
40.2k
      if (rc != SEPOL_OK) {
3112
3.27k
        cil_tree_log(current, CIL_ERR, "Failed to resolve %s in call argument list", arg->arg_str);
3113
3.27k
        goto exit;
3114
3.27k
      }
3115
37.0k
      arg->arg = datum;
3116
37.0k
      n = NODE(datum);
3117
133k
      while (n && n->flavor != CIL_ROOT) {
3118
96.2k
        if (n == current) {
3119
204
          symtab_t *s = datum->symtab;
3120
          /* Call arg should not resolve to declaration in the call
3121
           * Need to remove datum temporarily to resolve to a datum outside
3122
           * the call.
3123
           */
3124
204
          cil_symtab_remove_datum(datum);
3125
204
          rc = cil_resolve_name(current, arg->arg_str, sym_index, db, &(arg->arg));
3126
204
          if (rc != SEPOL_OK) {
3127
4
            cil_tree_log(current, CIL_ERR, "Failed to resolve %s in call argument list", arg->arg_str);
3128
4
            goto exit;
3129
4
          }
3130
200
          rc = cil_symtab_insert(s, datum->name, datum, NULL);
3131
200
          if (rc != SEPOL_OK) {
3132
0
            cil_tree_log(current, CIL_ERR, "Failed to re-insert datum while resolving %s in call argument list", arg->arg_str);
3133
0
            goto exit;
3134
0
          }
3135
200
          break;
3136
200
        }
3137
96.0k
        n = n->parent;
3138
96.0k
      }
3139
37.0k
    }
3140
40.2k
  }
3141
3142
56.9k
  return SEPOL_OK;
3143
3144
65.2k
exit:
3145
65.2k
  return rc;
3146
60.2k
}
3147
3148
int cil_resolve_name_call_args(struct cil_call *call, char *name, enum cil_sym_index sym_index, struct cil_symtab_datum **datum)
3149
15.6M
{
3150
15.6M
  struct cil_list_item *item;
3151
15.6M
  enum cil_sym_index param_index = CIL_SYM_UNKNOWN;
3152
15.6M
  int rc = SEPOL_ERR;
3153
3154
15.6M
  if (call == NULL || name == NULL) {
3155
0
    goto exit;
3156
0
  }
3157
3158
15.6M
  if (call->args == NULL) {
3159
15.3M
    goto exit;
3160
15.3M
  }
3161
3162
313k
  cil_list_for_each(item, call->args) {
3163
313k
    struct cil_args * arg = item->data;
3164
313k
    rc = cil_flavor_to_symtab_index(arg->flavor, &param_index);
3165
313k
    if (param_index == sym_index) {
3166
150k
      if (name == arg->param_str) {
3167
76.8k
        *datum = arg->arg;
3168
76.8k
        rc = *datum ? SEPOL_OK : SEPOL_ERR;
3169
76.8k
        goto exit;
3170
76.8k
      }
3171
150k
    }
3172
313k
  }
3173
3174
222k
  return SEPOL_ERR;
3175
3176
15.4M
exit:
3177
15.4M
  return rc;
3178
298k
}
3179
3180
int cil_resolve_expr(enum cil_flavor expr_type, struct cil_list *str_expr, struct cil_list **datum_expr, struct cil_tree_node *parent, struct cil_db *db)
3181
1.74M
{
3182
1.74M
  int rc = SEPOL_ERR;
3183
1.74M
  struct cil_list_item *curr;
3184
1.74M
  struct cil_symtab_datum *res_datum = NULL;
3185
1.74M
  enum cil_sym_index sym_index =  CIL_SYM_UNKNOWN;
3186
1.74M
  struct cil_list *datum_sub_expr;
3187
1.74M
  enum cil_flavor op = CIL_NONE;
3188
3189
1.74M
  switch (str_expr->flavor) {
3190
322k
  case CIL_BOOL:
3191
322k
    sym_index = CIL_SYM_BOOLS;
3192
322k
    break;
3193
8.92k
  case CIL_TUNABLE:
3194
8.92k
    sym_index = CIL_SYM_TUNABLES;
3195
8.92k
    break;
3196
239k
  case CIL_TYPE:
3197
239k
    sym_index = CIL_SYM_TYPES;
3198
239k
    break;
3199
91.1k
  case CIL_ROLE:
3200
91.1k
    sym_index = CIL_SYM_ROLES;
3201
91.1k
    break;
3202
56.5k
  case CIL_USER:
3203
56.5k
    sym_index = CIL_SYM_USERS;
3204
56.5k
    break;
3205
652k
  case CIL_CAT:
3206
652k
    sym_index = CIL_SYM_CATS;
3207
652k
    break;
3208
375k
  default:
3209
375k
    break;
3210
1.74M
  }
3211
3212
1.74M
  cil_list_init(datum_expr, str_expr->flavor);
3213
3214
3.26M
  cil_list_for_each(curr, str_expr) {
3215
3.26M
    switch (curr->flavor) {
3216
1.17M
    case CIL_STRING:
3217
1.17M
      rc = cil_resolve_name(parent, curr->data, sym_index, db, &res_datum);
3218
1.17M
      if (rc != SEPOL_OK) {
3219
33.3k
        goto exit;
3220
33.3k
      }
3221
1.14M
      if (sym_index == CIL_SYM_CATS && NODE(res_datum)->flavor == CIL_CATSET) {
3222
14.5k
        struct cil_catset *catset = (struct cil_catset *)res_datum;
3223
14.5k
        if (op == CIL_RANGE) {
3224
3
          cil_tree_log(parent, CIL_ERR, "Category set not allowed in category range");
3225
3
          rc = SEPOL_ERR;
3226
3
          goto exit;
3227
3
        }
3228
14.5k
        if (!res_datum->name) {
3229
          /* Anonymous category sets need to be resolved when encountered */
3230
1.24k
          if (!catset->cats->datum_expr) {
3231
506
            rc = cil_resolve_expr(expr_type, catset->cats->str_expr, &catset->cats->datum_expr, parent, db);
3232
506
            if (rc != SEPOL_OK) {
3233
63
              goto exit;
3234
63
            }
3235
506
          }
3236
1.18k
          cil_copy_list(catset->cats->datum_expr, &datum_sub_expr);
3237
1.18k
          cil_list_append(*datum_expr, CIL_LIST, datum_sub_expr);
3238
13.2k
        } else {
3239
13.2k
          cil_list_append(*datum_expr, CIL_DATUM, res_datum);
3240
13.2k
        }
3241
1.13M
      } else {
3242
1.13M
        if (sym_index == CIL_SYM_TYPES && (expr_type == CIL_CONSTRAIN || expr_type == CIL_VALIDATETRANS)) {
3243
92.9k
          cil_type_used(res_datum, CIL_ATTR_CONSTRAINT);
3244
92.9k
        }
3245
1.13M
        cil_list_append(*datum_expr, CIL_DATUM, res_datum);
3246
1.13M
      }
3247
1.14M
      break;
3248
1.14M
    case CIL_LIST: {
3249
440k
      rc = cil_resolve_expr(expr_type, curr->data, &datum_sub_expr, parent, db);
3250
440k
      if (rc != SEPOL_OK) {
3251
12.4k
        goto exit;
3252
12.4k
      }
3253
428k
      cil_list_append(*datum_expr, CIL_LIST, datum_sub_expr);
3254
428k
      break;
3255
440k
    }
3256
1.64M
    default:
3257
1.64M
      if (curr->flavor == CIL_OP) {
3258
1.05M
        op = (enum cil_flavor)(uintptr_t)curr->data;
3259
1.05M
      }
3260
1.64M
      cil_list_append(*datum_expr, curr->flavor, curr->data);
3261
1.64M
      break;
3262
3.26M
    }
3263
3.26M
  }
3264
1.69M
  return SEPOL_OK;
3265
3266
45.8k
exit:
3267
45.8k
  cil_list_destroy(datum_expr, CIL_FALSE);
3268
45.8k
  return rc;
3269
1.74M
}
3270
3271
int cil_resolve_boolif(struct cil_tree_node *current, struct cil_db *db)
3272
280k
{
3273
280k
  int rc = SEPOL_ERR;
3274
280k
  struct cil_booleanif *bif = (struct cil_booleanif*)current->data;
3275
3276
280k
  rc = cil_resolve_expr(CIL_BOOLEANIF, bif->str_expr, &bif->datum_expr, current, db);
3277
280k
  if (rc != SEPOL_OK) {
3278
28.5k
    goto exit;
3279
28.5k
  }
3280
3281
251k
  return SEPOL_OK;
3282
3283
28.5k
exit:
3284
28.5k
  return rc;
3285
280k
}
3286
3287
static int __cil_evaluate_tunable_expr(struct cil_list_item *curr);
3288
3289
static int __cil_evaluate_tunable_expr_helper(struct cil_list_item *curr)
3290
9.85k
{
3291
9.85k
  if (curr == NULL) {
3292
0
    return CIL_FALSE;
3293
9.85k
  } else if (curr->flavor == CIL_DATUM) {
3294
4.12k
    struct cil_tunable *tun = curr->data;
3295
4.12k
    return tun->value;
3296
5.73k
  } else if (curr->flavor == CIL_LIST) {
3297
5.73k
    struct cil_list *l = curr->data;
3298
5.73k
    return __cil_evaluate_tunable_expr(l->head);
3299
5.73k
  } else {
3300
0
    return CIL_FALSE;
3301
0
  }
3302
9.85k
}
3303
3304
static int __cil_evaluate_tunable_expr(struct cil_list_item *curr)
3305
8.53k
{
3306
  /* Assumes expression is well-formed */
3307
3308
8.53k
  if (curr == NULL) {
3309
0
    return CIL_FALSE;
3310
8.53k
  } else if (curr->flavor == CIL_OP) {
3311
1.39k
    uint16_t v1, v2;
3312
1.39k
    enum cil_flavor op_flavor = (enum cil_flavor)(uintptr_t)curr->data;
3313
3314
1.39k
    v1 = __cil_evaluate_tunable_expr_helper(curr->next);
3315
3316
1.39k
    if (op_flavor == CIL_NOT) return !v1;
3317
3318
1.03k
    v2 = __cil_evaluate_tunable_expr_helper(curr->next->next);
3319
3320
1.03k
    if (op_flavor == CIL_AND) return (v1 && v2);
3321
791
    else if (op_flavor == CIL_OR) return (v1 || v2);
3322
668
    else if (op_flavor == CIL_XOR) return (v1 ^ v2);
3323
549
    else if (op_flavor == CIL_EQ) return (v1 == v2);
3324
461
    else if (op_flavor == CIL_NEQ) return (v1 != v2);
3325
0
    else return CIL_FALSE;
3326
7.13k
  } else {
3327
7.13k
    uint16_t v;
3328
12.7k
    for (;curr; curr = curr->next) {
3329
7.42k
      v = __cil_evaluate_tunable_expr_helper(curr);
3330
7.42k
      if (v) return v;
3331
7.42k
    }
3332
5.27k
    return CIL_FALSE;
3333
7.13k
  }
3334
8.53k
}
3335
3336
int cil_resolve_tunif(struct cil_tree_node *current, struct cil_db *db)
3337
3.06k
{
3338
3.06k
  int rc = SEPOL_ERR;
3339
3.06k
  struct cil_tunableif *tif = (struct cil_tunableif*)current->data;
3340
3.06k
  uint16_t result = CIL_FALSE;
3341
3.06k
  struct cil_tree_node *true_node = NULL;
3342
3.06k
  struct cil_tree_node *false_node = NULL;
3343
3.06k
  struct cil_condblock *cb = NULL;
3344
3345
3.06k
  rc = cil_resolve_expr(CIL_TUNABLEIF, tif->str_expr, &tif->datum_expr, current, db);
3346
3.06k
  if (rc != SEPOL_OK) {
3347
264
    goto exit;
3348
264
  }
3349
3350
2.79k
  result = __cil_evaluate_tunable_expr(tif->datum_expr->head);
3351
3352
2.79k
  if (current->cl_head != NULL && current->cl_head->flavor == CIL_CONDBLOCK) {
3353
2.79k
    cb = current->cl_head->data;
3354
2.79k
    if (cb->flavor == CIL_CONDTRUE) {
3355
2.42k
      true_node = current->cl_head;
3356
2.42k
    } else if (cb->flavor == CIL_CONDFALSE) {
3357
369
      false_node = current->cl_head;
3358
369
    }
3359
2.79k
  }
3360
3361
2.79k
  if (current->cl_head != NULL && current->cl_head->next != NULL && current->cl_head->next->flavor == CIL_CONDBLOCK) {
3362
427
    cb = current->cl_head->next->data;
3363
427
    if (cb->flavor == CIL_CONDTRUE) {
3364
50
      true_node = current->cl_head->next;
3365
377
    } else if (cb->flavor == CIL_CONDFALSE) {
3366
377
      false_node = current->cl_head->next;
3367
377
    }
3368
427
  }
3369
3370
2.79k
  if (result == CIL_TRUE) {
3371
2.01k
    if (true_node != NULL) {
3372
1.69k
      rc = cil_copy_ast(db, true_node, current->parent);
3373
1.69k
      if (rc != SEPOL_OK) {
3374
3
        goto exit;
3375
3
      }
3376
1.69k
    }
3377
2.01k
  } else {
3378
786
    if (false_node != NULL) {
3379
11
      rc = cil_copy_ast(db, false_node, current->parent);
3380
11
      if (rc  != SEPOL_OK) {
3381
1
        goto exit;
3382
1
      }
3383
11
    }
3384
786
  }
3385
3386
2.79k
  cil_tree_children_destroy(current);
3387
2.79k
  current->cl_head = NULL;
3388
2.79k
  current->cl_tail = NULL;
3389
3390
2.79k
  return SEPOL_OK;
3391
3392
268
exit:
3393
268
  return rc;
3394
2.79k
}
3395
3396
int cil_resolve_userattributeset(struct cil_tree_node *current, struct cil_db *db)
3397
32.3k
{
3398
32.3k
  int rc = SEPOL_ERR;
3399
32.3k
  struct cil_userattributeset *attrusers = current->data;
3400
32.3k
  struct cil_symtab_datum *attr_datum = NULL;
3401
32.3k
  struct cil_tree_node *attr_node = NULL;
3402
32.3k
  struct cil_userattribute *attr = NULL;
3403
3404
32.3k
  rc = cil_resolve_name(current, attrusers->attr_str, CIL_SYM_USERS, db, &attr_datum);
3405
32.3k
  if (rc != SEPOL_OK) {
3406
3.25k
    goto exit;
3407
3.25k
  }
3408
29.0k
  attr_node = NODE(attr_datum);
3409
3410
29.0k
  if (attr_node->flavor != CIL_USERATTRIBUTE) {
3411
1
    rc = SEPOL_ERR;
3412
1
    cil_log(CIL_ERR, "Attribute user not an attribute\n");
3413
1
    goto exit;
3414
1
  }
3415
29.0k
  attr = (struct cil_userattribute*)attr_datum;
3416
29.0k
  attrusers->attr = attr;
3417
3418
29.0k
  rc = cil_resolve_expr(CIL_USERATTRIBUTESET, attrusers->str_expr, &attrusers->datum_expr, current, db);
3419
29.0k
  if (rc != SEPOL_OK) {
3420
365
    goto exit;
3421
365
  }
3422
3423
28.7k
  if (attr->expr_list == NULL) {
3424
14.1k
    cil_list_init(&attr->expr_list, CIL_USERATTRIBUTE);
3425
14.1k
  }
3426
3427
28.7k
  cil_list_append(attr->expr_list, CIL_LIST, attrusers->datum_expr);
3428
3429
28.7k
  return SEPOL_OK;
3430
3431
3.62k
exit:
3432
3.62k
  return rc;
3433
29.0k
}
3434
3435
/*
3436
 * Degenerate inheritance leads to exponential growth of the policy
3437
 * It can take many forms, but here is one example.
3438
 * ...
3439
 * (blockinherit ba)
3440
 * (block b0
3441
 *   (block b1
3442
 *     (block b2
3443
 *       (block b3
3444
 *         ...
3445
 *       )
3446
 *       (blockinherit b3)
3447
 *     )
3448
 *     (blockinherit b2)
3449
 *   )
3450
 *   (blockinherit b1)
3451
 * )
3452
 * (blockinherit b0)
3453
 * ...
3454
 * This leads to 2^4 copies of the content of block b3, 2^3 copies of the
3455
 * contents of block b2, etc.
3456
 */
3457
static unsigned cil_count_actual(struct cil_tree_node *node)
3458
594k
{
3459
594k
  unsigned count = 0;
3460
3461
594k
  if (node->flavor == CIL_BLOCKINHERIT) {
3462
16.6k
    count += 1;
3463
16.6k
  }
3464
3465
1.17M
  for (node = node->cl_head; node; node = node->next) {
3466
583k
    count += cil_count_actual(node);
3467
583k
  }
3468
3469
594k
  return count;
3470
594k
}
3471
3472
static int cil_check_inheritances(struct cil_tree_node *node, unsigned max, unsigned *count, struct cil_stack *stack, unsigned *loop)
3473
4.38M
{
3474
4.38M
  int rc;
3475
3476
4.38M
  if (node->flavor == CIL_BLOCKINHERIT) {
3477
211k
    struct cil_blockinherit *bi = node->data;
3478
211k
    *count += 1;
3479
211k
    if (*count > max) {
3480
28
      cil_tree_log(node, CIL_ERR, "Degenerate inheritance detected");
3481
28
      return SEPOL_ERR;
3482
28
    }
3483
211k
    if (bi->block) {
3484
211k
      struct cil_tree_node *block_node = NODE(bi->block);
3485
211k
      struct cil_stack_item *item;
3486
211k
      int i = 0;
3487
2.87M
      cil_stack_for_each(stack, i, item) {
3488
2.87M
        if (block_node == (struct cil_tree_node *)item->data) {
3489
25
          *loop = CIL_TRUE;
3490
25
          cil_tree_log(block_node, CIL_ERR, "Block inheritance loop found");
3491
25
          cil_tree_log(node, CIL_ERR, "  blockinherit");
3492
25
          return SEPOL_ERR;
3493
25
        }
3494
2.87M
      }
3495
211k
      cil_stack_push(stack, CIL_BLOCK, block_node);
3496
211k
      rc = cil_check_inheritances(block_node, max, count, stack, loop);
3497
211k
      cil_stack_pop(stack);
3498
211k
      if (rc != SEPOL_OK) {
3499
1.08k
        if (*loop == CIL_TRUE) {
3500
377
          cil_tree_log(node, CIL_ERR, "  blockinherit");
3501
377
        }
3502
1.08k
        return SEPOL_ERR;
3503
1.08k
      }
3504
211k
    }
3505
211k
  }
3506
3507
8.54M
  for (node = node->cl_head; node; node = node->next) {
3508
4.16M
    rc = cil_check_inheritances(node, max, count, stack, loop);
3509
4.16M
    if (rc != SEPOL_OK) {
3510
6.69k
      return SEPOL_ERR;
3511
6.69k
    }
3512
4.16M
  }
3513
3514
4.38M
  return SEPOL_OK;
3515
4.38M
}
3516
3517
static int cil_check_for_bad_inheritance(struct cil_tree_node *node)
3518
11.7k
{
3519
11.7k
  unsigned num_actual, max;
3520
11.7k
  unsigned num_potential = 0;
3521
11.7k
  unsigned loop = CIL_FALSE;
3522
11.7k
  struct cil_stack *stack;
3523
11.7k
  int rc;
3524
3525
11.7k
  num_actual = cil_count_actual(node);
3526
3527
11.7k
  max = num_actual * CIL_DEGENERATE_INHERITANCE_GROWTH;
3528
11.7k
  if (max < CIL_DEGENERATE_INHERITANCE_MINIMUM) {
3529
11.6k
    max = CIL_DEGENERATE_INHERITANCE_MINIMUM;
3530
11.6k
  }
3531
3532
11.7k
  cil_stack_init(&stack);
3533
11.7k
  rc = cil_check_inheritances(node, max, &num_potential, stack, &loop);
3534
11.7k
  cil_stack_destroy(&stack);
3535
3536
11.7k
  return rc;
3537
11.7k
}
3538
3539
static int __cil_resolve_ast_node(struct cil_tree_node *node, struct cil_args_resolve *args)
3540
85.9M
{
3541
85.9M
  int rc = SEPOL_OK;
3542
85.9M
  struct cil_db *db = args->db;
3543
85.9M
  enum cil_pass pass = 0;
3544
3545
85.9M
  pass = args->pass;
3546
85.9M
  switch (pass) {
3547
632k
  case CIL_PASS_TIF:
3548
632k
    if (node->flavor == CIL_TUNABLEIF) {
3549
3.06k
      rc = cil_resolve_tunif(node, db);
3550
3.06k
    }
3551
632k
    break;
3552
628k
  case CIL_PASS_IN_BEFORE:
3553
628k
    if (node->flavor == CIL_IN) {
3554
      // due to ordering issues, in statements are just gathered here and
3555
      // resolved together in cil_resolve_in_list once all are found
3556
14.2k
      struct cil_in *in = node->data;
3557
14.2k
      if (in->is_after == CIL_FALSE) {
3558
14.2k
        cil_list_prepend(args->in_list_before, CIL_NODE, node);
3559
14.2k
      }
3560
14.2k
    }
3561
628k
    break;
3562
583k
  case CIL_PASS_BLKIN_LINK:
3563
583k
    if (node->flavor == CIL_BLOCKINHERIT) {
3564
16.7k
      rc = cil_resolve_blockinherit_link(node, db);
3565
16.7k
    }
3566
583k
    break;
3567
2.79M
  case CIL_PASS_BLKIN_COPY:
3568
2.79M
    if (node->flavor == CIL_BLOCK) {
3569
355k
      rc = cil_resolve_blockinherit_copy(node, db);
3570
355k
    }
3571
2.79M
    break;
3572
3.54M
  case CIL_PASS_BLKABS:
3573
3.54M
    if (node->flavor == CIL_BLOCKABSTRACT) {
3574
971
      rc = cil_resolve_blockabstract(node, db, args->abstract_blocks);
3575
971
    }
3576
3.54M
    break;
3577
3.53M
  case CIL_PASS_IN_AFTER:
3578
3.53M
    if (node->flavor == CIL_IN) {
3579
      // due to ordering issues, in statements are just gathered here and
3580
      // resolved together in cil_resolve_in_list once all are found
3581
9.01k
      struct cil_in *in = node->data;
3582
9.01k
      if (in->is_after == CIL_TRUE) {
3583
0
        cil_list_prepend(args->in_list_after, CIL_NODE, node);
3584
0
      }
3585
9.01k
    }
3586
3.53M
    break;
3587
7.73M
  case CIL_PASS_CALL1:
3588
7.73M
    if (node->flavor == CIL_CALL && args->macro == NULL) {
3589
82.7k
      rc = cil_resolve_call(node, db);
3590
82.7k
    }
3591
7.73M
    break;
3592
10.0M
  case CIL_PASS_CALL2:
3593
10.0M
    if (node->flavor == CIL_CALL && args->macro == NULL) {
3594
122k
      rc = cil_resolve_call_args(node, db);
3595
122k
    }
3596
10.0M
    break;
3597
10.0M
  case CIL_PASS_ALIAS1:
3598
10.0M
    switch (node->flavor) {
3599
5.24k
    case CIL_TYPEALIASACTUAL:
3600
5.24k
      rc = cil_resolve_aliasactual(node, db, CIL_TYPE, CIL_TYPEALIAS);
3601
5.24k
      break;
3602
4.98k
    case CIL_SENSALIASACTUAL:
3603
4.98k
      rc = cil_resolve_aliasactual(node, db, CIL_SENS, CIL_SENSALIAS);
3604
4.98k
      break;
3605
3.72k
    case CIL_CATALIASACTUAL:
3606
3.72k
      rc = cil_resolve_aliasactual(node, db, CIL_CAT, CIL_CATALIAS);
3607
3.72k
      break;
3608
10.0M
    default: 
3609
10.0M
      break;
3610
10.0M
    }
3611
10.0M
    break;
3612
10.0M
  case CIL_PASS_ALIAS2:
3613
9.67M
    switch (node->flavor) {
3614
1.64k
    case CIL_TYPEALIAS:
3615
1.64k
      rc = cil_resolve_alias_to_actual(node, CIL_TYPE);
3616
1.64k
      break;
3617
1.29k
    case CIL_SENSALIAS:
3618
1.29k
      rc = cil_resolve_alias_to_actual(node, CIL_SENS);
3619
1.29k
      break;
3620
3.05k
    case CIL_CATALIAS:
3621
3.05k
      rc = cil_resolve_alias_to_actual(node, CIL_CAT);
3622
3.05k
      break;
3623
9.67M
    default:
3624
9.67M
      break;
3625
9.67M
    }
3626
9.67M
    break;
3627
9.67M
  case CIL_PASS_MISC1:
3628
9.42M
    switch (node->flavor) {
3629
23.2k
    case CIL_SIDORDER:
3630
23.2k
      rc = cil_resolve_sidorder(node, db, args->sidorder_lists);
3631
23.2k
      break;
3632
43.7k
    case CIL_CLASSORDER:
3633
43.7k
      rc = cil_resolve_classorder(node, db, args->classorder_lists, args->unordered_classorder_lists);
3634
43.7k
      break;
3635
16.4k
    case CIL_CATORDER:
3636
16.4k
      rc = cil_resolve_catorder(node, db, args->catorder_lists);
3637
16.4k
      break;
3638
5.24k
    case CIL_SENSITIVITYORDER:
3639
5.24k
      rc = cil_resolve_sensitivityorder(node, db, args->sensitivityorder_lists);
3640
5.24k
      break;
3641
280k
    case CIL_BOOLEANIF:
3642
280k
      rc = cil_resolve_boolif(node, db);
3643
280k
      break;
3644
9.05M
    default:
3645
9.05M
      break;
3646
9.42M
    }
3647
9.42M
    break;
3648
9.42M
  case CIL_PASS_MLS:
3649
9.21M
    switch (node->flavor) {
3650
5.57k
    case CIL_CATSET:
3651
5.57k
      rc = cil_resolve_catset(node, (struct cil_catset*)node->data, db);
3652
5.57k
      break;
3653
9.20M
    default:
3654
9.20M
      break;
3655
9.21M
    }
3656
9.21M
    break;
3657
9.21M
  case CIL_PASS_MISC2:
3658
9.20M
    switch (node->flavor) {
3659
30.3k
    case CIL_SENSCAT:
3660
30.3k
      rc = cil_resolve_senscat(node, db);
3661
30.3k
      break;
3662
10.9k
    case CIL_CLASSCOMMON:
3663
10.9k
      rc = cil_resolve_classcommon(node, db);
3664
10.9k
      break;
3665
9.16M
    default:
3666
9.16M
      break;
3667
9.20M
    }
3668
9.20M
    break;
3669
9.20M
  case CIL_PASS_MISC3:
3670
8.85M
    switch (node->flavor) {
3671
118k
    case CIL_TYPEATTRIBUTESET:
3672
118k
      rc = cil_resolve_typeattributeset(node, db);
3673
118k
      break;
3674
3.39k
    case CIL_EXPANDTYPEATTRIBUTE:
3675
3.39k
      rc = cil_resolve_expandtypeattribute(node, db);
3676
3.39k
      break;
3677
8.74k
    case CIL_TYPEBOUNDS:
3678
8.74k
      rc = cil_resolve_bounds(node, db, CIL_TYPE, CIL_TYPEATTRIBUTE);
3679
8.74k
      break;
3680
2.47k
    case CIL_TYPEPERMISSIVE:
3681
2.47k
      rc = cil_resolve_typepermissive(node, db);
3682
2.47k
      break;
3683
1.87k
    case CIL_TYPENEVERAUDIT:
3684
1.87k
      rc = cil_resolve_typeneveraudit(node, db);
3685
1.87k
      break;
3686
46.4k
    case CIL_NAMETYPETRANSITION:
3687
46.4k
      rc = cil_resolve_nametypetransition(node, db);
3688
46.4k
      break;
3689
35.3k
    case CIL_RANGETRANSITION:
3690
35.3k
      rc = cil_resolve_rangetransition(node, db);
3691
35.3k
      break;
3692
8.74k
    case CIL_CLASSPERMISSIONSET:
3693
8.74k
      rc = cil_resolve_classpermissionset(node, (struct cil_classpermissionset*)node->data, db);
3694
8.74k
      break;
3695
72.5k
    case CIL_CLASSMAPPING:
3696
72.5k
      rc = cil_resolve_classmapping(node, db);
3697
72.5k
      break;
3698
941k
    case CIL_AVRULE:
3699
972k
    case CIL_AVRULEX:
3700
972k
      rc = cil_resolve_avrule(node, db);
3701
972k
      break;
3702
6.35k
    case CIL_PERMISSIONX:
3703
6.35k
      rc = cil_resolve_permissionx(node, (struct cil_permissionx*)node->data, db);
3704
6.35k
      break;
3705
31.6k
    case CIL_DENY_RULE:
3706
31.6k
      rc = cil_resolve_deny_rule(node, db);
3707
31.6k
      break;
3708
73.3k
    case CIL_TYPE_RULE:
3709
73.3k
      rc = cil_resolve_type_rule(node, db);
3710
73.3k
      break;
3711
42.0k
    case CIL_USERROLE:
3712
42.0k
      rc = cil_resolve_userrole(node, db);
3713
42.0k
      break;
3714
31.1k
    case CIL_USERLEVEL:
3715
31.1k
      rc = cil_resolve_userlevel(node, db);
3716
31.1k
      break;
3717
447k
    case CIL_USERRANGE:
3718
447k
      rc = cil_resolve_userrange(node, db);
3719
447k
      break;
3720
1.06k
    case CIL_USERBOUNDS:
3721
1.06k
      rc = cil_resolve_bounds(node, db, CIL_USER, CIL_USERATTRIBUTE);
3722
1.06k
      break;
3723
2.29k
    case CIL_USERPREFIX:
3724
2.29k
      rc = cil_resolve_userprefix(node, db);
3725
2.29k
      break;
3726
1.45k
    case CIL_SELINUXUSER:
3727
3.85k
    case CIL_SELINUXUSERDEFAULT:
3728
3.85k
      rc = cil_resolve_selinuxuser(node, db);
3729
3.85k
      break;
3730
11.8k
    case CIL_ROLEATTRIBUTESET:
3731
11.8k
      rc = cil_resolve_roleattributeset(node, db);
3732
11.8k
      break;
3733
193k
    case CIL_ROLETYPE:
3734
193k
      rc = cil_resolve_roletype(node, db);
3735
193k
      break;
3736
27.4k
    case CIL_ROLETRANSITION:
3737
27.4k
      rc = cil_resolve_roletransition(node, db);
3738
27.4k
      break;
3739
8.06k
    case CIL_ROLEALLOW:
3740
8.06k
      rc = cil_resolve_roleallow(node, db);
3741
8.06k
      break;
3742
9.05k
    case CIL_ROLEBOUNDS:
3743
9.05k
      rc = cil_resolve_bounds(node, db, CIL_ROLE, CIL_ROLEATTRIBUTE);
3744
9.05k
      break;
3745
12.0k
    case CIL_LEVEL:
3746
12.0k
      rc = cil_resolve_level(node, (struct cil_level*)node->data, db);
3747
12.0k
      break;
3748
6.93k
    case CIL_LEVELRANGE:
3749
6.93k
      rc = cil_resolve_levelrange(node, (struct cil_levelrange*)node->data, db);
3750
6.93k
      break;
3751
65.6k
    case CIL_CONSTRAIN:
3752
65.6k
      rc = cil_resolve_constrain(node, db);
3753
65.6k
      break;
3754
65.8k
    case CIL_MLSCONSTRAIN:
3755
65.8k
      rc = cil_resolve_constrain(node, db);
3756
65.8k
      break;
3757
125k
    case CIL_VALIDATETRANS:
3758
140k
    case CIL_MLSVALIDATETRANS:
3759
140k
      rc = cil_resolve_validatetrans(node, db);
3760
140k
      break;
3761
4.94k
    case CIL_CONTEXT:
3762
4.94k
      rc = cil_resolve_context(node, (struct cil_context*)node->data, db);
3763
4.94k
      break;
3764
530k
    case CIL_FILECON:
3765
530k
      rc = cil_resolve_filecon(node, db);
3766
530k
      break;
3767
1.23M
    case CIL_IBPKEYCON:
3768
1.23M
      rc = cil_resolve_ibpkeycon(node, db);
3769
1.23M
      break;
3770
83.8k
    case CIL_PORTCON:
3771
83.8k
      rc = cil_resolve_portcon(node, db);
3772
83.8k
      break;
3773
39.0k
    case CIL_NODECON:
3774
39.0k
      rc = cil_resolve_nodecon(node, db);
3775
39.0k
      break;
3776
14.7k
    case CIL_GENFSCON:
3777
14.7k
      rc = cil_resolve_genfscon(node, db);
3778
14.7k
      break;
3779
16.6k
    case CIL_NETIFCON:
3780
16.6k
      rc = cil_resolve_netifcon(node, db);
3781
16.6k
      break;
3782
611k
    case CIL_IBENDPORTCON:
3783
611k
      rc = cil_resolve_ibendportcon(node, db);
3784
611k
      break;
3785
210k
    case CIL_PIRQCON:
3786
210k
      rc = cil_resolve_pirqcon(node, db);
3787
210k
      break;
3788
130k
    case CIL_IOMEMCON:
3789
130k
      rc = cil_resolve_iomemcon(node, db);
3790
130k
      break;
3791
8.55k
    case CIL_IOPORTCON:
3792
8.55k
      rc = cil_resolve_ioportcon(node, db);
3793
8.55k
      break;
3794
20.8k
    case CIL_PCIDEVICECON:
3795
20.8k
      rc = cil_resolve_pcidevicecon(node, db);
3796
20.8k
      break;
3797
3.31k
    case CIL_DEVICETREECON:
3798
3.31k
      rc = cil_resolve_devicetreecon(node, db);
3799
3.31k
      break;
3800
85.5k
    case CIL_FSUSE:
3801
85.5k
      rc = cil_resolve_fsuse(node, db);
3802
85.5k
      break;
3803
3.18k
    case CIL_SIDCONTEXT:
3804
3.18k
      rc = cil_resolve_sidcontext(node, db);
3805
3.18k
      break;
3806
14.6k
    case CIL_DEFAULTUSER:
3807
40.3k
    case CIL_DEFAULTROLE:
3808
52.7k
    case CIL_DEFAULTTYPE:
3809
52.7k
      rc = cil_resolve_default(node, db);
3810
52.7k
      break;
3811
61.5k
    case CIL_DEFAULTRANGE:
3812
61.5k
      rc = cil_resolve_defaultrange(node, db);
3813
61.5k
      break;
3814
32.3k
    case CIL_USERATTRIBUTESET:
3815
32.3k
      rc = cil_resolve_userattributeset(node, db);
3816
32.3k
      break;
3817
3.26M
    default:
3818
3.26M
      break;
3819
8.85M
    }
3820
8.85M
    break;
3821
8.85M
  default:
3822
0
    break;
3823
85.9M
  }
3824
3825
85.9M
  return rc;
3826
85.9M
}
3827
3828
static int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args)
3829
86.2M
{
3830
86.2M
  int rc = SEPOL_OK;
3831
86.2M
  struct cil_args_resolve *args = extra_args;
3832
86.2M
  enum cil_pass pass = args->pass;
3833
86.2M
  struct cil_tree_node *block = args->block;
3834
86.2M
  struct cil_tree_node *macro = args->macro;
3835
86.2M
  struct cil_tree_node *optional = args->optional;
3836
86.2M
  struct cil_tree_node *boolif = args->boolif;
3837
3838
86.2M
  if (node == NULL) {
3839
0
    goto exit;
3840
0
  }
3841
3842
86.2M
  if (block != NULL) {
3843
41.0M
    if (node->flavor == CIL_CAT ||
3844
41.0M
        node->flavor == CIL_SENS) {
3845
7
      cil_tree_log(node, CIL_ERR, "%s is not allowed in block", cil_node_to_string(node));
3846
7
      rc = SEPOL_ERR;
3847
7
      goto exit;
3848
7
    }
3849
41.0M
  }
3850
3851
86.2M
  if (macro != NULL) {
3852
235k
    if (node->flavor == CIL_TUNABLE ||
3853
235k
      node->flavor == CIL_IN ||
3854
235k
      node->flavor == CIL_BLOCK ||
3855
235k
        node->flavor == CIL_BLOCKINHERIT ||
3856
235k
        node->flavor == CIL_BLOCKABSTRACT ||
3857
235k
        node->flavor == CIL_MACRO) {
3858
20
      cil_tree_log(node, CIL_ERR, "%s is not allowed in macro", cil_node_to_string(node));
3859
20
      rc = SEPOL_ERR;
3860
20
      goto exit;
3861
20
    }
3862
235k
  }
3863
3864
86.2M
  if (optional != NULL) {
3865
18.3M
    if (node->flavor == CIL_TUNABLE ||
3866
18.3M
      node->flavor == CIL_IN ||
3867
18.3M
      node->flavor == CIL_BLOCK ||
3868
18.3M
      node->flavor == CIL_BLOCKABSTRACT ||
3869
18.3M
        node->flavor == CIL_MACRO) {
3870
6
      cil_tree_log(node, CIL_ERR, "%s is not allowed in optional", cil_node_to_string(node));
3871
6
      rc = SEPOL_ERR;
3872
6
      goto exit;
3873
6
    }
3874
18.3M
  }
3875
3876
86.2M
  if (boolif != NULL) {
3877
6.63M
    if (node->flavor != CIL_TUNABLEIF &&
3878
6.62M
      node->flavor != CIL_CALL &&
3879
6.62M
      node->flavor != CIL_CONDBLOCK &&
3880
4.04M
      node->flavor != CIL_AVRULE &&
3881
255k
      node->flavor != CIL_TYPE_RULE &&
3882
5.06k
      node->flavor != CIL_NAMETYPETRANSITION &&
3883
4.17k
      node->flavor != CIL_SRC_INFO &&
3884
3.08k
      ((args->db->policy_version < POLICYDB_VERSION_COND_XPERMS) ||
3885
3.08k
       (node->flavor != CIL_AVRULEX))) {
3886
25
      rc = SEPOL_ERR;
3887
6.63M
    } else if (node->flavor == CIL_AVRULE || node->flavor == CIL_AVRULEX) {
3888
3.78M
      struct cil_avrule *rule = node->data;
3889
3.78M
      if (rule->rule_kind == CIL_AVRULE_NEVERALLOW) {
3890
1
        rc = SEPOL_ERR;
3891
1
      }
3892
3.78M
    }
3893
6.63M
    if (rc == SEPOL_ERR) {
3894
26
      if (((struct cil_booleanif*)boolif->data)->preserved_tunable) {
3895
0
        cil_tree_log(node, CIL_ERR, "%s is not allowed in tunableif being treated as a booleanif", cil_node_to_string(node));
3896
26
      } else {
3897
26
        cil_tree_log(node, CIL_ERR, "%s is not allowed in booleanif", cil_node_to_string(node));
3898
26
      }
3899
26
      goto exit;
3900
26
    }
3901
6.63M
  }
3902
3903
86.2M
  if (node->flavor == CIL_MACRO) {
3904
344k
    if (pass > CIL_PASS_IN_AFTER) {
3905
261k
      *finished = CIL_TREE_SKIP_HEAD;
3906
261k
      rc = SEPOL_OK;
3907
261k
      goto exit;
3908
261k
    }
3909
344k
  }
3910
3911
85.9M
  if (node->flavor == CIL_BLOCK && ((((struct cil_block*)node->data)->is_abstract == CIL_TRUE) && (pass > CIL_PASS_BLKABS))) {
3912
9.44k
    *finished = CIL_TREE_SKIP_HEAD;
3913
9.44k
    rc = SEPOL_OK;
3914
9.44k
    goto exit;
3915
9.44k
  }
3916
3917
85.9M
  rc = __cil_resolve_ast_node(node, args);
3918
85.9M
  if (rc == SEPOL_ENOENT) {
3919
280k
    if (optional == NULL) {
3920
1.56k
      cil_tree_log(node, CIL_ERR, "Failed to resolve %s statement", cil_node_to_string(node));
3921
278k
    } else {
3922
278k
      if (!args->disabled_optional) {
3923
62.3k
        args->disabled_optional = optional;
3924
62.3k
      }
3925
278k
      cil_tree_log(node, CIL_INFO, "Failed to resolve %s statement", cil_node_to_string(node));
3926
278k
      cil_tree_log(optional, CIL_INFO, "Disabling optional '%s'", DATUM(optional->data)->name);
3927
278k
      rc = SEPOL_OK;
3928
278k
    }
3929
280k
    goto exit;
3930
280k
  }
3931
3932
85.6M
  return rc;
3933
3934
550k
exit:
3935
550k
  return rc;
3936
85.9M
}
3937
3938
static int __cil_resolve_ast_first_child_helper(struct cil_tree_node *current, void *extra_args)
3939
14.4M
{
3940
14.4M
  int rc = SEPOL_ERR;
3941
14.4M
  struct cil_args_resolve *args = extra_args;
3942
14.4M
  struct cil_tree_node *parent = NULL;
3943
3944
14.4M
  if (current == NULL || extra_args == NULL) {
3945
0
    goto exit;
3946
0
  }
3947
3948
14.4M
  parent = current->parent;
3949
3950
14.4M
  if (parent->flavor == CIL_BLOCK) {
3951
5.04M
    args->block = parent;
3952
9.37M
  } else if (parent->flavor == CIL_MACRO) {
3953
77.3k
    args->macro = parent;
3954
9.29M
  } else if (parent->flavor == CIL_OPTIONAL) {
3955
957k
    args->optional = parent;
3956
8.33M
  } else if (parent->flavor == CIL_BOOLEANIF) {
3957
2.43M
    args->boolif = parent;
3958
2.43M
  }
3959
3960
14.4M
  return SEPOL_OK;
3961
3962
0
exit:
3963
0
  return rc;
3964
3965
14.4M
}
3966
3967
static int __cil_resolve_ast_last_child_helper(struct cil_tree_node *current, void *extra_args)
3968
14.4M
{
3969
14.4M
  int rc = SEPOL_ERR;
3970
14.4M
  struct cil_args_resolve *args = extra_args;
3971
14.4M
  struct cil_tree_node *parent = NULL;
3972
3973
14.4M
  if (current == NULL ||  extra_args == NULL) {
3974
0
    goto exit;
3975
0
  }
3976
3977
14.4M
  parent = current->parent;
3978
3979
14.4M
  if (parent->flavor == CIL_BLOCK) {
3980
5.04M
    struct cil_tree_node *n = parent->parent;
3981
5.04M
    args->block = NULL;
3982
6.22M
    while (n && n->flavor != CIL_ROOT) {
3983
6.13M
      if (n->flavor == CIL_BLOCK) {
3984
4.96M
        args->block = n;
3985
4.96M
        break;
3986
4.96M
      }
3987
1.17M
      n = n->parent;
3988
1.17M
    }
3989
9.36M
  } else if (parent->flavor == CIL_MACRO) {
3990
77.3k
    args->macro = NULL;
3991
9.29M
  } else if (parent->flavor == CIL_OPTIONAL) {
3992
957k
    struct cil_tree_node *n = parent->parent;
3993
957k
    if (args->disabled_optional == parent) {
3994
62.3k
      *(args->changed) = CIL_TRUE;
3995
62.3k
      cil_list_append(args->to_destroy, CIL_NODE, parent);
3996
62.3k
      args->disabled_optional = NULL;
3997
62.3k
    }
3998
957k
    args->optional = NULL;
3999
11.4M
    while (n && n->flavor != CIL_ROOT) {
4000
10.5M
      if (n->flavor == CIL_OPTIONAL) {
4001
96.7k
        args->optional = n;
4002
96.7k
        break;
4003
96.7k
      }
4004
10.4M
      n = n->parent;
4005
10.4M
    }
4006
8.33M
  } else if (parent->flavor == CIL_BOOLEANIF) {
4007
2.43M
    args->boolif = NULL;
4008
2.43M
  }
4009
4010
14.4M
  return SEPOL_OK;
4011
4012
0
exit:
4013
0
  return rc;
4014
14.4M
}
4015
4016
int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
4017
12.3k
{
4018
12.3k
  int rc = SEPOL_ERR;
4019
12.3k
  struct cil_args_resolve extra_args;
4020
12.3k
  enum cil_pass pass = CIL_PASS_TIF;
4021
12.3k
  uint32_t changed = 0;
4022
4023
12.3k
  if (db == NULL || current == NULL) {
4024
0
    return rc;
4025
0
  }
4026
4027
12.3k
  extra_args.db = db;
4028
12.3k
  extra_args.pass = pass;
4029
12.3k
  extra_args.changed = &changed;
4030
12.3k
  extra_args.block = NULL;
4031
12.3k
  extra_args.macro = NULL;
4032
12.3k
  extra_args.optional = NULL;
4033
12.3k
  extra_args.disabled_optional = NULL;
4034
12.3k
  extra_args.boolif= NULL;
4035
12.3k
  extra_args.sidorder_lists = NULL;
4036
12.3k
  extra_args.classorder_lists = NULL;
4037
12.3k
  extra_args.unordered_classorder_lists = NULL;
4038
12.3k
  extra_args.catorder_lists = NULL;
4039
12.3k
  extra_args.sensitivityorder_lists = NULL;
4040
12.3k
  extra_args.in_list_before = NULL;
4041
12.3k
  extra_args.in_list_after = NULL;
4042
12.3k
  extra_args.abstract_blocks = NULL;
4043
4044
12.3k
  cil_list_init(&extra_args.to_destroy, CIL_NODE);
4045
12.3k
  cil_list_init(&extra_args.sidorder_lists, CIL_SIDORDER);
4046
12.3k
  cil_list_init(&extra_args.classorder_lists, CIL_CLASSORDER);
4047
12.3k
  cil_list_init(&extra_args.unordered_classorder_lists, CIL_CLASSORDER);
4048
12.3k
  cil_list_init(&extra_args.catorder_lists, CIL_CATORDER);
4049
12.3k
  cil_list_init(&extra_args.sensitivityorder_lists, CIL_SENSITIVITYORDER);
4050
12.3k
  cil_list_init(&extra_args.in_list_before, CIL_IN);
4051
12.3k
  cil_list_init(&extra_args.in_list_after, CIL_IN);
4052
12.3k
  cil_list_init(&extra_args.abstract_blocks, CIL_NODE);
4053
4054
187k
  for (pass = CIL_PASS_TIF; pass < CIL_PASS_NUM; pass++) {
4055
177k
    extra_args.pass = pass;
4056
177k
    rc = cil_tree_walk(current, __cil_resolve_ast_node_helper, __cil_resolve_ast_first_child_helper, __cil_resolve_ast_last_child_helper, &extra_args);
4057
177k
    if (rc != SEPOL_OK) {
4058
2.03k
      cil_log(CIL_INFO, "Pass %i of resolution failed\n", pass);
4059
2.03k
      goto exit;
4060
2.03k
    }
4061
4062
175k
    if (pass == CIL_PASS_IN_BEFORE) {
4063
12.2k
      rc = cil_resolve_in_list(extra_args.in_list_before, db);
4064
12.2k
      if (rc != SEPOL_OK) {
4065
470
        goto exit;
4066
470
      }
4067
11.7k
      cil_list_destroy(&extra_args.in_list_before, CIL_FALSE);
4068
163k
    } else if (pass == CIL_PASS_IN_AFTER) {
4069
11.6k
      rc = cil_resolve_in_list(extra_args.in_list_after, db);
4070
11.6k
      if (rc != SEPOL_OK) {
4071
0
        goto exit;
4072
0
      }
4073
11.6k
      cil_list_destroy(&extra_args.in_list_after, CIL_FALSE);
4074
11.6k
    }
4075
4076
175k
    if (pass == CIL_PASS_BLKABS) {
4077
11.6k
      struct cil_list_item *item;
4078
11.6k
      cil_list_for_each(item, extra_args.abstract_blocks) {
4079
957
        cil_mark_subtree_abstract(item->data);
4080
957
      }
4081
11.6k
    }
4082
4083
175k
    if (pass == CIL_PASS_BLKIN_LINK) {
4084
11.7k
      rc = cil_check_for_bad_inheritance(current);
4085
11.7k
      if (rc != SEPOL_OK) {
4086
53
        rc = SEPOL_ERR;
4087
53
        goto exit;
4088
53
      }
4089
11.7k
    }
4090
4091
175k
    if (pass == CIL_PASS_MISC1) {
4092
13.6k
      db->sidorder = __cil_ordered_lists_merge_all(&extra_args.sidorder_lists, NULL);
4093
13.6k
      if (db->sidorder == NULL) {
4094
40
        rc = SEPOL_ERR;
4095
40
        goto exit;
4096
40
      }
4097
13.5k
      db->classorder = __cil_ordered_lists_merge_all(&extra_args.classorder_lists, &extra_args.unordered_classorder_lists);
4098
13.5k
      if (db->classorder == NULL) {
4099
77
        rc = SEPOL_ERR;
4100
77
        goto exit;
4101
77
      }
4102
13.5k
      db->catorder = __cil_ordered_lists_merge_all(&extra_args.catorder_lists, NULL);
4103
13.5k
      if (db->catorder == NULL) {
4104
70
        rc = SEPOL_ERR;
4105
70
        goto exit;
4106
70
      }
4107
13.4k
      cil_set_cat_values(db->catorder, db);
4108
13.4k
      db->sensitivityorder = __cil_ordered_lists_merge_all(&extra_args.sensitivityorder_lists, NULL);
4109
13.4k
      if (db->sensitivityorder == NULL) {
4110
14
        rc = SEPOL_ERR;
4111
14
        goto exit;
4112
14
      }
4113
4114
13.4k
      rc = __cil_verify_ordered(current, CIL_SID);
4115
13.4k
      if (rc != SEPOL_OK) {
4116
97
        goto exit;
4117
97
      }
4118
4119
13.3k
      rc = __cil_verify_ordered(current, CIL_CLASS);
4120
13.3k
      if (rc != SEPOL_OK) {
4121
97
        goto exit;
4122
97
      }
4123
4124
13.2k
      rc = __cil_verify_ordered(current, CIL_CAT);
4125
13.2k
      if (rc != SEPOL_OK) {
4126
20
        goto exit;
4127
20
      }
4128
4129
13.2k
      rc = __cil_verify_ordered(current, CIL_SENS);
4130
13.2k
      if (rc != SEPOL_OK) {
4131
23
        goto exit;
4132
23
      }
4133
13.2k
    }
4134
4135
174k
    if (changed) {
4136
3.01k
      struct cil_list_item *item;
4137
3.01k
      if (pass > CIL_PASS_CALL1) {
4138
2.94k
        int has_decls = CIL_FALSE;
4139
4140
2.94k
        cil_list_for_each(item, extra_args.to_destroy) {
4141
2.94k
          has_decls = cil_tree_subtree_has_decl(item->data);
4142
2.94k
          if (has_decls) {
4143
2.94k
            break;
4144
2.94k
          }
4145
2.94k
        }
4146
4147
2.94k
        if (has_decls) {
4148
          /* Need to re-resolve because an optional was disabled that
4149
           * contained one or more declarations.
4150
           * Everything that needs to be reset comes after the
4151
           * CIL_PASS_CALL2 pass. We set pass to CIL_PASS_CALL1 because
4152
           * the pass++ will increment it to CIL_PASS_CALL2
4153
           */
4154
2.94k
          cil_log(CIL_INFO, "Resetting declarations\n");
4155
4156
2.94k
          if (pass >= CIL_PASS_MISC1) {
4157
2.73k
            cil_list_destroy(&extra_args.sidorder_lists, CIL_FALSE);
4158
2.73k
            cil_list_destroy(&extra_args.classorder_lists, CIL_FALSE);
4159
2.73k
            cil_list_destroy(&extra_args.catorder_lists, CIL_FALSE);
4160
2.73k
            cil_list_destroy(&extra_args.sensitivityorder_lists, CIL_FALSE);
4161
2.73k
            cil_list_destroy(&extra_args.unordered_classorder_lists, CIL_FALSE);
4162
2.73k
            cil_list_init(&extra_args.sidorder_lists, CIL_SIDORDER);
4163
2.73k
            cil_list_init(&extra_args.classorder_lists, CIL_CLASSORDER);
4164
2.73k
            cil_list_init(&extra_args.unordered_classorder_lists, CIL_CLASSORDER);
4165
2.73k
            cil_list_init(&extra_args.catorder_lists, CIL_CATORDER);
4166
2.73k
            cil_list_init(&extra_args.sensitivityorder_lists, CIL_SENSITIVITYORDER);
4167
2.73k
            cil_list_destroy(&db->sidorder, CIL_FALSE);
4168
2.73k
            cil_list_destroy(&db->classorder, CIL_FALSE);
4169
2.73k
            cil_list_destroy(&db->catorder, CIL_FALSE);
4170
2.73k
            cil_list_destroy(&db->sensitivityorder, CIL_FALSE);
4171
2.73k
          }
4172
4173
2.94k
          pass = CIL_PASS_CALL1;
4174
4175
2.94k
          rc = cil_reset_ast(current);
4176
2.94k
          if (rc != SEPOL_OK) {
4177
0
            cil_log(CIL_ERR, "Failed to reset declarations\n");
4178
0
            goto exit;
4179
0
          }
4180
2.94k
        }
4181
2.94k
      }
4182
59.8k
      cil_list_for_each(item, extra_args.to_destroy) {
4183
59.8k
        cil_tree_children_destroy(item->data);
4184
59.8k
      }
4185
3.01k
      cil_list_destroy(&extra_args.to_destroy, CIL_FALSE);
4186
3.01k
      cil_list_init(&extra_args.to_destroy, CIL_NODE);
4187
3.01k
      changed = 0;
4188
3.01k
    }
4189
174k
  }
4190
4191
9.31k
  rc = __cil_verify_initsids(db->sidorder);
4192
9.31k
  if (rc != SEPOL_OK) {
4193
2.43k
    goto exit;
4194
2.43k
  }
4195
4196
6.88k
  rc = SEPOL_OK;
4197
12.3k
exit:
4198
12.3k
  cil_list_destroy(&extra_args.sidorder_lists, CIL_FALSE);
4199
12.3k
  cil_list_destroy(&extra_args.classorder_lists, CIL_FALSE);
4200
12.3k
  cil_list_destroy(&extra_args.catorder_lists, CIL_FALSE);
4201
12.3k
  cil_list_destroy(&extra_args.sensitivityorder_lists, CIL_FALSE);
4202
12.3k
  cil_list_destroy(&extra_args.unordered_classorder_lists, CIL_FALSE);
4203
12.3k
  cil_list_destroy(&extra_args.to_destroy, CIL_FALSE);
4204
12.3k
  cil_list_destroy(&extra_args.in_list_before, CIL_FALSE);
4205
12.3k
  cil_list_destroy(&extra_args.in_list_after, CIL_FALSE);
4206
12.3k
  cil_list_destroy(&extra_args.abstract_blocks, CIL_FALSE);
4207
4208
12.3k
  return rc;
4209
6.88k
}
4210
4211
static int __cil_resolve_name_with_root(struct cil_db *db, char *name, enum cil_sym_index sym_index, struct cil_symtab_datum **datum)
4212
16.0M
{
4213
16.0M
  symtab_t *symtab = &((struct cil_root *)db->ast->root->data)->symtab[sym_index];
4214
4215
16.0M
  return cil_symtab_get_datum(symtab, name, datum);
4216
16.0M
}
4217
4218
static int __cil_resolve_name_with_parents(struct cil_tree_node *node, char *name, enum cil_sym_index sym_index, struct cil_symtab_datum **datum)
4219
47.9M
{
4220
47.9M
  int rc = SEPOL_ERR;
4221
47.9M
  symtab_t *symtab = NULL;
4222
4223
195M
  while (node != NULL && rc != SEPOL_OK) {
4224
186M
    switch (node->flavor) {
4225
34.5M
    case CIL_ROOT:
4226
34.5M
      goto exit;
4227
0
      break;
4228
88.1M
    case CIL_BLOCK: {
4229
88.1M
      struct cil_block *block = node->data;
4230
88.1M
      if (!block->is_abstract) {
4231
88.1M
        symtab = &block->symtab[sym_index];
4232
88.1M
        rc = cil_symtab_get_datum(symtab, name, datum);
4233
88.1M
      }
4234
88.1M
    }
4235
88.1M
      break;
4236
9.00M
    case CIL_BLOCKINHERIT: {
4237
9.00M
      struct cil_blockinherit *inherit = node->data;
4238
9.00M
      rc = __cil_resolve_name_with_parents(node->parent, name, sym_index, datum);
4239
9.00M
      if (rc != SEPOL_OK) {
4240
        /* Continue search in original block's parent */
4241
3.77M
        rc = __cil_resolve_name_with_parents(NODE(inherit->block)->parent, name, sym_index, datum);
4242
3.77M
        goto exit;
4243
3.77M
      }
4244
9.00M
    }
4245
5.22M
      break;
4246
5.22M
    case CIL_MACRO: {
4247
2.38k
      struct cil_macro *macro = node->data;
4248
2.38k
      symtab = &macro->symtab[sym_index];
4249
2.38k
      rc = cil_symtab_get_datum(symtab, name, datum);
4250
2.38k
    }
4251
2.38k
      break;
4252
15.6M
    case CIL_CALL: {
4253
15.6M
      struct cil_call *call = node->data;
4254
15.6M
      struct cil_macro *macro = call->macro;
4255
15.6M
      symtab = &macro->symtab[sym_index];
4256
15.6M
      rc = cil_symtab_get_datum(symtab, name, datum);
4257
15.6M
      if (rc == SEPOL_OK) {
4258
        /* If the name was declared in the macro, just look on the call side */
4259
323
        rc = SEPOL_ERR;
4260
15.6M
      } else {
4261
15.6M
        rc = cil_resolve_name_call_args(call, name, sym_index, datum);
4262
15.6M
        if (rc != SEPOL_OK) {
4263
          /* Continue search in macro's parent */
4264
15.5M
          rc = __cil_resolve_name_with_parents(NODE(call->macro)->parent, name, sym_index, datum);
4265
15.5M
        }
4266
15.6M
      }
4267
15.6M
    }
4268
15.6M
      break;
4269
452
    case CIL_IN:
4270
      /* In block symtabs only exist before resolving the AST */
4271
1.19M
    case CIL_CONDBLOCK:
4272
      /* Cond block symtabs only exist before resolving the AST */
4273
38.9M
    default:
4274
38.9M
      break;
4275
186M
    }
4276
4277
147M
    node = node->parent;
4278
147M
  }
4279
4280
47.9M
exit:
4281
47.9M
  return rc;
4282
47.9M
}
4283
4284
static int __cil_resolve_name_helper(struct cil_db *db, struct cil_tree_node *node, char *name, enum cil_sym_index sym_index, struct cil_symtab_datum **datum)
4285
19.6M
{
4286
19.6M
  int rc = SEPOL_ERR;
4287
4288
19.6M
  rc = __cil_resolve_name_with_parents(node, name, sym_index, datum);
4289
19.6M
  if (rc != SEPOL_OK) {
4290
16.0M
    rc = __cil_resolve_name_with_root(db, name, sym_index, datum);
4291
16.0M
  }
4292
19.6M
  return rc;
4293
19.6M
}
4294
4295
int cil_resolve_name(struct cil_tree_node *ast_node, char *name, enum cil_sym_index sym_index, struct cil_db *db, struct cil_symtab_datum **datum)
4296
19.7M
{
4297
19.7M
  int rc = SEPOL_ERR;
4298
19.7M
  struct cil_tree_node *node = NULL;
4299
4300
19.7M
  rc = cil_resolve_name_keep_aliases(ast_node, name, sym_index, db, datum);
4301
19.7M
  if (rc != SEPOL_OK) {
4302
273k
    goto exit;
4303
273k
  }
4304
4305
  /* If this datum is an alias, then return the actual node
4306
   * This depends on aliases already being processed
4307
   */
4308
19.4M
  node = NODE(*datum);
4309
19.4M
  if (node->flavor == CIL_TYPEALIAS || node->flavor == CIL_SENSALIAS
4310
19.4M
    || node->flavor == CIL_CATALIAS) {
4311
7.32k
    struct cil_alias *alias = (struct cil_alias *)(*datum);
4312
7.32k
    if (alias->actual) {
4313
7.06k
      *datum = alias->actual;
4314
7.06k
    }
4315
7.32k
  }
4316
4317
19.4M
  rc = SEPOL_OK;
4318
4319
19.7M
exit:
4320
19.7M
  return rc;
4321
19.4M
}
4322
4323
int cil_resolve_name_keep_aliases(struct cil_tree_node *ast_node, char *name, enum cil_sym_index sym_index, struct cil_db *db, struct cil_symtab_datum **datum)
4324
19.7M
{
4325
19.7M
  int rc = SEPOL_ERR;
4326
19.7M
  struct cil_tree_node *node = NULL;
4327
4328
19.7M
  if (name == NULL || sym_index >= CIL_SYM_NUM) {
4329
16
    cil_log(CIL_ERR, "Invalid call to cil_resolve_name\n");
4330
16
    goto exit;
4331
16
  }
4332
4333
19.7M
  *datum = NULL;
4334
4335
19.7M
  if (db->qualified_names || strchr(name,'.') == NULL) {
4336
    /* Using qualified names or No '.' in name */
4337
19.5M
    rc = __cil_resolve_name_helper(db, ast_node->parent, name, sym_index, datum);
4338
19.5M
    if (rc != SEPOL_OK) {
4339
260k
      goto exit;
4340
260k
    }
4341
19.5M
  } else {
4342
173k
    char *sp = NULL;
4343
173k
    char *name_dup = cil_strdup(name);
4344
173k
    char *current = strtok_r(name_dup, ".", &sp);
4345
173k
    char *next = strtok_r(NULL, ".", &sp);
4346
173k
    symtab_t *symtab = NULL;
4347
4348
173k
    if (current == NULL) {
4349
      /* Only dots */
4350
833
      cil_tree_log(ast_node, CIL_ERR, "Invalid name %s", name);
4351
833
      free(name_dup);
4352
833
      goto exit;
4353
833
    }
4354
4355
172k
    node = ast_node;
4356
172k
    if (*name == '.') {
4357
      /* Leading '.' */
4358
95.0k
      symtab = &((struct cil_root *)db->ast->root->data)->symtab[CIL_SYM_BLOCKS];
4359
95.0k
    } else {
4360
77.3k
      rc = __cil_resolve_name_helper(db, node->parent, current, CIL_SYM_BLOCKS, datum);
4361
77.3k
      if (rc != SEPOL_OK) {
4362
15.0k
        free(name_dup);
4363
15.0k
        goto exit;
4364
15.0k
      }
4365
62.2k
      symtab = (*datum)->symtab;
4366
62.2k
    }
4367
    /* Keep looking up blocks by name until only last part of name remains */
4368
213k
    while (next != NULL) {
4369
56.7k
      rc = cil_symtab_get_datum(symtab, current, datum);
4370
56.7k
      if (rc != SEPOL_OK) {
4371
473
        free(name_dup);
4372
473
        goto exit;
4373
473
      }
4374
56.2k
      node = NODE(*datum);
4375
56.2k
      if (node->flavor == CIL_BLOCK) {
4376
41.7k
        symtab = &((struct cil_block*)node->data)->symtab[CIL_SYM_BLOCKS];
4377
41.7k
      } else {
4378
14.4k
        if (ast_node->flavor != CIL_IN) {
4379
3
          cil_log(CIL_WARN, "Can only use %s name for name resolution in \"in\" blocks\n", cil_node_to_string(node));
4380
3
          free(name_dup);
4381
3
          rc = SEPOL_ERR;
4382
3
          goto exit;
4383
3
        }
4384
14.4k
        if (node->flavor == CIL_MACRO) {
4385
11.8k
          struct cil_macro *macro = node->data;
4386
11.8k
          symtab = &macro->symtab[sym_index];
4387
11.8k
        }
4388
14.4k
      }
4389
56.2k
      current = next;
4390
56.2k
      next = strtok_r(NULL, ".", &sp);
4391
56.2k
    }
4392
156k
    symtab = &(symtab[sym_index]);
4393
156k
    rc = cil_symtab_get_datum(symtab, current, datum);
4394
156k
    free(name_dup);
4395
156k
    if (rc != SEPOL_OK) {
4396
3.89k
      goto exit;
4397
3.89k
    }
4398
156k
  }
4399
4400
19.4M
  rc = SEPOL_OK;
4401
4402
19.7M
exit:
4403
19.7M
  if (rc != SEPOL_OK) {
4404
280k
    *datum = NULL;
4405
280k
  }
4406
4407
19.7M
  return rc;
4408
19.4M
}