3
* Author : Stephen Smalley, <sds@epoch.ncsc.mil>
6
/* Updated: David Caplan, <dac@tresys.com>
8
* Added conditional policy language extensions
10
* Copyright (C) 2003 - 2004 Tresys Technology, LLC
11
* This program is free software; you can redistribute it and/or modify
12
* it under the terms of the GNU General Public License as published by
13
* the Free Software Foundation, version 2.
22
#include "checkpolicy.h"
23
#include "conditional.h"
29
policydb_t *policydbp;
35
extern unsigned long policydb_lineno;
38
extern int yywarn(char *msg);
39
extern int yyerror(char *msg);
41
static char errormsg[255];
43
static int insert_separator(int push);
44
static int insert_id(char *id,int push);
45
static int define_class(void);
46
static int define_initial_sid(void);
47
static int define_common_perms(void);
48
static int define_av_perms(int inherits);
49
static int define_sens(void);
50
static int define_dominance(void);
51
static int define_category(void);
52
static int define_level(void);
53
static int define_common_base(void);
54
static int define_av_base(void);
55
static int define_attrib(void);
56
static int define_typealias(void);
57
static int define_type(int alias);
58
static int define_compute_type(int which);
59
static int define_te_avtab(int which);
60
static int define_role_types(void);
61
static role_datum_t *merge_roles_dom(role_datum_t *r1,role_datum_t *r2);
62
static role_datum_t *define_role_dom(role_datum_t *r);
63
static int define_role_trans(void);
64
static int define_role_allow(void);
65
static int define_constraint(constraint_expr_t *expr);
66
static int define_bool();
67
static int define_conditional(cond_expr_t *expr,cond_av_list_t *t_list, cond_av_list_t *f_list );
68
static cond_expr_t *define_cond_expr(__u32 expr_type, void *arg1, void* arg2);
69
static cond_av_list_t *define_cond_pol_list(cond_av_list_t *avlist, cond_av_list_t *stmt);
70
static cond_av_list_t *define_cond_compute_type(int which);
71
static cond_av_list_t *define_cond_te_avtab(int which);
72
static cond_av_list_t *cond_list_append(cond_av_list_t *sl, avtab_key_t *key, avtab_datum_t *datum);
73
static void cond_reduce_insert_list(cond_av_list_t *new, cond_av_list_t **active, cond_av_list_t **inactive, int state );
74
static uintptr_t define_cexpr(__u32 expr_type, uintptr_t arg1, uintptr_t arg2);
75
static int define_user(void);
76
static int parse_security_context(context_struct_t *c);
77
static int define_initial_sid_context(void);
78
static int define_fs_use(int behavior);
79
static int define_genfs_context(int has_type);
80
static int define_fs_context(unsigned int major, unsigned int minor);
81
static int define_port_context(unsigned int low, unsigned int high);
82
static int define_netif_context(void);
83
static int define_ipv4_node_context(unsigned int addr, unsigned int mask);
84
static int define_ipv6_node_context(void);
93
%type <ptr> cond_expr cond_expr_prim cond_pol_list
94
%type <ptr> cond_allow_def cond_auditallow_def cond_auditdeny_def cond_dontaudit_def
95
%type <ptr> cond_transition_def cond_te_avtab_def cond_rule_def
96
%type <ptr> role_def roles
97
%type <valptr> cexpr cexpr_prim op roleop
98
%type <val> ipv4_addr_def number
117
%token TYPE_TRANSITION
120
%token ROLE_TRANSITION
123
%token DOM DOMBY INCOMP
136
%token FSCON PORTCON NETIFCON NODECON
137
%token FSUSEXATTR FSUSETASK FSUSETRANS
139
%token U1 U2 R1 R2 T1 T2
140
%token NOT AND OR XOR
143
%token USER_IDENTIFIER
153
%left EQUALS NOTEQUAL
155
policy : classes initial_sids access_vectors
156
{ if (pass == 1) { if (policydb_index_classes(policydbp)) return -1; } }
157
opt_mls te_rbac users opt_constraints
158
{ if (pass == 1) { if (policydb_index_bools(policydbp)) return -1;}
159
if (pass == 2) { if (policydb_index_others(policydbp)) return -1;} }
160
initial_sid_contexts opt_fs_contexts fs_uses opt_genfs_contexts net_contexts
165
class_def : CLASS identifier
166
{if (define_class()) return -1;}
168
initial_sids : initial_sid_def
169
| initial_sids initial_sid_def
171
initial_sid_def : SID identifier
172
{if (define_initial_sid()) return -1;}
174
access_vectors : opt_common_perms av_perms
176
opt_common_perms : common_perms
179
common_perms : common_perms_def
180
| common_perms common_perms_def
182
common_perms_def : COMMON identifier '{' identifier_list '}'
183
{if (define_common_perms()) return -1;}
185
av_perms : av_perms_def
186
| av_perms av_perms_def
188
av_perms_def : CLASS identifier '{' identifier_list '}'
189
{if (define_av_perms(FALSE)) return -1;}
190
| CLASS identifier INHERITS identifier
191
{if (define_av_perms(TRUE)) return -1;}
192
| CLASS identifier INHERITS identifier '{' identifier_list '}'
193
{if (define_av_perms(TRUE)) return -1;}
198
mls : sensitivities dominance opt_categories levels base_perms
200
sensitivities : sensitivity_def
201
| sensitivities sensitivity_def
203
sensitivity_def : SENSITIVITY identifier alias_def ';'
204
{if (define_sens()) return -1;}
205
| SENSITIVITY identifier ';'
206
{if (define_sens()) return -1;}
208
alias_def : ALIAS names
210
dominance : DOMINANCE identifier
211
{if (define_dominance()) return -1;}
212
| DOMINANCE '{' identifier_list '}'
213
{if (define_dominance()) return -1;}
215
opt_categories : categories
218
categories : category_def
219
| categories category_def
221
category_def : CATEGORY identifier alias_def ';'
222
{if (define_category()) return -1;}
223
| CATEGORY identifier ';'
224
{if (define_category()) return -1;}
229
level_def : LEVEL identifier ':' id_comma_list ';'
230
{if (define_level()) return -1;}
231
| LEVEL identifier ';'
232
{if (define_level()) return -1;}
234
base_perms : opt_common_base av_base
236
opt_common_base : common_base
239
common_base : common_base_def
240
| common_base common_base_def
242
common_base_def : COMMON identifier '{' perm_base_list '}'
243
{if (define_common_base()) return -1;}
245
av_base : av_base_def
246
| av_base av_base_def
248
av_base_def : CLASS identifier '{' perm_base_list '}'
249
{if (define_av_base()) return -1;}
251
{if (define_av_base()) return -1;}
253
perm_base_list : perm_base
254
| perm_base_list perm_base
256
perm_base : identifier ':' identifier
257
{if (insert_separator(0)) return -1;}
258
| identifier ':' '{' identifier_list '}'
259
{if (insert_separator(0)) return -1;}
261
te_rbac : te_rbac_decl
262
| te_rbac te_rbac_decl
264
te_rbac_decl : te_decl
268
rbac_decl : role_type_def
273
te_decl : attribute_def
281
attribute_def : ATTRIBUTE identifier ';'
282
{ if (define_attrib()) return -1;}
284
type_def : TYPE identifier alias_def opt_attr_list ';'
285
{if (define_type(1)) return -1;}
286
| TYPE identifier opt_attr_list ';'
287
{if (define_type(0)) return -1;}
289
typealias_def : TYPEALIAS identifier alias_def
290
{if (define_typealias()) return -1;}
292
opt_attr_list : ',' id_comma_list
295
bool_def : BOOL identifier bool_val ';'
296
{if (define_bool()) return -1;}
299
{ if (insert_id("T",0)) return -1; }
301
{ if (insert_id("F",0)) return -1; }
303
cond_stmt_def : IF cond_expr '{' cond_pol_list '}'
304
{ if (pass == 2) { if (define_conditional((cond_expr_t*)$2, (cond_av_list_t*)$4,(cond_av_list_t*) 0) < 0) return -1; }}
305
| IF cond_expr '{' cond_pol_list '}' ELSE '{' cond_pol_list '}'
306
{ if (pass == 2) { if (define_conditional((cond_expr_t*)$2,(cond_av_list_t*)$4,(cond_av_list_t*)$8) < 0 ) return -1; }}
308
cond_expr : '(' cond_expr ')'
311
{ $$ = define_cond_expr(COND_NOT, $2, 0);
312
if ($$ == 0) return -1; }
313
| cond_expr AND cond_expr
314
{ $$ = define_cond_expr(COND_AND, $1, $3);
315
if ($$ == 0) return -1; }
316
| cond_expr OR cond_expr
317
{ $$ = define_cond_expr(COND_OR, $1, $3);
318
if ($$ == 0) return -1; }
319
| cond_expr XOR cond_expr
320
{ $$ = define_cond_expr(COND_XOR, $1, $3);
321
if ($$ == 0) return -1; }
322
| cond_expr EQUALS cond_expr
323
{ $$ = define_cond_expr(COND_EQ, $1, $3);
324
if ($$ == 0) return -1; }
325
| cond_expr NOTEQUAL cond_expr
326
{ $$ = define_cond_expr(COND_NEQ, $1, $3);
327
if ($$ == 0) return -1; }
331
cond_expr_prim : identifier
332
{ $$ = define_cond_expr(COND_BOOL,0, 0);
333
if ($$ == COND_ERR) return -1; }
335
cond_pol_list : cond_rule_def
336
{ $$ = define_cond_pol_list((cond_av_list_t *) 0, (cond_av_list_t *)$1);}
337
| cond_pol_list cond_rule_def
338
{ $$ = define_cond_pol_list((cond_av_list_t *)$1, (cond_av_list_t *)$2); }
340
cond_rule_def : cond_transition_def
345
cond_transition_def : TYPE_TRANSITION names names ':' names identifier ';'
346
{ $$ = define_cond_compute_type(AVTAB_TRANSITION) ;
347
if ($$ == COND_ERR) return -1;}
348
| TYPE_MEMBER names names ':' names identifier ';'
349
{ $$ = define_cond_compute_type(AVTAB_MEMBER) ;
350
if ($$ == COND_ERR) return -1;}
351
| TYPE_CHANGE names names ':' names identifier ';'
352
{ $$ = define_cond_compute_type(AVTAB_CHANGE) ;
353
if ($$ == COND_ERR) return -1;}
355
cond_te_avtab_def : cond_allow_def
357
| cond_auditallow_def
364
cond_allow_def : ALLOW names names ':' names names ';'
365
{ $$ = define_cond_te_avtab(AVTAB_ALLOWED) ;
366
if ($$ == COND_ERR) return -1; }
368
cond_auditallow_def : AUDITALLOW names names ':' names names ';'
369
{ $$ = define_cond_te_avtab(AVTAB_AUDITALLOW) ;
370
if ($$ == COND_ERR) return -1; }
372
cond_auditdeny_def : AUDITDENY names names ':' names names ';'
373
{ $$ = define_cond_te_avtab(AVTAB_AUDITDENY) ;
374
if ($$ == COND_ERR) return -1; }
376
cond_dontaudit_def : DONTAUDIT names names ':' names names ';'
377
{ $$ = define_cond_te_avtab(-AVTAB_AUDITDENY);
378
if ($$ == COND_ERR) return -1; }
380
transition_def : TYPE_TRANSITION names names ':' names identifier ';'
381
{if (define_compute_type(AVTAB_TRANSITION)) return -1;}
382
| TYPE_MEMBER names names ':' names identifier ';'
383
{if (define_compute_type(AVTAB_MEMBER)) return -1;}
384
| TYPE_CHANGE names names ':' names identifier ';'
385
{if (define_compute_type(AVTAB_CHANGE)) return -1;}
387
te_avtab_def : allow_def
393
allow_def : ALLOW names names ':' names names ';'
394
{if (define_te_avtab(AVTAB_ALLOWED)) return -1; }
396
auditallow_def : AUDITALLOW names names ':' names names ';'
397
{if (define_te_avtab(AVTAB_AUDITALLOW)) return -1; }
399
auditdeny_def : AUDITDENY names names ':' names names ';'
400
{if (define_te_avtab(AVTAB_AUDITDENY)) return -1; }
402
dontaudit_def : DONTAUDIT names names ':' names names ';'
403
{if (define_te_avtab(-AVTAB_AUDITDENY)) return -1; }
405
neverallow_def : NEVERALLOW names names ':' names names ';'
406
{if (define_te_avtab(-AVTAB_ALLOWED)) return -1; }
408
role_type_def : ROLE identifier TYPES names ';'
409
{if (define_role_types()) return -1;}
411
role_dominance : DOMINANCE '{' roles '}'
413
role_trans_def : ROLE_TRANSITION names names identifier ';'
414
{if (define_role_trans()) return -1; }
416
role_allow_def : ALLOW names names ';'
417
{if (define_role_allow()) return -1; }
422
{ $$ = merge_roles_dom((role_datum_t*)$1, (role_datum_t*)$2); if ($$ == 0) return -1;}
424
role_def : ROLE identifier_push ';'
425
{$$ = define_role_dom(NULL); if ($$ == 0) return -1;}
426
| ROLE identifier_push '{' roles '}'
427
{$$ = define_role_dom((role_datum_t*)$4); if ($$ == 0) return -1;}
429
opt_constraints : constraints
432
constraints : constraint_def
433
| constraints constraint_def
435
constraint_def : CONSTRAIN names names cexpr ';'
436
{ if (define_constraint((constraint_expr_t*)$4)) return -1; }
438
cexpr : '(' cexpr ')'
441
{ $$ = define_cexpr(CEXPR_NOT, $2, 0);
442
if ($$ == 0) return -1; }
444
{ $$ = define_cexpr(CEXPR_AND, $1, $3);
445
if ($$ == 0) return -1; }
447
{ $$ = define_cexpr(CEXPR_OR, $1, $3);
448
if ($$ == 0) return -1; }
452
cexpr_prim : U1 op U2
453
{ $$ = define_cexpr(CEXPR_ATTR, CEXPR_USER, $2);
454
if ($$ == 0) return -1; }
456
{ $$ = define_cexpr(CEXPR_ATTR, CEXPR_ROLE, $2);
457
if ($$ == 0) return -1; }
459
{ $$ = define_cexpr(CEXPR_ATTR, CEXPR_TYPE, $2);
460
if ($$ == 0) return -1; }
461
| U1 op { if (insert_separator(1)) return -1; } user_names_push
462
{ $$ = define_cexpr(CEXPR_NAMES, CEXPR_USER, $2);
463
if ($$ == 0) return -1; }
464
| U2 op { if (insert_separator(1)) return -1; } user_names_push
465
{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_USER | CEXPR_TARGET), $2);
466
if ($$ == 0) return -1; }
467
| R1 op { if (insert_separator(1)) return -1; } names_push
468
{ $$ = define_cexpr(CEXPR_NAMES, CEXPR_ROLE, $2);
469
if ($$ == 0) return -1; }
470
| R2 op { if (insert_separator(1)) return -1; } names_push
471
{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_ROLE | CEXPR_TARGET), $2);
472
if ($$ == 0) return -1; }
473
| T1 op { if (insert_separator(1)) return -1; } names_push
474
{ $$ = define_cexpr(CEXPR_NAMES, CEXPR_TYPE, $2);
475
if ($$ == 0) return -1; }
476
| T2 op { if (insert_separator(1)) return -1; } names_push
477
{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_TYPE | CEXPR_TARGET), $2);
478
if ($$ == 0) return -1; }
480
{ $$ = define_cexpr(CEXPR_ATTR, CEXPR_USER, CEXPR_EQ);
481
if ($$ == 0) return -1; }
482
| SOURCE ROLE { if (insert_separator(1)) return -1; } names_push
483
{ $$ = define_cexpr(CEXPR_NAMES, CEXPR_ROLE, CEXPR_EQ);
484
if ($$ == 0) return -1; }
485
| TARGET ROLE { if (insert_separator(1)) return -1; } names_push
486
{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_ROLE | CEXPR_TARGET), CEXPR_EQ);
487
if ($$ == 0) return -1; }
489
{ $$ = define_cexpr(CEXPR_ATTR, CEXPR_ROLE, $2);
490
if ($$ == 0) return -1; }
491
| SOURCE TYPE { if (insert_separator(1)) return -1; } names_push
492
{ $$ = define_cexpr(CEXPR_NAMES, CEXPR_TYPE, CEXPR_EQ);
493
if ($$ == 0) return -1; }
494
| TARGET TYPE { if (insert_separator(1)) return -1; } names_push
495
{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_TYPE | CEXPR_TARGET), CEXPR_EQ);
496
if ($$ == 0) return -1; }
508
{ $$ = CEXPR_DOMBY; }
510
{ $$ = CEXPR_INCOMP; }
518
user_def : USER user_id ROLES names opt_user_ranges ';'
519
{if (define_user()) return -1;}
521
opt_user_ranges : RANGES user_ranges
524
user_ranges : mls_range_def
525
| '{' user_range_def_list '}'
527
user_range_def_list : mls_range_def
528
| user_range_def_list mls_range_def
530
initial_sid_contexts : initial_sid_context_def
531
| initial_sid_contexts initial_sid_context_def
533
initial_sid_context_def : SID identifier security_context_def
534
{if (define_initial_sid_context()) return -1;}
536
opt_fs_contexts : fs_contexts
539
fs_contexts : fs_context_def
540
| fs_contexts fs_context_def
542
fs_context_def : FSCON number number security_context_def security_context_def
543
{if (define_fs_context($2,$3)) return -1;}
545
net_contexts : opt_port_contexts opt_netif_contexts opt_node_contexts
547
opt_port_contexts : port_contexts
550
port_contexts : port_context_def
551
| port_contexts port_context_def
553
port_context_def : PORTCON identifier number security_context_def
554
{if (define_port_context($3,$3)) return -1;}
555
| PORTCON identifier number '-' number security_context_def
556
{if (define_port_context($3,$5)) return -1;}
558
opt_netif_contexts : netif_contexts
561
netif_contexts : netif_context_def
562
| netif_contexts netif_context_def
564
netif_context_def : NETIFCON identifier security_context_def security_context_def
565
{if (define_netif_context()) return -1;}
567
opt_node_contexts : node_contexts
570
node_contexts : node_context_def
571
| node_contexts node_context_def
573
node_context_def : NODECON ipv4_addr_def ipv4_addr_def security_context_def
574
{if (define_ipv4_node_context($2,$3)) return -1;}
575
| NODECON ipv6_addr ipv6_addr security_context_def
576
{if (define_ipv6_node_context()) return -1;}
581
fs_use_def : FSUSEXATTR identifier security_context_def ';'
582
{if (define_fs_use(SECURITY_FS_USE_XATTR)) return -1;}
583
| FSUSETASK identifier security_context_def ';'
584
{if (define_fs_use(SECURITY_FS_USE_TASK)) return -1;}
585
| FSUSETRANS identifier security_context_def ';'
586
{if (define_fs_use(SECURITY_FS_USE_TRANS)) return -1;}
588
opt_genfs_contexts : genfs_contexts
591
genfs_contexts : genfs_context_def
592
| genfs_contexts genfs_context_def
594
genfs_context_def : GENFSCON identifier path '-' identifier security_context_def
595
{if (define_genfs_context(1)) return -1;}
596
| GENFSCON identifier path '-' '-' {insert_id("-", 0);} security_context_def
597
{if (define_genfs_context(1)) return -1;}
598
| GENFSCON identifier path security_context_def
599
{if (define_genfs_context(0)) return -1;}
601
ipv4_addr_def : number '.' number '.' number '.' number
604
unsigned char *p = ((unsigned char *)&addr);
613
security_context_def : user_id ':' identifier ':' identifier opt_mls_range_def
615
opt_mls_range_def : ':' mls_range_def
618
mls_range_def : mls_level_def '-' mls_level_def
619
{if (insert_separator(0)) return -1;}
621
{if (insert_separator(0)) return -1;}
623
mls_level_def : identifier ':' id_comma_list
624
{if (insert_separator(0)) return -1;}
626
{if (insert_separator(0)) return -1;}
628
id_comma_list : identifier
629
| id_comma_list ',' identifier
636
{ if (insert_separator(0)) return -1; }
638
{ if (insert_separator(0)) return -1; }
640
{ if (insert_id("*", 0)) return -1;
641
if (insert_separator(0)) return -1; }
643
{ if (insert_id("~", 0)) return -1;
644
if (insert_separator(0)) return -1; }
645
| tilde nested_id_set
646
{ if (insert_id("~", 0)) return -1;
647
if (insert_separator(0)) return -1; }
648
| identifier '-' { if (insert_id("-", 0)) return -1; } identifier
649
{ if (insert_separator(0)) return -1; }
652
{ if (insert_id("~", 1)) return -1; }
654
asterisk_push : asterisk
655
{ if (insert_id("*", 1)) return -1; }
657
names_push : identifier_push
658
| '{' identifier_list_push '}'
660
| tilde_push identifier_push
661
| tilde_push '{' identifier_list_push '}'
663
identifier_list_push : identifier_push
664
| identifier_list_push identifier_push
666
identifier_push : IDENTIFIER
667
{ if (insert_id(yytext, 1)) return -1; }
669
identifier_list : identifier
670
| identifier_list identifier
672
nested_id_set : '{' nested_id_list '}'
674
nested_id_list : nested_id_element | nested_id_list nested_id_element
676
nested_id_element : identifier | '-' { if (insert_id("-", 0)) return -1; } identifier | nested_id_set
678
identifier : IDENTIFIER
679
{ if (insert_id(yytext,0)) return -1; }
681
user_identifier : USER_IDENTIFIER
682
{ if (insert_id(yytext,0)) return -1; }
684
user_identifier_push : USER_IDENTIFIER
685
{ if (insert_id(yytext, 1)) return -1; }
687
user_identifier_list_push : user_identifier_push
688
| identifier_list_push user_identifier_push
689
| user_identifier_list_push identifier_push
690
| user_identifier_list_push user_identifier_push
692
user_names_push : names_push
693
| user_identifier_push
694
| '{' user_identifier_list_push '}'
695
| tilde_push user_identifier_push
696
| tilde_push '{' user_identifier_list_push '}'
699
{ if (insert_id(yytext,0)) return -1; }
702
{ $$ = strtoul(yytext,NULL,0); }
704
ipv6_addr : IPV6_ADDR
705
{ if (insert_id(yytext,0)) return -1; }
710
static int insert_separator(int push)
715
error = queue_push(id_queue, 0);
717
error = queue_insert(id_queue, 0);
720
yyerror("queue overflow");
726
static int insert_id(char *id, int push)
731
newid = (char *) malloc(strlen(id) + 1);
733
yyerror("out of memory");
738
error = queue_push(id_queue, (queue_element_t) newid);
740
error = queue_insert(id_queue, (queue_element_t) newid);
743
yyerror("queue overflow");
751
static int define_class(void)
754
class_datum_t *datum = 0;
759
id = queue_remove(id_queue);
764
id = (char *) queue_remove(id_queue);
766
yyerror("no class name for class definition?");
769
datum = (class_datum_t *) malloc(sizeof(class_datum_t));
771
yyerror("out of memory");
774
memset(datum, 0, sizeof(class_datum_t));
775
datum->value = ++policydbp->p_classes.nprim;
777
ret = hashtab_insert(policydbp->p_classes.table,
778
(hashtab_key_t) id, (hashtab_datum_t) datum);
780
if (ret == HASHTAB_PRESENT) {
781
--policydbp->p_classes.nprim;
782
yyerror("duplicate class definition");
785
if (ret == HASHTAB_OVERFLOW) {
786
yyerror("hash table overflow");
799
static int define_initial_sid(void)
802
ocontext_t *newc = 0, *c, *head;
806
id = queue_remove(id_queue);
811
id = (char *) queue_remove(id_queue);
813
yyerror("no sid name for SID definition?");
816
newc = (ocontext_t *) malloc(sizeof(ocontext_t));
818
yyerror("out of memory");
821
memset(newc, 0, sizeof(ocontext_t));
823
context_init(&newc->context[0]);
824
head = policydbp->ocontexts[OCON_ISID];
826
for (c = head; c; c = c->next) {
827
if (!strcmp(newc->u.name, c->u.name)) {
828
sprintf(errormsg, "duplicate initial SID %s", id);
835
newc->sid[0] = head->sid[0] + 1;
840
policydbp->ocontexts[OCON_ISID] = newc;
852
static int define_common_perms(void)
854
char *id = 0, *perm = 0;
855
common_datum_t *comdatum = 0;
856
perm_datum_t *perdatum = 0;
861
while ((id = queue_remove(id_queue)))
866
id = (char *) queue_remove(id_queue);
868
yyerror("no common name for common perm definition?");
871
comdatum = (common_datum_t *) malloc(sizeof(common_datum_t));
873
yyerror("out of memory");
876
memset(comdatum, 0, sizeof(common_datum_t));
877
comdatum->value = ++policydbp->p_commons.nprim;
878
ret = hashtab_insert(policydbp->p_commons.table,
879
(hashtab_key_t) id, (hashtab_datum_t) comdatum);
881
if (ret == HASHTAB_PRESENT) {
882
yyerror("duplicate common definition");
885
if (ret == HASHTAB_OVERFLOW) {
886
yyerror("hash table overflow");
889
if (symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE)) {
890
yyerror("out of memory");
893
while ((perm = queue_remove(id_queue))) {
894
perdatum = (perm_datum_t *) malloc(sizeof(perm_datum_t));
896
yyerror("out of memory");
899
memset(perdatum, 0, sizeof(perm_datum_t));
900
perdatum->value = ++comdatum->permissions.nprim;
902
#ifdef CONFIG_SECURITY_SELINUX_MLS
904
* By default, we set all four base permissions on this
905
* permission. This means that if base_permissions is not
906
* explicitly defined for this permission, then this
907
* permission will only be granted in the equivalent case.
909
perdatum->base_perms = MLS_BASE_READ | MLS_BASE_WRITE |
910
MLS_BASE_READBY | MLS_BASE_WRITEBY;
913
if (perdatum->value >= (sizeof(access_vector_t) * 8)) {
914
yyerror("too many permissions to fit in an access vector");
917
ret = hashtab_insert(comdatum->permissions.table,
918
(hashtab_key_t) perm,
919
(hashtab_datum_t) perdatum);
921
if (ret == HASHTAB_PRESENT) {
922
sprintf(errormsg, "duplicate permission %s in common %s",
927
if (ret == HASHTAB_OVERFLOW) {
928
yyerror("hash table overflow");
951
static int define_av_perms(int inherits)
954
class_datum_t *cladatum;
955
common_datum_t *comdatum;
956
perm_datum_t *perdatum = 0, *perdatum2 = 0;
961
while ((id = queue_remove(id_queue)))
966
id = (char *) queue_remove(id_queue);
968
yyerror("no tclass name for av perm definition?");
971
cladatum = (class_datum_t *) hashtab_search(policydbp->p_classes.table,
974
sprintf(errormsg, "class %s is not defined", id);
980
if (cladatum->comdatum || cladatum->permissions.nprim) {
981
yyerror("duplicate access vector definition");
984
if (symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE)) {
985
yyerror("out of memory");
989
id = (char *) queue_remove(id_queue);
991
yyerror("no inherits name for access vector definition?");
994
comdatum = (common_datum_t *) hashtab_search(policydbp->p_commons.table,
998
sprintf(errormsg, "common %s is not defined", id);
1002
cladatum->comkey = id;
1003
cladatum->comdatum = comdatum;
1006
* Class-specific permissions start with values
1007
* after the last common permission.
1009
cladatum->permissions.nprim += comdatum->permissions.nprim;
1011
while ((id = queue_remove(id_queue))) {
1012
perdatum = (perm_datum_t *) malloc(sizeof(perm_datum_t));
1014
yyerror("out of memory");
1017
memset(perdatum, 0, sizeof(perm_datum_t));
1018
perdatum->value = ++cladatum->permissions.nprim;
1020
#ifdef CONFIG_SECURITY_SELINUX_MLS
1022
* By default, we set all four base permissions on this
1023
* permission. This means that if base_permissions is not
1024
* explicitly defined for this permission, then this
1025
* permission will only be granted in the equivalent case.
1027
perdatum->base_perms = MLS_BASE_READ | MLS_BASE_WRITE |
1028
MLS_BASE_READBY | MLS_BASE_WRITEBY;
1029
/* actual value set in define_av_base */
1032
if (perdatum->value >= (sizeof(access_vector_t) * 8)) {
1033
yyerror("too many permissions to fit in an access vector");
1038
* Class-specific permissions and
1039
* common permissions exist in the same
1042
perdatum2 = (perm_datum_t *) hashtab_search(cladatum->comdatum->permissions.table,
1043
(hashtab_key_t) id);
1045
sprintf(errormsg, "permission %s conflicts with an inherited permission", id);
1050
ret = hashtab_insert(cladatum->permissions.table,
1052
(hashtab_datum_t) perdatum);
1054
if (ret == HASHTAB_PRESENT) {
1055
sprintf(errormsg, "duplicate permission %s", id);
1059
if (ret == HASHTAB_OVERFLOW) {
1060
yyerror("hash table overflow");
1076
static int define_sens(void)
1078
#ifdef CONFIG_SECURITY_SELINUX_MLS
1080
mls_level_t *level = 0;
1081
level_datum_t *datum = 0, *aliasdatum = 0;
1086
while ((id = queue_remove(id_queue)))
1091
id = (char *) queue_remove(id_queue);
1093
yyerror("no sensitivity name for sensitivity definition?");
1096
level = (mls_level_t *) malloc(sizeof(mls_level_t));
1098
yyerror("out of memory");
1101
memset(level, 0, sizeof(mls_level_t));
1102
level->sens = 0; /* actual value set in define_dominance */
1103
++policydbp->p_levels.nprim;
1104
ebitmap_init(&level->cat); /* actual value set in define_level */
1106
datum = (level_datum_t *) malloc(sizeof(level_datum_t));
1108
yyerror("out of memory");
1111
memset(datum, 0, sizeof(level_datum_t));
1112
datum->isalias = FALSE;
1113
datum->level = level;
1115
ret = hashtab_insert(policydbp->p_levels.table,
1116
(hashtab_key_t) id, (hashtab_datum_t) datum);
1118
if (ret == HASHTAB_PRESENT) {
1119
--policydbp->p_levels.nprim;
1120
sprintf(errormsg, "duplicate definition for sensitivity %s", id);
1124
if (ret == HASHTAB_OVERFLOW) {
1125
yyerror("hash table overflow");
1129
while ((id = queue_remove(id_queue))) {
1130
aliasdatum = (level_datum_t *) malloc(sizeof(level_datum_t));
1132
yyerror("out of memory");
1135
memset(aliasdatum, 0, sizeof(level_datum_t));
1136
aliasdatum->isalias = TRUE;
1137
aliasdatum->level = level;
1139
ret = hashtab_insert(policydbp->p_levels.table,
1140
(hashtab_key_t) id, (hashtab_datum_t) aliasdatum);
1142
if (ret == HASHTAB_PRESENT) {
1143
sprintf(errormsg, "duplicate definition for level %s", id);
1147
if (ret == HASHTAB_OVERFLOW) {
1148
yyerror("hash table overflow");
1171
yyerror("sensitivity definition in non-MLS configuration");
1176
static int define_dominance(void)
1178
#ifdef CONFIG_SECURITY_SELINUX_MLS
1179
level_datum_t *datum;
1184
while ((id = queue_remove(id_queue)))
1190
while ((id = (char *) queue_remove(id_queue))) {
1191
datum = (level_datum_t *) hashtab_search(policydbp->p_levels.table,
1192
(hashtab_key_t) id);
1194
sprintf(errormsg, "unknown sensitivity %s used in dominance definition", id);
1199
if (datum->level->sens != 0) {
1200
sprintf(errormsg, "sensitivity %s occurs multiply in dominance definition", id);
1205
datum->level->sens = ++order;
1207
/* no need to keep sensitivity name */
1211
if (order != policydbp->p_levels.nprim) {
1212
yyerror("all sensitivities must be specified in dominance definition");
1217
yyerror("dominance definition in non-MLS configuration");
1222
static int define_category(void)
1224
#ifdef CONFIG_SECURITY_SELINUX_MLS
1226
cat_datum_t *datum = 0, *aliasdatum = 0;
1230
while ((id = queue_remove(id_queue)))
1235
id = (char *) queue_remove(id_queue);
1237
yyerror("no category name for category definition?");
1240
datum = (cat_datum_t *) malloc(sizeof(cat_datum_t));
1242
yyerror("out of memory");
1245
memset(datum, 0, sizeof(cat_datum_t));
1246
datum->isalias = FALSE;
1247
datum->value = ++policydbp->p_cats.nprim;
1249
ret = hashtab_insert(policydbp->p_cats.table,
1250
(hashtab_key_t) id, (hashtab_datum_t) datum);
1252
if (ret == HASHTAB_PRESENT) {
1253
--policydbp->p_cats.nprim;
1254
sprintf(errormsg, "duplicate definition for category %s", id);
1258
if (ret == HASHTAB_OVERFLOW) {
1259
yyerror("hash table overflow");
1263
while ((id = queue_remove(id_queue))) {
1264
aliasdatum = (cat_datum_t *) malloc(sizeof(cat_datum_t));
1266
yyerror("out of memory");
1269
memset(aliasdatum, 0, sizeof(cat_datum_t));
1270
aliasdatum->isalias = TRUE;
1271
aliasdatum->value = datum->value;
1273
ret = hashtab_insert(policydbp->p_cats.table,
1274
(hashtab_key_t) id, (hashtab_datum_t) aliasdatum);
1276
if (ret == HASHTAB_PRESENT) {
1277
sprintf(errormsg, "duplicate definition for category %s", id);
1281
if (ret == HASHTAB_OVERFLOW) {
1282
yyerror("hash table overflow");
1303
yyerror("category definition in non-MLS configuration");
1309
static int define_level(void)
1311
#ifdef CONFIG_SECURITY_SELINUX_MLS
1314
level_datum_t *levdatum;
1315
cat_datum_t *catdatum;
1319
while ((id = queue_remove(id_queue)))
1324
id = (char *) queue_remove(id_queue);
1326
yyerror("no level name for level definition?");
1329
levdatum = (level_datum_t *) hashtab_search(policydbp->p_levels.table,
1330
(hashtab_key_t) id);
1332
sprintf(errormsg, "unknown sensitivity %s used in level definition", id);
1337
if (ebitmap_length(&levdatum->level->cat)) {
1338
sprintf(errormsg, "sensitivity %s used in multiple level definitions", id);
1345
while ((id = queue_remove(id_queue))) {
1346
catdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
1347
(hashtab_key_t) id);
1349
sprintf(errormsg, "unknown category %s used in level definition", id);
1354
if (ebitmap_set_bit(&levdatum->level->cat, catdatum->value - 1, TRUE)) {
1355
yyerror("out of memory");
1360
/* no need to keep category name */
1368
policydbp->nlevels += n;
1372
yyerror("level definition in non-MLS configuration");
1378
static int define_common_base(void)
1380
#ifdef CONFIG_SECURITY_SELINUX_MLS
1381
char *id, *perm, *base;
1382
common_datum_t *comdatum;
1383
perm_datum_t *perdatum;
1387
id = queue_remove(id_queue); free(id);
1388
while ((id = queue_remove(id_queue))) {
1390
while ((id = queue_remove(id_queue))) {
1397
id = (char *) queue_remove(id_queue);
1399
yyerror("no common name for common base definition?");
1402
comdatum = (common_datum_t *) hashtab_search(policydbp->p_commons.table,
1403
(hashtab_key_t) id);
1405
sprintf(errormsg, "common %s is not defined", id);
1410
while ((perm = queue_remove(id_queue))) {
1411
perdatum = (perm_datum_t *) hashtab_search(comdatum->permissions.table,
1412
(hashtab_key_t) perm);
1414
sprintf(errormsg, "permission %s is not defined for common %s", perm, id);
1422
* An explicit definition of base_permissions for this
1423
* permission. Reset the value to zero.
1425
perdatum->base_perms = 0;
1427
while ((base = queue_remove(id_queue))) {
1428
if (!strcmp(base, "read"))
1429
perdatum->base_perms |= MLS_BASE_READ;
1430
else if (!strcmp(base, "write"))
1431
perdatum->base_perms |= MLS_BASE_WRITE;
1432
else if (!strcmp(base, "readby"))
1433
perdatum->base_perms |= MLS_BASE_READBY;
1434
else if (!strcmp(base, "writeby"))
1435
perdatum->base_perms |= MLS_BASE_WRITEBY;
1436
else if (strcmp(base, "none")) {
1437
sprintf(errormsg, "base permission %s is not defined", base);
1452
yyerror("MLS base permission definition in non-MLS configuration");
1458
#ifdef CONFIG_SECURITY_SELINUX_MLS
1459
static int common_base_set(hashtab_key_t key, hashtab_datum_t datum, void *p)
1461
perm_datum_t *perdatum;
1462
class_datum_t *cladatum;
1464
perdatum = (perm_datum_t *) datum;
1465
cladatum = (class_datum_t *) p;
1467
if (perdatum->base_perms & MLS_BASE_READ)
1468
cladatum->mlsperms.read |= (1 << (perdatum->value - 1));
1470
if (perdatum->base_perms & MLS_BASE_WRITE)
1471
cladatum->mlsperms.write |= (1 << (perdatum->value - 1));
1473
if (perdatum->base_perms & MLS_BASE_READBY)
1474
cladatum->mlsperms.readby |= (1 << (perdatum->value - 1));
1476
if (perdatum->base_perms & MLS_BASE_WRITEBY)
1477
cladatum->mlsperms.writeby |= (1 << (perdatum->value - 1));
1483
static int define_av_base(void)
1485
#ifdef CONFIG_SECURITY_SELINUX_MLS
1487
class_datum_t *cladatum;
1488
perm_datum_t *perdatum;
1491
id = queue_remove(id_queue); free(id);
1492
while ((id = queue_remove(id_queue))) {
1494
while ((id = queue_remove(id_queue))) {
1501
id = (char *) queue_remove(id_queue);
1503
yyerror("no tclass name for av base definition?");
1506
cladatum = (class_datum_t *) hashtab_search(policydbp->p_classes.table,
1507
(hashtab_key_t) id);
1509
sprintf(errormsg, "class %s is not defined", id);
1517
* Determine which common permissions should be included in each MLS
1518
* vector for this access vector definition.
1520
if (cladatum->comdatum)
1521
hashtab_map(cladatum->comdatum->permissions.table, common_base_set, cladatum);
1523
while ((id = queue_remove(id_queue))) {
1524
perdatum = (perm_datum_t *) hashtab_search(cladatum->permissions.table,
1525
(hashtab_key_t) id);
1527
sprintf(errormsg, "permission %s is not defined", id);
1533
* An explicit definition of base_permissions for this
1534
* permission. Reset the value to zero.
1536
perdatum->base_perms = 0;
1538
while ((base = queue_remove(id_queue))) {
1539
if (!strcmp(base, "read")) {
1540
perdatum->base_perms |= MLS_BASE_READ;
1541
cladatum->mlsperms.read |= (1 << (perdatum->value - 1));
1542
} else if (!strcmp(base, "write")) {
1543
perdatum->base_perms |= MLS_BASE_WRITE;
1544
cladatum->mlsperms.write |= (1 << (perdatum->value - 1));
1545
} else if (!strcmp(base, "readby")) {
1546
perdatum->base_perms |= MLS_BASE_READBY;
1547
cladatum->mlsperms.readby |= (1 << (perdatum->value - 1));
1548
} else if (!strcmp(base, "writeby")) {
1549
perdatum->base_perms |= MLS_BASE_WRITEBY;
1550
cladatum->mlsperms.writeby |= (1 << (perdatum->value - 1));
1551
} else if (strcmp(base, "none")) {
1552
sprintf(errormsg, "base permission %s is not defined", base);
1565
yyerror("MLS base permission definition in non-MLS configuration");
1570
static int define_attrib(void)
1578
free(queue_remove(id_queue));
1582
id = (char *) queue_remove(id_queue);
1587
attr = hashtab_search(policydbp->p_types.table, id);
1589
sprintf(errormsg, "duplicate declaration for attribute %s\n",
1595
attr = (type_datum_t *) malloc(sizeof(type_datum_t));
1597
yyerror("out of memory");
1600
memset(attr, 0, sizeof(type_datum_t));
1601
attr->isattr = TRUE;
1602
ret = hashtab_insert(policydbp->p_types.table,
1603
id, (hashtab_datum_t) attr);
1605
yyerror("hash table overflow");
1612
static int define_typealias(void)
1615
type_datum_t *t, *aliasdatum;;
1620
while ((id = queue_remove(id_queue)))
1625
id = (char *) queue_remove(id_queue);
1627
yyerror("no type name for typealias definition?");
1631
t = hashtab_search(policydbp->p_types.table, id);
1632
if (!t || t->isattr) {
1633
sprintf(errormsg, "unknown type %s", id);
1639
while ((id = queue_remove(id_queue))) {
1640
aliasdatum = (type_datum_t *) malloc(sizeof(type_datum_t));
1642
yyerror("out of memory");
1645
memset(aliasdatum, 0, sizeof(type_datum_t));
1646
aliasdatum->value = t->value;
1648
ret = hashtab_insert(policydbp->p_types.table,
1649
(hashtab_key_t) id, (hashtab_datum_t) aliasdatum);
1651
if (ret == HASHTAB_PRESENT) {
1652
sprintf(errormsg, "name conflict for type alias %s", id);
1658
if (ret == HASHTAB_OVERFLOW) {
1659
yyerror("hash table overflow");
1668
static int define_type(int alias)
1671
type_datum_t *datum, *aliasdatum, *attr;
1672
int ret, newattr = 0;
1676
while ((id = queue_remove(id_queue)))
1679
while ((id = queue_remove(id_queue)))
1685
id = (char *) queue_remove(id_queue);
1687
yyerror("no type name for type definition?");
1691
datum = (type_datum_t *) malloc(sizeof(type_datum_t));
1693
yyerror("out of memory");
1697
memset(datum, 0, sizeof(type_datum_t));
1698
datum->primary = TRUE;
1699
datum->value = ++policydbp->p_types.nprim;
1701
ret = hashtab_insert(policydbp->p_types.table,
1702
(hashtab_key_t) id, (hashtab_datum_t) datum);
1704
if (ret == HASHTAB_PRESENT) {
1705
--policydbp->p_types.nprim;
1707
sprintf(errormsg, "name conflict for type %s", id);
1712
if (ret == HASHTAB_OVERFLOW) {
1713
yyerror("hash table overflow");
1720
while ((id = queue_remove(id_queue))) {
1721
aliasdatum = (type_datum_t *) malloc(sizeof(type_datum_t));
1723
yyerror("out of memory");
1726
memset(aliasdatum, 0, sizeof(type_datum_t));
1727
aliasdatum->value = datum->value;
1729
ret = hashtab_insert(policydbp->p_types.table,
1730
(hashtab_key_t) id, (hashtab_datum_t) aliasdatum);
1732
if (ret == HASHTAB_PRESENT) {
1733
sprintf(errormsg, "name conflict for type alias %s", id);
1739
if (ret == HASHTAB_OVERFLOW) {
1740
yyerror("hash table overflow");
1748
while ((id = queue_remove(id_queue))) {
1749
#ifdef CONFIG_SECURITY_SELINUX_MLS
1750
if (!strcmp(id, "mlstrustedreader")) {
1751
if (ebitmap_set_bit(&policydbp->trustedreaders, datum->value - 1, TRUE)) {
1752
yyerror("out of memory");
1756
} else if (!strcmp(id, "mlstrustedwriter")) {
1757
if (ebitmap_set_bit(&policydbp->trustedwriters, datum->value - 1, TRUE)) {
1758
yyerror("out of memory");
1762
} else if (!strcmp(id, "mlstrustedobject")) {
1763
if (ebitmap_set_bit(&policydbp->trustedobjects, datum->value - 1, TRUE)) {
1764
yyerror("out of memory");
1770
attr = hashtab_search(policydbp->p_types.table, id);
1772
sprintf(errormsg, "attribute %s is not declared", id);
1774
/* treat it as a fatal error */
1778
/* Warn but automatically define the attribute.
1779
Useful for quickly finding all those attributes you
1780
forgot to declare. */
1782
attr = (type_datum_t *) malloc(sizeof(type_datum_t));
1784
yyerror("out of memory");
1787
memset(attr, 0, sizeof(type_datum_t));
1788
attr->isattr = TRUE;
1789
ret = hashtab_insert(policydbp->p_types.table,
1790
id, (hashtab_datum_t) attr);
1792
yyerror("hash table overflow");
1801
if (!attr->isattr) {
1802
sprintf(errormsg, "%s is a type, not an attribute", id);
1810
ebitmap_set_bit(&attr->types, datum->value - 1, TRUE);
1816
struct val_to_name {
1821
static int type_val_to_name_helper(hashtab_key_t key, hashtab_datum_t datum, void *p)
1823
type_datum_t *typdatum;
1824
struct val_to_name *v = p;
1826
typdatum = (type_datum_t *) datum;
1828
if (v->val == typdatum->value) {
1836
static char *type_val_to_name(unsigned int val)
1838
struct val_to_name v;
1842
rc = hashtab_map(policydbp->p_types.table,
1843
type_val_to_name_helper, &v);
1850
static int set_types(ebitmap_t *set,
1858
if (strcmp(id, "*") == 0) {
1859
/* set all types not in negset */
1860
for (i = 0; i < policydbp->p_types.nprim; i++) {
1861
if (!ebitmap_get_bit(negset, i))
1862
ebitmap_set_bit(set, i, TRUE);
1868
if (strcmp(id, "~") == 0) {
1869
/* complement the set */
1870
for (i = 0; i < policydbp->p_types.nprim; i++) {
1871
if (ebitmap_get_bit(set, i))
1872
ebitmap_set_bit(set, i, FALSE);
1874
ebitmap_set_bit(set, i, TRUE);
1880
if (strcmp(id, "-") == 0) {
1886
t = hashtab_search(policydbp->p_types.table, id);
1888
sprintf(errormsg, "unknown type %s", id);
1895
/* set or clear all types with this attribute,
1896
but do not set anything explicitly cleared previously */
1897
for (i = ebitmap_startbit(&t->types); i < ebitmap_length(&t->types); i++) {
1898
if (!ebitmap_get_bit(&t->types, i))
1901
ebitmap_set_bit(set, i, FALSE);
1902
ebitmap_set_bit(negset, i, TRUE);
1903
} else if (!ebitmap_get_bit(negset, i)) {
1904
ebitmap_set_bit(set, i, TRUE);
1907
char *name = type_val_to_name(i+1);
1908
sprintf(errormsg, "ignoring %s due to prior -%s", name, name);
1914
/* set or clear one type, but do not set anything
1915
explicitly cleared previously */
1917
ebitmap_set_bit(set, t->value - 1, FALSE);
1918
ebitmap_set_bit(negset, t->value - 1, TRUE);
1919
} else if (!ebitmap_get_bit(negset, t->value - 1)) {
1920
ebitmap_set_bit(set, t->value - 1, TRUE);
1923
sprintf(errormsg, "ignoring %s due to prior -%s", id, id);
1935
static int define_compute_type(int which)
1939
avtab_datum_t avdatum, *avdatump;
1940
type_datum_t *datum;
1941
class_datum_t *cladatum;
1942
ebitmap_t stypes, ttypes, tclasses, negset;
1945
unsigned int i, j, k;
1948
while ((id = queue_remove(id_queue)))
1950
while ((id = queue_remove(id_queue)))
1952
while ((id = queue_remove(id_queue)))
1954
id = queue_remove(id_queue);
1959
ebitmap_init(&stypes);
1960
ebitmap_init(&ttypes);
1961
ebitmap_init(&tclasses);
1963
ebitmap_init(&negset);
1964
while ((id = queue_remove(id_queue))) {
1965
if (set_types(&stypes, &negset, id, &add))
1968
ebitmap_destroy(&negset);
1970
ebitmap_init(&negset);
1971
while ((id = queue_remove(id_queue))) {
1972
if (set_types(&ttypes, &negset, id, &add))
1975
ebitmap_destroy(&negset);
1977
while ((id = queue_remove(id_queue))) {
1978
cladatum = hashtab_search(policydbp->p_classes.table, id);
1980
sprintf(errormsg, "unknown class %s", id);
1984
ebitmap_set_bit(&tclasses, cladatum->value - 1, TRUE);
1988
id = (char *) queue_remove(id_queue);
1990
yyerror("no newtype?");
1993
datum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
1994
(hashtab_key_t) id);
1995
if (!datum || datum->isattr) {
1996
sprintf(errormsg, "unknown type %s", id);
2001
for (i = ebitmap_startbit(&stypes); i < ebitmap_length(&stypes); i++) {
2002
if (!ebitmap_get_bit(&stypes, i))
2004
for (j = ebitmap_startbit(&ttypes); j < ebitmap_length(&ttypes); j++) {
2005
if (!ebitmap_get_bit(&ttypes, j))
2007
for (k = ebitmap_startbit(&tclasses); k < ebitmap_length(&tclasses); k++) {
2008
if (!ebitmap_get_bit(&tclasses, k))
2010
avkey.source_type = i + 1;
2011
avkey.target_type = j + 1;
2012
avkey.target_class = k + 1;
2013
avdatump = avtab_search(&policydbp->te_avtab, &avkey, AVTAB_TYPE);
2016
case AVTAB_TRANSITION:
2017
newtype = avtab_transition(avdatump);
2020
newtype = avtab_member(avdatump);
2023
newtype = avtab_change(avdatump);
2026
if ( (avdatump->specified & which) &&
2027
(newtype != datum->value) ) {
2028
sprintf(errormsg, "conflicting rule for (%s, %s:%s): default was %s, is now %s", type_val_to_name(i+1), type_val_to_name(j+1), policydbp->p_class_val_to_name[k],
2029
type_val_to_name(newtype),
2030
type_val_to_name(datum->value));
2033
avdatump->specified |= which;
2035
case AVTAB_TRANSITION:
2036
avtab_transition(avdatump) = datum->value;
2039
avtab_member(avdatump) = datum->value;
2042
avtab_change(avdatump) = datum->value;
2046
memset(&avdatum, 0, sizeof avdatum);
2047
avdatum.specified |= which;
2049
case AVTAB_TRANSITION:
2050
avtab_transition(&avdatum) = datum->value;
2053
avtab_member(&avdatum) = datum->value;
2056
avtab_change(&avdatum) = datum->value;
2059
ret = avtab_insert(&policydbp->te_avtab, &avkey, &avdatum);
2061
yyerror("hash table overflow");
2075
static cond_av_list_t *define_cond_compute_type(int which)
2078
cond_av_list_t *sub_list;
2080
avtab_datum_t avdatum, *avdatump;
2081
type_datum_t *datum;
2082
class_datum_t *cladatum;
2083
ebitmap_t stypes, ttypes, tclasses, negset;
2085
int i, j, k, add = 1;
2088
while ((id = queue_remove(id_queue)))
2090
while ((id = queue_remove(id_queue)))
2092
while ((id = queue_remove(id_queue)))
2094
id = queue_remove(id_queue);
2096
return (cond_av_list_t *)1; /* any non-NULL value */
2099
ebitmap_init(&stypes);
2100
ebitmap_init(&ttypes);
2101
ebitmap_init(&tclasses);
2103
ebitmap_init(&negset);
2104
while ((id = queue_remove(id_queue))) {
2105
if (set_types(&stypes, &negset, id, &add))
2108
ebitmap_destroy(&negset);
2110
ebitmap_init(&negset);
2111
while ((id = queue_remove(id_queue))) {
2112
if (set_types(&ttypes, &negset, id, &add))
2115
ebitmap_destroy(&negset);
2117
while ((id = queue_remove(id_queue))) {
2118
cladatum = hashtab_search(policydbp->p_classes.table, id);
2120
sprintf(errormsg, "unknown class %s", id);
2124
ebitmap_set_bit(&tclasses, cladatum->value - 1, TRUE);
2128
id = (char *) queue_remove(id_queue);
2130
yyerror("no newtype?");
2133
datum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
2134
(hashtab_key_t) id);
2135
if (!datum || datum->isattr) {
2136
sprintf(errormsg, "unknown type %s", id);
2141
/* create sub_list to be passed back and appended to true or false list */
2142
sub_list = (cond_av_list_t *) 0;
2144
for (i = ebitmap_startbit(&stypes); i < ebitmap_length(&stypes); i++) {
2145
if (!ebitmap_get_bit(&stypes, i))
2147
for (j = ebitmap_startbit(&ttypes); j < ebitmap_length(&ttypes); j++) {
2148
if (!ebitmap_get_bit(&ttypes, j))
2150
for (k = ebitmap_startbit(&tclasses); k < ebitmap_length(&tclasses); k++) {
2151
if (!ebitmap_get_bit(&tclasses, k))
2153
avkey.source_type = i + 1;
2154
avkey.target_type = j + 1;
2155
avkey.target_class = k + 1;
2156
avdatump = avtab_search(&policydbp->te_avtab, &avkey, AVTAB_TYPE);
2158
/* does rule exist in base policy? */
2159
if ((avdatump) && (avdatump->specified & which)) {
2161
case AVTAB_TRANSITION:
2162
newtype = avtab_transition(avdatump);
2165
newtype = avtab_member(avdatump);
2168
newtype = avtab_change(avdatump);
2171
if ( (newtype != datum->value) ) {
2172
sprintf(errormsg, "conflicting type rule for conditional "
2173
"(%s, %s:%s) in base: default is %s, conditional %s "
2175
type_val_to_name(i+1),
2176
type_val_to_name(j+1),
2177
policydbp->p_class_val_to_name[k],
2178
type_val_to_name(newtype),
2179
type_val_to_name(datum->value));
2182
sprintf(errormsg, "conditional type rule (%s, %s:%s): "
2183
"has same default, %s, as rule in base policy; "
2184
"conditional %s will be ignored",
2185
type_val_to_name(i+1),
2186
type_val_to_name(j+1),
2187
policydbp->p_class_val_to_name[k],
2188
type_val_to_name(newtype),
2189
type_val_to_name(datum->value));
2193
/* rule does not exist in base policy */
2196
memset(&avdatum, 0, sizeof avdatum);
2197
avdatum.specified |= which;
2199
case AVTAB_TRANSITION:
2200
avtab_transition(&avdatum) = datum->value;
2203
avtab_member(&avdatum) = datum->value;
2206
avtab_change(&avdatum) = datum->value;
2209
/* add rule to sub list */
2210
sub_list = cond_list_append(sub_list, &avkey, &avdatum);
2211
if (sub_list == COND_ERR) {
2212
yyerror("list overflow");
2226
static cond_av_list_t *cond_list_append(cond_av_list_t *sl, avtab_key_t *key, avtab_datum_t *datum) {
2228
cond_av_list_t *n, *end;
2230
n = (cond_av_list_t *) malloc(sizeof(cond_av_list_t));
2232
yyerror("out of memory");
2235
memset(n, 0, sizeof(cond_av_list_t));
2237
for(end=sl; end->next != NULL; end = end->next);
2243
/* construct new node */
2244
n->node = (avtab_ptr_t) malloc(sizeof(struct avtab_node));
2246
yyerror("out of memory");
2249
memset(n->node, 0, sizeof(struct avtab_node));
2250
n->node->key = *key;
2251
n->node->datum = *datum;
2252
/* the next two fields get filled in when we add to true/false list */
2253
n->node->next = (avtab_ptr_t) 0;
2254
n->node->parse_context = (void *) 0;
2260
static int perm_name(hashtab_key_t key, hashtab_datum_t datum, void *data)
2262
struct val_to_name *v = data;
2263
perm_datum_t *perdatum;
2265
perdatum = (perm_datum_t *) datum;
2267
if (v->val == perdatum->value) {
2276
char *av_to_string(__u32 tclass, access_vector_t av)
2278
struct val_to_name v;
2279
static char avbuf[1024];
2280
class_datum_t *cladatum;
2281
char *perm = NULL, *p;
2285
cladatum = policydbp->class_val_to_struct[tclass-1];
2287
for (i = 0; i < cladatum->permissions.nprim; i++) {
2288
if (av & (1 << i)) {
2290
rc = hashtab_map(cladatum->permissions.table,
2292
if (!rc && cladatum->comdatum) {
2294
cladatum->comdatum->permissions.table,
2300
sprintf(p, " %s", perm);
2309
static int define_bool()
2312
cond_bool_datum_t *datum;
2317
while ((id = queue_remove(id_queue)))
2322
id = (char *) queue_remove(id_queue);
2324
yyerror("no identifier for bool definition?");
2329
id = (char *) queue_remove(id_queue);
2331
yyerror("no default value for bool definition?");
2336
datum = (cond_bool_datum_t *) malloc(sizeof(cond_bool_datum_t));
2338
yyerror("out of memory");
2343
memset(datum, 0, sizeof(cond_bool_datum_t));
2344
datum->state = (int)(id[0] == 'T') ? 1 : 0;
2345
datum->value = ++policydbp->p_bools.nprim;
2347
ret = hashtab_insert(policydbp->p_bools.table,
2348
(hashtab_key_t) name, (hashtab_datum_t) datum);
2350
if (ret == HASHTAB_PRESENT) {
2351
--policydbp->p_bools.nprim;
2353
sprintf(errormsg, "name conflict for bool %s", id);
2359
if (ret == HASHTAB_OVERFLOW) {
2360
yyerror("hash table overflow");
2369
static cond_av_list_t *define_cond_pol_list( cond_av_list_t *avlist, cond_av_list_t *sl )
2371
cond_av_list_t *end;
2374
/* return something so we get through pass 1 */
2375
return (cond_av_list_t *)1;
2378
/* if we've started collecting sub lists, prepend to start of collection
2379
because it's probably less iterations than appending. */
2380
if (!sl) return avlist;
2381
else if (!avlist) return sl;
2384
while (end->next) end = end->next;
2390
static int te_avtab_helper(int which, unsigned int stype, unsigned int ttype,
2391
ebitmap_t *tclasses, access_vector_t *avp)
2395
avtab_datum_t avdatum, *avdatump;
2399
if (which == -AVTAB_ALLOWED) {
2400
yyerror("neverallow should not reach this function.");
2404
for (k = ebitmap_startbit(tclasses); k < ebitmap_length(tclasses); k++) {
2405
if (!ebitmap_get_bit(tclasses, k))
2407
avkey.source_type = stype + 1;
2408
avkey.target_type = ttype + 1;
2409
avkey.target_class = k + 1;
2410
avdatump = avtab_search(&policydbp->te_avtab, &avkey, AVTAB_AV);
2412
memset(&avdatum, 0, sizeof avdatum);
2413
avdatum.specified = (which > 0) ? which : -which;
2414
ret = avtab_insert(&policydbp->te_avtab, &avkey, &avdatum);
2416
yyerror("hash table overflow");
2419
avdatump = avtab_search(&policydbp->te_avtab, &avkey, AVTAB_AV);
2421
yyerror("inserted entry vanished!");
2426
avdatump->specified |= ((which > 0) ? which : -which);
2430
avtab_allowed(avdatump) |= avp[k];
2432
case AVTAB_AUDITALLOW:
2433
avtab_auditallow(avdatump) |= avp[k];
2435
case AVTAB_AUDITDENY:
2436
avtab_auditdeny(avdatump) |= avp[k];
2438
case -AVTAB_AUDITDENY:
2439
if (avtab_auditdeny(avdatump))
2440
avtab_auditdeny(avdatump) &= ~avp[k];
2442
avtab_auditdeny(avdatump) = ~avp[k];
2450
static cond_av_list_t *cond_te_avtab_helper(int which, int stype, int ttype,
2451
ebitmap_t *tclasses, access_vector_t *avp )
2456
avtab_datum_t avdatum;
2459
if (which == -AVTAB_ALLOWED) {
2460
yyerror("neverallow should not reach this function.");
2464
/* create sub_list to be passed back and appended to true or false list */
2465
sl = (cond_av_list_t *) 0;
2467
for (k = ebitmap_startbit(tclasses); k < ebitmap_length(tclasses); k++) {
2468
if (!ebitmap_get_bit(tclasses, k))
2471
avkey.source_type = stype + 1;
2472
avkey.target_type = ttype + 1;
2473
avkey.target_class = k + 1;
2475
/* build the datum */
2476
memset(&avdatum, 0, sizeof avdatum);
2477
avdatum.specified = (which > 0) ? which : -which;
2481
avtab_allowed(&avdatum) = avp[k];
2483
case AVTAB_AUDITALLOW:
2484
avtab_auditallow(&avdatum) = avp[k];
2486
case AVTAB_AUDITDENY:
2487
yyerror("AUDITDENY statements are not allowed in a conditional block; use DONTAUDIT");
2489
case -AVTAB_AUDITDENY:
2490
avtab_auditdeny(&avdatum) = ~avp[k];
2494
/* add to temporary list */
2495
sl = cond_list_append(sl, &avkey, &avdatum);
2497
if (sl == COND_ERR) {
2498
yyerror("list overflow");
2506
static cond_av_list_t *define_cond_te_avtab(int which)
2509
cond_av_list_t *sub_list, *self_list, *n;
2510
class_datum_t *cladatum;
2511
perm_datum_t *perdatum;
2512
ebitmap_t stypes, ttypes, tclasses, negset;
2513
access_vector_t *avp;
2514
int i, j, hiclass, self = 0, add = 1;
2517
while ((id = queue_remove(id_queue)))
2519
while ((id = queue_remove(id_queue)))
2521
while ((id = queue_remove(id_queue)))
2523
while ((id = queue_remove(id_queue)))
2525
return (cond_av_list_t *) 1; /* any non-NULL value */
2528
ebitmap_init(&stypes);
2529
ebitmap_init(&ttypes);
2530
ebitmap_init(&tclasses);
2532
ebitmap_init(&negset);
2533
while ((id = queue_remove(id_queue))) {
2534
if (set_types(&stypes, &negset, id, &add))
2537
ebitmap_destroy(&negset);
2539
ebitmap_init(&negset);
2540
while ((id = queue_remove(id_queue))) {
2541
if (strcmp(id, "self") == 0) {
2545
if (set_types(&ttypes, &negset, id, &add))
2548
ebitmap_destroy(&negset);
2551
while ((id = queue_remove(id_queue))) {
2552
cladatum = hashtab_search(policydbp->p_classes.table, id);
2554
sprintf(errormsg, "unknown class %s used in rule", id);
2558
ebitmap_set_bit(&tclasses, cladatum->value - 1, TRUE);
2559
if (cladatum->value > hiclass)
2560
hiclass = cladatum->value;
2564
avp = malloc(hiclass * sizeof(access_vector_t));
2566
yyerror("out of memory");
2569
for (i = 0; i < hiclass; i++)
2571
while ((id = queue_remove(id_queue))) {
2572
for (i = ebitmap_startbit(&tclasses); i < ebitmap_length(&tclasses); i++) {
2573
if (!ebitmap_get_bit(&tclasses, i))
2575
cladatum = policydbp->class_val_to_struct[i];
2577
if (strcmp(id, "*") == 0) {
2578
/* set all permissions in the class */
2583
if (strcmp(id, "~") == 0) {
2584
/* complement the set */
2585
if (which == -AVTAB_AUDITDENY)
2586
yywarn("dontaudit rule with a ~?");
2591
perdatum = hashtab_search(cladatum->permissions.table,
2594
if (cladatum->comdatum) {
2595
perdatum = hashtab_search(cladatum->comdatum->permissions.table,
2600
sprintf(errormsg, "permission %s is not defined for class %s", id, policydbp->p_class_val_to_name[i]);
2605
avp[i] |= (1 << (perdatum->value - 1));
2611
sub_list = (cond_av_list_t *) 0;
2612
self_list = (cond_av_list_t *) 0;
2613
for (i = ebitmap_startbit(&stypes); i < ebitmap_length(&stypes); i++) {
2614
if (!ebitmap_get_bit(&stypes, i))
2617
if ((self_list = cond_te_avtab_helper(which, i, i, &tclasses, avp )) == COND_ERR)
2620
for (j = ebitmap_startbit(&ttypes); j < ebitmap_length(&ttypes); j++) {
2621
if (!ebitmap_get_bit(&ttypes, j))
2623
if ((sub_list = cond_te_avtab_helper(which, i, j, &tclasses, avp)) == COND_ERR)
2625
/* add the self_list, if any, and the sub_list */
2628
while (n->next != (cond_av_list_t *)0) n = n->next;
2631
self_list = sub_list;
2636
ebitmap_destroy(&stypes);
2637
ebitmap_destroy(&ttypes);
2638
ebitmap_destroy(&tclasses);
2647
static int define_te_avtab(int which)
2650
class_datum_t *cladatum;
2651
perm_datum_t *perdatum;
2652
ebitmap_t stypes, ttypes, tclasses, negset;
2653
access_vector_t *avp;
2654
unsigned int i, j, hiclass;
2655
int self = 0, add = 1;
2656
te_assert_t *newassert;
2659
while ((id = queue_remove(id_queue)))
2661
while ((id = queue_remove(id_queue)))
2663
while ((id = queue_remove(id_queue)))
2665
while ((id = queue_remove(id_queue)))
2670
ebitmap_init(&stypes);
2671
ebitmap_init(&ttypes);
2672
ebitmap_init(&tclasses);
2674
ebitmap_init(&negset);
2675
while ((id = queue_remove(id_queue))) {
2676
if (set_types(&stypes, &negset, id, &add))
2679
ebitmap_destroy(&negset);
2681
ebitmap_init(&negset);
2682
while ((id = queue_remove(id_queue))) {
2683
if (strcmp(id, "self") == 0) {
2687
if (set_types(&ttypes, &negset, id, &add))
2690
ebitmap_destroy(&negset);
2693
while ((id = queue_remove(id_queue))) {
2694
cladatum = hashtab_search(policydbp->p_classes.table, id);
2696
sprintf(errormsg, "unknown class %s used in rule", id);
2700
ebitmap_set_bit(&tclasses, cladatum->value - 1, TRUE);
2701
if (cladatum->value > hiclass)
2702
hiclass = cladatum->value;
2706
avp = malloc(hiclass * sizeof(access_vector_t));
2708
yyerror("out of memory");
2711
for (i = 0; i < hiclass; i++)
2714
while ((id = queue_remove(id_queue))) {
2715
for (i = ebitmap_startbit(&tclasses); i < ebitmap_length(&tclasses); i++) {
2716
if (!ebitmap_get_bit(&tclasses, i))
2718
cladatum = policydbp->class_val_to_struct[i];
2720
if (strcmp(id, "*") == 0) {
2721
/* set all permissions in the class */
2726
if (strcmp(id, "~") == 0) {
2727
/* complement the set */
2728
if (which == -AVTAB_AUDITDENY)
2729
yywarn("dontaudit rule with a ~?");
2734
perdatum = hashtab_search(cladatum->permissions.table,
2737
if (cladatum->comdatum) {
2738
perdatum = hashtab_search(cladatum->comdatum->permissions.table,
2743
sprintf(errormsg, "permission %s is not defined for class %s", id, policydbp->p_class_val_to_name[i]);
2748
avp[i] |= (1 << (perdatum->value - 1));
2754
if (which == -AVTAB_ALLOWED) {
2755
newassert = malloc(sizeof(te_assert_t));
2757
yyerror("out of memory");
2760
memset(newassert, 0, sizeof(te_assert_t));
2761
newassert->stypes = stypes;
2762
newassert->ttypes = ttypes;
2763
newassert->tclasses = tclasses;
2764
newassert->self = self;
2765
newassert->avp = avp;
2766
newassert->line = policydb_lineno;
2767
newassert->next = te_assertions;
2768
te_assertions = newassert;
2772
for (i = ebitmap_startbit(&stypes); i < ebitmap_length(&stypes); i++) {
2773
if (!ebitmap_get_bit(&stypes, i))
2776
if (te_avtab_helper(which, i, i, &tclasses, avp))
2779
for (j = ebitmap_startbit(&ttypes); j < ebitmap_length(&ttypes); j++) {
2780
if (!ebitmap_get_bit(&ttypes, j))
2782
if (te_avtab_helper(which, i, j, &tclasses, avp))
2787
ebitmap_destroy(&stypes);
2788
ebitmap_destroy(&ttypes);
2789
ebitmap_destroy(&tclasses);
2798
static int role_val_to_name_helper(hashtab_key_t key, hashtab_datum_t datum, void *p)
2800
struct val_to_name *v = p;
2801
role_datum_t *roldatum;
2803
roldatum = (role_datum_t *) datum;
2805
if (v->val == roldatum->value) {
2814
static char *role_val_to_name(unsigned int val)
2816
struct val_to_name v;
2820
rc = hashtab_map(policydbp->p_roles.table,
2821
role_val_to_name_helper, &v);
2827
static int define_role_types(void)
2835
while ((id = queue_remove(id_queue)))
2840
role_id = queue_remove(id_queue);
2842
role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
2845
role = (role_datum_t *) malloc(sizeof(role_datum_t));
2847
yyerror("out of memory");
2851
memset(role, 0, sizeof(role_datum_t));
2852
role->value = ++policydbp->p_roles.nprim;
2853
ebitmap_set_bit(&role->dominates, role->value-1, TRUE);
2854
ret = hashtab_insert(policydbp->p_roles.table,
2855
(hashtab_key_t) role_id, (hashtab_datum_t) role);
2858
yyerror("hash table overflow");
2866
ebitmap_init(&negset);
2867
while ((id = queue_remove(id_queue))) {
2868
if (set_types(&role->types, &negset, id, &add))
2871
ebitmap_destroy(&negset);
2877
static role_datum_t *
2878
merge_roles_dom(role_datum_t * r1, role_datum_t * r2)
2883
return (role_datum_t *)1; /* any non-NULL value */
2886
new = malloc(sizeof(role_datum_t));
2888
yyerror("out of memory");
2891
memset(new, 0, sizeof(role_datum_t));
2892
new->value = 0; /* temporary role */
2893
if (ebitmap_or(&new->dominates, &r1->dominates, &r2->dominates)) {
2894
yyerror("out of memory");
2897
if (ebitmap_or(&new->types, &r1->types, &r2->types)) {
2898
yyerror("out of memory");
2902
/* free intermediate result */
2903
ebitmap_destroy(&r1->types);
2904
ebitmap_destroy(&r1->dominates);
2908
/* free intermediate result */
2909
yyerror("right hand role is temporary?");
2910
ebitmap_destroy(&r2->types);
2911
ebitmap_destroy(&r2->dominates);
2918
static role_datum_t *
2919
define_role_dom(role_datum_t * r)
2927
role_id = queue_remove(id_queue);
2929
return (role_datum_t *)1; /* any non-NULL value */
2932
role_id = queue_remove(id_queue);
2933
role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
2936
role = (role_datum_t *) malloc(sizeof(role_datum_t));
2938
yyerror("out of memory");
2942
memset(role, 0, sizeof(role_datum_t));
2943
role->value = ++policydbp->p_roles.nprim;
2944
ebitmap_set_bit(&role->dominates, role->value-1, TRUE);
2945
ret = hashtab_insert(policydbp->p_roles.table,
2946
(hashtab_key_t) role_id, (hashtab_datum_t) role);
2949
yyerror("hash table overflow");
2956
for (i = ebitmap_startbit(&r->dominates); i < ebitmap_length(&r->dominates); i++) {
2957
if (ebitmap_get_bit(&r->dominates, i))
2958
ebitmap_set_bit(&role->dominates, i, TRUE);
2960
for (i = ebitmap_startbit(&r->types); i < ebitmap_length(&r->types); i++) {
2961
if (ebitmap_get_bit(&r->types, i))
2962
ebitmap_set_bit(&role->types, i, TRUE);
2965
/* free intermediate result */
2966
ebitmap_destroy(&r->types);
2967
ebitmap_destroy(&r->dominates);
2975
static int set_roles(ebitmap_t *set,
2981
if (strcmp(id, "*") == 0) {
2983
for (i = 0; i < policydbp->p_roles.nprim; i++)
2984
ebitmap_set_bit(set, i, TRUE);
2989
if (strcmp(id, "~") == 0) {
2990
/* complement the set */
2991
for (i = 0; i < policydbp->p_roles.nprim; i++) {
2992
if (ebitmap_get_bit(set, i))
2993
ebitmap_set_bit(set, i, FALSE);
2995
ebitmap_set_bit(set, i, TRUE);
3001
r = hashtab_search(policydbp->p_roles.table, id);
3003
sprintf(errormsg, "unknown role %s", id);
3010
ebitmap_set_bit(set, r->value - 1, TRUE);
3016
static int define_role_trans(void)
3020
ebitmap_t roles, types, negset;
3021
struct role_trans *tr = 0;
3026
while ((id = queue_remove(id_queue)))
3028
while ((id = queue_remove(id_queue)))
3030
id = queue_remove(id_queue);
3035
ebitmap_init(&roles);
3036
ebitmap_init(&types);
3038
while ((id = queue_remove(id_queue))) {
3039
if (set_roles(&roles, id))
3043
ebitmap_init(&negset);
3044
while ((id = queue_remove(id_queue))) {
3045
if (set_types(&types, &negset, id, &add))
3048
ebitmap_destroy(&negset);
3050
id = (char *) queue_remove(id_queue);
3052
yyerror("no new role in transition definition?");
3055
role = hashtab_search(policydbp->p_roles.table, id);
3057
sprintf(errormsg, "unknown role %s used in transition definition", id);
3062
for (i = ebitmap_startbit(&roles); i < ebitmap_length(&roles); i++) {
3063
if (!ebitmap_get_bit(&roles, i))
3065
for (j = ebitmap_startbit(&types); j < ebitmap_length(&types); j++) {
3066
if (!ebitmap_get_bit(&types, j))
3069
for (tr = policydbp->role_tr; tr; tr = tr->next) {
3070
if (tr->role == (i+1) && tr->type == (j+1)) {
3071
sprintf(errormsg, "duplicate role transition defined for (%s,%s)",
3072
role_val_to_name(i+1), type_val_to_name(j+1));
3078
tr = malloc(sizeof(struct role_trans));
3080
yyerror("out of memory");
3083
memset(tr, 0, sizeof(struct role_trans));
3086
tr->new_role = role->value;
3087
tr->next = policydbp->role_tr;
3088
policydbp->role_tr = tr;
3099
static int define_role_allow(void)
3102
ebitmap_t roles, new_roles;
3103
struct role_allow *ra = 0;
3107
while ((id = queue_remove(id_queue)))
3109
while ((id = queue_remove(id_queue)))
3114
ebitmap_init(&roles);
3115
ebitmap_init(&new_roles);
3117
while ((id = queue_remove(id_queue))) {
3118
if (set_roles(&roles, id))
3123
while ((id = queue_remove(id_queue))) {
3124
if (set_roles(&new_roles, id))
3128
for (i = ebitmap_startbit(&roles); i < ebitmap_length(&roles); i++) {
3129
if (!ebitmap_get_bit(&roles, i))
3131
for (j = ebitmap_startbit(&new_roles); j < ebitmap_length(&new_roles); j++) {
3132
if (!ebitmap_get_bit(&new_roles, j))
3135
for (ra = policydbp->role_allow; ra; ra = ra->next) {
3136
if (ra->role == (i+1) && ra->new_role == (j+1))
3143
ra = malloc(sizeof(struct role_allow));
3145
yyerror("out of memory");
3148
memset(ra, 0, sizeof(struct role_allow));
3151
ra->next = policydbp->role_allow;
3152
policydbp->role_allow = ra;
3160
static int define_constraint(constraint_expr_t * expr)
3162
struct constraint_node *node;
3164
class_datum_t *cladatum;
3165
perm_datum_t *perdatum;
3167
constraint_expr_t *e;
3172
while ((id = queue_remove(id_queue)))
3174
while ((id = queue_remove(id_queue)))
3180
for (e = expr; e; e = e->next) {
3181
switch (e->expr_type) {
3184
yyerror("illegal constraint expression");
3191
yyerror("illegal constraint expression");
3198
if (depth == (CEXPR_MAXDEPTH-1)) {
3199
yyerror("constraint expression is too deep");
3205
yyerror("illegal constraint expression");
3210
yyerror("illegal constraint expression");
3214
ebitmap_init(&classmap);
3215
while ((id = queue_remove(id_queue))) {
3216
cladatum = (class_datum_t *) hashtab_search(policydbp->p_classes.table,
3217
(hashtab_key_t) id);
3219
sprintf(errormsg, "class %s is not defined", id);
3220
ebitmap_destroy(&classmap);
3225
if (ebitmap_set_bit(&classmap, cladatum->value - 1, TRUE)) {
3226
yyerror("out of memory");
3227
ebitmap_destroy(&classmap);
3231
node = malloc(sizeof(struct constraint_node));
3233
yyerror("out of memory");
3236
memset(node, 0, sizeof(constraint_node_t));
3238
node->permissions = 0;
3240
node->next = cladatum->constraints;
3241
cladatum->constraints = node;
3246
while ((id = queue_remove(id_queue))) {
3247
for (i = ebitmap_startbit(&classmap); i < ebitmap_length(&classmap); i++) {
3248
if (ebitmap_get_bit(&classmap, i)) {
3249
cladatum = policydbp->class_val_to_struct[i];
3250
node = cladatum->constraints;
3252
perdatum = (perm_datum_t *) hashtab_search(cladatum->permissions.table,
3253
(hashtab_key_t) id);
3255
if (cladatum->comdatum) {
3256
perdatum = (perm_datum_t *) hashtab_search(cladatum->comdatum->permissions.table,
3257
(hashtab_key_t) id);
3260
sprintf(errormsg, "permission %s is not defined", id);
3263
ebitmap_destroy(&classmap);
3267
node->permissions |= (1 << (perdatum->value - 1));
3273
ebitmap_destroy(&classmap);
3279
define_cexpr(__u32 expr_type, uintptr_t arg1, uintptr_t arg2)
3281
struct constraint_expr *expr, *e1 = NULL, *e2;
3290
if (expr_type == CEXPR_NAMES) {
3291
while ((id = queue_remove(id_queue)))
3294
return 1; /* any non-NULL value */
3297
expr = malloc(sizeof(struct constraint_expr));
3299
yyerror("out of memory");
3302
memset(expr, 0, sizeof(constraint_expr_t));
3303
expr->expr_type = expr_type;
3305
switch (expr_type) {
3308
e2 = (struct constraint_expr *) arg1;
3313
if (!e1 || e1->next) {
3314
yyerror("illegal constraint expression");
3323
e2 = (struct constraint_expr *) arg1;
3328
if (!e1 || e1->next) {
3329
yyerror("illegal constraint expression");
3333
e1->next = (struct constraint_expr *) arg2;
3336
e2 = (struct constraint_expr *) arg2;
3341
if (!e1 || e1->next) {
3342
yyerror("illegal constraint expression");
3351
return (uintptr_t)expr;
3355
ebitmap_init(&negset);
3356
while ((id = (char *) queue_remove(id_queue))) {
3357
if (expr->attr & CEXPR_USER) {
3358
user = (user_datum_t *) hashtab_search(policydbp->p_users.table,
3359
(hashtab_key_t) id);
3361
sprintf(errormsg, "unknown user %s", id);
3367
} else if (expr->attr & CEXPR_ROLE) {
3368
role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
3369
(hashtab_key_t) id);
3371
sprintf(errormsg, "unknown role %s", id);
3377
} else if (expr->attr & CEXPR_TYPE) {
3378
if (set_types(&expr->names, &negset, id, &add)) {
3384
yyerror("invalid constraint expression");
3388
if (ebitmap_set_bit(&expr->names, val - 1, TRUE)) {
3389
yyerror("out of memory");
3390
ebitmap_destroy(&expr->names);
3396
ebitmap_destroy(&negset);
3397
return (uintptr_t)expr;
3399
yyerror("invalid constraint expression");
3404
yyerror("invalid constraint expression");
3409
static int define_conditional(cond_expr_t *expr, cond_av_list_t *t, cond_av_list_t *f )
3412
cond_node_t *cn, tmp, *cn_new;
3416
/* expression cannot be NULL */
3418
yyerror("illegal conditional expression");
3421
/* Must have at least one rule in true list */
3423
yyerror("must have at least one rule in true list");
3428
/* verify expression */
3430
for (e = expr; e; e = e->next) {
3431
switch (e->expr_type) {
3434
yyerror("illegal conditional expression; Bad NOT");
3444
yyerror("illegal conditional expression; Bad binary op");
3450
if (depth == (COND_EXPR_MAXDEPTH-1)) {
3451
yyerror("conditional expression is like totally too deep");
3457
yyerror("illegal conditional expression");
3462
yyerror("illegal conditional expression");
3466
/* use tmp conditional node to partially build new node */
3472
/* normalize/precompute expression */
3473
if (normalize_expr(policydbp, cn) < 0) {
3474
yyerror("problem normalizing conditional expression");
3478
/* get the existing conditional node, or a new one*/
3479
cn_new = cond_node_search(policydbp, cn);
3481
cond_reduce_insert_list (cn->true_list, &cn_new->true_list, &cn_new->false_list, cn_new->cur_state);
3482
cond_reduce_insert_list (cn->false_list, &cn_new->false_list, &cn_new->true_list, !cn_new->cur_state);
3484
yyerror("could not get a conditional node");
3493
/* Set the ENABLE bit and parse_context for each rule and check rules to see if they already exist.
3494
* Insert rules into the conditional db when appropriate.
3496
* new - list of rules to potentially add/insert
3497
* active - list to add rule to, and address to use as parse_context
3498
* inactive - opposite rule list in same conditional
3499
* state - whether rules in new are on or off by default.
3501
* There are 4 possible conditions for a TYPE_* rule. Allow rules are always inserted or
3502
* OR'd with existing allow rules on the same side of the same conditional.
3504
* 1) Not present anywhere -> add it
3505
* 2) Already in cond, same side -> warn, replace default in prev rule, delete this rule
3506
* 3) Just added to opp side -> search again (we may still add this rule)
3507
* 4) In another conditional (either side) -> warn, delete this rule
3509
static void cond_reduce_insert_list(cond_av_list_t *new, cond_av_list_t **active, cond_av_list_t **inactive, int state)
3512
cond_av_list_t *c, *top;
3514
__u32 old_data = 0, new_data = 0;
3517
/* loop through all the rules in the list */
3520
/* is conditional rule a TYPE_* rule that's already in a conditional? */
3521
/* [note that we checked to see if it's in the base when we parsed the rule] */
3522
if ((c->node->datum.specified & AVTAB_TYPE) &&
3523
((dup = avtab_search_node(&policydbp->te_cond_avtab, &c->node->key, c->node->datum.specified & AVTAB_TYPE)) != NULL) ){
3525
/* is the rule we found in the current rule list or the equivalent */
3526
if (dup->parse_context == active) {
3527
/* change original default */
3528
switch(c->node->datum.specified & AVTAB_TYPE) {
3529
case AVTAB_TRANSITION:
3530
old_data = avtab_transition(&dup->datum);
3531
new_data = avtab_transition(&c->node->datum);
3532
avtab_transition(&dup->datum) = new_data;
3535
old_data = avtab_member(&dup->datum);
3536
new_data = avtab_member(&c->node->datum);
3537
avtab_member(&dup->datum) = new_data;
3540
old_data = avtab_change(&dup->datum);
3541
new_data = avtab_change(&c->node->datum);
3542
avtab_change(&dup->datum) = new_data;
3545
sprintf(errormsg, "duplicate type rule on same side of conditional for (%s, %s:%s); overwrote original default %s with %s",
3546
type_val_to_name(c->node->key.source_type),
3547
type_val_to_name(c->node->key.target_type),
3548
policydbp->p_class_val_to_name[c->node->key.target_class],
3549
type_val_to_name(old_data),
3550
type_val_to_name(new_data));
3555
/* if the rule we found is in the opposite rule list that's OK*/
3556
if (dup->parse_context == inactive) {
3559
/* the rule we found must be in another conditional */
3560
sprintf(errormsg, "discarding conflicting conditional type rule for (%s, %s:%s); may only be in one conditional",
3561
type_val_to_name(c->node->key.source_type),
3562
type_val_to_name(c->node->key.target_type),
3563
policydbp->p_class_val_to_name[c->node->key.target_class]);
3568
} while ( (dup = avtab_search_node_next(dup, c->node->datum.specified & AVTAB_TYPE)) != NULL);
3570
} /* end dealing with TYPE_* rules */
3571
else if ( (c->node->datum.specified & AVTAB_AV ) &&
3572
((dup = avtab_search_node(&policydbp->te_cond_avtab, &c->node->key, c->node->datum.specified & AVTAB_AV)) != NULL) ){
3574
/* we only care if the same AV rule is on the same side of the same conditional */
3575
if (dup->parse_context == active) {
3576
/* add to original */
3577
switch(c->node->datum.specified & AVTAB_AV) {
3579
new_data = avtab_allowed(&c->node->datum);
3580
avtab_allowed(&dup->datum) |= new_data;
3582
case AVTAB_AUDITALLOW:
3583
new_data = avtab_auditallow(&c->node->datum);
3584
avtab_auditallow(&dup->datum) |= new_data;
3586
case AVTAB_AUDITDENY:
3587
new_data = avtab_auditdeny(&c->node->datum);
3588
/* Since a '0' in an auditdeny mask represents a
3589
* permission we do NOT want to audit (dontaudit), we use
3590
* the '&' operand to ensure that all '0's in the mask
3591
* are retained (much unlike the allow and auditallow cases).
3593
avtab_auditdeny(&dup->datum) &= new_data;
3599
} while ( (dup = avtab_search_node_next(dup, c->node->datum.specified & AVTAB_AV)) != NULL);
3600
} /* end dealing with ALLOW rules */
3603
/* Either insert the rule into the policy and active list, or discard the rule */
3605
c->node = avtab_insert_with_parse_context(&policydbp->te_cond_avtab,
3609
/* set whether the rule is enabled/disabled */
3611
c->node->datum.specified |= AVTAB_ENABLED;
3613
c->node->datum.specified &= ~AVTAB_ENABLED;
3616
/* prepend new rule to active list */
3632
static cond_expr_t *
3633
define_cond_expr(__u32 expr_type, void* arg1, void* arg2)
3635
struct cond_expr *expr, *e1 = NULL, *e2;
3636
cond_bool_datum_t *bool_var;
3639
/* expressions are handled in the second pass */
3641
if (expr_type == COND_BOOL) {
3642
while ((id = queue_remove(id_queue))) {
3646
return (cond_expr_t *)1; /* any non-NULL value */
3649
/* create a new expression struct */
3650
expr = malloc(sizeof(struct cond_expr));
3652
yyerror("out of memory");
3655
memset(expr, 0, sizeof(cond_expr_t));
3656
expr->expr_type = expr_type;
3658
/* create the type asked for */
3659
switch (expr_type) {
3662
e2 = (struct cond_expr *) arg1;
3667
if (!e1 || e1->next) {
3668
yyerror("illegal conditional NOT expression");
3673
return (struct cond_expr *) arg1;
3680
e2 = (struct cond_expr *) arg1;
3685
if (!e1 || e1->next) {
3686
yyerror("illegal left side of conditional binary op expression");
3690
e1->next = (struct cond_expr *) arg2;
3693
e2 = (struct cond_expr *) arg2;
3698
if (!e1 || e1->next) {
3699
yyerror("illegal right side of conditional binary op expression");
3704
return (struct cond_expr *) arg1;
3706
id = (char *) queue_remove(id_queue) ;
3708
yyerror("bad conditional; expected boolean id");
3713
bool_var = (cond_bool_datum_t *) hashtab_search(policydbp->p_bools.table,
3714
(hashtab_key_t) id);
3716
sprintf(errormsg, "unknown boolean %s in conditional expression", id);
3722
expr->bool = bool_var->value;
3726
yyerror("illegal conditional expression");
3732
static int set_user_roles(ebitmap_t *set,
3738
if (strcmp(id, "*") == 0) {
3740
for (i = 0; i < policydbp->p_roles.nprim; i++)
3741
ebitmap_set_bit(set, i, TRUE);
3746
if (strcmp(id, "~") == 0) {
3747
/* complement the set */
3748
for (i = 0; i < policydbp->p_roles.nprim; i++) {
3749
if (ebitmap_get_bit(set, i))
3750
ebitmap_set_bit(set, i, FALSE);
3752
ebitmap_set_bit(set, i, TRUE);
3758
r = hashtab_search(policydbp->p_roles.table, id);
3760
sprintf(errormsg, "unknown role %s", id);
3766
/* set the role and every role it dominates */
3767
for (i = ebitmap_startbit(&r->dominates); i < ebitmap_length(&r->dominates); i++) {
3768
if (ebitmap_get_bit(&r->dominates, i))
3769
ebitmap_set_bit(set, i, TRUE);
3776
static int define_user(void)
3779
user_datum_t *usrdatum;
3781
#ifdef CONFIG_SECURITY_SELINUX_MLS
3782
mls_range_list_t *rnode;
3783
level_datum_t *levdatum;
3784
cat_datum_t *catdatum;
3790
while ((id = queue_remove(id_queue)))
3792
#ifdef CONFIG_SECURITY_SELINUX_MLS
3793
while ((id = queue_remove(id_queue))) {
3795
for (l = 0; l < 2; l++) {
3796
while ((id = queue_remove(id_queue))) {
3805
id = (char *) queue_remove(id_queue);
3807
yyerror("no user name for user definition?");
3810
usrdatum = (user_datum_t *) hashtab_search(policydbp->p_users.table,
3811
(hashtab_key_t) id);
3813
usrdatum = (user_datum_t *) malloc(sizeof(user_datum_t));
3815
yyerror("out of memory");
3819
memset(usrdatum, 0, sizeof(user_datum_t));
3820
usrdatum->value = ++policydbp->p_users.nprim;
3821
ebitmap_init(&usrdatum->roles);
3822
ret = hashtab_insert(policydbp->p_users.table,
3823
(hashtab_key_t) id, (hashtab_datum_t) usrdatum);
3825
yyerror("hash table overflow");
3833
while ((id = queue_remove(id_queue))) {
3834
if (set_user_roles(&usrdatum->roles, id))
3838
#ifdef CONFIG_SECURITY_SELINUX_MLS
3839
id = queue_remove(id_queue);
3841
rnode = (mls_range_list_t *) malloc(sizeof(mls_range_list_t));
3843
yyerror("out of memory");
3847
memset(rnode, 0, sizeof(mls_range_list_t));
3848
levdatum = (level_datum_t *) hashtab_search(policydbp->p_levels.table,
3849
(hashtab_key_t) "unclassified");
3851
yyerror("no range for user");
3854
rnode->range.level[0].sens = levdatum->level->sens;
3855
rnode->range.level[1].sens = levdatum->level->sens;
3856
rnode->next = usrdatum->ranges;
3857
usrdatum->ranges = rnode;
3861
rnode = (mls_range_list_t *) malloc(sizeof(mls_range_list_t));
3863
yyerror("out of memory");
3867
memset(rnode, 0, sizeof(mls_range_list_t));
3869
for (l = 0; l < 2; l++) {
3870
levdatum = (level_datum_t *) hashtab_search(policydbp->p_levels.table,
3871
(hashtab_key_t) id);
3873
sprintf(errormsg, "unknown sensitivity %s used in user range definition", id);
3879
rnode->range.level[l].sens = levdatum->level->sens;
3880
ebitmap_init(&rnode->range.level[l].cat);
3884
while ((id = queue_remove(id_queue))) {
3885
catdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
3886
(hashtab_key_t) id);
3888
sprintf(errormsg, "unknown category %s used in user range definition", id);
3893
if (!(ebitmap_get_bit(&levdatum->level->cat, catdatum->value - 1))) {
3894
sprintf(errormsg, "category %s cannot be associated with level %s", id, levid);
3899
if (ebitmap_set_bit(&rnode->range.level[l].cat, catdatum->value - 1, TRUE)) {
3900
yyerror("out of memory");
3903
ebitmap_destroy(&rnode->range.level[l].cat);
3909
* no need to keep category name
3915
* no need to keep sensitivity name
3919
id = queue_remove(id_queue);
3925
rnode->range.level[1].sens = rnode->range.level[0].sens;
3926
if (ebitmap_cpy(&rnode->range.level[1].cat, &rnode->range.level[0].cat)) {
3927
yyerror("out of memory");
3929
ebitmap_destroy(&rnode->range.level[0].cat);
3934
relation = mls_level_relation(rnode->range.level[1], rnode->range.level[0]);
3935
if (!(relation & (MLS_RELATION_DOM | MLS_RELATION_EQ))) {
3936
/* high does not dominate low */
3937
yyerror("high does not dominate low");
3938
ebitmap_destroy(&rnode->range.level[0].cat);
3939
ebitmap_destroy(&rnode->range.level[1].cat);
3943
rnode->next = usrdatum->ranges;
3944
usrdatum->ranges = rnode;
3945
} while ((id = queue_remove(id_queue)));
3953
static int parse_security_context(context_struct_t * c)
3957
type_datum_t *typdatum;
3958
user_datum_t *usrdatum;
3959
#ifdef CONFIG_SECURITY_SELINUX_MLS
3961
level_datum_t *levdatum;
3962
cat_datum_t *catdatum;
3967
id = queue_remove(id_queue); free(id); /* user */
3968
id = queue_remove(id_queue); free(id); /* role */
3969
id = queue_remove(id_queue); free(id); /* type */
3970
#ifdef CONFIG_SECURITY_SELINUX_MLS
3971
id = queue_remove(id_queue); free(id);
3972
for (l = 0; l < 2; l++) {
3973
while ((id = queue_remove(id_queue))) {
3983
/* extract the user */
3984
id = queue_remove(id_queue);
3986
yyerror("no effective user?");
3989
usrdatum = (user_datum_t *) hashtab_search(policydbp->p_users.table,
3990
(hashtab_key_t) id);
3992
sprintf(errormsg, "user %s is not defined", id);
3997
c->user = usrdatum->value;
3999
/* no need to keep the user name */
4002
/* extract the role */
4003
id = (char *) queue_remove(id_queue);
4005
yyerror("no role name for sid context definition?");
4008
role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
4009
(hashtab_key_t) id);
4011
sprintf(errormsg, "role %s is not defined", id);
4016
c->role = role->value;
4018
/* no need to keep the role name */
4022
/* extract the type */
4023
id = (char *) queue_remove(id_queue);
4025
yyerror("no type name for sid context definition?");
4028
typdatum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
4029
(hashtab_key_t) id);
4030
if (!typdatum || typdatum->isattr) {
4031
sprintf(errormsg, "type %s is not defined", id);
4036
c->type = typdatum->value;
4038
/* no need to keep the type name */
4041
#ifdef CONFIG_SECURITY_SELINUX_MLS
4042
/* extract the low sensitivity */
4043
id = (char *) queue_head(id_queue);
4044
if (!id || strcmp(id, "system_u") == 0 /* hack */) {
4045
/* No MLS component to the security context. Try
4046
to use a default 'unclassified' value. */
4047
levdatum = (level_datum_t *) hashtab_search(policydbp->p_levels.table,
4048
(hashtab_key_t) "unclassified");
4050
yyerror("no sensitivity name for sid context definition?");
4053
c->range.level[0].sens = levdatum->level->sens;
4054
c->range.level[1].sens = levdatum->level->sens;
4058
id = (char *) queue_remove(id_queue);
4059
for (l = 0; l < 2; l++) {
4060
levdatum = (level_datum_t *) hashtab_search(policydbp->p_levels.table,
4061
(hashtab_key_t) id);
4063
sprintf(errormsg, "Sensitivity %s is not defined", id);
4068
c->range.level[l].sens = levdatum->level->sens;
4070
/* extract low category set */
4072
while ((id = queue_remove(id_queue))) {
4073
catdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
4074
(hashtab_key_t) id);
4076
sprintf(errormsg, "unknown category %s used in initial sid context", id);
4082
if (ebitmap_set_bit(&c->range.level[l].cat,
4083
catdatum->value - 1, TRUE)) {
4084
yyerror("out of memory");
4089
/* no need to keep category name */
4093
/* no need to keep the sensitivity name */
4096
/* extract high sensitivity */
4097
id = (char *) queue_remove(id_queue);
4103
c->range.level[1].sens = c->range.level[0].sens;
4104
if (ebitmap_cpy(&c->range.level[1].cat, &c->range.level[0].cat)) {
4106
yyerror("out of memory");
4113
if (!policydb_context_isvalid(policydbp, c)) {
4114
yyerror("invalid security context");
4126
static int define_initial_sid_context(void)
4129
ocontext_t *c, *head;
4132
id = (char *) queue_remove(id_queue); free(id);
4133
parse_security_context(NULL);
4137
id = (char *) queue_remove(id_queue);
4139
yyerror("no sid name for SID context definition?");
4142
head = policydbp->ocontexts[OCON_ISID];
4143
for (c = head; c; c = c->next) {
4144
if (!strcmp(id, c->u.name))
4149
sprintf(errormsg, "SID %s is not defined", id);
4154
if (c->context[0].user) {
4155
sprintf(errormsg, "The context for SID %s is multiply defined", id);
4160
/* no need to keep the sid name */
4163
if (parse_security_context(&c->context[0]))
4169
static int define_fs_context(unsigned int major, unsigned int minor)
4171
ocontext_t *newc, *c, *head;
4174
parse_security_context(NULL);
4175
parse_security_context(NULL);
4179
newc = (ocontext_t *) malloc(sizeof(ocontext_t));
4181
yyerror("out of memory");
4184
memset(newc, 0, sizeof(ocontext_t));
4186
newc->u.name = (char *) malloc(6);
4187
if (!newc->u.name) {
4188
yyerror("out of memory");
4192
sprintf(newc->u.name, "%02x:%02x", major, minor);
4194
if (parse_security_context(&newc->context[0])) {
4199
if (parse_security_context(&newc->context[1])) {
4200
context_destroy(&newc->context[0]);
4205
head = policydbp->ocontexts[OCON_FS];
4207
for (c = head; c; c = c->next) {
4208
if (!strcmp(newc->u.name, c->u.name)) {
4209
sprintf(errormsg, "duplicate entry for file system %s", newc->u.name);
4211
context_destroy(&newc->context[0]);
4212
context_destroy(&newc->context[1]);
4220
policydbp->ocontexts[OCON_FS] = newc;
4225
static int define_port_context(unsigned int low, unsigned int high)
4231
id = (char *) queue_remove(id_queue); free(id);
4232
parse_security_context(NULL);
4236
newc = malloc(sizeof(ocontext_t));
4238
yyerror("out of memory");
4241
memset(newc, 0, sizeof(ocontext_t));
4243
id = (char *) queue_remove(id_queue);
4248
if ((strcmp(id, "tcp") == 0) || (strcmp(id, "TCP") == 0)) {
4249
newc->u.port.protocol = IPPROTO_TCP;
4250
} else if ((strcmp(id, "udp") == 0) || (strcmp(id, "UDP") == 0)) {
4251
newc->u.port.protocol = IPPROTO_UDP;
4253
sprintf(errormsg, "unrecognized protocol %s", id);
4259
newc->u.port.low_port = low;
4260
newc->u.port.high_port = high;
4262
if (parse_security_context(&newc->context[0])) {
4266
newc->next = policydbp->ocontexts[OCON_PORT];
4267
policydbp->ocontexts[OCON_PORT] = newc;
4271
static int define_netif_context(void)
4273
ocontext_t *newc, *c, *head;
4276
free(queue_remove(id_queue));
4277
parse_security_context(NULL);
4278
parse_security_context(NULL);
4282
newc = (ocontext_t *) malloc(sizeof(ocontext_t));
4284
yyerror("out of memory");
4287
memset(newc, 0, sizeof(ocontext_t));
4289
newc->u.name = (char *) queue_remove(id_queue);
4290
if (!newc->u.name) {
4294
if (parse_security_context(&newc->context[0])) {
4299
if (parse_security_context(&newc->context[1])) {
4300
context_destroy(&newc->context[0]);
4305
head = policydbp->ocontexts[OCON_NETIF];
4307
for (c = head; c; c = c->next) {
4308
if (!strcmp(newc->u.name, c->u.name)) {
4309
sprintf(errormsg, "duplicate entry for network interface %s", newc->u.name);
4311
context_destroy(&newc->context[0]);
4312
context_destroy(&newc->context[1]);
4320
policydbp->ocontexts[OCON_NETIF] = newc;
4324
static int define_ipv4_node_context(unsigned int addr, unsigned int mask)
4326
ocontext_t *newc, *c, *l, *head;
4329
parse_security_context(NULL);
4333
newc = malloc(sizeof(ocontext_t));
4335
yyerror("out of memory");
4338
memset(newc, 0, sizeof(ocontext_t));
4340
newc->u.node.addr = addr;
4341
newc->u.node.mask = mask;
4343
if (parse_security_context(&newc->context[0])) {
4347
/* Place this at the end of the list, to retain
4348
the matching order specified in the configuration. */
4349
head = policydbp->ocontexts[OCON_NODE];
4350
for (l = NULL, c = head; c; l = c, c = c->next);
4355
policydbp->ocontexts[OCON_NODE] = newc;
4360
static int define_ipv6_node_context(void)
4364
struct in6_addr addr, mask;
4365
ocontext_t *newc, *c, *l, *head;
4368
free(queue_remove(id_queue));
4369
free(queue_remove(id_queue));
4370
parse_security_context(NULL);
4374
id = queue_remove(id_queue);
4376
yyerror("failed to read ipv6 address");
4381
rc = inet_pton(AF_INET6, id, &addr);
4384
yyerror("failed to parse ipv6 address");
4390
id = queue_remove(id_queue);
4392
yyerror("failed to read ipv6 address");
4397
rc = inet_pton(AF_INET6, id, &mask);
4400
yyerror("failed to parse ipv6 mask");
4406
newc = malloc(sizeof(ocontext_t));
4408
yyerror("out of memory");
4413
memset(newc, 0, sizeof(ocontext_t));
4414
memcpy(&newc->u.node6.addr[0], &addr.s6_addr32[0], 16);
4415
memcpy(&newc->u.node6.mask[0], &mask.s6_addr32[0], 16);
4417
if (parse_security_context(&newc->context[0])) {
4423
/* Place this at the end of the list, to retain
4424
the matching order specified in the configuration. */
4425
head = policydbp->ocontexts[OCON_NODE6];
4426
for (l = NULL, c = head; c; l = c, c = c->next);
4431
policydbp->ocontexts[OCON_NODE6] = newc;
4438
static int define_fs_use(int behavior)
4440
ocontext_t *newc, *c, *head;
4443
free(queue_remove(id_queue));
4444
parse_security_context(NULL);
4448
newc = (ocontext_t *) malloc(sizeof(ocontext_t));
4450
yyerror("out of memory");
4453
memset(newc, 0, sizeof(ocontext_t));
4455
newc->u.name = (char *) queue_remove(id_queue);
4456
if (!newc->u.name) {
4460
newc->v.behavior = behavior;
4461
if (parse_security_context(&newc->context[0])) {
4467
head = policydbp->ocontexts[OCON_FSUSE];
4469
for (c = head; c; c = c->next) {
4470
if (!strcmp(newc->u.name, c->u.name)) {
4471
sprintf(errormsg, "duplicate fs_use entry for filesystem type %s", newc->u.name);
4473
context_destroy(&newc->context[0]);
4481
policydbp->ocontexts[OCON_FSUSE] = newc;
4485
static int define_genfs_context_helper(char *fstype, int has_type)
4487
struct genfs *genfs_p, *genfs, *newgenfs;
4488
ocontext_t *newc, *c, *head, *p;
4494
free(queue_remove(id_queue));
4496
free(queue_remove(id_queue));
4497
parse_security_context(NULL);
4501
for (genfs_p = NULL, genfs = policydbp->genfs;
4502
genfs; genfs_p = genfs, genfs = genfs->next) {
4503
if (strcmp(fstype, genfs->fstype) <= 0)
4507
if (!genfs || strcmp(fstype, genfs->fstype)) {
4508
newgenfs = malloc(sizeof(struct genfs));
4510
yyerror("out of memory");
4513
memset(newgenfs, 0, sizeof(struct genfs));
4514
newgenfs->fstype = fstype;
4515
newgenfs->next = genfs;
4517
genfs_p->next = newgenfs;
4519
policydbp->genfs = newgenfs;
4523
newc = (ocontext_t *) malloc(sizeof(ocontext_t));
4525
yyerror("out of memory");
4528
memset(newc, 0, sizeof(ocontext_t));
4530
newc->u.name = (char *) queue_remove(id_queue);
4534
type = (char *) queue_remove(id_queue);
4538
sprintf(errormsg, "invalid type %s", type);
4544
newc->v.sclass = SECCLASS_BLK_FILE;
4547
newc->v.sclass = SECCLASS_CHR_FILE;
4550
newc->v.sclass = SECCLASS_DIR;
4553
newc->v.sclass = SECCLASS_FIFO_FILE;
4556
newc->v.sclass = SECCLASS_LNK_FILE;
4559
newc->v.sclass = SECCLASS_SOCK_FILE;
4562
newc->v.sclass = SECCLASS_FILE;
4565
sprintf(errormsg, "invalid type %s", type);
4570
if (parse_security_context(&newc->context[0]))
4575
for (p = NULL, c = head; c; p = c, c = c->next) {
4576
if (!strcmp(newc->u.name, c->u.name) &&
4577
(!newc->v.sclass || !c->v.sclass || newc->v.sclass == c->v.sclass)) {
4578
sprintf(errormsg, "duplicate entry for genfs entry (%s, %s)", fstype, newc->u.name);
4582
len = strlen(newc->u.name);
4583
len2 = strlen(c->u.name);
4597
context_destroy(&newc->context[0]);
4606
static int define_genfs_context(int has_type)
4608
return define_genfs_context_helper(queue_remove(id_queue), has_type);