11 | 11 |
*
|
12 | 12 |
* Added conditional policy language extensions
|
13 | 13 |
*
|
|
14 |
* Updated: Joshua Brindle <jbrindle@tresys.com>
|
|
15 |
* Karl MacMillan <kmacmillan@tresys.com>
|
|
16 |
* Jason Tang <jtang@tresys.com>
|
|
17 |
*
|
|
18 |
* Added support for binary policy modules
|
|
19 |
*
|
14 | 20 |
* Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
|
15 | |
* Copyright (C) 2003 - 2004 Tresys Technology, LLC
|
|
21 |
* Copyright (C) 2003 - 2005 Tresys Technology, LLC
|
16 | 22 |
* This program is free software; you can redistribute it and/or modify
|
17 | 23 |
* it under the terms of the GNU General Public License as published by
|
18 | 24 |
* the Free Software Foundation, version 2.
|
|
22 | 28 |
|
23 | 29 |
%{
|
24 | 30 |
#include <sys/types.h>
|
|
31 |
#include <assert.h>
|
|
32 |
#include <stdarg.h>
|
25 | 33 |
#include <stdint.h>
|
|
34 |
#include <stdio.h>
|
|
35 |
#include <stdlib.h>
|
|
36 |
#include <string.h>
|
26 | 37 |
#include <sys/socket.h>
|
27 | 38 |
#include <netinet/in.h>
|
28 | 39 |
#include <arpa/inet.h>
|
29 | 40 |
#include <stdlib.h>
|
30 | 41 |
|
|
42 |
#include <sepol/expand.h>
|
31 | 43 |
#include <sepol/policydb.h>
|
32 | 44 |
#include <sepol/services.h>
|
33 | 45 |
#include <sepol/conditional.h>
|
|
35 | 47 |
#include <sepol/hierarchy.h>
|
36 | 48 |
#include "queue.h"
|
37 | 49 |
#include "checkpolicy.h"
|
|
50 |
#include "module_compiler.h"
|
38 | 51 |
|
39 | 52 |
/*
|
40 | 53 |
* We need the following so we have a valid error return code in yacc
|
41 | 54 |
* when we have a parse error for a conditional rule. We can't check
|
42 | 55 |
* for NULL (ie 0) because that is a potentially valid return.
|
43 | 56 |
*/
|
44 | |
static cond_av_list_t *conditional_unused_error_code;
|
45 | |
#define COND_ERR (cond_av_list_t *)&conditional_unused_error_code
|
|
57 |
static avrule_t *conditional_unused_error_code;
|
|
58 |
#define COND_ERR (avrule_t *)&conditional_unused_error_code
|
46 | 59 |
|
47 | 60 |
#define TRUE 1
|
48 | 61 |
#define FALSE 0
|
49 | 62 |
|
50 | 63 |
policydb_t *policydbp;
|
51 | 64 |
queue_t id_queue = 0;
|
52 | |
unsigned int pass;
|
|
65 |
static unsigned int pass;
|
53 | 66 |
char *curfile = 0;
|
54 | |
unsigned int curline;
|
55 | 67 |
|
56 | 68 |
extern unsigned long policydb_lineno;
|
|
69 |
extern unsigned long source_lineno;
|
|
70 |
extern unsigned int policydb_errors;
|
|
71 |
extern unsigned int policyvers;
|
57 | 72 |
|
58 | 73 |
extern char yytext[];
|
59 | 74 |
extern int yylex(void);
|
60 | 75 |
extern int yywarn(char *msg);
|
61 | 76 |
extern int yyerror(char *msg);
|
62 | 77 |
|
63 | |
static char errormsg[255];
|
|
78 |
#define ERRORMSG_LEN 255
|
|
79 |
static char errormsg[ERRORMSG_LEN + 1] = {0};
|
64 | 80 |
|
65 | 81 |
static int insert_separator(int push);
|
66 | 82 |
static int insert_id(char *id,int push);
|
|
87 | 103 |
static int define_role_allow(void);
|
88 | 104 |
static int define_constraint(constraint_expr_t *expr);
|
89 | 105 |
static int define_validatetrans(constraint_expr_t *expr);
|
90 | |
static int define_bool();
|
91 | |
static int define_conditional(cond_expr_t *expr,cond_av_list_t *t_list, cond_av_list_t *f_list );
|
|
106 |
static int define_bool(void);
|
|
107 |
static int define_conditional(cond_expr_t *expr, avrule_t *t_list, avrule_t *f_list );
|
92 | 108 |
static cond_expr_t *define_cond_expr(uint32_t expr_type, void *arg1, void* arg2);
|
93 | |
static cond_av_list_t *define_cond_pol_list(cond_av_list_t *avlist, cond_av_list_t *stmt);
|
94 | |
static cond_av_list_t *define_cond_compute_type(int which);
|
95 | |
static cond_av_list_t *define_cond_te_avtab(int which);
|
96 | |
static cond_av_list_t *cond_list_append(cond_av_list_t *sl, avtab_key_t *key, avtab_datum_t *datum);
|
97 | |
static void cond_reduce_insert_list(cond_av_list_t *new, cond_av_list_t **active, cond_av_list_t **inactive, int state );
|
|
109 |
static avrule_t *define_cond_pol_list(avrule_t *avlist, avrule_t *stmt);
|
|
110 |
static avrule_t *define_cond_compute_type(int which);
|
|
111 |
static avrule_t *define_cond_te_avtab(int which);
|
98 | 112 |
static uintptr_t define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2);
|
99 | 113 |
static int define_user(void);
|
100 | 114 |
static int parse_security_context(context_struct_t *c);
|
|
106 | 120 |
static int define_netif_context(void);
|
107 | 121 |
static int define_ipv4_node_context(unsigned int addr, unsigned int mask);
|
108 | 122 |
static int define_ipv6_node_context(void);
|
|
123 |
|
|
124 |
typedef int (* require_func_t)();
|
|
125 |
|
109 | 126 |
%}
|
110 | 127 |
|
111 | 128 |
%union {
|
112 | 129 |
unsigned int val;
|
113 | 130 |
uintptr_t valptr;
|
114 | 131 |
void *ptr;
|
|
132 |
require_func_t require_func;
|
115 | 133 |
}
|
116 | 134 |
|
117 | 135 |
%type <ptr> cond_expr cond_expr_prim cond_pol_list
|
|
120 | 138 |
%type <ptr> role_def roles
|
121 | 139 |
%type <valptr> cexpr cexpr_prim op role_mls_op
|
122 | 140 |
%type <val> ipv4_addr_def number
|
|
141 |
%type <require_func> require_decl_def
|
123 | 142 |
|
124 | 143 |
%token PATH
|
125 | 144 |
%token CLONE
|
|
174 | 193 |
%token EQUALS
|
175 | 194 |
%token NOTEQUAL
|
176 | 195 |
%token IPV6_ADDR
|
|
196 |
%token MODULE VERSION_IDENTIFIER REQUIRE OPTIONAL
|
177 | 197 |
|
178 | 198 |
%left OR
|
179 | 199 |
%left XOR
|
|
181 | 201 |
%right NOT
|
182 | 202 |
%left EQUALS NOTEQUAL
|
183 | 203 |
%%
|
184 | |
policy : classes initial_sids access_vectors
|
185 | |
{ if (pass == 1) { if (policydb_index_classes(policydbp)) return -1; } }
|
|
204 |
policy : base_policy
|
|
205 |
| module_policy
|
|
206 |
;
|
|
207 |
base_policy : { if (define_policy(pass, 0) == -1) return -1; }
|
|
208 |
classes initial_sids access_vectors
|
|
209 |
{ if (pass == 1) { if (policydb_index_classes(policydbp)) return -1; }
|
|
210 |
else if (pass == 2) { if (policydb_index_others(policydbp, 0)) return -1; }}
|
186 | 211 |
opt_mls te_rbac users opt_constraints
|
187 | 212 |
{ if (pass == 1) { if (policydb_index_bools(policydbp)) return -1;}
|
188 | |
if (pass == 2) { if (policydb_index_others(policydbp, 1)) return -1;} }
|
|
213 |
else if (pass == 2) { if (policydb_index_others(policydbp, 0)) return -1;}}
|
189 | 214 |
initial_sid_contexts opt_fs_contexts fs_uses opt_genfs_contexts net_contexts
|
190 | 215 |
;
|
191 | 216 |
classes : class_def
|
|
277 | 302 |
;
|
278 | 303 |
te_rbac_decl : te_decl
|
279 | 304 |
| rbac_decl
|
|
305 |
| cond_stmt_def
|
280 | 306 |
| ';'
|
281 | 307 |
;
|
282 | 308 |
rbac_decl : role_type_def
|
|
292 | 318 |
| transition_def
|
293 | 319 |
| range_trans_def
|
294 | 320 |
| te_avtab_def
|
295 | |
| cond_stmt_def
|
296 | 321 |
;
|
297 | 322 |
attribute_def : ATTRIBUTE identifier ';'
|
298 | 323 |
{ if (define_attrib()) return -1;}
|
|
320 | 345 |
{ if (insert_id("F",0)) return -1; }
|
321 | 346 |
;
|
322 | 347 |
cond_stmt_def : IF cond_expr '{' cond_pol_list '}'
|
323 | |
{ if (pass == 2) { if (define_conditional((cond_expr_t*)$2, (cond_av_list_t*)$4,(cond_av_list_t*) 0) < 0) return -1; }}
|
|
348 |
{ if (pass == 2) { if (define_conditional((cond_expr_t*)$2, (avrule_t*)$4, (avrule_t*) 0) < 0) return -1; }}
|
324 | 349 |
| IF cond_expr '{' cond_pol_list '}' ELSE '{' cond_pol_list '}'
|
325 | |
{ if (pass == 2) { if (define_conditional((cond_expr_t*)$2,(cond_av_list_t*)$4,(cond_av_list_t*)$8) < 0 ) return -1; }}
|
|
350 |
{ if (pass == 2) { if (define_conditional((cond_expr_t*)$2,(avrule_t*)$4,(avrule_t*)$8) < 0 ) return -1; }}
|
326 | 351 |
| IF cond_expr '{' cond_pol_list '}' ELSE '{' '}'
|
327 | |
{ if (pass == 2) { if (define_conditional((cond_expr_t*)$2,(cond_av_list_t*)$4,(cond_av_list_t*) 0) < 0 ) return -1; }}
|
|
352 |
{ if (pass == 2) { if (define_conditional((cond_expr_t*)$2,(avrule_t*)$4,(avrule_t*) 0) < 0 ) return -1; }}
|
328 | 353 |
| IF cond_expr '{' '}' ELSE '{' cond_pol_list '}'
|
329 | |
{ if (pass == 2) { if (define_conditional((cond_expr_t*)$2,(cond_av_list_t*) 0,(cond_av_list_t*) $7) < 0 ) return -1; }}
|
|
354 |
{ if (pass == 2) { if (define_conditional((cond_expr_t*)$2,(avrule_t*) 0,(avrule_t*) $7) < 0 ) return -1; }}
|
330 | 355 |
| IF cond_expr '{' '}' ELSE '{' '}'
|
331 | 356 |
/* do nothing */
|
332 | 357 |
| IF cond_expr '{' '}'
|
|
360 | 385 |
if ($$ == COND_ERR) return -1; }
|
361 | 386 |
;
|
362 | 387 |
cond_pol_list : cond_rule_def
|
363 | |
{ $$ = define_cond_pol_list((cond_av_list_t *) 0, (cond_av_list_t *)$1);}
|
|
388 |
{ $$ = define_cond_pol_list((avrule_t *) 0, (avrule_t *)$1);}
|
364 | 389 |
| cond_pol_list cond_rule_def
|
365 | |
{ $$ = define_cond_pol_list((cond_av_list_t *)$1, (cond_av_list_t *)$2); }
|
|
390 |
{ $$ = define_cond_pol_list((avrule_t *)$1, (avrule_t *)$2); }
|
366 | 391 |
;
|
367 | 392 |
cond_rule_def : cond_transition_def
|
368 | 393 |
{ $$ = $1; }
|
|
370 | 395 |
{ $$ = $1; }
|
371 | 396 |
;
|
372 | 397 |
cond_transition_def : TYPE_TRANSITION names names ':' names identifier ';'
|
373 | |
{ $$ = define_cond_compute_type(AVTAB_TRANSITION) ;
|
|
398 |
{ $$ = define_cond_compute_type(AVRULE_TRANSITION) ;
|
374 | 399 |
if ($$ == COND_ERR) return -1;}
|
375 | 400 |
| TYPE_MEMBER names names ':' names identifier ';'
|
376 | |
{ $$ = define_cond_compute_type(AVTAB_MEMBER) ;
|
|
401 |
{ $$ = define_cond_compute_type(AVRULE_MEMBER) ;
|
377 | 402 |
if ($$ == COND_ERR) return -1;}
|
378 | 403 |
| TYPE_CHANGE names names ':' names identifier ';'
|
379 | |
{ $$ = define_cond_compute_type(AVTAB_CHANGE) ;
|
|
404 |
{ $$ = define_cond_compute_type(AVRULE_CHANGE) ;
|
380 | 405 |
if ($$ == COND_ERR) return -1;}
|
381 | 406 |
;
|
382 | 407 |
cond_te_avtab_def : cond_allow_def
|
|
389 | 414 |
{ $$ = $1; }
|
390 | 415 |
;
|
391 | 416 |
cond_allow_def : ALLOW names names ':' names names ';'
|
392 | |
{ $$ = define_cond_te_avtab(AVTAB_ALLOWED) ;
|
|
417 |
{ $$ = define_cond_te_avtab(AVRULE_ALLOWED) ;
|
393 | 418 |
if ($$ == COND_ERR) return -1; }
|
394 | 419 |
;
|
395 | 420 |
cond_auditallow_def : AUDITALLOW names names ':' names names ';'
|
396 | |
{ $$ = define_cond_te_avtab(AVTAB_AUDITALLOW) ;
|
|
421 |
{ $$ = define_cond_te_avtab(AVRULE_AUDITALLOW) ;
|
397 | 422 |
if ($$ == COND_ERR) return -1; }
|
398 | 423 |
;
|
399 | 424 |
cond_auditdeny_def : AUDITDENY names names ':' names names ';'
|
400 | |
{ $$ = define_cond_te_avtab(AVTAB_AUDITDENY) ;
|
|
425 |
{ $$ = define_cond_te_avtab(AVRULE_AUDITDENY) ;
|
401 | 426 |
if ($$ == COND_ERR) return -1; }
|
402 | 427 |
;
|
403 | 428 |
cond_dontaudit_def : DONTAUDIT names names ':' names names ';'
|
404 | |
{ $$ = define_cond_te_avtab(-AVTAB_AUDITDENY);
|
|
429 |
{ $$ = define_cond_te_avtab(AVRULE_DONTAUDIT);
|
405 | 430 |
if ($$ == COND_ERR) return -1; }
|
406 | 431 |
;
|
407 | 432 |
transition_def : TYPE_TRANSITION names names ':' names identifier ';'
|
408 | |
{if (define_compute_type(AVTAB_TRANSITION)) return -1;}
|
|
433 |
{if (define_compute_type(AVRULE_TRANSITION)) return -1;}
|
409 | 434 |
| TYPE_MEMBER names names ':' names identifier ';'
|
410 | |
{if (define_compute_type(AVTAB_MEMBER)) return -1;}
|
|
435 |
{if (define_compute_type(AVRULE_MEMBER)) return -1;}
|
411 | 436 |
| TYPE_CHANGE names names ':' names identifier ';'
|
412 | |
{if (define_compute_type(AVTAB_CHANGE)) return -1;}
|
|
437 |
{if (define_compute_type(AVRULE_CHANGE)) return -1;}
|
413 | 438 |
;
|
414 | 439 |
range_trans_def : RANGE_TRANSITION names names mls_range_def ';'
|
415 | 440 |
{ if (define_range_trans()) return -1; }
|
|
421 | 446 |
| neverallow_def
|
422 | 447 |
;
|
423 | 448 |
allow_def : ALLOW names names ':' names names ';'
|
424 | |
{if (define_te_avtab(AVTAB_ALLOWED)) return -1; }
|
|
449 |
{if (define_te_avtab(AVRULE_ALLOWED)) return -1; }
|
425 | 450 |
;
|
426 | 451 |
auditallow_def : AUDITALLOW names names ':' names names ';'
|
427 | |
{if (define_te_avtab(AVTAB_AUDITALLOW)) return -1; }
|
|
452 |
{if (define_te_avtab(AVRULE_AUDITALLOW)) return -1; }
|
428 | 453 |
;
|
429 | 454 |
auditdeny_def : AUDITDENY names names ':' names names ';'
|
430 | |
{if (define_te_avtab(AVTAB_AUDITDENY)) return -1; }
|
|
455 |
{if (define_te_avtab(AVRULE_AUDITDENY)) return -1; }
|
431 | 456 |
;
|
432 | 457 |
dontaudit_def : DONTAUDIT names names ':' names names ';'
|
433 | |
{if (define_te_avtab(-AVTAB_AUDITDENY)) return -1; }
|
|
458 |
{if (define_te_avtab(AVRULE_DONTAUDIT)) return -1; }
|
434 | 459 |
;
|
435 | 460 |
neverallow_def : NEVERALLOW names names ':' names names ';'
|
436 | |
{if (define_te_avtab(-AVTAB_ALLOWED)) return -1; }
|
|
461 |
{if (define_te_avtab(AVRULE_NEVERALLOW)) return -1; }
|
437 | 462 |
;
|
438 | 463 |
role_type_def : ROLE identifier TYPES names ';'
|
439 | 464 |
{if (define_role_types()) return -1;}
|
|
465 |
| ROLE identifier';'
|
|
466 |
{if (define_role_types()) return -1;}
|
440 | 467 |
;
|
441 | 468 |
role_dominance : DOMINANCE '{' roles '}'
|
442 | 469 |
;
|
|
643 | 670 |
{if (define_fs_use(SECURITY_FS_USE_TRANS)) return -1;}
|
644 | 671 |
;
|
645 | 672 |
opt_genfs_contexts : genfs_contexts
|
646 | |
|
|
|
673 |
|
|
647 | 674 |
;
|
648 | |
genfs_contexts : genfs_context_def
|
649 | |
| genfs_contexts genfs_context_def
|
650 | |
;
|
|
675 |
genfs_contexts : genfs_context_def
|
|
676 |
| genfs_contexts genfs_context_def
|
|
677 |
;
|
651 | 678 |
genfs_context_def : GENFSCON identifier path '-' identifier security_context_def
|
652 | 679 |
{if (define_genfs_context(1)) return -1;}
|
653 | 680 |
| GENFSCON identifier path '-' '-' {insert_id("-", 0);} security_context_def
|
|
761 | 788 |
ipv6_addr : IPV6_ADDR
|
762 | 789 |
{ if (insert_id(yytext,0)) return -1; }
|
763 | 790 |
;
|
|
791 |
|
|
792 |
/*********** module grammar below ***********/
|
|
793 |
|
|
794 |
module_policy : module_def avrules_block
|
|
795 |
{ if (end_avrule_block(pass) == -1) return -1;
|
|
796 |
if (policydb_index_others(policydbp, 0)) return -1;
|
|
797 |
}
|
|
798 |
;
|
|
799 |
module_def : MODULE identifier version_identifier ';'
|
|
800 |
{ if (define_policy(pass, 1) == -1) return -1; }
|
|
801 |
;
|
|
802 |
version_identifier : VERSION_IDENTIFIER
|
|
803 |
{ if (insert_id(yytext,0)) return -1; }
|
|
804 |
;
|
|
805 |
avrules_block : avrule_decls avrule_user_defs
|
|
806 |
;
|
|
807 |
avrule_decls : avrule_decl avrule_decls
|
|
808 |
| avrule_decl
|
|
809 |
;
|
|
810 |
avrule_decl : rbac_decl
|
|
811 |
| te_decl
|
|
812 |
| cond_stmt_def
|
|
813 |
| require_block
|
|
814 |
| optional_block
|
|
815 |
| ';'
|
|
816 |
;
|
|
817 |
require_block : REQUIRE '{' require_list '}'
|
|
818 |
;
|
|
819 |
require_list : require_decl require_list
|
|
820 |
| require_decl
|
|
821 |
;
|
|
822 |
require_decl : require_class ';'
|
|
823 |
| require_decl_def require_id_list ';'
|
|
824 |
;
|
|
825 |
require_class : CLASS identifier names
|
|
826 |
{ if (require_class(pass)) return -1; }
|
|
827 |
;
|
|
828 |
require_decl_def : ROLE { $$ = require_role; }
|
|
829 |
| TYPE { $$ = require_type; }
|
|
830 |
| ATTRIBUTE { $$ = require_attribute; }
|
|
831 |
| USER { $$ = require_user; }
|
|
832 |
| BOOL { $$ = require_bool; }
|
|
833 |
/* MLS-enabled modules are not implemented at this time.
|
|
834 |
| SENSITIVITY { $$ = require_sens; }
|
|
835 |
| CATEGORY { $$ = require_cat; }
|
|
836 |
*/
|
|
837 |
;
|
|
838 |
require_id_list : identifier
|
|
839 |
{ if ($<require_func>0 (pass)) return -1; }
|
|
840 |
| require_id_list ',' identifier
|
|
841 |
{ if ($<require_func>0 (pass)) return -1; }
|
|
842 |
;
|
|
843 |
optional_block : optional_decl '{' avrules_block '}'
|
|
844 |
{ if (end_avrule_block(pass) == -1) return -1; }
|
|
845 |
optional_else
|
|
846 |
{ if (end_optional(pass) == -1) return -1; }
|
|
847 |
;
|
|
848 |
optional_else : else_decl '{' avrules_block '}'
|
|
849 |
{ if (end_avrule_block(pass) == -1) return -1; }
|
|
850 |
| /* empty */
|
|
851 |
;
|
|
852 |
optional_decl : OPTIONAL
|
|
853 |
{ if (begin_optional(pass) == -1) return -1; }
|
|
854 |
;
|
|
855 |
else_decl : ELSE
|
|
856 |
{ if (begin_optional_else(pass) == -1) return -1; }
|
|
857 |
;
|
|
858 |
avrule_user_defs : user_def avrule_user_defs
|
|
859 |
| /* empty */
|
|
860 |
;
|
764 | 861 |
%%
|
|
862 |
|
|
863 |
/* initialize all of the state variables for the scanner/parser */
|
|
864 |
void init_parser(int pass_number)
|
|
865 |
{
|
|
866 |
policydb_lineno = 1;
|
|
867 |
source_lineno = 1;
|
|
868 |
policydb_errors = 0;
|
|
869 |
pass = pass_number;
|
|
870 |
}
|
|
871 |
|
|
872 |
void yyerror2(char *fmt, ...)
|
|
873 |
{
|
|
874 |
va_list ap;
|
|
875 |
va_start(ap, fmt);
|
|
876 |
vsnprintf(errormsg, ERRORMSG_LEN, fmt, ap);
|
|
877 |
yyerror(errormsg);
|
|
878 |
va_end(ap);
|
|
879 |
}
|
|
880 |
|
|
881 |
|
765 | 882 |
#define DEBUG 1
|
766 | 883 |
|
767 | 884 |
static int insert_separator(int push)
|
|
804 | 921 |
return 0;
|
805 | 922 |
}
|
806 | 923 |
|
807 | |
/* If the identifier has a dot within it return 1, else return 0. */
|
|
924 |
/* Add a rule onto an avtab hash table only if it does not already
|
|
925 |
* exist. (Note that the avtab is discarded afterwards; it will be
|
|
926 |
* regenerated during expansion.) Return 1 if rule was added (or
|
|
927 |
* otherwise handled successfully), 0 if it conflicted with something,
|
|
928 |
* or -1 on error. */
|
|
929 |
static int insert_check_type_rule(avrule_t *rule, avtab_t *avtab, cond_av_list_t **list, cond_av_list_t **other)
|
|
930 |
{
|
|
931 |
char *error_msg = NULL;
|
|
932 |
int ret;
|
|
933 |
|
|
934 |
ret = expand_rule(policydbp, rule, avtab, list, other, 0, &error_msg);
|
|
935 |
switch (ret) {
|
|
936 |
case 0: {
|
|
937 |
if (error_msg == NULL) {
|
|
938 |
yywarn("Conflicting rule");
|
|
939 |
}
|
|
940 |
else {
|
|
941 |
yywarn(error_msg);
|
|
942 |
}
|
|
943 |
free(error_msg);
|
|
944 |
break;
|
|
945 |
}
|
|
946 |
case -1: {
|
|
947 |
if (error_msg == NULL) {
|
|
948 |
yyerror("Error inserting rule");
|
|
949 |
}
|
|
950 |
else {
|
|
951 |
yyerror(error_msg);
|
|
952 |
}
|
|
953 |
free(error_msg);
|
|
954 |
break;
|
|
955 |
}
|
|
956 |
}
|
|
957 |
return ret;
|
|
958 |
}
|
|
959 |
|
|
960 |
/* If the identifier has a dot within it and that its first character
|
|
961 |
is not a dot then return 1, else return 0. */
|
808 | 962 |
static int id_has_dot(char *id)
|
809 | 963 |
{
|
810 | 964 |
if (strchr(id, '.') >= id + 1) {
|
|
818 | 972 |
char *id = 0;
|
819 | 973 |
class_datum_t *datum = 0;
|
820 | 974 |
int ret;
|
821 | |
|
|
975 |
uint32_t value;
|
822 | 976 |
|
823 | 977 |
if (pass == 2) {
|
824 | 978 |
id = queue_remove(id_queue);
|
|
842 | 996 |
goto bad;
|
843 | 997 |
}
|
844 | 998 |
memset(datum, 0, sizeof(class_datum_t));
|
845 | |
datum->value = ++policydbp->p_classes.nprim;
|
846 | |
|
847 | |
ret = hashtab_insert(policydbp->p_classes.table,
|
848 | |
(hashtab_key_t) id, (hashtab_datum_t) datum);
|
849 | |
|
850 | |
if (ret == HASHTAB_PRESENT) {
|
851 | |
--policydbp->p_classes.nprim;
|
852 | |
yyerror("duplicate class definition");
|
853 | |
goto bad;
|
854 | |
}
|
855 | |
if (ret == HASHTAB_OVERFLOW) {
|
856 | |
yyerror("hash table overflow");
|
857 | |
goto bad;
|
858 | |
}
|
|
999 |
ret = declare_symbol(SYM_CLASSES, id, datum, &value, &value);
|
|
1000 |
switch(ret) {
|
|
1001 |
case -3: {
|
|
1002 |
yyerror("Out of memory!");
|
|
1003 |
goto bad;
|
|
1004 |
}
|
|
1005 |
case -2: {
|
|
1006 |
yyerror2("duplicate declaration of class %s", id);
|
|
1007 |
goto bad;
|
|
1008 |
}
|
|
1009 |
case -1: {
|
|
1010 |
yyerror("could not declare class here");
|
|
1011 |
goto bad;
|
|
1012 |
}
|
|
1013 |
case 0:
|
|
1014 |
case 1: {
|
|
1015 |
break;
|
|
1016 |
}
|
|
1017 |
default: {
|
|
1018 |
assert(0); /* should never get here */
|
|
1019 |
}
|
|
1020 |
}
|
|
1021 |
datum->value = value;
|
859 | 1022 |
return 0;
|
860 | 1023 |
|
861 | 1024 |
bad:
|
|
938 | 1101 |
yyerror("no common name for common perm definition?");
|
939 | 1102 |
return -1;
|
940 | 1103 |
}
|
|
1104 |
comdatum = hashtab_search(policydbp->p_commons.table, id);
|
|
1105 |
if (comdatum) {
|
|
1106 |
snprintf(errormsg, ERRORMSG_LEN,
|
|
1107 |
"duplicate declaration for common %s\n", id);
|
|
1108 |
yyerror(errormsg);
|
|
1109 |
return -1;
|
|
1110 |
}
|
941 | 1111 |
comdatum = (common_datum_t *) malloc(sizeof(common_datum_t));
|
942 | 1112 |
if (!comdatum) {
|
943 | 1113 |
yyerror("out of memory");
|
944 | 1114 |
goto bad;
|
945 | 1115 |
}
|
946 | 1116 |
memset(comdatum, 0, sizeof(common_datum_t));
|
947 | |
comdatum->value = ++policydbp->p_commons.nprim;
|
948 | 1117 |
ret = hashtab_insert(policydbp->p_commons.table,
|
949 | 1118 |
(hashtab_key_t) id, (hashtab_datum_t) comdatum);
|
950 | 1119 |
|
|
956 | 1125 |
yyerror("hash table overflow");
|
957 | 1126 |
goto bad;
|
958 | 1127 |
}
|
|
1128 |
comdatum->value = ++policydbp->p_commons.nprim;
|
959 | 1129 |
if (symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE)) {
|
960 | 1130 |
yyerror("out of memory");
|
961 | 1131 |
goto bad;
|
|
1107 | 1277 |
yyerror("hash table overflow");
|
1108 | 1278 |
goto bad;
|
1109 | 1279 |
}
|
|
1280 |
if (add_perm_to_class(perdatum->value, cladatum->value)) {
|
|
1281 |
yyerror("out of memory");
|
|
1282 |
goto bad;
|
|
1283 |
}
|
1110 | 1284 |
}
|
1111 | 1285 |
|
1112 | 1286 |
return 0;
|
|
1126 | 1300 |
mls_level_t *level = 0;
|
1127 | 1301 |
level_datum_t *datum = 0, *aliasdatum = 0;
|
1128 | 1302 |
int ret;
|
|
1303 |
uint32_t value; /* dummy variable -- its value is never used */
|
1129 | 1304 |
|
1130 | 1305 |
if (!mlspol) {
|
1131 | 1306 |
yyerror("sensitivity definition in non-MLS configuration");
|
|
1154 | 1329 |
}
|
1155 | 1330 |
memset(level, 0, sizeof(mls_level_t));
|
1156 | 1331 |
level->sens = 0; /* actual value set in define_dominance */
|
1157 | |
++policydbp->p_levels.nprim;
|
1158 | 1332 |
ebitmap_init(&level->cat); /* actual value set in define_level */
|
1159 | 1333 |
|
1160 | 1334 |
datum = (level_datum_t *) malloc(sizeof(level_datum_t));
|
|
1166 | 1340 |
datum->isalias = FALSE;
|
1167 | 1341 |
datum->level = level;
|
1168 | 1342 |
|
1169 | |
ret = hashtab_insert(policydbp->p_levels.table,
|
1170 | |
(hashtab_key_t) id, (hashtab_datum_t) datum);
|
1171 | |
|
1172 | |
if (ret == HASHTAB_PRESENT) {
|
1173 | |
--policydbp->p_levels.nprim;
|
1174 | |
sprintf(errormsg, "duplicate definition for sensitivity %s", id);
|
1175 | |
yyerror(errormsg);
|
1176 | |
goto bad;
|
1177 | |
}
|
1178 | |
if (ret == HASHTAB_OVERFLOW) {
|
1179 | |
yyerror("hash table overflow");
|
1180 | |
goto bad;
|
1181 | |
}
|
1182 | |
|
|
1343 |
ret = declare_symbol(SYM_LEVELS, id, datum, &value, &value);
|
|
1344 |
switch(ret) {
|
|
1345 |
case -3: {
|
|
1346 |
yyerror("Out of memory!");
|
|
1347 |
goto bad;
|
|
1348 |
}
|
|
1349 |
case -2: {
|
|
1350 |
yyerror("duplicate declaration of sensitivity level");
|
|
1351 |
goto bad;
|
|
1352 |
}
|
|
1353 |
case -1: {
|
|
1354 |
yyerror("could not declare sensitivity level here");
|
|
1355 |
goto bad;
|
|
1356 |
}
|
|
1357 |
case 0:
|
|
1358 |
case 1: {
|
|
1359 |
break;
|
|
1360 |
}
|
|
1361 |
default: {
|
|
1362 |
assert(0); /* should never get here */
|
|
1363 |
}
|
|
1364 |
}
|
|
1365 |
|
1183 | 1366 |
while ((id = queue_remove(id_queue))) {
|
1184 | 1367 |
if (id_has_dot(id)) {
|
1185 | 1368 |
yyerror("sensitivity aliases may not contain periods");
|
|
1194 | 1377 |
aliasdatum->isalias = TRUE;
|
1195 | 1378 |
aliasdatum->level = level;
|
1196 | 1379 |
|
1197 | |
ret = hashtab_insert(policydbp->p_levels.table,
|
1198 | |
(hashtab_key_t) id, (hashtab_datum_t) aliasdatum);
|
1199 | |
|
1200 | |
if (ret == HASHTAB_PRESENT) {
|
1201 | |
sprintf(errormsg, "duplicate definition for level %s", id);
|
1202 | |
yyerror(errormsg);
|
1203 | |
goto bad_alias;
|
1204 | |
}
|
1205 | |
if (ret == HASHTAB_OVERFLOW) {
|
1206 | |
yyerror("hash table overflow");
|
1207 | |
goto bad_alias;
|
1208 | |
}
|
|
1380 |
ret = declare_symbol(SYM_LEVELS, id, aliasdatum, NULL, &value);
|
|
1381 |
switch(ret) {
|
|
1382 |
case -3: {
|
|
1383 |
yyerror("Out of memory!");
|
|
1384 |
goto bad_alias;
|
|
1385 |
}
|
|
1386 |
case -2: {
|
|
1387 |
yyerror("duplicate declaration of sensitivity alias");
|
|
1388 |
goto bad_alias;
|
|
1389 |
}
|
|
1390 |
case -1: {
|
|
1391 |
yyerror("could not declare sensitivity alias here");
|
|
1392 |
goto bad_alias;
|
|
1393 |
}
|
|
1394 |
case 0:
|
|
1395 |
case 1: {
|
|
1396 |
break;
|
|
1397 |
}
|
|
1398 |
default: {
|
|
1399 |
assert(0); /* should never get here */
|
|
1400 |
}
|
|
1401 |
}
|
1209 | 1402 |
}
|
1210 | 1403 |
|
1211 | 1404 |
return 0;
|
|
1278 | 1471 |
char *id;
|
1279 | 1472 |
cat_datum_t *datum = 0, *aliasdatum = 0;
|
1280 | 1473 |
int ret;
|
|
1474 |
uint32_t value;
|
1281 | 1475 |
|
1282 | 1476 |
if (!mlspol) {
|
1283 | 1477 |
yyerror("category definition in non-MLS configuration");
|
|
1306 | 1500 |
}
|
1307 | 1501 |
memset(datum, 0, sizeof(cat_datum_t));
|
1308 | 1502 |
datum->isalias = FALSE;
|
1309 | |
datum->value = ++policydbp->p_cats.nprim;
|
1310 | |
|
1311 | |
ret = hashtab_insert(policydbp->p_cats.table,
|
1312 | |
(hashtab_key_t) id, (hashtab_datum_t) datum);
|
1313 | |
|
1314 | |
if (ret == HASHTAB_PRESENT) {
|
1315 | |
--policydbp->p_cats.nprim;
|
1316 | |
sprintf(errormsg, "duplicate definition for category %s", id);
|
1317 | |
yyerror(errormsg);
|
1318 | |
goto bad;
|
1319 | |
}
|
1320 | |
if (ret == HASHTAB_OVERFLOW) {
|
1321 | |
yyerror("hash table overflow");
|
1322 | |
goto bad;
|
1323 | |
}
|
|
1503 |
|
|
1504 |
ret = declare_symbol(SYM_CATS, id, datum, &value, &value);
|
|
1505 |
switch(ret) {
|
|
1506 |
case -3: {
|
|
1507 |
yyerror("Out of memory!");
|
|
1508 |
goto bad;
|
|
1509 |
}
|
|
1510 |
case -2: {
|
|
1511 |
yyerror("duplicate declaration of category");
|
|
1512 |
goto bad;
|
|
1513 |
}
|
|
1514 |
case -1: {
|
|
1515 |
yyerror("could not declare category here");
|
|
1516 |
goto bad;
|
|
1517 |
}
|
|
1518 |
case 0:
|
|
1519 |
case 1: {
|
|
1520 |
break;
|
|
1521 |
}
|
|
1522 |
default: {
|
|
1523 |
assert(0); /* should never get here */
|
|
1524 |
}
|
|
1525 |
}
|
|
1526 |
datum->value = value;
|
1324 | 1527 |
|
1325 | 1528 |
while ((id = queue_remove(id_queue))) {
|
1326 | 1529 |
if (id_has_dot(id)) {
|
|
1336 | 1539 |
aliasdatum->isalias = TRUE;
|
1337 | 1540 |
aliasdatum->value = datum->value;
|
1338 | 1541 |
|
1339 | |
ret = hashtab_insert(policydbp->p_cats.table,
|
1340 | |
(hashtab_key_t) id, (hashtab_datum_t) aliasdatum);
|
1341 | |
|
1342 | |
if (ret == HASHTAB_PRESENT) {
|
1343 | |
sprintf(errormsg, "duplicate definition for category %s", id);
|
1344 | |
yyerror(errormsg);
|
1345 | |
goto bad_alias;
|
1346 | |
}
|
1347 | |
if (ret == HASHTAB_OVERFLOW) {
|
1348 | |
yyerror("hash table overflow");
|
1349 | |
goto bad_alias;
|
1350 | |
}
|
|
1542 |
ret = declare_symbol(SYM_CATS, id, aliasdatum, NULL, &datum->value);
|
|
1543 |
switch(ret) {
|
|
1544 |
case -3: {
|
|
1545 |
yyerror("Out of memory!");
|
|
1546 |
goto bad_alias;
|
|
1547 |
}
|
|
1548 |
case -2: {
|
|
1549 |
yyerror("duplicate declaration of category aliases");
|
|
1550 |
goto bad_alias;
|
|
1551 |
}
|
|
1552 |
case -1: {
|
|
1553 |
yyerror("could not declare category aliases here");
|
|
1554 |
goto bad_alias;
|
|
1555 |
}
|
|
1556 |
case 0:
|
|
1557 |
case 1: {
|
|
1558 |
break;
|
|
1559 |
}
|
|
1560 |
default: {
|
|
1561 |
assert(0); /* should never get here */
|
|
1562 |
}
|
|
1563 |
}
|
1351 | 1564 |
}
|
1352 | 1565 |
|
1353 | 1566 |
return 0;
|
|
1462 | 1675 |
|
1463 | 1676 |
static int define_attrib(void)
|
1464 | 1677 |
{
|
1465 | |
char *id;
|
1466 | |
type_datum_t *attr;
|
1467 | |
int ret;
|
1468 | |
|
1469 | |
|
1470 | 1678 |
if (pass == 2) {
|
1471 | 1679 |
free(queue_remove(id_queue));
|
1472 | 1680 |
return 0;
|
1473 | 1681 |
}
|
1474 | 1682 |
|
1475 | |
id = (char *) queue_remove(id_queue);
|
1476 | |
if (!id) {
|
1477 | |
return -1;
|
1478 | |
}
|
1479 | |
|
1480 | |
attr = hashtab_search(policydbp->p_types.table, id);
|
1481 | |
if (attr) {
|
1482 | |
sprintf(errormsg, "duplicate declaration for attribute %s\n",
|
1483 | |
id);
|
1484 | |
yyerror(errormsg);
|
1485 | |
return -1;
|
1486 | |
}
|
1487 | |
|
1488 | |
attr = (type_datum_t *) malloc(sizeof(type_datum_t));
|
1489 | |
if (!attr) {
|
1490 | |
yyerror("out of memory");
|
1491 | |
return -1;
|
1492 | |
}
|
1493 | |
memset(attr, 0, sizeof(type_datum_t));
|
1494 | |
attr->isattr = TRUE;
|
1495 | |
ret = hashtab_insert(policydbp->p_types.table,
|
1496 | |
id, (hashtab_datum_t) attr);
|
1497 | |
if (ret) {
|
1498 | |
yyerror("hash table overflow");
|
1499 | |
return -1;
|
1500 | |
}
|
1501 | |
|
|
1683 |
if (declare_type(TRUE, TRUE) == NULL) {
|
|
1684 |
return -1;
|
|
1685 |
}
|
|
1686 |
return 0;
|
|
1687 |
}
|
|
1688 |
|
|
1689 |
static int add_aliases_to_type(type_datum_t *type)
|
|
1690 |
{
|
|
1691 |
char *id;
|
|
1692 |
type_datum_t *aliasdatum = NULL;
|
|
1693 |
int ret;
|
|
1694 |
while ((id = queue_remove(id_queue))) {
|
|
1695 |
if (id_has_dot(id)) {
|
|
1696 |
free(id);
|
|
1697 |
yyerror("type alias identifiers may not contain periods");
|
|
1698 |
return -1;
|
|
1699 |
}
|
|
1700 |
aliasdatum = (type_datum_t *) malloc(sizeof(type_datum_t));
|
|
1701 |
if (!aliasdatum) {
|
|
1702 |
free(id);
|
|
1703 |
yyerror("Out of memory!");
|
|
1704 |
return -1;
|
|
1705 |
}
|
|
1706 |
memset(aliasdatum, 0, sizeof(type_datum_t));
|
|
1707 |
aliasdatum->value = type->value;
|
|
1708 |
|
|
1709 |
ret = declare_symbol(SYM_TYPES, id, aliasdatum,
|
|
1710 |
NULL, &aliasdatum->value);
|
|
1711 |
switch(ret) {
|
|
1712 |
case -3: {
|
|
1713 |
yyerror("Out of memory!");
|
|
1714 |
goto cleanup;
|
|
1715 |
}
|
|
1716 |
case -2: {
|
|
1717 |
yyerror2("duplicate declaration of alias %s", id);
|
|
1718 |
goto cleanup;
|
|
1719 |
}
|
|
1720 |
case -1: {
|
|
1721 |
yyerror("could not declare alias here");
|
|
1722 |
goto cleanup;
|
|
1723 |
}
|
|
1724 |
case 0:
|
|
1725 |
case 1: {
|
|
1726 |
break;
|
|
1727 |
}
|
|
1728 |
default: {
|
|
1729 |
assert(0); /* should never get here */
|
|
1730 |
}
|
|
1731 |
}
|
|
1732 |
}
|
1502 | 1733 |
return 0;
|
|
1734 |
cleanup:
|
|
1735 |
free(id);
|
|
1736 |
type_datum_destroy(aliasdatum);
|
|
1737 |
free(aliasdatum);
|
|
1738 |
return -1;
|
1503 | 1739 |
}
|
1504 | 1740 |
|
1505 | 1741 |
static int define_typealias(void)
|
1506 | 1742 |
{
|
1507 | 1743 |
char *id;
|
1508 | |
type_datum_t *t, *aliasdatum;
|
1509 | |
int ret;
|
|
1744 |
type_datum_t *t;
|
1510 | 1745 |
|
1511 | 1746 |
if (pass == 2) {
|
1512 | 1747 |
while ((id = queue_remove(id_queue)))
|
|
1520 | 1755 |
return -1;
|
1521 | 1756 |
}
|
1522 | 1757 |
|
|
1758 |
if (!is_id_in_scope(SYM_TYPES, id)) {
|
|
1759 |
yyerror2("type %s is not within scope", id);
|
|
1760 |
free(id);
|
|
1761 |
return -1;
|
|
1762 |
}
|
|
1763 |
t = hashtab_search(policydbp->p_types.table, id);
|
|
1764 |
if (!t || t->isattr) {
|
|
1765 |
sprintf(errormsg, "unknown type %s, or it was already declared as an attribute", id);
|
|
1766 |
yyerror(errormsg);
|
|
1767 |
free(id);
|
|
1768 |
return -1;
|
|
1769 |
}
|
|
1770 |
return add_aliases_to_type(t);
|
|
1771 |
}
|
|
1772 |
|
|
1773 |
static int define_typeattribute(void)
|
|
1774 |
{
|
|
1775 |
char *id;
|
|
1776 |
type_datum_t *t, *attr;
|
|
1777 |
|
|
1778 |
if (pass == 2) {
|
|
1779 |
while ((id = queue_remove(id_queue)))
|
|
1780 |
free(id);
|
|
1781 |
return 0;
|
|
1782 |
}
|
|
1783 |
|
|
1784 |
id = (char *)queue_remove(id_queue);
|
|
1785 |
if (!id) {
|
|
1786 |
yyerror("no type name for typeattribute definition?");
|
|
1787 |
return -1;
|
|
1788 |
}
|
|
1789 |
|
|
1790 |
if (!is_id_in_scope(SYM_TYPES, id)) {
|
|
1791 |
yyerror2("type %s is not within scope", id);
|
|
1792 |
free(id);
|
|
1793 |
return -1;
|
|
1794 |
}
|
1523 | 1795 |
t = hashtab_search(policydbp->p_types.table, id);
|
1524 | 1796 |
if (!t || t->isattr) {
|
1525 | 1797 |
sprintf(errormsg, "unknown type %s", id);
|
|
1527 | 1799 |
free(id);
|
1528 | 1800 |
return -1;
|
1529 | 1801 |
}
|
|
1802 |
if ((t = get_local_type(id, t->value)) == NULL) {
|
|
1803 |
yyerror("Out of memory!");
|
|
1804 |
return -1;
|
|
1805 |
}
|
1530 | 1806 |
|
1531 | 1807 |
while ((id = queue_remove(id_queue))) {
|
1532 | |
if (id_has_dot(id)) {
|
|
1808 |
if (!is_id_in_scope(SYM_TYPES, id)) {
|
|
1809 |
yyerror2("attribute %s is not within scope", id);
|
1533 | 1810 |
free(id);
|
1534 | |
yyerror("type alias identifiers may not contain periods");
|
1535 | 1811 |
return -1;
|
1536 | 1812 |
}
|
1537 | |
aliasdatum = (type_datum_t *) malloc(sizeof(type_datum_t));
|
1538 | |
if (!aliasdatum) {
|
1539 | |
free(id);
|
1540 | |
yyerror("out of memory");
|
1541 | |
return -1;
|
1542 | |
}
|
1543 | |
memset(aliasdatum, 0, sizeof(type_datum_t));
|
1544 | |
aliasdatum->value = t->value;
|
1545 | |
|
1546 | |
ret = hashtab_insert(policydbp->p_types.table,
|
1547 | |
(hashtab_key_t) id, (hashtab_datum_t) aliasdatum);
|
1548 | |
|
1549 | |
if (ret == HASHTAB_PRESENT) {
|
1550 | |
sprintf(errormsg, "name conflict for type alias %s", id);
|
1551 | |
yyerror(errormsg);
|
1552 | |
free(aliasdatum);
|
1553 | |
free(id);
|
1554 | |
return -1;
|
1555 | |
}
|
1556 | |
if (ret == HASHTAB_OVERFLOW) {
|
1557 | |
yyerror("hash table overflow");
|
1558 | |
free(aliasdatum);
|
1559 | |
free(id);
|
1560 | |
return -1;
|
1561 | |
}
|
1562 | |
}
|
1563 | |
return 0;
|
1564 | |
}
|
1565 | |
|
1566 | |
static int define_typeattribute(void)
|
1567 | |
{
|
1568 | |
char *id;
|
1569 | |
type_datum_t *t, *attr;
|
1570 | |
|
1571 | |
if (pass == 2) {
|
1572 | |
while ((id = queue_remove(id_queue)))
|
1573 | |
free(id);
|
1574 | |
return 0;
|
1575 | |
}
|
1576 | |
|
1577 | |
id = (char *)queue_remove(id_queue);
|
1578 | |
if (!id) {
|
1579 | |
yyerror("no type name for typeattribute definition?");
|
1580 | |
return -1;
|
1581 | |
}
|
1582 | |
|
1583 | |
t = hashtab_search(policydbp->p_types.table, id);
|
1584 | |
if (!t || t->isattr) {
|
1585 | |
sprintf(errormsg, "unknown type %s", id);
|
1586 | |
yyerror(errormsg);
|
1587 | |
free(id);
|
1588 | |
return -1;
|
1589 | |
}
|
1590 | |
|
1591 | |
while ((id = queue_remove(id_queue))) {
|
1592 | 1813 |
attr = hashtab_search(policydbp->p_types.table, id);
|
1593 | |
if (!attr) {
|
|
1814 |
if (!attr) {
|
1594 | 1815 |
sprintf(errormsg, "attribute %s is not declared", id);
|
1595 | 1816 |
/* treat it as a fatal error */
|
1596 | 1817 |
yyerror(errormsg);
|
|
1619 | 1840 |
static int define_type(int alias)
|
1620 | 1841 |
{
|
1621 | 1842 |
char *id;
|
1622 | |
type_datum_t *datum, *aliasdatum, *attr;
|
1623 | |
int ret, newattr = 0;
|
1624 | |
|
|
1843 |
type_datum_t *datum, *attr;
|
|
1844 |
int newattr = 0;
|
1625 | 1845 |
|
1626 | 1846 |
if (pass == 2) {
|
1627 | 1847 |
while ((id = queue_remove(id_queue)))
|
|
1633 | 1853 |
return 0;
|
1634 | 1854 |
}
|
1635 | 1855 |
|
1636 | |
id = (char *) queue_remove(id_queue);
|
1637 | |
if (!id) {
|
1638 | |
yyerror("no type name for type definition?");
|
1639 | |
return -1;
|
1640 | |
}
|
1641 | |
|
1642 | |
datum = (type_datum_t *) malloc(sizeof(type_datum_t));
|
1643 | |
if (!datum) {
|
1644 | |
yyerror("out of memory");
|
1645 | |
free(id);
|
1646 | |
return -1;
|
1647 | |
}
|
1648 | |
memset(datum, 0, sizeof(type_datum_t));
|
1649 | |
datum->primary = TRUE;
|
1650 | |
datum->value = ++policydbp->p_types.nprim;
|
1651 | |
|
1652 | |
ret = hashtab_insert(policydbp->p_types.table,
|
1653 | |
(hashtab_key_t) id, (hashtab_datum_t) datum);
|
1654 | |
|
1655 | |
if (ret == HASHTAB_PRESENT) {
|
1656 | |
--policydbp->p_types.nprim;
|
1657 | |
free(datum);
|
1658 | |
sprintf(errormsg, "name conflict for type %s", id);
|
1659 | |
yyerror(errormsg);
|
1660 | |
free(id);
|
1661 | |
return -1;
|
1662 | |
}
|
1663 | |
if (ret == HASHTAB_OVERFLOW) {
|
1664 | |
yyerror("hash table overflow");
|
1665 | |
free(datum);
|
1666 | |
free(id);
|
1667 | |
return -1;
|
1668 | |
}
|
1669 | |
|
1670 | |
if (alias) {
|
1671 | |
while ((id = queue_remove(id_queue))) {
|
1672 | |
aliasdatum = (type_datum_t *) malloc(sizeof(type_datum_t));
|
1673 | |
if (!aliasdatum) {
|
1674 | |
yyerror("out of memory");
|
1675 | |
return -1;
|
1676 | |
}
|
1677 | |
memset(aliasdatum, 0, sizeof(type_datum_t));
|
1678 | |
aliasdatum->value = datum->value;
|
1679 | |
|
1680 | |
ret = hashtab_insert(policydbp->p_types.table,
|
1681 | |
(hashtab_key_t) id, (hashtab_datum_t) aliasdatum);
|
1682 | |
|
1683 | |
if (ret == HASHTAB_PRESENT) {
|
1684 | |
sprintf(errormsg, "name conflict for type alias %s", id);
|
1685 | |
yyerror(errormsg);
|
1686 | |
free(aliasdatum);
|
1687 | |
free(id);
|
1688 | |
return -1;
|
1689 | |
}
|
1690 | |
if (ret == HASHTAB_OVERFLOW) {
|
1691 | |
yyerror("hash table overflow");
|
1692 | |
free(aliasdatum);
|
1693 | |
free(id);
|
1694 | |
return -1;
|
1695 | |
}
|
1696 | |
}
|
|
1856 |
if ((datum = declare_type(TRUE, FALSE)) == NULL) {
|
|
1857 |
return -1;
|
|
1858 |
}
|
|
1859 |
|
|
1860 |
if (alias) {
|
|
1861 |
if (add_aliases_to_type(datum) == -1) {
|
|
1862 |
return -1;
|
|
1863 |
}
|
1697 | 1864 |
}
|
1698 | 1865 |
|
1699 | 1866 |
while ((id = queue_remove(id_queue))) {
|
|
1867 |
if (!is_id_in_scope(SYM_TYPES, id)) {
|
|
1868 |
yyerror2("attribute %s is not within scope", id);
|
|
1869 |
free(id);
|
|
1870 |
return -1;
|
|
1871 |
}
|
1700 | 1872 |
attr = hashtab_search(policydbp->p_types.table, id);
|
1701 | 1873 |
if (!attr) {
|
1702 | 1874 |
sprintf(errormsg, "attribute %s is not declared", id);
|
1703 | |
#if 1
|
|
1875 |
|
1704 | 1876 |
/* treat it as a fatal error */
|
1705 | 1877 |
yyerror(errormsg);
|
1706 | 1878 |
return -1;
|
1707 | |
#else
|
1708 | |
/* Warn but automatically define the attribute.
|
1709 | |
Useful for quickly finding all those attributes you
|
1710 | |
forgot to declare. */
|
1711 | |
yywarn(errormsg);
|
1712 | |
attr = (type_datum_t *) malloc(sizeof(type_datum_t));
|
1713 | |
if (!attr) {
|
1714 | |
yyerror("out of memory");
|
1715 | |
return -1;
|
1716 | |
}
|
1717 | |
memset(attr, 0, sizeof(type_datum_t));
|
1718 | |
attr->isattr = TRUE;
|
1719 | |
ret = hashtab_insert(policydbp->p_types.table,
|
1720 | |
id, (hashtab_datum_t) attr);
|
1721 | |
if (ret) {
|
1722 | |
yyerror("hash table overflow");
|
1723 | |
return -1;
|
1724 | |
}
|
1725 | |
newattr = 1;
|
1726 | |
#endif
|
1727 | 1879 |
} else {
|
1728 | 1880 |
newattr = 0;
|
1729 | 1881 |
}
|
|
1734 | 1886 |
return -1;
|
1735 | 1887 |
}
|
1736 | 1888 |
|
1737 | |
if (!newattr)
|
1738 | |
free(id);
|
|
1889 |
if ((attr = get_local_type(id, attr->value)) == NULL) {
|
|
1890 |
yyerror("Out of memory!");
|
|
1891 |
return -1;
|
|
1892 |
}
|
1739 | 1893 |
|
1740 | 1894 |
ebitmap_set_bit(&attr->types, datum->value - 1, TRUE);
|
1741 | 1895 |
}
|
|
1743 | 1897 |
return 0;
|
1744 | 1898 |
}
|
1745 | 1899 |
|
1746 | |
struct val_to_name {
|
1747 | |
unsigned int val;
|
1748 | |
char *name;
|
1749 | |
};
|
1750 | |
|
1751 | |
static int type_val_to_name_helper(hashtab_key_t key, hashtab_datum_t datum, void *p)
|
1752 | |
{
|
1753 | |
type_datum_t *typdatum;
|
1754 | |
struct val_to_name *v = p;
|
1755 | |
|
1756 | |
typdatum = (type_datum_t *) datum;
|
1757 | |
|
1758 | |
if (v->val == typdatum->value) {
|
1759 | |
v->name = key;
|
1760 | |
return 1;
|
1761 | |
}
|
1762 | |
|
1763 | |
return 0;
|
1764 | |
}
|
1765 | |
|
1766 | |
static char *type_val_to_name(unsigned int val)
|
1767 | |
{
|
1768 | |
struct val_to_name v;
|
1769 | |
int rc;
|
1770 | |
|
1771 | |
v.val = val;
|
1772 | |
rc = hashtab_map(policydbp->p_types.table,
|
1773 | |
type_val_to_name_helper, &v);
|
1774 | |
if (rc)
|
1775 | |
return v.name;
|
1776 | |
return NULL;
|
1777 | |
}
|
1778 | |
|
1779 | |
|
1780 | |
static int set_types(ebitmap_t *set,
|
1781 | |
ebitmap_t *negset,
|
|
1900 |
/* Adds a type, given by its textual name, to a typeset. If *add is
|
|
1901 |
0, then add the type to the negative set; otherwise if *add is 1
|
|
1902 |
then add it to the positive side. */
|
|
1903 |
static int set_types(type_set_t *set,
|
1782 | 1904 |
char *id,
|
1783 | |
int *add)
|
|
1905 |
int *add,
|
|
1906 |
char starallowed)
|
1784 | 1907 |
{
|
1785 | 1908 |
type_datum_t *t;
|
1786 | |
unsigned int i;
|
1787 | 1909 |
|
1788 | 1910 |
if (strcmp(id, "*") == 0) {
|
1789 | |
/* set all types not in negset */
|
1790 | |
for (i = 0; i < policydbp->p_types.nprim; i++) {
|
1791 | |
if (!ebitmap_get_bit(negset, i))
|
1792 | |
ebitmap_set_bit(set, i, TRUE);
|
1793 | |
}
|
|
1911 |
if (!starallowed) {
|
|
1912 |
yyerror("* not allowed in this type of rule");
|
|
1913 |
return -1;
|
|
1914 |
}
|
|
1915 |
/* set TYPE_STAR flag */
|
|
1916 |
set->flags = TYPE_STAR;
|
1794 | 1917 |
free(id);
|
|
1918 |
*add = 1;
|
1795 | 1919 |
return 0;
|
1796 | 1920 |
}
|
1797 | 1921 |
|
1798 | 1922 |
if (strcmp(id, "~") == 0) {
|
|
1923 |
if (!starallowed) {
|
|
1924 |
yyerror("~ not allowed in this type of rule");
|
|
1925 |
return -1;
|
|
1926 |
}
|
1799 | 1927 |
/* complement the set */
|
1800 | |
for (i = 0; i < policydbp->p_types.nprim; i++) {
|
1801 | |
if (ebitmap_get_bit(set, i))
|
1802 | |
ebitmap_set_bit(set, i, FALSE);
|
1803 | |
else
|
1804 | |
ebitmap_set_bit(set, i, TRUE);
|
1805 | |
}
|
|
1928 |
set->flags = TYPE_COMP;
|
1806 | 1929 |
free(id);
|
|
1930 |
*add = 1;
|
1807 | 1931 |
return 0;
|
1808 | 1932 |
}
|
1809 | 1933 |
|
|
1813 | 1937 |
return 0;
|
1814 | 1938 |
}
|
1815 | 1939 |
|
|
1940 |
if (!is_id_in_scope(SYM_TYPES, id)) {
|
|
1941 |
yyerror2("type %s is not within scope", id);
|
|
1942 |
free(id);
|
|
1943 |
return -1;
|
|
1944 |
}
|
1816 | 1945 |
t = hashtab_search(policydbp->p_types.table, id);
|
1817 | 1946 |
if (!t) {
|
1818 | |
sprintf(errormsg, "unknown type %s", id);
|
|
1947 |
snprintf(errormsg, ERRORMSG_LEN, "unknown type %s", id);
|
1819 | 1948 |
yyerror(errormsg);
|
1820 | 1949 |
free(id);
|
1821 | 1950 |
return -1;
|
1822 | 1951 |
}
|
1823 | 1952 |
|
1824 | |
if (t->isattr) {
|
1825 | |
/* set or clear all types with this attribute,
|
1826 | |
but do not set anything explicitly cleared previously */
|
1827 | |
for (i = ebitmap_startbit(&t->types); i < ebitmap_length(&t->types); i++) {
|
1828 | |
if (!ebitmap_get_bit(&t->types, i))
|
1829 | |
continue;
|
1830 | |
if (!(*add)) {
|
1831 | |
ebitmap_set_bit(set, i, FALSE);
|
1832 | |
ebitmap_set_bit(negset, i, TRUE);
|
1833 | |
} else if (!ebitmap_get_bit(negset, i)) {
|
1834 | |
ebitmap_set_bit(set, i, TRUE);
|
1835 | |
#if VERBOSE
|
1836 | |
} else {
|
1837 | |
char *name = type_val_to_name(i+1);
|
1838 | |
sprintf(errormsg, "ignoring %s due to prior -%s", name, name);
|
1839 | |
yywarn(errormsg);
|
1840 | |
#endif
|
1841 | |
}
|
1842 | |
}
|
1843 | |
} else {
|
1844 | |
/* set or clear one type, but do not set anything
|
1845 | |
explicitly cleared previously */
|
1846 | |
if (!(*add)) {
|
1847 | |
ebitmap_set_bit(set, t->value - 1, FALSE);
|
1848 | |
ebitmap_set_bit(negset, t->value - 1, TRUE);
|
1849 | |
} else if (!ebitmap_get_bit(negset, t->value - 1)) {
|
1850 | |
ebitmap_set_bit(set, t->value - 1, TRUE);
|
1851 | |
#if VERBOSE
|
1852 | |
} else {
|
1853 | |
sprintf(errormsg, "ignoring %s due to prior -%s", id, id);
|
1854 | |
yywarn(errormsg);
|
1855 | |
#endif
|
1856 | |
}
|
1857 | |
}
|
1858 | |
|
|
1953 |
if (*add == 0) {
|
|
1954 |
ebitmap_set_bit(&set->negset, t->value - 1, TRUE);
|
|
1955 |
}
|
|
1956 |
else {
|
|
1957 |
ebitmap_set_bit(&set->types, t->value - 1, TRUE);
|
|
1958 |
}
|
1859 | 1959 |
free(id);
|
1860 | 1960 |
*add = 1;
|
1861 | 1961 |
return 0;
|
1862 | 1962 |
}
|
1863 | 1963 |
|
1864 | |
|
1865 | |
static int define_compute_type(int which)
|
|
1964 |
static int define_compute_type_helper(int which, avrule_t **rule)
|
1866 | 1965 |
{
|
1867 | 1966 |
char *id;
|
1868 | |
avtab_key_t avkey;
|
1869 | |
avtab_datum_t avdatum, *avdatump;
|
1870 | 1967 |
type_datum_t *datum;
|
1871 | 1968 |
class_datum_t *cladatum;
|
1872 | |
ebitmap_t stypes, ttypes, tclasses, negset;
|
1873 | |
uint32_t newtype = 0;
|
1874 | |
int ret, add = 1;
|
1875 | |
unsigned int i, j, k;
|
|
1969 |
ebitmap_t tclasses;
|
|
1970 |
ebitmap_node_t *node;
|
|
1971 |
avrule_t *avrule;
|
|
1972 |
class_perm_node_t *perm;
|
|
1973 |
int i, add = 1;
|
|
1974 |
|
|
1975 |
avrule = malloc(sizeof(avrule_t));
|
|
1976 |
if (!avrule) {
|
|
1977 |
yyerror("out of memory");
|
|
1978 |
return -1;
|
|
1979 |
}
|
|
1980 |
avrule_init(avrule);
|
|
1981 |
avrule->specified = which;
|
|
1982 |
avrule->line = policydb_lineno;
|
|
1983 |
|
|
1984 |
while ((id = queue_remove(id_queue))) {
|
|
1985 |
if (set_types(&avrule->stypes, id, &add, 0))
|
|
1986 |
return -1;
|
|
1987 |
}
|
|
1988 |
add = 1;
|
|
1989 |
while ((id = queue_remove(id_queue))) {
|
|
1990 |
if (set_types(&avrule->ttypes, id, &add, 0))
|
|
1991 |
return -1;
|
|
1992 |
}
|
|
1993 |
|
|
1994 |
ebitmap_init(&tclasses);
|
|
1995 |
while ((id = queue_remove(id_queue))) {
|
|
1996 |
uint32_t classvalue;
|
|
1997 |
if (!is_id_in_scope(SYM_CLASSES, id)) {
|
|
1998 |
yyerror2("class %s is not within scope", id);
|
|
1999 |
free(id);
|
|
2000 |
goto bad;
|
|
2001 |
}
|
|
2002 |
cladatum = hashtab_search(policydbp->p_classes.table, id);
|
|
2003 |
if (!cladatum) {
|
|
2004 |
sprintf(errormsg, "unknown class %s", id);
|
|
2005 |
yyerror(errormsg);
|
|
2006 |
goto bad;
|
|
2007 |
}
|
|
2008 |
if (policyvers < POLICYDB_VERSION_NLCLASS &&
|
|
2009 |
(cladatum->value >= SECCLASS_NETLINK_ROUTE_SOCKET &&
|
|
2010 |
cladatum->value <= SECCLASS_NETLINK_DNRT_SOCKET)) {
|
|
2011 |
sprintf(errormsg, "remapping class %s to netlink_socket "
|
|
2012 |
"for policy version %d", id, policyvers);
|
|
2013 |
yywarn(errormsg);
|
|
2014 |
classvalue = SECCLASS_NETLINK_SOCKET;
|
|
2015 |
}
|
|
2016 |
else {
|
|
2017 |
classvalue = cladatum->value;
|
|
2018 |
}
|
|
2019 |
ebitmap_set_bit(&tclasses, classvalue - 1, TRUE);
|
|
2020 |
free(id);
|
|
2021 |
}
|
|
2022 |
|
|
2023 |
id = (char *) queue_remove(id_queue);
|
|
2024 |
if (!id) {
|
|
2025 |
yyerror("no newtype?");
|
|
2026 |
goto bad;
|
|
2027 |
}
|
|
2028 |
if (!is_id_in_scope(SYM_TYPES, id)) {
|
|
2029 |
yyerror2("type %s is not within scope", id);
|
|
2030 |
free(id);
|
|
2031 |
goto bad;
|
|
2032 |
}
|
|
2033 |
datum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
|
|
2034 |
(hashtab_key_t) id);
|
|
2035 |
if (!datum || datum->isattr) {
|
|
2036 |
sprintf(errormsg, "unknown type %s", id);
|
|
2037 |
yyerror(errormsg);
|
|
2038 |
goto bad;
|
|
2039 |
}
|
|
2040 |
|
|
2041 |
ebitmap_for_each_bit(&tclasses, node, i) {
|
|
2042 |
if (ebitmap_node_get_bit(node, i)) {
|
|
2043 |
perm = malloc(sizeof(class_perm_node_t));
|
|
2044 |
if (!perm) {
|
|
2045 |
yyerror("out of memory");
|
|
2046 |
return -1;
|
|
2047 |
}
|
|
2048 |
class_perm_node_init(perm);
|
|
2049 |
perm->class = i + 1;
|
|
2050 |
perm->data = datum->value;
|
|
2051 |
perm->next = avrule->perms;
|
|
2052 |
avrule->perms = perm;
|
|
2053 |
}
|
|
2054 |
}
|
|
2055 |
ebitmap_destroy(&tclasses);
|
|
2056 |
|
|
2057 |
*rule = avrule;
|
|
2058 |
return 0;
|
|
2059 |
|
|
2060 |
bad:
|
|
2061 |
avrule_destroy(avrule);
|
|
2062 |
free(avrule);
|
|
2063 |
return -1;
|
|
2064 |
}
|
|
2065 |
|
|
2066 |
static int define_compute_type(int which)
|
|
2067 |
{
|
|
2068 |
char *id;
|
|
2069 |
avrule_t *avrule;
|
|
2070 |
int retval;
|
1876 | 2071 |
|
1877 | 2072 |
if (pass == 1) {
|
1878 | 2073 |
while ((id = queue_remove(id_queue)))
|
|
1885 | 2080 |
free(id);
|
1886 | 2081 |
return 0;
|
1887 | 2082 |
}
|
1888 | |
|
1889 | |
ebitmap_init(&stypes);
|
1890 | |
ebitmap_init(&ttypes);
|
1891 | |
ebitmap_init(&tclasses);
|
1892 | |
|
1893 | |
ebitmap_init(&negset);
|
1894 | |
while ((id = queue_remove(id_queue))) {
|
1895 | |
if (set_types(&stypes, &negset, id, &add))
|
1896 | |
return -1;
|
1897 | |
}
|
1898 | |
ebitmap_destroy(&negset);
|
1899 | |
|
1900 | |
ebitmap_init(&negset);
|
1901 | |
while ((id = queue_remove(id_queue))) {
|
1902 | |
if (set_types(&ttypes, &negset, id, &add))
|
1903 | |
return -1;
|
1904 | |
}
|
1905 | |
ebitmap_destroy(&negset);
|
1906 | |
|
1907 | |
while ((id = queue_remove(id_queue))) {
|
1908 | |
cladatum = hashtab_search(policydbp->p_classes.table, id);
|
1909 | |
if (!cladatum) {
|
1910 | |
sprintf(errormsg, "unknown class %s", id);
|
1911 | |
yyerror(errormsg);
|
1912 | |
goto bad;
|
1913 | |
}
|
1914 | |
ebitmap_set_bit(&tclasses, cladatum->value - 1, TRUE);
|
1915 | |
free(id);
|
1916 | |
}
|
1917 | |
|
1918 | |
id = (char *) queue_remove(id_queue);
|
1919 | |
if (!id) {
|
1920 | |
yyerror("no newtype?");
|
1921 | |
goto bad;
|
1922 | |
}
|
1923 | |
datum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
|
1924 | |
(hashtab_key_t) id);
|
1925 | |
if (!datum || datum->isattr) {
|
1926 | |
sprintf(errormsg, "unknown type %s", id);
|
1927 | |
yyerror(errormsg);
|
1928 | |
goto bad;
|
1929 | |
}
|
1930 | |
|
1931 | |
for (i = ebitmap_startbit(&stypes); i < ebitmap_length(&stypes); i++) {
|
1932 | |
if (!ebitmap_get_bit(&stypes, i))
|
1933 | |
continue;
|
1934 | |
for (j = ebitmap_startbit(&ttypes); j < ebitmap_length(&ttypes); j++) {
|
1935 | |
if (!ebitmap_get_bit(&ttypes, j))
|
1936 | |
continue;
|
1937 | |
for (k = ebitmap_startbit(&tclasses); k < ebitmap_length(&tclasses); k++) {
|
1938 | |
if (!ebitmap_get_bit(&tclasses, k))
|
1939 | |
continue;
|
1940 | |
avkey.source_type = i + 1;
|
1941 | |
avkey.target_type = j + 1;
|
1942 | |
avkey.target_class = k + 1;
|
1943 | |
avdatump = avtab_search(&policydbp->te_avtab, &avkey, AVTAB_TYPE);
|
1944 | |
if (avdatump) {
|
1945 | |
switch (which) {
|
1946 | |
case AVTAB_TRANSITION:
|
1947 | |
newtype = avtab_transition(avdatump);
|
1948 | |
break;
|
1949 | |
case AVTAB_MEMBER:
|
1950 | |
newtype = avtab_member(avdatump);
|
1951 | |
break;
|
1952 | |
case AVTAB_CHANGE:
|
1953 | |
newtype = avtab_change(avdatump);
|
1954 | |
break;
|
1955 | |
}
|
1956 | |
if ( (avdatump->specified & which) &&
|
1957 | |
(newtype != datum->value) ) {
|
1958 | |
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],
|
1959 | |
type_val_to_name(newtype),
|
1960 | |
type_val_to_name(datum->value));
|
1961 | |
yywarn(errormsg);
|
1962 | |
}
|
1963 | |
avdatump->specified |= which;
|
1964 | |
switch (which) {
|
1965 | |
case AVTAB_TRANSITION:
|
1966 | |
avtab_transition(avdatump) = datum->value;
|
1967 | |
break;
|
1968 | |
case AVTAB_MEMBER:
|
1969 | |
avtab_member(avdatump) = datum->value;
|
1970 | |
break;
|
1971 | |
case AVTAB_CHANGE:
|
1972 | |
avtab_change(avdatump) = datum->value;
|
1973 | |
break;
|
1974 | |
}
|
1975 | |
} else {
|
1976 | |
memset(&avdatum, 0, sizeof avdatum);
|
1977 | |
avdatum.specified |= which;
|
1978 | |
switch (which) {
|
1979 | |
case AVTAB_TRANSITION:
|
1980 | |
avtab_transition(&avdatum) = datum->value;
|
1981 | |
break;
|
1982 | |
case AVTAB_MEMBER:
|
1983 | |
avtab_member(&avdatum) = datum->value;
|
1984 | |
break;
|
1985 | |
case AVTAB_CHANGE:
|
1986 | |
avtab_change(&avdatum) = datum->value;
|
1987 | |
break;
|
1988 | |
}
|
1989 | |
ret = avtab_insert(&policydbp->te_avtab, &avkey, &avdatum);
|
1990 | |
if (ret) {
|
1991 | |
yyerror("hash table overflow");
|
1992 | |
goto bad;
|
1993 | |
}
|
1994 | |
}
|
1995 | |
}
|
1996 | |
}
|
1997 | |
}
|
1998 | |
|
1999 | |
return 0;
|
2000 | |
|
2001 | |
bad:
|
2002 | |
return -1;
|
2003 | |
}
|
2004 | |
|
2005 | |
static cond_av_list_t *define_cond_compute_type(int which)
|
|
2083 |
|
|
2084 |
if (define_compute_type_helper(which, &avrule))
|
|
2085 |
return -1;
|
|
2086 |
|
|
2087 |
retval = insert_check_type_rule(avrule, &policydbp->te_avtab, NULL, NULL);
|
|
2088 |
switch (retval) {
|
|
2089 |
case 1: {
|
|
2090 |
/* append this avrule to the end of the current rules list */
|
|
2091 |
append_avrule(avrule);
|
|
2092 |
return 0;
|
|
2093 |
}
|
|
2094 |
case 0: {
|
|
2095 |
/* rule conflicted, so don't actually add this rule */
|
|
2096 |
avrule_destroy(avrule);
|
|
2097 |
free(avrule);
|
|
2098 |
return 0;
|
|
2099 |
}
|
|
2100 |
case -1: {
|
|
2101 |
avrule_destroy(avrule);
|
|
2102 |
free(avrule);
|
|
2103 |
return -1;
|
|
2104 |
}
|
|
2105 |
default: {
|
|
2106 |
assert(0); /* should never get here */
|
|
2107 |
}
|
|
2108 |
}
|
|
2109 |
}
|
|
2110 |
|
|
2111 |
static avrule_t *define_cond_compute_type(int which)
|
2006 | 2112 |
{
|
2007 | 2113 |
char *id;
|
2008 | |
cond_av_list_t *sub_list;
|
2009 | |
avtab_key_t avkey;
|
2010 | |
avtab_datum_t avdatum, *avdatump;
|
2011 | |
type_datum_t *datum;
|
2012 | |
class_datum_t *cladatum;
|
2013 | |
ebitmap_t stypes, ttypes, tclasses, negset;
|
2014 | |
uint32_t newtype = 0;
|
2015 | |
int i, j, k, add = 1;
|
2016 | |
|
2017 | |
if (pass == 1) {
|
2018 | |
while ((id = queue_remove(id_queue)))
|
2019 | |
free(id);
|
2020 | |
while ((id = queue_remove(id_queue)))
|
2021 | |
free(id);
|
2022 | |
while ((id = queue_remove(id_queue)))
|
2023 | |
free(id);
|
2024 | |
id = queue_remove(id_queue);
|
2025 | |
free(id);
|
2026 | |
return (cond_av_list_t *)1; /* any non-NULL value */
|
2027 | |
}
|
2028 | |
|
2029 | |
ebitmap_init(&stypes);
|
2030 | |
ebitmap_init(&ttypes);
|
2031 | |
ebitmap_init(&tclasses);
|
2032 | |
|
2033 | |
ebitmap_init(&negset);
|
2034 | |
while ((id = queue_remove(id_queue))) {
|
2035 | |
if (set_types(&stypes, &negset, id, &add))
|
2036 | |
return COND_ERR;
|
2037 | |
}
|
2038 | |
ebitmap_destroy(&negset);
|
2039 | |
|
2040 | |
ebitmap_init(&negset);
|
2041 | |
while ((id = queue_remove(id_queue))) {
|
2042 | |
if (set_types(&ttypes, &negset, id, &add))
|
2043 | |
return COND_ERR;
|
2044 | |
}
|
2045 | |
ebitmap_destroy(&negset);
|
2046 | |
|
2047 | |
while ((id = queue_remove(id_queue))) {
|
2048 | |
cladatum = hashtab_search(policydbp->p_classes.table, id);
|
2049 | |
if (!cladatum) {
|
2050 | |
sprintf(errormsg, "unknown class %s", id);
|
2051 | |
yyerror(errormsg);
|
2052 | |
goto bad;
|
2053 | |
}
|
2054 | |
ebitmap_set_bit(&tclasses, cladatum->value - 1, TRUE);
|
2055 | |
free(id);
|
2056 | |
}
|
2057 | |
|
2058 | |
id = (char *) queue_remove(id_queue);
|
2059 | |
if (!id) {
|
2060 | |
yyerror("no newtype?");
|
2061 | |
goto bad;
|
2062 | |
}
|
2063 | |
datum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
|
2064 | |
(hashtab_key_t) id);
|
2065 | |
if (!datum || datum->isattr) {
|
2066 | |
sprintf(errormsg, "unknown type %s", id);
|
2067 | |
yyerror(errormsg);
|
2068 | |
goto bad;
|
2069 | |
}
|
2070 | |
|
2071 | |
/* create sub_list to be passed back and appended to true or false list */
|
2072 | |
sub_list = (cond_av_list_t *) 0;
|
2073 | |
|
2074 | |
for (i = ebitmap_startbit(&stypes); i < ebitmap_length(&stypes); i++) {
|
2075 | |
if (!ebitmap_get_bit(&stypes, i))
|
2076 | |
continue;
|
2077 | |
for (j = ebitmap_startbit(&ttypes); j < ebitmap_length(&ttypes); j++) {
|
2078 | |
if (!ebitmap_get_bit(&ttypes, j))
|
2079 | |
continue;
|
2080 | |
for (k = ebitmap_startbit(&tclasses); k < ebitmap_length(&tclasses); k++) {
|
2081 | |
if (!ebitmap_get_bit(&tclasses, k))
|
2082 | |
continue;
|
2083 | |
avkey.source_type = i + 1;
|
2084 | |
avkey.target_type = j + 1;
|
2085 | |
avkey.target_class = k + 1;
|
2086 | |
avdatump = avtab_search(&policydbp->te_avtab, &avkey, AVTAB_TYPE);
|
2087 | |
|
2088 | |
/* does rule exist in base policy? */
|
2089 | |
if ((avdatump) && (avdatump->specified & which)) {
|
2090 | |
switch (which) {
|
2091 | |
case AVTAB_TRANSITION:
|
2092 | |
newtype = avtab_transition(avdatump);
|
2093 | |
break;
|
2094 | |
case AVTAB_MEMBER:
|
2095 | |
newtype = avtab_member(avdatump);
|
2096 | |
break;
|
2097 | |
case AVTAB_CHANGE:
|
2098 | |
newtype = avtab_change(avdatump);
|
2099 | |
break;
|
2100 | |
}
|
2101 | |
if ( (newtype != datum->value) ) {
|
2102 | |
sprintf(errormsg, "conflicting type rule for conditional "
|
2103 | |
"(%s, %s:%s) in base: default is %s, conditional %s "
|
2104 | |
"will be ignored",
|
2105 | |
type_val_to_name(i+1),
|
2106 | |
type_val_to_name(j+1),
|
2107 | |
policydbp->p_class_val_to_name[k],
|
2108 | |
type_val_to_name(newtype),
|
2109 | |
type_val_to_name(datum->value));
|
2110 | |
yywarn(errormsg);
|
2111 | |
} else {
|
2112 | |
sprintf(errormsg, "conditional type rule (%s, %s:%s): "
|
2113 | |
"has same default, %s, as rule in base policy; "
|
2114 | |
"conditional %s will be ignored",
|
2115 | |
type_val_to_name(i+1),
|
2116 | |
type_val_to_name(j+1),
|
2117 | |
policydbp->p_class_val_to_name[k],
|
2118 | |
type_val_to_name(newtype),
|
2119 | |
type_val_to_name(datum->value));
|
2120 | |
yywarn(errormsg);
|
2121 | |
}
|
2122 | |
}
|
2123 | |
/* rule does not exist in base policy */
|
2124 | |
else {
|
2125 | |
|
2126 | |
memset(&avdatum, 0, sizeof avdatum);
|
2127 | |
avdatum.specified |= which;
|
2128 | |
switch (which) {
|
2129 | |
case AVTAB_TRANSITION:
|
2130 | |
avtab_transition(&avdatum) = datum->value;
|
2131 | |
break;
|
2132 | |
case AVTAB_MEMBER:
|
2133 | |
avtab_member(&avdatum) = datum->value;
|
2134 | |
break;
|
2135 | |
case AVTAB_CHANGE:
|
2136 | |
avtab_change(&avdatum) = datum->value;
|
2137 | |
break;
|
2138 | |
}
|
2139 | |
/* add rule to sub list */
|
2140 | |
sub_list = cond_list_append(sub_list, &avkey, &avdatum);
|
2141 | |
if (sub_list == COND_ERR) {
|
2142 | |
yyerror("list overflow");
|
2143 | |
goto bad;
|
2144 | |
}
|
2145 | |
}
|
2146 | |
}
|
2147 | |
}
|
2148 | |
}
|
2149 | |
|
2150 | |
return sub_list;
|
2151 | |
|
2152 | |
bad:
|
2153 | |
return COND_ERR;
|
2154 | |
}
|
2155 | |
|
2156 | |
static cond_av_list_t *cond_list_append(cond_av_list_t *sl, avtab_key_t *key, avtab_datum_t *datum) {
|
2157 | |
|
2158 | |
cond_av_list_t *n, *end;
|
2159 | |
|
2160 | |
n = (cond_av_list_t *) malloc(sizeof(cond_av_list_t));
|
2161 | |
if (!n) {
|
2162 | |
yyerror("out of memory");
|
2163 | |
return COND_ERR;
|
2164 | |
}
|
2165 | |
memset(n, 0, sizeof(cond_av_list_t));
|
2166 | |
if (sl) {
|
2167 | |
for(end=sl; end->next != NULL; end = end->next);
|
2168 | |
end->next = n;
|
2169 | |
}
|
2170 | |
else sl = n;
|
2171 | |
n->next = NULL;
|
2172 | |
|
2173 | |
/* construct new node */
|
2174 | |
n->node = (avtab_ptr_t) malloc(sizeof(struct avtab_node));
|
2175 | |
if (!n->node) {
|
2176 | |
yyerror("out of memory");
|
2177 | |
return COND_ERR;
|
2178 | |
}
|
2179 | |
memset(n->node, 0, sizeof(struct avtab_node));
|
2180 | |
n->node->key = *key;
|
2181 | |
n->node->datum = *datum;
|
2182 | |
/* the next two fields get filled in when we add to true/false list */
|
2183 | |
n->node->next = (avtab_ptr_t) 0;
|
2184 | |
n->node->parse_context = (void *) 0;
|
2185 | |
|
2186 | |
return(sl);
|
2187 | |
}
|
2188 | |
|
2189 | |
|
2190 | |
static int perm_name(hashtab_key_t key, hashtab_datum_t datum, void *data)
|
2191 | |
{
|
2192 | |
struct val_to_name *v = data;
|
2193 | |
perm_datum_t *perdatum;
|
2194 | |
|
2195 | |
perdatum = (perm_datum_t *) datum;
|
2196 | |
|
2197 | |
if (v->val == perdatum->value) {
|
2198 | |
v->name = key;
|
2199 | |
return 1;
|
2200 | |
}
|
2201 | |
|
2202 | |
return 0;
|
2203 | |
}
|
2204 | |
|
2205 | |
|
2206 | |
char *av_to_string(uint32_t tclass, sepol_access_vector_t av)
|
2207 | |
{
|
2208 | |
struct val_to_name v;
|
2209 | |
static char avbuf[1024];
|
2210 | |
class_datum_t *cladatum;
|
2211 | |
char *perm = NULL, *p;
|
2212 | |
unsigned int i;
|
2213 | |
int rc;
|
2214 | |
|
2215 | |
cladatum = policydbp->class_val_to_struct[tclass-1];
|
2216 | |
p = avbuf;
|
2217 | |
for (i = 0; i < cladatum->permissions.nprim; i++) {
|
2218 | |
if (av & (1 << i)) {
|
2219 | |
v.val = i+1;
|
2220 | |
rc = hashtab_map(cladatum->permissions.table,
|
2221 | |
perm_name, &v);
|
2222 | |
if (!rc && cladatum->comdatum) {
|
2223 | |
rc = hashtab_map(
|
2224 | |
cladatum->comdatum->permissions.table,
|
2225 | |
perm_name, &v);
|
2226 | |
}
|
2227 | |
if (rc)
|
2228 | |
perm = v.name;
|
2229 | |
if (perm) {
|
2230 | |
sprintf(p, " %s", perm);
|
2231 | |
p += strlen(p);
|
2232 | |
}
|
2233 | |
}
|
2234 | |
}
|
2235 | |
|
2236 | |
return avbuf;
|
2237 | |
}
|
2238 | |
|
2239 | |
static int define_bool()
|
2240 | |
{
|
2241 | |
char *id, *name;
|
2242 | |
cond_bool_datum_t *datum;
|
2243 | |
int ret;
|
2244 | |
|
2245 | |
|
2246 | |
if (pass == 2) {
|
2247 | |
while ((id = queue_remove(id_queue)))
|
2248 | |
free(id);
|
2249 | |
return 0;
|
2250 | |
}
|
2251 | |
|
2252 | |
id = (char *) queue_remove(id_queue);
|
2253 | |
if (!id) {
|
2254 | |
yyerror("no identifier for bool definition?");
|
2255 | |
return -1;
|
2256 | |
}
|
2257 | |
if (id_has_dot(id)) {
|
2258 | |
free(id);
|
2259 | |
yyerror("boolean identifiers may not contain periods");
|
2260 | |
return -1;
|
2261 | |
}
|
2262 | |
name = id;
|
2263 | |
|
2264 | |
id = (char *) queue_remove(id_queue);
|
2265 | |
if (!id) {
|
2266 | |
yyerror("no default value for bool definition?");
|
2267 | |
free(name);
|
2268 | |
return -1;
|
2269 | |
}
|
2270 | |
|
2271 | |
datum = (cond_bool_datum_t *) malloc(sizeof(cond_bool_datum_t));
|
2272 | |
if (!datum) {
|
2273 | |
yyerror("out of memory");
|
2274 | |
free(id);
|
2275 | |
free(name);
|
2276 | |
return -1;
|
2277 | |
}
|
2278 | |
memset(datum, 0, sizeof(cond_bool_datum_t));
|
2279 | |
datum->state = (int)(id[0] == 'T') ? 1 : 0;
|
2280 | |
datum->value = ++policydbp->p_bools.nprim;
|
2281 | |
|
2282 | |
ret = hashtab_insert(policydbp->p_bools.table,
|
2283 | |
(hashtab_key_t) name, (hashtab_datum_t) datum);
|
2284 | |
|
2285 | |
if (ret == HASHTAB_PRESENT) {
|
2286 | |
--policydbp->p_bools.nprim;
|
2287 | |
free(datum);
|
2288 | |
sprintf(errormsg, "name conflict for bool %s", id);
|
2289 | |
yyerror(errormsg);
|
2290 | |
free(id);
|
2291 | |
free(name);
|
2292 | |
return -1;
|
2293 | |
}
|
2294 | |
if (ret == HASHTAB_OVERFLOW) {
|
2295 | |
yyerror("hash table overflow");
|
2296 | |
free(datum);
|
2297 | |
free(id);
|
2298 | |
free(name);
|
2299 | |
return -1;
|
2300 | |
}
|
2301 | |
return 0;
|
2302 | |
}
|
2303 | |
|
2304 | |
static cond_av_list_t *define_cond_pol_list( cond_av_list_t *avlist, cond_av_list_t *sl )
|
2305 | |
{
|
2306 | |
cond_av_list_t *end;
|
2307 | |
|
2308 | |
if (pass == 1) {
|
2309 | |
/* return something so we get through pass 1 */
|
2310 | |
return (cond_av_list_t *)1;
|
2311 | |
}
|
2312 | |
|
2313 | |
/* if we've started collecting sub lists, prepend to start of collection
|
2314 | |
because it's probably less iterations than appending. */
|
2315 | |
if (!sl) return avlist;
|
2316 | |
else if (!avlist) return sl;
|
2317 | |
else {
|
2318 | |
end = sl;
|
2319 | |
while (end->next) end = end->next;
|
2320 | |
end->next = avlist;
|
2321 | |
}
|
2322 | |
return sl;
|
2323 | |
}
|
2324 | |
|
2325 | |
static int te_avtab_helper(int which, unsigned int stype, unsigned int ttype,
|
2326 | |
ebitmap_t *tclasses, sepol_access_vector_t *avp)
|
2327 | |
|
2328 | |
{
|
2329 | |
avtab_key_t avkey;
|
2330 | |
avtab_datum_t avdatum, *avdatump;
|
2331 | |
int ret;
|
2332 | |
unsigned int k;
|
2333 | |
|
2334 | |
if (which == -AVTAB_ALLOWED) {
|
2335 | |
yyerror("neverallow should not reach this function.");
|
2336 | |
return -1;
|
2337 | |
}
|
2338 | |
|
2339 | |
for (k = ebitmap_startbit(tclasses); k < ebitmap_length(tclasses); k++) {
|
2340 | |
if (!ebitmap_get_bit(tclasses, k))
|
2341 | |
continue;
|
2342 | |
avkey.source_type = stype + 1;
|
2343 | |
avkey.target_type = ttype + 1;
|
2344 | |
avkey.target_class = k + 1;
|
2345 | |
avdatump = avtab_search(&policydbp->te_avtab, &avkey, AVTAB_AV);
|
2346 | |
if (!avdatump) {
|
2347 | |
memset(&avdatum, 0, sizeof avdatum);
|
2348 | |
avdatum.specified = (which > 0) ? which : -which;
|
2349 | |
ret = avtab_insert(&policydbp->te_avtab, &avkey, &avdatum);
|
2350 | |
if (ret) {
|
2351 | |
yyerror("hash table overflow");
|
2352 | |
return -1;
|
2353 | |
}
|
2354 | |
avdatump = avtab_search(&policydbp->te_avtab, &avkey, AVTAB_AV);
|
2355 | |
if (!avdatump) {
|
2356 | |
yyerror("inserted entry vanished!");
|
2357 | |
return -1;
|
2358 | |
}
|
2359 | |
}
|
2360 | |
|
2361 | |
avdatump->specified |= ((which > 0) ? which : -which);
|
2362 | |
|
2363 | |
switch (which) {
|
2364 | |
case AVTAB_ALLOWED:
|
2365 | |
avtab_allowed(avdatump) |= avp[k];
|
2366 | |
break;
|
2367 | |
case AVTAB_AUDITALLOW:
|
2368 | |
avtab_auditallow(avdatump) |= avp[k];
|
2369 | |
break;
|
2370 | |
case AVTAB_AUDITDENY:
|
2371 | |
avtab_auditdeny(avdatump) |= avp[k];
|
2372 | |
break;
|
2373 | |
case -AVTAB_AUDITDENY:
|
2374 | |
if (avtab_auditdeny(avdatump))
|
2375 | |
avtab_auditdeny(avdatump) &= ~avp[k];
|
2376 | |
else
|
2377 | |
avtab_auditdeny(avdatump) = ~avp[k];
|
2378 | |
break;
|
2379 | |
}
|
2380 | |
}
|
2381 | |
|
2382 | |
return 0;
|
2383 | |
}
|
2384 | |
|
2385 | |
static cond_av_list_t *cond_te_avtab_helper(int which, int stype, int ttype,
|
2386 | |
ebitmap_t *tclasses, sepol_access_vector_t *avp )
|
2387 | |
|
2388 | |
{
|
2389 | |
cond_av_list_t *sl;
|
2390 | |
avtab_key_t avkey;
|
2391 | |
avtab_datum_t avdatum;
|
2392 | |
int k;
|
2393 | |
|
2394 | |
if (which == -AVTAB_ALLOWED) {
|
2395 | |
yyerror("neverallow should not reach this function.");
|
2396 | |
return COND_ERR;
|
2397 | |
}
|
2398 | |
|
2399 | |
/* create sub_list to be passed back and appended to true or false list */
|
2400 | |
sl = (cond_av_list_t *) 0;
|
2401 | |
|
2402 | |
for (k = ebitmap_startbit(tclasses); k < ebitmap_length(tclasses); k++) {
|
2403 | |
if (!ebitmap_get_bit(tclasses, k))
|
2404 | |
continue;
|
2405 | |
/* build the key */
|
2406 | |
avkey.source_type = stype + 1;
|
2407 | |
avkey.target_type = ttype + 1;
|
2408 | |
avkey.target_class = k + 1;
|
2409 | |
|
2410 | |
/* build the datum */
|
2411 | |
memset(&avdatum, 0, sizeof avdatum);
|
2412 | |
avdatum.specified = (which > 0) ? which : -which;
|
2413 | |
|
2414 | |
switch (which) {
|
2415 | |
case AVTAB_ALLOWED:
|
2416 | |
avtab_allowed(&avdatum) = avp[k];
|
2417 | |
break;
|
2418 | |
case AVTAB_AUDITALLOW:
|
2419 | |
avtab_auditallow(&avdatum) = avp[k];
|
2420 | |
break;
|
2421 | |
case AVTAB_AUDITDENY:
|
2422 | |
yyerror("AUDITDENY statements are not allowed in a conditional block; use DONTAUDIT");
|
2423 | |
return COND_ERR;
|
2424 | |
case -AVTAB_AUDITDENY:
|
2425 | |
avtab_auditdeny(&avdatum) = ~avp[k];
|
2426 | |
break;
|
2427 | |
}
|
2428 | |
|
2429 | |
/* add to temporary list */
|
2430 | |
sl = cond_list_append(sl, &avkey, &avdatum);
|
2431 | |
|
2432 | |
if (sl == COND_ERR) {
|
2433 | |
yyerror("list overflow");
|
2434 | |
return COND_ERR;
|
2435 | |
}
|
2436 | |
}
|
2437 | |
|
2438 | |
return sl;
|
2439 | |
}
|
2440 | |
|
2441 | |
static cond_av_list_t *define_cond_te_avtab(int which)
|
2442 | |
{
|
2443 | |
char *id;
|
2444 | |
cond_av_list_t *sub_list, *final_list, *tail;
|
2445 | |
class_datum_t *cladatum;
|
2446 | |
perm_datum_t *perdatum;
|
2447 | |
ebitmap_t stypes, ttypes, tclasses, negset;
|
2448 | |
sepol_access_vector_t *avp;
|
2449 | |
int i, j, hiclass, self = 0, add = 1;
|
2450 | |
int suppress = 0;
|
|
2114 |
avrule_t *avrule;
|
2451 | 2115 |
|
2452 | 2116 |
if (pass == 1) {
|
2453 | 2117 |
while ((id = queue_remove(id_queue)))
|
|
2456 | 2120 |
free(id);
|
2457 | 2121 |
while ((id = queue_remove(id_queue)))
|
2458 | 2122 |
free(id);
|
2459 | |
while ((id = queue_remove(id_queue)))
|
|
2123 |
id = queue_remove(id_queue);
|
|
2124 |
free(id);
|
|
2125 |
return (avrule_t*)1;
|
|
2126 |
}
|
|
2127 |
|
|
2128 |
if (define_compute_type_helper(which, &avrule))
|
|
2129 |
return COND_ERR;
|
|
2130 |
|
|
2131 |
return avrule;
|
|
2132 |
}
|
|
2133 |
|
|
2134 |
static int define_bool(void)
|
|
2135 |
{
|
|
2136 |
char *id, *bool_value;
|
|
2137 |
cond_bool_datum_t *datum;
|
|
2138 |
int ret;
|
|
2139 |
uint32_t value;
|
|
2140 |
|
|
2141 |
if (pass == 2) {
|
|
2142 |
while ((id = queue_remove(id_queue)))
|
2460 | 2143 |
free(id);
|
2461 | |
return (cond_av_list_t *) 1; /* any non-NULL value */
|
2462 | |
}
|
2463 | |
|
2464 | |
ebitmap_init(&stypes);
|
2465 | |
ebitmap_init(&ttypes);
|
2466 | |
ebitmap_init(&tclasses);
|
2467 | |
|
2468 | |
ebitmap_init(&negset);
|
|
2144 |
return 0;
|
|
2145 |
}
|
|
2146 |
|
|
2147 |
id = (char *) queue_remove(id_queue);
|
|
2148 |
if (!id) {
|
|
2149 |
yyerror("no identifier for bool definition?");
|
|
2150 |
return -1;
|
|
2151 |
}
|
|
2152 |
if (id_has_dot(id)) {
|
|
2153 |
free(id);
|
|
2154 |
yyerror("boolean identifiers may not contain periods");
|
|
2155 |
return -1;
|
|
2156 |
}
|
|
2157 |
datum = (cond_bool_datum_t *) malloc(sizeof(cond_bool_datum_t));
|
|
2158 |
if (!datum) {
|
|
2159 |
yyerror("out of memory");
|
|
2160 |
free(id);
|
|
2161 |
return -1;
|
|
2162 |
}
|
|
2163 |
memset(datum, 0, sizeof(cond_bool_datum_t));
|
|
2164 |
ret = declare_symbol(SYM_BOOLS, id, datum, &value, &value);
|
|
2165 |
switch(ret) {
|
|
2166 |
case -3: {
|
|
2167 |
yyerror("Out of memory!");
|
|
2168 |
goto cleanup;
|
|
2169 |
}
|
|
2170 |
case -2: {
|
|
2171 |
yyerror2("duplicate declaration of boolean %s", id);
|
|
2172 |
goto cleanup;
|
|
2173 |
}
|
|
2174 |
case -1: {
|
|
2175 |
yyerror("could not declare boolean here");
|
|
2176 |
goto cleanup;
|
|
2177 |
}
|
|
2178 |
case 0:
|
|
2179 |
case 1: {
|
|
2180 |
break;
|
|
2181 |
}
|
|
2182 |
default: {
|
|
2183 |
assert(0); /* should never get here */
|
|
2184 |
}
|
|
2185 |
}
|
|
2186 |
datum->value = value;
|
|
2187 |
|
|
2188 |
bool_value = (char *) queue_remove(id_queue);
|
|
2189 |
if (!bool_value) {
|
|
2190 |
yyerror("no default value for bool definition?");
|
|
2191 |
free(id);
|
|
2192 |
return -1;
|
|
2193 |
}
|
|
2194 |
|
|
2195 |
datum->state = (int)(bool_value[0] == 'T') ? 1 : 0;
|
|
2196 |
return 0;
|
|
2197 |
cleanup:
|
|
2198 |
cond_destroy_bool(id, datum, NULL);
|
|
2199 |
return -1;
|
|
2200 |
}
|
|
2201 |
|
|
2202 |
static avrule_t *define_cond_pol_list(avrule_t *avlist, avrule_t *sl)
|
|
2203 |
{
|
|
2204 |
if (pass == 1) {
|
|
2205 |
/* return something so we get through pass 1 */
|
|
2206 |
return (avrule_t *)1;
|
|
2207 |
}
|
|
2208 |
|
|
2209 |
/* prepend the new avlist to the pre-existing one */
|
|
2210 |
sl->next = avlist;
|
|
2211 |
return sl;
|
|
2212 |
}
|
|
2213 |
|
|
2214 |
static int define_te_avtab_helper(int which, avrule_t **rule)
|
|
2215 |
{
|
|
2216 |
char *id;
|
|
2217 |
class_datum_t *cladatum;
|
|
2218 |
perm_datum_t *perdatum = NULL;
|
|
2219 |
class_perm_node_t *perms, *tail = NULL, *cur_perms = NULL;
|
|
2220 |
ebitmap_t tclasses;
|
|
2221 |
ebitmap_node_t *node;
|
|
2222 |
avrule_t *avrule;
|
|
2223 |
unsigned int i, hiclass;
|
|
2224 |
int add = 1, ret = 0;
|
|
2225 |
int suppress = 0;
|
|
2226 |
|
|
2227 |
avrule = (avrule_t*)malloc(sizeof(avrule_t));
|
|
2228 |
if (!avrule) {
|
|
2229 |
yyerror("memory error");
|
|
2230 |
ret = -1;
|
|
2231 |
goto out;
|
|
2232 |
}
|
|
2233 |
avrule_init(avrule);
|
|
2234 |
avrule->specified = which;
|
|
2235 |
avrule->line = policydb_lineno;
|
|
2236 |
|
2469 | 2237 |
while ((id = queue_remove(id_queue))) {
|
2470 | |
if (set_types(&stypes, &negset, id, &add))
|
2471 | |
return COND_ERR;
|
2472 | |
}
|
2473 | |
ebitmap_destroy(&negset);
|
2474 | |
|
2475 | |
ebitmap_init(&negset);
|
|
2238 |
if (set_types(&avrule->stypes, id, &add, which == AVRULE_NEVERALLOW? 1 : 0 )) {
|
|
2239 |
ret = -1;
|
|
2240 |
goto out;
|
|
2241 |
}
|
|
2242 |
}
|
|
2243 |
add = 1;
|
2476 | 2244 |
while ((id = queue_remove(id_queue))) {
|
2477 | 2245 |
if (strcmp(id, "self") == 0) {
|
2478 | |
self = 1;
|
|
2246 |
avrule->flags |= RULE_SELF;
|
2479 | 2247 |
continue;
|
2480 | 2248 |
}
|
2481 | |
if (set_types(&ttypes, &negset, id, &add))
|
2482 | |
return COND_ERR;
|
2483 | |
}
|
2484 | |
ebitmap_destroy(&negset);
|
|
2249 |
if (set_types(&avrule->ttypes, id, &add, which == AVRULE_NEVERALLOW? 1 : 0 )) {
|
|
2250 |
ret = -1;
|
|
2251 |
goto out;
|
|
2252 |
}
|
|
2253 |
}
|
2485 | 2254 |
|
2486 | 2255 |
hiclass = 0;
|
|
2256 |
ebitmap_init(&tclasses);
|
2487 | 2257 |
while ((id = queue_remove(id_queue))) {
|
2488 | 2258 |
uint32_t classvalue;
|
2489 | 2259 |
|
|
2260 |
if (!is_id_in_scope(SYM_CLASSES, id)) {
|
|
2261 |
yyerror2("class %s is not within scope", id);
|
|
2262 |
ret = -1;
|
|
2263 |
goto out;
|
|
2264 |
}
|
2490 | 2265 |
cladatum = hashtab_search(policydbp->p_classes.table, id);
|
2491 | 2266 |
if (!cladatum) {
|
2492 | 2267 |
sprintf(errormsg, "unknown class %s used in rule", id);
|
2493 | 2268 |
yyerror(errormsg);
|
2494 | |
goto bad;
|
2495 | |
}
|
2496 | |
|
2497 | |
if (policyvers < POLICYDB_VERSION_NLCLASS &&
|
|
2269 |
ret = -1;
|
|
2270 |
goto out;
|
|
2271 |
}
|
|
2272 |
if (policyvers < POLICYDB_VERSION_NLCLASS &&
|
2498 | 2273 |
(cladatum->value >= SECCLASS_NETLINK_ROUTE_SOCKET &&
|
2499 | 2274 |
cladatum->value <= SECCLASS_NETLINK_DNRT_SOCKET)) {
|
2500 | 2275 |
sprintf(errormsg, "remapping class %s to netlink_socket "
|
|
2511 | 2286 |
free(id);
|
2512 | 2287 |
}
|
2513 | 2288 |
|
2514 | |
avp = malloc(hiclass * sizeof(sepol_access_vector_t));
|
2515 | |
if (!avp) {
|
2516 | |
yyerror("out of memory");
|
2517 | |
return COND_ERR;
|
2518 | |
}
|
2519 | |
for (i = 0; i < hiclass; i++)
|
2520 | |
avp[i] = 0;
|
|
2289 |
perms = NULL;
|
|
2290 |
ebitmap_for_each_bit(&tclasses, node, i) {
|
|
2291 |
if (!ebitmap_node_get_bit(node, i))
|
|
2292 |
continue;
|
|
2293 |
cur_perms = (class_perm_node_t *)malloc(sizeof(class_perm_node_t));
|
|
2294 |
if (!cur_perms) {
|
|
2295 |
yyerror("out of memory");
|
|
2296 |
ret = -1;
|
|
2297 |
goto out;
|
|
2298 |
}
|
|
2299 |
class_perm_node_init(cur_perms);
|
|
2300 |
cur_perms->class = i + 1;
|
|
2301 |
if (!perms)
|
|
2302 |
perms = cur_perms;
|
|
2303 |
if (tail)
|
|
2304 |
tail->next = cur_perms;
|
|
2305 |
tail = cur_perms;
|
|
2306 |
}
|
|
2307 |
|
2521 | 2308 |
while ((id = queue_remove(id_queue))) {
|
2522 | |
for (i = ebitmap_startbit(&tclasses); i < ebitmap_length(&tclasses); i++) {
|
2523 | |
if (!ebitmap_get_bit(&tclasses, i))
|
|
2309 |
cur_perms = perms;
|
|
2310 |
ebitmap_for_each_bit(&tclasses, node, i) {
|
|
2311 |
if (!ebitmap_node_get_bit(node, i))
|
2524 | 2312 |
continue;
|
2525 | 2313 |
cladatum = policydbp->class_val_to_struct[i];
|
2526 | 2314 |
|
2527 | 2315 |
if (strcmp(id, "*") == 0) {
|
2528 | 2316 |
/* set all permissions in the class */
|
2529 | |
avp[i] = ~0;
|
2530 | |
continue;
|
|
2317 |
cur_perms->data = ~0U;
|
|
2318 |
goto next;
|
2531 | 2319 |
}
|
2532 | 2320 |
|
2533 | 2321 |
if (strcmp(id, "~") == 0) {
|
2534 | 2322 |
/* complement the set */
|
2535 | |
if (which == -AVTAB_AUDITDENY)
|
|
2323 |
if (which == AVRULE_DONTAUDIT)
|
2536 | 2324 |
yywarn("dontaudit rule with a ~?");
|
2537 | |
avp[i] = ~avp[i];
|
2538 | |
continue;
|
|
2325 |
cur_perms->data = ~cur_perms->data;
|
|
2326 |
goto next;
|
2539 | 2327 |
}
|
2540 | 2328 |
|
2541 | |
perdatum = hashtab_search(cladatum->permissions.table,
|
2542 | |
id);
|
|
2329 |
perdatum = hashtab_search(cladatum->permissions.table, id);
|
2543 | 2330 |
if (!perdatum) {
|
2544 | 2331 |
if (cladatum->comdatum) {
|
2545 | 2332 |
perdatum = hashtab_search(cladatum->comdatum->permissions.table,
|
|
2551 | 2338 |
if (!suppress)
|
2552 | 2339 |
yyerror(errormsg);
|
2553 | 2340 |
continue;
|
|
2341 |
}
|
|
2342 |
else if (!is_perm_in_scope(id, policydbp->p_class_val_to_name[i])) {
|
|
2343 |
if (!suppress) {
|
|
2344 |
yyerror2("permission %s of class %s is not within scope",
|
|
2345 |
id, policydbp->p_class_val_to_name[i]);
|
|
2346 |
}
|
|
2347 |
continue;
|
|
2348 |
} else {
|
|
2349 |
cur_perms->data |= 1U << (perdatum->value - 1);
|
2554 | 2350 |
}
|
2555 | |
|
2556 | |
avp[i] |= (1 << (perdatum->value - 1));
|
|
2351 |
next:
|
|
2352 |
cur_perms = cur_perms->next;
|
2557 | 2353 |
}
|
2558 | 2354 |
|
2559 | 2355 |
free(id);
|
2560 | 2356 |
}
|
2561 | |
|
2562 | |
sub_list = NULL;
|
2563 | |
tail = NULL;
|
2564 | |
final_list = NULL;
|
2565 | |
|
2566 | |
if (self) {
|
2567 | |
for (i = ebitmap_startbit(&stypes); i < ebitmap_length(&stypes); i++) {
|
2568 | |
if (!ebitmap_get_bit(&stypes, i))
|
2569 | |
continue;
|
2570 | |
if (self) {
|
2571 | |
if ((sub_list = cond_te_avtab_helper(which, i, i, &tclasses, avp )) == COND_ERR)
|
2572 | |
return COND_ERR;
|
2573 | |
if (final_list) {
|
2574 | |
tail->next = sub_list;
|
2575 | |
while (tail->next != NULL)
|
2576 | |
tail = tail->next;
|
2577 | |
} else {
|
2578 | |
final_list = sub_list;
|
2579 | |
tail = final_list;
|
2580 | |
while (tail->next != NULL)
|
2581 | |
tail = tail->next;
|
2582 | |
}
|
2583 | |
}
|
2584 | |
}
|
2585 | |
}
|
2586 | |
for (i = ebitmap_startbit(&stypes); i < ebitmap_length(&stypes); i++) {
|
2587 | |
if (!ebitmap_get_bit(&stypes, i))
|
2588 | |
continue;
|
2589 | |
for (j = ebitmap_startbit(&ttypes); j < ebitmap_length(&ttypes); j++) {
|
2590 | |
if (!ebitmap_get_bit(&ttypes, j))
|
2591 | |
continue;
|
2592 | |
if ((sub_list = cond_te_avtab_helper(which, i, j, &tclasses, avp)) == COND_ERR)
|
2593 | |
return COND_ERR;
|
2594 | |
if (final_list) {
|
2595 | |
tail->next = sub_list;
|
2596 | |
while (tail->next != NULL)
|
2597 | |
tail = tail->next;
|
2598 | |
} else {
|
2599 | |
final_list = sub_list;
|
2600 | |
tail = final_list;
|
2601 | |
while (tail->next != NULL)
|
2602 | |
tail = tail->next;
|
2603 | |
}
|
2604 | |
}
|
2605 | |
}
|
2606 | |
|
2607 | |
ebitmap_destroy(&stypes);
|
2608 | |
ebitmap_destroy(&ttypes);
|
|
2357 |
|
2609 | 2358 |
ebitmap_destroy(&tclasses);
|
2610 | |
free(avp);
|
|
2359 |
|
|
2360 |
avrule->perms = perms;
|
|
2361 |
*rule = avrule;
|
|
2362 |
|
|
2363 |
out:
|
|
2364 |
return ret;
|
|
2365 |
|
|
2366 |
}
|
|
2367 |
|
|
2368 |
static avrule_t *define_cond_te_avtab(int which)
|
|
2369 |
{
|
|
2370 |
char *id;
|
|
2371 |
avrule_t *avrule;
|
|
2372 |
int i;
|
|
2373 |
|
|
2374 |
if (pass == 1) {
|
|
2375 |
for (i = 0; i < 4; i++) {
|
|
2376 |
while ((id = queue_remove(id_queue)))
|
|
2377 |
free(id);
|
|
2378 |
}
|
|
2379 |
return (avrule_t *) 1; /* any non-NULL value */
|
|
2380 |
}
|
2611 | 2381 |
|
2612 | |
return final_list;
|
2613 | |
bad:
|
2614 | |
return COND_ERR;
|
2615 | |
}
|
2616 | |
|
|
2382 |
if (define_te_avtab_helper(which, &avrule))
|
|
2383 |
return COND_ERR;
|
|
2384 |
|
|
2385 |
return avrule;
|
|
2386 |
}
|
2617 | 2387 |
|
2618 | 2388 |
static int define_te_avtab(int which)
|
2619 | 2389 |
{
|
2620 | 2390 |
char *id;
|
2621 | |
class_datum_t *cladatum;
|
2622 | |
perm_datum_t *perdatum;
|
2623 | |
ebitmap_t stypes, ttypes, tclasses, negset;
|
2624 | |
sepol_access_vector_t *avp;
|
2625 | |
unsigned int i, j, hiclass;
|
2626 | |
int self = 0, add = 1;
|
2627 | |
te_assert_t *newassert;
|
2628 | |
int suppress = 0;
|
|
2391 |
avrule_t *avrule;
|
|
2392 |
int i;
|
2629 | 2393 |
|
2630 | 2394 |
if (pass == 1) {
|
2631 | |
while ((id = queue_remove(id_queue)))
|
2632 | |
free(id);
|
2633 | |
while ((id = queue_remove(id_queue)))
|
2634 | |
free(id);
|
2635 | |
while ((id = queue_remove(id_queue)))
|
2636 | |
free(id);
|
2637 | |
while ((id = queue_remove(id_queue)))
|
2638 | |
free(id);
|
|
2395 |
for (i = 0; i < 4; i++) {
|
|
2396 |
while ((id = queue_remove(id_queue)))
|
|
2397 |
free(id);
|
|
2398 |
}
|
2639 | 2399 |
return 0;
|
2640 | 2400 |
}
|
2641 | |
|
2642 | |
ebitmap_init(&stypes);
|
2643 | |
ebitmap_init(&ttypes);
|
2644 | |
ebitmap_init(&tclasses);
|
2645 | |
|
2646 | |
ebitmap_init(&negset);
|
2647 | |
while ((id = queue_remove(id_queue))) {
|
2648 | |
if (set_types(&stypes, &negset, id, &add))
|
2649 | |
return -1;
|
2650 | |
}
|
2651 | |
ebitmap_destroy(&negset);
|
2652 | |
|
2653 | |
ebitmap_init(&negset);
|
2654 | |
while ((id = queue_remove(id_queue))) {
|
2655 | |
if (strcmp(id, "self") == 0) {
|
2656 | |
self = 1;
|
2657 | |
continue;
|
2658 | |
}
|
2659 | |
if (set_types(&ttypes, &negset, id, &add))
|
2660 | |
return -1;
|
2661 | |
}
|
2662 | |
ebitmap_destroy(&negset);
|
2663 | |
|
2664 | |
hiclass = 0;
|
2665 | |
while ((id = queue_remove(id_queue))) {
|
2666 | |
uint32_t classvalue;
|
2667 | |
|
2668 | |
cladatum = hashtab_search(policydbp->p_classes.table, id);
|
2669 | |
if (!cladatum) {
|
2670 | |
sprintf(errormsg, "unknown class %s used in rule", id);
|
2671 | |
yyerror(errormsg);
|
2672 | |
goto bad;
|
2673 | |
}
|
2674 | |
|
2675 | |
if (policyvers < POLICYDB_VERSION_NLCLASS &&
|
2676 | |
(cladatum->value >= SECCLASS_NETLINK_ROUTE_SOCKET &&
|
2677 | |
cladatum->value <= SECCLASS_NETLINK_DNRT_SOCKET)) {
|
2678 | |
sprintf(errormsg, "remapping class %s to netlink_socket "
|
2679 | |
"for policy version %d", id, policyvers);
|
2680 | |
yywarn(errormsg);
|
2681 | |
classvalue = SECCLASS_NETLINK_SOCKET;
|
2682 | |
suppress = 1;
|
2683 | |
} else
|
2684 | |
classvalue = cladatum->value;
|
2685 | |
|
2686 | |
ebitmap_set_bit(&tclasses, classvalue - 1, TRUE);
|
2687 | |
if (classvalue > hiclass)
|
2688 | |
hiclass = classvalue;
|
2689 | |
free(id);
|
2690 | |
}
|
2691 | |
|
2692 | |
avp = malloc(hiclass * sizeof(sepol_access_vector_t));
|
2693 | |
if (!avp) {
|
2694 | |
yyerror("out of memory");
|
2695 | |
return -1;
|
2696 | |
}
|
2697 | |
for (i = 0; i < hiclass; i++)
|
2698 | |
avp[i] = 0;
|
2699 | |
|
2700 | |
while ((id = queue_remove(id_queue))) {
|
2701 | |
for (i = ebitmap_startbit(&tclasses); i < ebitmap_length(&tclasses); i++) {
|
2702 | |
if (!ebitmap_get_bit(&tclasses, i))
|
2703 | |
continue;
|
2704 | |
cladatum = policydbp->class_val_to_struct[i];
|
2705 | |
|
2706 | |
if (strcmp(id, "*") == 0) {
|
2707 | |
/* set all permissions in the class */
|
2708 | |
avp[i] = ~0U;
|
2709 | |
continue;
|
2710 | |
}
|
2711 | |
|
2712 | |
if (strcmp(id, "~") == 0) {
|
2713 | |
/* complement the set */
|
2714 | |
if (which == -AVTAB_AUDITDENY)
|
2715 | |
yywarn("dontaudit rule with a ~?");
|
2716 | |
avp[i] = ~avp[i];
|
2717 | |
continue;
|
2718 | |
}
|
2719 | |
|
2720 | |
perdatum = hashtab_search(cladatum->permissions.table,
|
2721 | |
id);
|
2722 | |
if (!perdatum) {
|
2723 | |
if (cladatum->comdatum) {
|
2724 | |
perdatum = hashtab_search(cladatum->comdatum->permissions.table,
|
2725 | |
id);
|
2726 | |
}
|
2727 | |
}
|
2728 | |
if (!perdatum) {
|
2729 | |
sprintf(errormsg, "permission %s is not defined for class %s", id, policydbp->p_class_val_to_name[i]);
|
2730 | |
if (!suppress)
|
2731 | |
yyerror(errormsg);
|
2732 | |
continue;
|
2733 | |
}
|
2734 | |
|
2735 | |
avp[i] |= (1 << (perdatum->value - 1));
|
2736 | |
}
|
2737 | |
|
2738 | |
free(id);
|
2739 | |
}
|
2740 | |
|
2741 | |
if (which == -AVTAB_ALLOWED) {
|
2742 | |
newassert = malloc(sizeof(te_assert_t));
|
2743 | |
if (!newassert) {
|
2744 | |
yyerror("out of memory");
|
2745 | |
return -1;
|
2746 | |
}
|
2747 | |
memset(newassert, 0, sizeof(te_assert_t));
|
2748 | |
newassert->stypes = stypes;
|
2749 | |
newassert->ttypes = ttypes;
|
2750 | |
newassert->tclasses = tclasses;
|
2751 | |
newassert->self = self;
|
2752 | |
newassert->avp = avp;
|
2753 | |
newassert->line = policydb_lineno;
|
2754 | |
newassert->next = te_assertions;
|
2755 | |
te_assertions = newassert;
|
2756 | |
return 0;
|
2757 | |
}
|
2758 | |
|
2759 | |
for (i = ebitmap_startbit(&stypes); i < ebitmap_length(&stypes); i++) {
|
2760 | |
if (!ebitmap_get_bit(&stypes, i))
|
2761 | |
continue;
|
2762 | |
if (self) {
|
2763 | |
if (te_avtab_helper(which, i, i, &tclasses, avp))
|
2764 | |
return -1;
|
2765 | |
}
|
2766 | |
for (j = ebitmap_startbit(&ttypes); j < ebitmap_length(&ttypes); j++) {
|
2767 | |
if (!ebitmap_get_bit(&ttypes, j))
|
2768 | |
continue;
|
2769 | |
if (te_avtab_helper(which, i, j, &tclasses, avp))
|
2770 | |
return -1;
|
2771 | |
}
|
2772 | |
}
|
2773 | |
|
2774 | |
ebitmap_destroy(&stypes);
|
2775 | |
ebitmap_destroy(&ttypes);
|
2776 | |
ebitmap_destroy(&tclasses);
|
2777 | |
free(avp);
|
2778 | |
|
|
2401 |
|
|
2402 |
if (define_te_avtab_helper(which, &avrule))
|
|
2403 |
return -1;
|
|
2404 |
|
|
2405 |
/* append this avrule to the end of the current rules list */
|
|
2406 |
append_avrule(avrule);
|
2779 | 2407 |
return 0;
|
2780 | |
bad:
|
2781 | |
return -1;
|
2782 | |
}
|
2783 | |
|
2784 | |
|
2785 | |
static int role_val_to_name_helper(hashtab_key_t key, hashtab_datum_t datum, void *p)
|
2786 | |
{
|
2787 | |
struct val_to_name *v = p;
|
2788 | |
role_datum_t *roldatum;
|
2789 | |
|
2790 | |
roldatum = (role_datum_t *) datum;
|
2791 | |
|
2792 | |
if (v->val == roldatum->value) {
|
2793 | |
v->name = key;
|
2794 | |
return 1;
|
2795 | |
}
|
2796 | |
|
2797 | |
return 0;
|
2798 | |
}
|
2799 | |
|
2800 | |
|
2801 | |
static char *role_val_to_name(unsigned int val)
|
2802 | |
{
|
2803 | |
struct val_to_name v;
|
2804 | |
int rc;
|
2805 | |
|
2806 | |
v.val = val;
|
2807 | |
rc = hashtab_map(policydbp->p_roles.table,
|
2808 | |
role_val_to_name_helper, &v);
|
2809 | |
if (rc)
|
2810 | |
return v.name;
|
2811 | |
return NULL;
|
2812 | 2408 |
}
|
2813 | 2409 |
|
2814 | 2410 |
static int define_role_types(void)
|
2815 | 2411 |
{
|
2816 | 2412 |
role_datum_t *role;
|
2817 | |
char *role_id, *id;
|
2818 | |
int ret, add = 1;
|
2819 | |
ebitmap_t negset;
|
|
2413 |
char *id;
|
|
2414 |
int add = 1;
|
2820 | 2415 |
|
2821 | 2416 |
if (pass == 1) {
|
2822 | 2417 |
while ((id = queue_remove(id_queue)))
|
|
2824 | 2419 |
return 0;
|
2825 | 2420 |
}
|
2826 | 2421 |
|
2827 | |
role_id = queue_remove(id_queue);
|
2828 | |
|
2829 | |
role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
|
2830 | |
role_id);
|
2831 | |
if (!role) {
|
2832 | |
role = (role_datum_t *) malloc(sizeof(role_datum_t));
|
2833 | |
if (!role) {
|
2834 | |
yyerror("out of memory");
|
2835 | |
free(role_id);
|
2836 | |
return -1;
|
2837 | |
}
|
2838 | |
memset(role, 0, sizeof(role_datum_t));
|
2839 | |
role->value = ++policydbp->p_roles.nprim;
|
2840 | |
ebitmap_set_bit(&role->dominates, role->value-1, TRUE);
|
2841 | |
ret = hashtab_insert(policydbp->p_roles.table,
|
2842 | |
(hashtab_key_t) role_id, (hashtab_datum_t) role);
|
2843 | |
|
2844 | |
if (ret) {
|
2845 | |
yyerror("hash table overflow");
|
2846 | |
free(role);
|
2847 | |
free(role_id);
|
2848 | |
return -1;
|
2849 | |
}
|
2850 | |
} else
|
2851 | |
free(role_id);
|
2852 | |
|
2853 | |
ebitmap_init(&negset);
|
|
2422 |
if ((role = declare_role()) == NULL) {
|
|
2423 |
return -1;
|
|
2424 |
}
|
2854 | 2425 |
while ((id = queue_remove(id_queue))) {
|
2855 | |
if (set_types(&role->types, &negset, id, &add))
|
2856 | |
return -1;
|
2857 | |
}
|
2858 | |
ebitmap_destroy(&negset);
|
|
2426 |
if (set_types(&role->types, id, &add, 0))
|
|
2427 |
return -1;
|
|
2428 |
}
|
|
2429 |
|
2859 | 2430 |
|
2860 | 2431 |
return 0;
|
2861 | 2432 |
}
|
|
2881 | 2452 |
yyerror("out of memory");
|
2882 | 2453 |
return NULL;
|
2883 | 2454 |
}
|
2884 | |
if (ebitmap_or(&new->types, &r1->types, &r2->types)) {
|
|
2455 |
if (ebitmap_or(&new->types.types, &r1->types.types, &r2->types.types)) {
|
2885 | 2456 |
yyerror("out of memory");
|
2886 | 2457 |
return NULL;
|
2887 | 2458 |
}
|
2888 | 2459 |
if (!r1->value) {
|
2889 | 2460 |
/* free intermediate result */
|
2890 | |
ebitmap_destroy(&r1->types);
|
|
2461 |
type_set_destroy(&r1->types);
|
2891 | 2462 |
ebitmap_destroy(&r1->dominates);
|
2892 | 2463 |
free(r1);
|
2893 | 2464 |
}
|
2894 | 2465 |
if (!r2->value) {
|
2895 | 2466 |
/* free intermediate result */
|
2896 | 2467 |
yyerror("right hand role is temporary?");
|
2897 | |
ebitmap_destroy(&r2->types);
|
|
2468 |
type_set_destroy(&r2->types);
|
2898 | 2469 |
ebitmap_destroy(&r2->dominates);
|
2899 | 2470 |
free(r2);
|
2900 | 2471 |
}
|
|
2906 | 2477 |
{
|
2907 | 2478 |
role_datum_t *rdp = (role_datum_t *) arg;
|
2908 | 2479 |
role_datum_t *rdatum = (role_datum_t *) datum;
|
|
2480 |
ebitmap_t *types = NULL;
|
|
2481 |
ebitmap_node_t *node;
|
2909 | 2482 |
int i;
|
2910 | 2483 |
|
2911 | 2484 |
/* Don't bother to process against self role */
|
|
2915 | 2488 |
/* If a dominating role found */
|
2916 | 2489 |
if (ebitmap_get_bit(&(rdatum->dominates), rdp->value - 1))
|
2917 | 2490 |
{
|
|
2491 |
if (type_set_expand(&rdp->types, types, policydbp, 1))
|
|
2492 |
return -1;
|
2918 | 2493 |
/* raise types and dominates from dominated role */
|
2919 | |
for (i = ebitmap_startbit(&rdp->dominates);
|
2920 | |
i < ebitmap_length(&rdp->dominates); i++)
|
2921 | |
{
|
2922 | |
if (ebitmap_get_bit(&rdp->dominates, i))
|
|
2494 |
ebitmap_for_each_bit(&rdp->dominates, node, i) {
|
|
2495 |
if (ebitmap_node_get_bit(node, i))
|
2923 | 2496 |
ebitmap_set_bit(&rdatum->dominates, i, TRUE);
|
2924 | 2497 |
}
|
2925 | |
for (i = ebitmap_startbit(&rdp->types);
|
2926 | |
i < ebitmap_length(&rdp->types); i++)
|
2927 | |
{
|
2928 | |
if (ebitmap_get_bit(&rdp->types, i))
|
2929 | |
ebitmap_set_bit(&rdatum->types, i, TRUE);
|
|
2498 |
ebitmap_for_each_bit(types, node, i) {
|
|
2499 |
if (ebitmap_node_get_bit(node, i))
|
|
2500 |
ebitmap_set_bit(&rdatum->types.types, i, TRUE);
|
2930 | 2501 |
}
|
2931 | 2502 |
}
|
2932 | 2503 |
|
|
2939 | 2510 |
{
|
2940 | 2511 |
role_datum_t *role;
|
2941 | 2512 |
char *role_id;
|
|
2513 |
ebitmap_t *types = NULL;
|
|
2514 |
ebitmap_node_t *node;
|
2942 | 2515 |
unsigned int i;
|
2943 | 2516 |
int ret;
|
2944 | 2517 |
|
|
2949 | 2522 |
}
|
2950 | 2523 |
|
2951 | 2524 |
role_id = queue_remove(id_queue);
|
|
2525 |
if (!is_id_in_scope(SYM_ROLES, role_id)) {
|
|
2526 |
yyerror2("role %s is not within scope", role_id);
|
|
2527 |
free(role_id);
|
|
2528 |
return NULL;
|
|
2529 |
}
|
2952 | 2530 |
role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
|
2953 | 2531 |
role_id);
|
2954 | 2532 |
if (!role) {
|
|
2959 | 2537 |
return NULL;
|
2960 | 2538 |
}
|
2961 | 2539 |
memset(role, 0, sizeof(role_datum_t));
|
2962 | |
role->value = ++policydbp->p_roles.nprim;
|
2963 | 2540 |
ebitmap_set_bit(&role->dominates, role->value-1, TRUE);
|
2964 | |
ret = hashtab_insert(policydbp->p_roles.table,
|
2965 | |
(hashtab_key_t) role_id, (hashtab_datum_t) role);
|
2966 | |
|
2967 | |
if (ret) {
|
2968 | |
yyerror("hash table overflow");
|
2969 | |
free(role);
|
2970 | |
free(role_id);
|
|
2541 |
ret = declare_symbol(SYM_ROLES, (hashtab_key_t) role_id, (hashtab_datum_t) role, &role->value, &role->value);
|
|
2542 |
switch(ret) {
|
|
2543 |
case -3: {
|
|
2544 |
yyerror("Out of memory!");
|
|
2545 |
goto cleanup;
|
|
2546 |
}
|
|
2547 |
case -2: {
|
|
2548 |
yyerror2("duplicate declaration of role %s", role_id);
|
|
2549 |
goto cleanup;
|
|
2550 |
}
|
|
2551 |
case -1: {
|
|
2552 |
yyerror("could not declare role here");
|
|
2553 |
goto cleanup;
|
|
2554 |
}
|
|
2555 |
case 0:
|
|
2556 |
case 1: {
|
|
2557 |
break;
|
|
2558 |
}
|
|
2559 |
default: {
|
|
2560 |
assert(0); /* should never get here */
|
|
2561 |
}
|
|
2562 |
}
|
|
2563 |
}
|
|
2564 |
if (r) {
|
|
2565 |
ebitmap_for_each_bit(&r->dominates, node, i) {
|
|
2566 |
if (ebitmap_node_get_bit(node, i))
|
|
2567 |
ebitmap_set_bit(&role->dominates, i, TRUE);
|
|
2568 |
}
|
|
2569 |
if (type_set_expand(&r->types, types, policydbp, 1))
|
2971 | 2570 |
return NULL;
|
2972 | |
}
|
2973 | |
}
|
2974 | |
if (r) {
|
2975 | |
for (i = ebitmap_startbit(&r->dominates); i < ebitmap_length(&r->dominates); i++) {
|
2976 | |
if (ebitmap_get_bit(&r->dominates, i))
|
2977 | |
ebitmap_set_bit(&role->dominates, i, TRUE);
|
2978 | |
}
|
2979 | |
for (i = ebitmap_startbit(&r->types); i < ebitmap_length(&r->types); i++) {
|
2980 | |
if (ebitmap_get_bit(&r->types, i))
|
2981 | |
ebitmap_set_bit(&role->types, i, TRUE);
|
|
2571 |
ebitmap_for_each_bit(types, node, i) {
|
|
2572 |
if (ebitmap_node_get_bit(node, i))
|
|
2573 |
ebitmap_set_bit(&role->types.types, i, TRUE);
|
2982 | 2574 |
}
|
2983 | 2575 |
if (!r->value) {
|
2984 | 2576 |
/* free intermediate result */
|
2985 | |
ebitmap_destroy(&r->types);
|
|
2577 |
type_set_destroy(&r->types);
|
2986 | 2578 |
ebitmap_destroy(&r->dominates);
|
2987 | 2579 |
free(r);
|
2988 | 2580 |
}
|
|
2994 | 2586 |
dominate_role_recheck, role);
|
2995 | 2587 |
}
|
2996 | 2588 |
return role;
|
2997 | |
}
|
2998 | |
|
2999 | |
|
3000 | |
static int set_roles(ebitmap_t *set,
|
|
2589 |
cleanup:
|
|
2590 |
free(role_id);
|
|
2591 |
role_datum_destroy(role);
|
|
2592 |
free(role);
|
|
2593 |
return NULL;
|
|
2594 |
}
|
|
2595 |
|
|
2596 |
static int set_roles(role_set_t *set,
|
3001 | 2597 |
char *id)
|
3002 | 2598 |
{
|
3003 | 2599 |
role_datum_t *r;
|
3004 | |
unsigned int i;
|
3005 | 2600 |
|
3006 | 2601 |
if (strcmp(id, "*") == 0) {
|
3007 | |
/* set all roles */
|
3008 | |
for (i = 0; i < policydbp->p_roles.nprim; i++)
|
3009 | |
ebitmap_set_bit(set, i, TRUE);
|
3010 | 2602 |
free(id);
|
3011 | |
return 0;
|
|
2603 |
yyerror("* is not allowed for role sets");
|
|
2604 |
return -1;
|
3012 | 2605 |
}
|
3013 | 2606 |
|
3014 | 2607 |
if (strcmp(id, "~") == 0) {
|
3015 | |
/* complement the set */
|
3016 | |
for (i = 0; i < policydbp->p_roles.nprim; i++) {
|
3017 | |
if (ebitmap_get_bit(set, i))
|
3018 | |
ebitmap_set_bit(set, i, FALSE);
|
3019 | |
else
|
3020 | |
ebitmap_set_bit(set, i, TRUE);
|
3021 | |
}
|
3022 | 2608 |
free(id);
|
3023 | |
return 0;
|
3024 | |
}
|
3025 | |
|
|
2609 |
yyerror("~ is not allowed for role sets");
|
|
2610 |
return -1;
|
|
2611 |
}
|
|
2612 |
if (!is_id_in_scope(SYM_ROLES, id)) {
|
|
2613 |
yyerror2("role %s is not within scope", id);
|
|
2614 |
free(id);
|
|
2615 |
return -1;
|
|
2616 |
}
|
3026 | 2617 |
r = hashtab_search(policydbp->p_roles.table, id);
|
3027 | 2618 |
if (!r) {
|
3028 | |
sprintf(errormsg, "unknown role %s", id);
|
3029 | |
yyerror(errormsg);
|
|
2619 |
yyerror2("unknown role %s", id);
|
3030 | 2620 |
free(id);
|
3031 | 2621 |
return -1;
|
3032 | 2622 |
}
|
3033 | 2623 |
|
3034 | |
/* set one role */
|
3035 | |
ebitmap_set_bit(set, r->value - 1, TRUE);
|
|
2624 |
ebitmap_set_bit(&set->roles, r->value - 1, TRUE);
|
3036 | 2625 |
free(id);
|
3037 | 2626 |
return 0;
|
3038 | 2627 |
}
|
|
3042 | 2631 |
{
|
3043 | 2632 |
char *id;
|
3044 | 2633 |
role_datum_t *role;
|
3045 | |
ebitmap_t roles, types, negset;
|
3046 | |
struct role_trans *tr = 0;
|
|
2634 |
role_set_t roles;
|
|
2635 |
type_set_t types;
|
|
2636 |
ebitmap_t e_types, e_roles;
|
|
2637 |
ebitmap_node_t *tnode, *rnode;
|
|
2638 |
struct role_trans *tr = NULL;
|
|
2639 |
struct role_trans_rule *rule = NULL;
|
3047 | 2640 |
unsigned int i, j;
|
3048 | 2641 |
int add = 1;
|
3049 | 2642 |
|
|
3057 | 2650 |
return 0;
|
3058 | 2651 |
}
|
3059 | 2652 |
|
3060 | |
ebitmap_init(&roles);
|
3061 | |
ebitmap_init(&types);
|
|
2653 |
role_set_init(&roles);
|
|
2654 |
ebitmap_init(&e_roles);
|
|
2655 |
type_set_init(&types);
|
|
2656 |
ebitmap_init(&e_types);
|
3062 | 2657 |
|
3063 | 2658 |
while ((id = queue_remove(id_queue))) {
|
3064 | 2659 |
if (set_roles(&roles, id))
|
3065 | 2660 |
return -1;
|
3066 | 2661 |
}
|
3067 | |
|
3068 | |
ebitmap_init(&negset);
|
|
2662 |
add = 1;
|
3069 | 2663 |
while ((id = queue_remove(id_queue))) {
|
3070 | |
if (set_types(&types, &negset, id, &add))
|
|
2664 |
if (set_types(&types, id, &add, 0))
|
3071 | 2665 |
return -1;
|
3072 | 2666 |
}
|
3073 | |
ebitmap_destroy(&negset);
|
3074 | 2667 |
|
3075 | 2668 |
id = (char *) queue_remove(id_queue);
|
3076 | 2669 |
if (!id) {
|
3077 | 2670 |
yyerror("no new role in transition definition?");
|
3078 | 2671 |
goto bad;
|
3079 | 2672 |
}
|
|
2673 |
if (!is_id_in_scope(SYM_ROLES, id)) {
|
|
2674 |
yyerror2("role %s is not within scope", id);
|
|
2675 |
free(id);
|
|
2676 |
goto bad;
|
|
2677 |
}
|
3080 | 2678 |
role = hashtab_search(policydbp->p_roles.table, id);
|
3081 | 2679 |
if (!role) {
|
3082 | 2680 |
sprintf(errormsg, "unknown role %s used in transition definition", id);
|
|
3084 | 2682 |
goto bad;
|
3085 | 2683 |
}
|
3086 | 2684 |
|
3087 | |
for (i = ebitmap_startbit(&roles); i < ebitmap_length(&roles); i++) {
|
3088 | |
if (!ebitmap_get_bit(&roles, i))
|
|
2685 |
/* This ebitmap business is just to ensure that there are not conflicting role_trans rules */
|
|
2686 |
if (role_set_expand(&roles, &e_roles, policydbp))
|
|
2687 |
goto bad;
|
|
2688 |
|
|
2689 |
if (type_set_expand(&types, &e_types, policydbp, 1))
|
|
2690 |
goto bad;
|
|
2691 |
|
|
2692 |
ebitmap_for_each_bit(&e_roles, rnode, i) {
|
|
2693 |
if (!ebitmap_node_get_bit(rnode, i))
|
3089 | 2694 |
continue;
|
3090 | |
for (j = ebitmap_startbit(&types); j < ebitmap_length(&types); j++) {
|
3091 | |
if (!ebitmap_get_bit(&types, j))
|
|
2695 |
ebitmap_for_each_bit(&e_types, tnode, j) {
|
|
2696 |
if (!ebitmap_node_get_bit(tnode, j))
|
3092 | 2697 |
continue;
|
3093 | 2698 |
|
3094 | 2699 |
for (tr = policydbp->role_tr; tr; tr = tr->next) {
|
3095 | 2700 |
if (tr->role == (i+1) && tr->type == (j+1)) {
|
3096 | 2701 |
sprintf(errormsg, "duplicate role transition defined for (%s,%s)",
|
3097 | |
role_val_to_name(i+1), type_val_to_name(j+1));
|
|
2702 |
policydbp->p_role_val_to_name[i], policydbp->p_type_val_to_name[j]);
|
3098 | 2703 |
yyerror(errormsg);
|
3099 | 2704 |
goto bad;
|
3100 | 2705 |
}
|
|
3113 | 2718 |
policydbp->role_tr = tr;
|
3114 | 2719 |
}
|
3115 | 2720 |
}
|
|
2721 |
/* Now add the real rule */
|
|
2722 |
rule = malloc(sizeof(struct role_trans_rule));
|
|
2723 |
if (!rule) {
|
|
2724 |
yyerror("out of memory");
|
|
2725 |
return -1;
|
|
2726 |
}
|
|
2727 |
memset(rule, 0, sizeof(struct role_trans_rule));
|
|
2728 |
rule->roles = roles;
|
|
2729 |
rule->types = types;
|
|
2730 |
rule->new_role = role->value;
|
|
2731 |
|
|
2732 |
append_role_trans(rule);
|
|
2733 |
|
|
2734 |
ebitmap_destroy(&e_roles);
|
|
2735 |
ebitmap_destroy(&e_types);
|
3116 | 2736 |
|
3117 | 2737 |
return 0;
|
3118 | 2738 |
|
|
3124 | 2744 |
static int define_role_allow(void)
|
3125 | 2745 |
{
|
3126 | 2746 |
char *id;
|
3127 | |
ebitmap_t roles, new_roles;
|
3128 | |
struct role_allow *ra = 0;
|
3129 | |
unsigned int i, j;
|
|
2747 |
struct role_allow_rule *ra = 0;
|
3130 | 2748 |
|
3131 | 2749 |
if (pass == 1) {
|
3132 | 2750 |
while ((id = queue_remove(id_queue)))
|
|
3136 | 2754 |
return 0;
|
3137 | 2755 |
}
|
3138 | 2756 |
|
3139 | |
ebitmap_init(&roles);
|
3140 | |
ebitmap_init(&new_roles);
|
3141 | |
|
|
2757 |
ra = malloc(sizeof(role_allow_rule_t));
|
|
2758 |
if (!ra) {
|
|
2759 |
yyerror("out of memory");
|
|
2760 |
return -1;
|
|
2761 |
}
|
|
2762 |
role_allow_rule_init(ra);
|
|
2763 |
|
3142 | 2764 |
while ((id = queue_remove(id_queue))) {
|
3143 | |
if (set_roles(&roles, id))
|
|
2765 |
if (set_roles(&ra->roles, id))
|
3144 | 2766 |
return -1;
|
3145 | 2767 |
}
|
3146 | 2768 |
|
3147 | 2769 |
|
3148 | 2770 |
while ((id = queue_remove(id_queue))) {
|
3149 | |
if (set_roles(&new_roles, id))
|
|
2771 |
if (set_roles(&ra->new_roles, id))
|
3150 | 2772 |
return -1;
|
3151 | 2773 |
}
|
3152 | 2774 |
|
3153 | |
for (i = ebitmap_startbit(&roles); i < ebitmap_length(&roles); i++) {
|
3154 | |
if (!ebitmap_get_bit(&roles, i))
|
3155 | |
continue;
|
3156 | |
for (j = ebitmap_startbit(&new_roles); j < ebitmap_length(&new_roles); j++) {
|
3157 | |
if (!ebitmap_get_bit(&new_roles, j))
|
3158 | |
continue;
|
3159 | |
|
3160 | |
for (ra = policydbp->role_allow; ra; ra = ra->next) {
|
3161 | |
if (ra->role == (i+1) && ra->new_role == (j+1))
|
3162 | |
break;
|
|
2775 |
append_role_allow(ra);
|
|
2776 |
return 0;
|
|
2777 |
}
|
|
2778 |
|
|
2779 |
static constraint_expr_t *constraint_expr_clone(constraint_expr_t *expr)
|
|
2780 |
{
|
|
2781 |
constraint_expr_t *h = NULL, *l = NULL, *e, *newe;
|
|
2782 |
for (e = expr; e; e = e->next) {
|
|
2783 |
newe = malloc(sizeof(*newe));
|
|
2784 |
if (!newe)
|
|
2785 |
goto oom;
|
|
2786 |
if (constraint_expr_init(newe) == -1) {
|
|
2787 |
free(newe);
|
|
2788 |
goto oom;
|
|
2789 |
}
|
|
2790 |
if (l)
|
|
2791 |
l->next = newe;
|
|
2792 |
else
|
|
2793 |
h = newe;
|
|
2794 |
l = newe;
|
|
2795 |
newe->expr_type = e->expr_type;
|
|
2796 |
newe->attr = e->attr;
|
|
2797 |
newe->op = e->op;
|
|
2798 |
if (newe->expr_type == CEXPR_NAMES) {
|
|
2799 |
if (newe->attr & CEXPR_TYPE) {
|
|
2800 |
if (type_set_cpy(newe->type_names, e->type_names))
|
|
2801 |
goto oom;
|
|
2802 |
} else {
|
|
2803 |
if (ebitmap_cpy(&newe->names, &e->names))
|
|
2804 |
goto oom;
|
3163 | 2805 |
}
|
3164 | |
|
3165 | |
if (ra)
|
3166 | |
continue;
|
3167 | |
|
3168 | |
ra = malloc(sizeof(struct role_allow));
|
3169 | |
if (!ra) {
|
3170 | |
yyerror("out of memory");
|
3171 | |
return -1;
|
3172 | |
}
|
3173 | |
memset(ra, 0, sizeof(struct role_allow));
|
3174 | |
ra->role = i+1;
|
3175 | |
ra->new_role = j+1;
|
3176 | |
ra->next = policydbp->role_allow;
|
3177 | |
policydbp->role_allow = ra;
|
3178 | |
}
|
3179 | |
}
|
3180 | |
|
3181 | |
return 0;
|
|
2806 |
}
|
|
2807 |
}
|
|
2808 |
|
|
2809 |
return h;
|
|
2810 |
oom:
|
|
2811 |
e = h;
|
|
2812 |
while (e) {
|
|
2813 |
l = e;
|
|
2814 |
e = e->next;
|
|
2815 |
constraint_expr_destroy(e);
|
|
2816 |
}
|
|
2817 |
return NULL;
|
3182 | 2818 |
}
|
3183 | 2819 |
|
3184 | 2820 |
|
|
3189 | 2825 |
class_datum_t *cladatum;
|
3190 | 2826 |
perm_datum_t *perdatum;
|
3191 | 2827 |
ebitmap_t classmap;
|
|
2828 |
ebitmap_node_t *enode;
|
3192 | 2829 |
constraint_expr_t *e;
|
3193 | 2830 |
unsigned int i;
|
3194 | 2831 |
int depth;
|
|
2832 |
unsigned char useexpr = 1;
|
3195 | 2833 |
|
3196 | 2834 |
if (pass == 1) {
|
3197 | 2835 |
while ((id = queue_remove(id_queue)))
|
|
3242 | 2880 |
|
3243 | 2881 |
ebitmap_init(&classmap);
|
3244 | 2882 |
while ((id = queue_remove(id_queue))) {
|
|
2883 |
if (!is_id_in_scope(SYM_CLASSES, id)) {
|
|
2884 |
yyerror2("class %s is not within scope", id);
|
|
2885 |
free(id);
|
|
2886 |
return -1;
|
|
2887 |
}
|
3245 | 2888 |
cladatum = (class_datum_t *) hashtab_search(policydbp->p_classes.table,
|
3246 | 2889 |
(hashtab_key_t) id);
|
3247 | 2890 |
if (!cladatum) {
|
|
3263 | 2906 |
return -1;
|
3264 | 2907 |
}
|
3265 | 2908 |
memset(node, 0, sizeof(constraint_node_t));
|
3266 | |
node->expr = expr;
|
|
2909 |
if (useexpr) {
|
|
2910 |
node->expr = expr;
|
|
2911 |
useexpr = 0;
|
|
2912 |
} else {
|
|
2913 |
node->expr = constraint_expr_clone(expr);
|
|
2914 |
}
|
|
2915 |
if (!node->expr) {
|
|
2916 |
yyerror("out of memory");
|
|
2917 |
return -1;
|
|
2918 |
}
|
3267 | 2919 |
node->permissions = 0;
|
3268 | 2920 |
|
3269 | 2921 |
node->next = cladatum->constraints;
|
|
3273 | 2925 |
}
|
3274 | 2926 |
|
3275 | 2927 |
while ((id = queue_remove(id_queue))) {
|
3276 | |
for (i = ebitmap_startbit(&classmap); i < ebitmap_length(&classmap); i++) {
|
3277 | |
if (ebitmap_get_bit(&classmap, i)) {
|
|
2928 |
ebitmap_for_each_bit(&classmap, enode, i) {
|
|
2929 |
if (ebitmap_node_get_bit(enode, i)) {
|
3278 | 2930 |
cladatum = policydbp->class_val_to_struct[i];
|
3279 | 2931 |
node = cladatum->constraints;
|
3280 | 2932 |
|
|
3312 | 2964 |
ebitmap_t classmap;
|
3313 | 2965 |
constraint_expr_t *e;
|
3314 | 2966 |
int depth;
|
|
2967 |
unsigned char useexpr = 1;
|
3315 | 2968 |
|
3316 | 2969 |
if (pass == 1) {
|
3317 | 2970 |
while ((id = queue_remove(id_queue)))
|
|
3356 | 3009 |
|
3357 | 3010 |
ebitmap_init(&classmap);
|
3358 | 3011 |
while ((id = queue_remove(id_queue))) {
|
|
3012 |
if (!is_id_in_scope(SYM_CLASSES, id)) {
|
|
3013 |
yyerror2("class %s is not within scope", id);
|
|
3014 |
free(id);
|
|
3015 |
return -1;
|
|
3016 |
}
|
3359 | 3017 |
cladatum = (class_datum_t *)hashtab_search(policydbp->p_classes.table, (hashtab_key_t)id);
|
3360 | 3018 |
if (!cladatum) {
|
3361 | 3019 |
sprintf(errormsg, "class %s is not defined", id);
|
|
3377 | 3035 |
return -1;
|
3378 | 3036 |
}
|
3379 | 3037 |
memset(node, 0, sizeof(constraint_node_t));
|
3380 | |
node->expr = expr;
|
|
3038 |
if (useexpr) {
|
|
3039 |
node->expr = expr;
|
|
3040 |
useexpr = 0;
|
|
3041 |
} else {
|
|
3042 |
node->expr = constraint_expr_clone(expr);
|
|
3043 |
}
|
3381 | 3044 |
node->permissions = 0;
|
3382 | 3045 |
|
3383 | 3046 |
node->next = cladatum->validatetrans;
|
|
3401 | 3064 |
ebitmap_t negset;
|
3402 | 3065 |
char *id;
|
3403 | 3066 |
uint32_t val;
|
3404 | |
int add = 1;
|
|
3067 |
int add = 1;
|
3405 | 3068 |
|
3406 | 3069 |
if (pass == 1) {
|
3407 | 3070 |
if (expr_type == CEXPR_NAMES) {
|
|
3411 | 3074 |
return 1; /* any non-NULL value */
|
3412 | 3075 |
}
|
3413 | 3076 |
|
3414 | |
expr = malloc(sizeof(struct constraint_expr));
|
3415 | |
if (!expr) {
|
|
3077 |
if ((expr = malloc(sizeof(*expr))) == NULL ||
|
|
3078 |
constraint_expr_init(expr) == - 1) {
|
3416 | 3079 |
yyerror("out of memory");
|
|
3080 |
free(expr);
|
3417 | 3081 |
return 0;
|
3418 | 3082 |
}
|
3419 | |
memset(expr, 0, sizeof(constraint_expr_t));
|
3420 | 3083 |
expr->expr_type = expr_type;
|
3421 | 3084 |
|
3422 | 3085 |
switch (expr_type) {
|
|
3429 | 3092 |
}
|
3430 | 3093 |
if (!e1 || e1->next) {
|
3431 | 3094 |
yyerror("illegal constraint expression");
|
3432 | |
free(expr);
|
|
3095 |
constraint_expr_destroy(expr);
|
3433 | 3096 |
return 0;
|
3434 | 3097 |
}
|
3435 | 3098 |
e1->next = expr;
|
|
3444 | 3107 |
}
|
3445 | 3108 |
if (!e1 || e1->next) {
|
3446 | 3109 |
yyerror("illegal constraint expression");
|
3447 | |
free(expr);
|
|
3110 |
constraint_expr_destroy(expr);
|
3448 | 3111 |
return 0;
|
3449 | 3112 |
}
|
3450 | 3113 |
e1->next = (struct constraint_expr *) arg2;
|
|
3457 | 3120 |
}
|
3458 | 3121 |
if (!e1 || e1->next) {
|
3459 | 3122 |
yyerror("illegal constraint expression");
|
3460 | |
free(expr);
|
|
3123 |
constraint_expr_destroy(expr);
|
3461 | 3124 |
return 0;
|
3462 | 3125 |
}
|
3463 | 3126 |
e1->next = expr;
|
|
3467 | 3130 |
expr->op = arg2;
|
3468 | 3131 |
return (uintptr_t)expr;
|
3469 | 3132 |
case CEXPR_NAMES:
|
|
3133 |
add = 1;
|
3470 | 3134 |
expr->attr = arg1;
|
3471 | 3135 |
expr->op = arg2;
|
3472 | 3136 |
ebitmap_init(&negset);
|
3473 | 3137 |
while ((id = (char *) queue_remove(id_queue))) {
|
3474 | 3138 |
if (expr->attr & CEXPR_USER) {
|
|
3139 |
if (!is_id_in_scope(SYM_USERS, id)) {
|
|
3140 |
yyerror2("user %s is not within scope", id);
|
|
3141 |
constraint_expr_destroy(expr);
|
|
3142 |
return 0;
|
|
3143 |
}
|
3475 | 3144 |
user = (user_datum_t *) hashtab_search(policydbp->p_users.table,
|
3476 | 3145 |
(hashtab_key_t) id);
|
3477 | 3146 |
if (!user) {
|
3478 | 3147 |
sprintf(errormsg, "unknown user %s", id);
|
3479 | 3148 |
yyerror(errormsg);
|
3480 | |
free(expr);
|
|
3149 |
constraint_expr_destroy(expr);
|
3481 | 3150 |
return 0;
|
3482 | 3151 |
}
|
3483 | 3152 |
val = user->value;
|
3484 | 3153 |
} else if (expr->attr & CEXPR_ROLE) {
|
|
3154 |
if (!is_id_in_scope(SYM_ROLES, id)) {
|
|
3155 |
yyerror2("role %s is not within scope", id);
|
|
3156 |
constraint_expr_destroy(expr);
|
|
3157 |
return 0;
|
|
3158 |
}
|
3485 | 3159 |
role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
|
3486 | 3160 |
(hashtab_key_t) id);
|
3487 | 3161 |
if (!role) {
|
3488 | 3162 |
sprintf(errormsg, "unknown role %s", id);
|
3489 | 3163 |
yyerror(errormsg);
|
3490 | |
free(expr);
|
|
3164 |
constraint_expr_destroy(expr);
|
3491 | 3165 |
return 0;
|
3492 | 3166 |
}
|
3493 | 3167 |
val = role->value;
|
3494 | 3168 |
} else if (expr->attr & CEXPR_TYPE) {
|
3495 | |
if (set_types(&expr->names, &negset, id, &add)) {
|
3496 | |
free(expr);
|
|
3169 |
if (set_types(expr->type_names, id, &add, 0)) {
|
|
3170 |
constraint_expr_destroy(expr);
|
3497 | 3171 |
return 0;
|
3498 | 3172 |
}
|
3499 | 3173 |
continue;
|
3500 | 3174 |
} else {
|
3501 | 3175 |
yyerror("invalid constraint expression");
|
3502 | |
free(expr);
|
|
3176 |
constraint_expr_destroy(expr);
|
3503 | 3177 |
return 0;
|
3504 | 3178 |
}
|
3505 | 3179 |
if (ebitmap_set_bit(&expr->names, val - 1, TRUE)) {
|
3506 | 3180 |
yyerror("out of memory");
|
3507 | 3181 |
ebitmap_destroy(&expr->names);
|
3508 | |
free(expr);
|
|
3182 |
constraint_expr_destroy(expr);
|
3509 | 3183 |
return 0;
|
3510 | 3184 |
}
|
3511 | 3185 |
free(id);
|
|
3514 | 3188 |
return (uintptr_t)expr;
|
3515 | 3189 |
default:
|
3516 | 3190 |
yyerror("invalid constraint expression");
|
3517 | |
free(expr);
|
|
3191 |
constraint_expr_destroy(expr);
|
3518 | 3192 |
return 0;
|
3519 | 3193 |
}
|
3520 | 3194 |
|
|
3523 | 3197 |
return 0;
|
3524 | 3198 |
}
|
3525 | 3199 |
|
3526 | |
static int define_conditional(cond_expr_t *expr, cond_av_list_t *t, cond_av_list_t *f )
|
|
3200 |
static int define_conditional(cond_expr_t *expr, avrule_t *t, avrule_t *f )
|
3527 | 3201 |
{
|
3528 | 3202 |
cond_expr_t *e;
|
3529 | |
cond_node_t *cn, tmp, *cn_new;
|
3530 | |
int depth;
|
3531 | |
|
|
3203 |
int depth, retval;
|
|
3204 |
cond_node_t cn, *cn_old;
|
|
3205 |
avrule_t *tmp, *last_tmp;
|
3532 | 3206 |
|
3533 | 3207 |
/* expression cannot be NULL */
|
3534 | 3208 |
if ( !expr) {
|
|
3589 | 3263 |
}
|
3590 | 3264 |
|
3591 | 3265 |
/* use tmp conditional node to partially build new node */
|
3592 | |
cn = &tmp;
|
3593 | |
cn->expr = expr;
|
3594 | |
cn->true_list = t;
|
3595 | |
cn->false_list = f;
|
3596 | |
|
|
3266 |
memset(&cn, 0, sizeof(cn));
|
|
3267 |
cn.expr = expr;
|
|
3268 |
cn.avtrue_list = t;
|
|
3269 |
cn.avfalse_list = f;
|
|
3270 |
|
3597 | 3271 |
/* normalize/precompute expression */
|
3598 | |
if (cond_normalize_expr(policydbp, cn) < 0) {
|
|
3272 |
if (cond_normalize_expr(policydbp, &cn) < 0) {
|
3599 | 3273 |
yyerror("problem normalizing conditional expression");
|
3600 | 3274 |
return -1;
|
3601 | 3275 |
}
|
3602 | 3276 |
|
3603 | |
/* get the existing conditional node, or a new one*/
|
3604 | |
cn_new = cond_node_search(policydbp, cn);
|
3605 | |
if(cn_new) {
|
3606 | |
cond_reduce_insert_list (cn->true_list, &cn_new->true_list, &cn_new->false_list, cn_new->cur_state);
|
3607 | |
cond_reduce_insert_list (cn->false_list, &cn_new->false_list, &cn_new->true_list, !cn_new->cur_state);
|
3608 | |
} else {
|
3609 | |
yyerror("could not get a conditional node");
|
3610 | |
return -1;
|
3611 | |
}
|
3612 | |
|
|
3277 |
/* get the existing conditional node, or create a new one*/
|
|
3278 |
cn_old = get_current_cond_list(&cn);
|
|
3279 |
if (!cn_old) {
|
|
3280 |
return -1;
|
|
3281 |
}
|
|
3282 |
|
|
3283 |
/* verify te rules -- both true and false branches of conditional */
|
|
3284 |
tmp = cn.avtrue_list;
|
|
3285 |
last_tmp = NULL;
|
|
3286 |
while (tmp) {
|
|
3287 |
if (!tmp->specified & AVRULE_TRANSITION)
|
|
3288 |
continue;
|
|
3289 |
retval = insert_check_type_rule(tmp,
|
|
3290 |
&policydbp->te_cond_avtab,
|
|
3291 |
&cn_old->true_list, &cn_old->false_list);
|
|
3292 |
switch (retval) {
|
|
3293 |
case 1: {
|
|
3294 |
last_tmp = tmp;
|
|
3295 |
tmp = tmp->next;
|
|
3296 |
break;
|
|
3297 |
}
|
|
3298 |
case 0: {
|
|
3299 |
/* rule conflicted, so remove it from consideration */
|
|
3300 |
if (last_tmp == NULL) {
|
|
3301 |
cn.avtrue_list = cn.avtrue_list->next;
|
|
3302 |
avrule_destroy(tmp);
|
|
3303 |
free(tmp);
|
|
3304 |
tmp = cn.avtrue_list;
|
|
3305 |
}
|
|
3306 |
else {
|
|
3307 |
last_tmp->next = tmp->next;
|
|
3308 |
avrule_destroy(tmp);
|
|
3309 |
free(tmp);
|
|
3310 |
tmp = last_tmp->next;
|
|
3311 |
}
|
|
3312 |
break;
|
|
3313 |
}
|
|
3314 |
case -1: {
|
|
3315 |
return -1;
|
|
3316 |
}
|
|
3317 |
default: {
|
|
3318 |
assert(0); /* should never get here */
|
|
3319 |
}
|
|
3320 |
}
|
|
3321 |
}
|
|
3322 |
|
|
3323 |
tmp = cn.avfalse_list;
|
|
3324 |
last_tmp = NULL;
|
|
3325 |
while (tmp) {
|
|
3326 |
if (!tmp->specified & AVRULE_TRANSITION)
|
|
3327 |
continue;
|
|
3328 |
retval = insert_check_type_rule(tmp,
|
|
3329 |
&policydbp->te_cond_avtab,
|
|
3330 |
&cn_old->false_list, &cn_old->true_list);
|
|
3331 |
switch (retval) {
|
|
3332 |
case 1: {
|
|
3333 |
last_tmp = tmp;
|
|
3334 |
tmp = tmp->next;
|
|
3335 |
break;
|
|
3336 |
}
|
|
3337 |
case 0: {
|
|
3338 |
/* rule conflicted, so remove it from consideration */
|
|
3339 |
if (last_tmp == NULL) {
|
|
3340 |
cn.avfalse_list = cn.avfalse_list->next;
|
|
3341 |
avrule_destroy(tmp);
|
|
3342 |
free(tmp);
|
|
3343 |
tmp = cn.avfalse_list;
|
|
3344 |
}
|
|
3345 |
else {
|
|
3346 |
last_tmp->next = tmp->next;
|
|
3347 |
avrule_destroy(tmp);
|
|
3348 |
free(tmp);
|
|
3349 |
tmp = last_tmp->next;
|
|
3350 |
}
|
|
3351 |
break;
|
|
3352 |
}
|
|
3353 |
case -1: {
|
|
3354 |
return -1;
|
|
3355 |
}
|
|
3356 |
default: {
|
|
3357 |
assert(0); /* should never get here */
|
|
3358 |
}
|
|
3359 |
}
|
|
3360 |
}
|
|
3361 |
|
|
3362 |
append_cond_list(&cn);
|
|
3363 |
|
|
3364 |
/* note that there is no check here for duplicate rules, nor
|
|
3365 |
* check that rule already exists in base -- that will be
|
|
3366 |
* handled during conditional expansion, in expand.c */
|
|
3367 |
|
|
3368 |
cn.avtrue_list = NULL;
|
|
3369 |
cn.avfalse_list = NULL;
|
|
3370 |
cond_node_destroy(&cn);
|
3613 | 3371 |
|
3614 | 3372 |
return 0;
|
3615 | |
}
|
3616 | |
|
3617 | |
|
3618 | |
/* Set the ENABLE bit and parse_context for each rule and check rules to see if they already exist.
|
3619 | |
* Insert rules into the conditional db when appropriate.
|
3620 | |
*
|
3621 | |
* new - list of rules to potentially add/insert
|
3622 | |
* active - list to add rule to, and address to use as parse_context
|
3623 | |
* inactive - opposite rule list in same conditional
|
3624 | |
* state - whether rules in new are on or off by default.
|
3625 | |
*
|
3626 | |
* There are 4 possible conditions for a TYPE_* rule. Allow rules are always inserted or
|
3627 | |
* OR'd with existing allow rules on the same side of the same conditional.
|
3628 | |
*
|
3629 | |
* 1) Not present anywhere -> add it
|
3630 | |
* 2) Already in cond, same side -> warn, replace default in prev rule, delete this rule
|
3631 | |
* 3) Just added to opp side -> search again (we may still add this rule)
|
3632 | |
* 4) In another conditional (either side) -> warn, delete this rule
|
3633 | |
*/
|
3634 | |
static void cond_reduce_insert_list(cond_av_list_t *new, cond_av_list_t **active, cond_av_list_t **inactive, int state)
|
3635 | |
{
|
3636 | |
int add_rule = 1;
|
3637 | |
cond_av_list_t *c, *top;
|
3638 | |
avtab_ptr_t dup;
|
3639 | |
uint32_t old_data = 0, new_data = 0;
|
3640 | |
|
3641 | |
top = c = new;
|
3642 | |
/* loop through all the rules in the list */
|
3643 | |
while(c) {
|
3644 | |
|
3645 | |
/* is conditional rule a TYPE_* rule that's already in a conditional? */
|
3646 | |
/* [note that we checked to see if it's in the base when we parsed the rule] */
|
3647 | |
if ((c->node->datum.specified & AVTAB_TYPE) &&
|
3648 | |
((dup = avtab_search_node(&policydbp->te_cond_avtab, &c->node->key, c->node->datum.specified & AVTAB_TYPE)) != NULL) ){
|
3649 | |
do {
|
3650 | |
/* is the rule we found in the current rule list or the equivalent */
|
3651 | |
if (dup->parse_context == active) {
|
3652 | |
/* change original default */
|
3653 | |
switch(c->node->datum.specified & AVTAB_TYPE) {
|
3654 | |
case AVTAB_TRANSITION:
|
3655 | |
old_data = avtab_transition(&dup->datum);
|
3656 | |
new_data = avtab_transition(&c->node->datum);
|
3657 | |
avtab_transition(&dup->datum) = new_data;
|
3658 | |
break;
|
3659 | |
case AVTAB_MEMBER:
|
3660 | |
old_data = avtab_member(&dup->datum);
|
3661 | |
new_data = avtab_member(&c->node->datum);
|
3662 | |
avtab_member(&dup->datum) = new_data;
|
3663 | |
break;
|
3664 | |
case AVTAB_CHANGE:
|
3665 | |
old_data = avtab_change(&dup->datum);
|
3666 | |
new_data = avtab_change(&c->node->datum);
|
3667 | |
avtab_change(&dup->datum) = new_data;
|
3668 | |
break;
|
3669 | |
}
|
3670 | |
sprintf(errormsg, "duplicate type rule on same side of conditional for (%s, %s:%s); overwrote original default %s with %s",
|
3671 | |
type_val_to_name(c->node->key.source_type),
|
3672 | |
type_val_to_name(c->node->key.target_type),
|
3673 | |
policydbp->p_class_val_to_name[c->node->key.target_class],
|
3674 | |
type_val_to_name(old_data),
|
3675 | |
type_val_to_name(new_data));
|
3676 | |
yywarn(errormsg);
|
3677 | |
add_rule = 0;
|
3678 | |
break;
|
3679 | |
}
|
3680 | |
/* if the rule we found is in the opposite rule list that's OK*/
|
3681 | |
if (dup->parse_context == inactive) {
|
3682 | |
continue;
|
3683 | |
} else {
|
3684 | |
/* the rule we found must be in another conditional */
|
3685 | |
sprintf(errormsg, "discarding conflicting conditional type rule for (%s, %s:%s); may only be in one conditional",
|
3686 | |
type_val_to_name(c->node->key.source_type),
|
3687 | |
type_val_to_name(c->node->key.target_type),
|
3688 | |
policydbp->p_class_val_to_name[c->node->key.target_class]);
|
3689 | |
yywarn(errormsg);
|
3690 | |
add_rule = 0;
|
3691 | |
break;
|
3692 | |
}
|
3693 | |
} while ( (dup = avtab_search_node_next(dup, c->node->datum.specified & AVTAB_TYPE)) != NULL);
|
3694 | |
|
3695 | |
} /* end dealing with TYPE_* rules */
|
3696 | |
else if ( (c->node->datum.specified & AVTAB_AV ) &&
|
3697 | |
((dup = avtab_search_node(&policydbp->te_cond_avtab, &c->node->key, c->node->datum.specified & AVTAB_AV)) != NULL) ){
|
3698 | |
do {
|
3699 | |
/* we only care if the same AV rule is on the same side of the same conditional */
|
3700 | |
if (dup->parse_context == active) {
|
3701 | |
/* add to original */
|
3702 | |
switch(c->node->datum.specified & AVTAB_AV) {
|
3703 | |
case AVTAB_ALLOWED:
|
3704 | |
new_data = avtab_allowed(&c->node->datum);
|
3705 | |
avtab_allowed(&dup->datum) |= new_data;
|
3706 | |
break;
|
3707 | |
case AVTAB_AUDITALLOW:
|
3708 | |
new_data = avtab_auditallow(&c->node->datum);
|
3709 | |
avtab_auditallow(&dup->datum) |= new_data;
|
3710 | |
break;
|
3711 | |
case AVTAB_AUDITDENY:
|
3712 | |
new_data = avtab_auditdeny(&c->node->datum);
|
3713 | |
/* Since a '0' in an auditdeny mask represents a
|
3714 | |
* permission we do NOT want to audit (dontaudit), we use
|
3715 | |
* the '&' operand to ensure that all '0's in the mask
|
3716 | |
* are retained (much unlike the allow and auditallow cases).
|
3717 | |
*/
|
3718 | |
avtab_auditdeny(&dup->datum) &= new_data;
|
3719 | |
break;
|
3720 | |
}
|
3721 | |
add_rule = 0;
|
3722 | |
break;
|
3723 | |
}
|
3724 | |
} while ( (dup = avtab_search_node_next(dup, c->node->datum.specified & AVTAB_AV)) != NULL);
|
3725 | |
} /* end dealing with ALLOW rules */
|
3726 | |
|
3727 | |
top = c->next;
|
3728 | |
/* Either insert the rule into the policy and active list, or discard the rule */
|
3729 | |
if (add_rule) {
|
3730 | |
c->node = avtab_insert_with_parse_context(&policydbp->te_cond_avtab,
|
3731 | |
&c->node->key,
|
3732 | |
&c->node->datum,
|
3733 | |
active);
|
3734 | |
/* set whether the rule is enabled/disabled */
|
3735 | |
if (state) {
|
3736 | |
c->node->datum.specified |= AVTAB_ENABLED;
|
3737 | |
} else {
|
3738 | |
c->node->datum.specified &= ~AVTAB_ENABLED;
|
3739 | |
}
|
3740 | |
|
3741 | |
/* prepend new rule to active list */
|
3742 | |
c->next = *active;
|
3743 | |
*active = c;
|
3744 | |
} else {
|
3745 | |
/* discard rule */
|
3746 | |
free(c->node);
|
3747 | |
free(c);
|
3748 | |
|
3749 | |
add_rule = 1;
|
3750 | |
}
|
3751 | |
/* next rule */
|
3752 | |
c = top;
|
3753 | |
|
3754 | |
} /* while */
|
3755 | 3373 |
}
|
3756 | 3374 |
|
3757 | 3375 |
static cond_expr_t *
|
|
3835 | 3453 |
free(expr);
|
3836 | 3454 |
return NULL;
|
3837 | 3455 |
}
|
|
3456 |
if (!is_id_in_scope(SYM_BOOLS, id)) {
|
|
3457 |
yyerror2("boolean %s is not within scope", id);
|
|
3458 |
free(id);
|
|
3459 |
free(expr);
|
|
3460 |
return NULL;
|
|
3461 |
}
|
3838 | 3462 |
bool_var = (cond_bool_datum_t *) hashtab_search(policydbp->p_bools.table,
|
3839 | 3463 |
(hashtab_key_t) id);
|
3840 | 3464 |
if (!bool_var) {
|
|
3854 | 3478 |
}
|
3855 | 3479 |
|
3856 | 3480 |
|
3857 | |
static int set_user_roles(ebitmap_t *set,
|
|
3481 |
static int set_user_roles(role_set_t *set,
|
3858 | 3482 |
char *id)
|
3859 | 3483 |
{
|
3860 | 3484 |
role_datum_t *r;
|
3861 | 3485 |
unsigned int i;
|
|
3486 |
ebitmap_node_t *node;
|
3862 | 3487 |
|
3863 | 3488 |
if (strcmp(id, "*") == 0) {
|
3864 | |
/* set all roles */
|
3865 | |
for (i = 0; i < policydbp->p_roles.nprim; i++)
|
3866 | |
ebitmap_set_bit(set, i, TRUE);
|
3867 | 3489 |
free(id);
|
3868 | |
return 0;
|
|
3490 |
yyerror("* is not allowed in user declarations");
|
|
3491 |
return -1;
|
3869 | 3492 |
}
|
3870 | 3493 |
|
3871 | 3494 |
if (strcmp(id, "~") == 0) {
|
3872 | |
/* complement the set */
|
3873 | |
for (i = 0; i < policydbp->p_roles.nprim; i++) {
|
3874 | |
if (ebitmap_get_bit(set, i))
|
3875 | |
ebitmap_set_bit(set, i, FALSE);
|
3876 | |
else
|
3877 | |
ebitmap_set_bit(set, i, TRUE);
|
3878 | |
}
|
3879 | 3495 |
free(id);
|
3880 | |
return 0;
|
3881 | |
}
|
3882 | |
|
|
3496 |
yyerror("~ is not allowed in user declarations");
|
|
3497 |
return -1;
|
|
3498 |
}
|
|
3499 |
|
|
3500 |
if (!is_id_in_scope(SYM_ROLES, id)) {
|
|
3501 |
yyerror2("role %s is not within scope", id);
|
|
3502 |
free(id);
|
|
3503 |
return -1;
|
|
3504 |
}
|
3883 | 3505 |
r = hashtab_search(policydbp->p_roles.table, id);
|
3884 | 3506 |
if (!r) {
|
3885 | 3507 |
sprintf(errormsg, "unknown role %s", id);
|
|
3889 | 3511 |
}
|
3890 | 3512 |
|
3891 | 3513 |
/* set the role and every role it dominates */
|
3892 | |
for (i = ebitmap_startbit(&r->dominates); i < ebitmap_length(&r->dominates); i++) {
|
3893 | |
if (ebitmap_get_bit(&r->dominates, i))
|
3894 | |
ebitmap_set_bit(set, i, TRUE);
|
|
3514 |
ebitmap_for_each_bit(&r->dominates, node, i) {
|
|
3515 |
if (ebitmap_node_get_bit(node, i))
|
|
3516 |
ebitmap_set_bit(&set->roles, i, TRUE);
|
3895 | 3517 |
}
|
3896 | 3518 |
free(id);
|
3897 | 3519 |
return 0;
|
|
3963 | 3585 |
{
|
3964 | 3586 |
char *id;
|
3965 | 3587 |
user_datum_t *usrdatum;
|
3966 | |
int ret;
|
3967 | 3588 |
level_datum_t *levdatum;
|
3968 | 3589 |
int l;
|
3969 | 3590 |
|
|
3987 | 3608 |
return 0;
|
3988 | 3609 |
}
|
3989 | 3610 |
|
3990 | |
id = (char *) queue_remove(id_queue);
|
3991 | |
if (!id) {
|
3992 | |
yyerror("no user name for user definition?");
|
3993 | |
return -1;
|
3994 | |
}
|
3995 | |
usrdatum = (user_datum_t *) hashtab_search(policydbp->p_users.table,
|
3996 | |
(hashtab_key_t) id);
|
3997 | |
if (!usrdatum) {
|
3998 | |
usrdatum = (user_datum_t *) malloc(sizeof(user_datum_t));
|
3999 | |
if (!usrdatum) {
|
4000 | |
yyerror("out of memory");
|
4001 | |
free(id);
|
4002 | |
return -1;
|
4003 | |
}
|
4004 | |
memset(usrdatum, 0, sizeof(user_datum_t));
|
4005 | |
usrdatum->value = ++policydbp->p_users.nprim;
|
4006 | |
ebitmap_init(&usrdatum->roles);
|
4007 | |
ret = hashtab_insert(policydbp->p_users.table,
|
4008 | |
(hashtab_key_t) id, (hashtab_datum_t) usrdatum);
|
4009 | |
if (ret) {
|
4010 | |
yyerror("hash table overflow");
|
4011 | |
free(usrdatum);
|
4012 | |
free(id);
|
4013 | |
return -1;
|
4014 | |
}
|
4015 | |
} else
|
4016 | |
free(id);
|
|
3611 |
if ((usrdatum = declare_user()) == NULL) {
|
|
3612 |
return -1;
|
|
3613 |
}
|
4017 | 3614 |
|
4018 | 3615 |
while ((id = queue_remove(id_queue))) {
|
4019 | 3616 |
if (set_user_roles(&usrdatum->roles, id))
|
|
4148 | 3745 |
yyerror("no effective user?");
|
4149 | 3746 |
goto bad;
|
4150 | 3747 |
}
|
|
3748 |
if (!is_id_in_scope(SYM_USERS, id)) {
|
|
3749 |
yyerror2("user %s is not within scope", id);
|
|
3750 |
free(id);
|
|
3751 |
goto bad;
|
|
3752 |
}
|
4151 | 3753 |
usrdatum = (user_datum_t *) hashtab_search(policydbp->p_users.table,
|
4152 | 3754 |
(hashtab_key_t) id);
|
4153 | 3755 |
if (!usrdatum) {
|
|
4167 | 3769 |
yyerror("no role name for sid context definition?");
|
4168 | 3770 |
return -1;
|
4169 | 3771 |
}
|
|
3772 |
if (!is_id_in_scope(SYM_ROLES, id)) {
|
|
3773 |
yyerror2("role %s is not within scope", id);
|
|
3774 |
free(id);
|
|
3775 |
return -1;
|
|
3776 |
}
|
4170 | 3777 |
role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
|
4171 | 3778 |
(hashtab_key_t) id);
|
4172 | 3779 |
if (!role) {
|
|
4187 | 3794 |
yyerror("no type name for sid context definition?");
|
4188 | 3795 |
return -1;
|
4189 | 3796 |
}
|
|
3797 |
if (!is_id_in_scope(SYM_TYPES, id)) {
|
|
3798 |
yyerror2("type %s is not within scope", id);
|
|
3799 |
free(id);
|
|
3800 |
return -1;
|
|
3801 |
}
|
4190 | 3802 |
typdatum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
|
4191 | 3803 |
(hashtab_key_t) id);
|
4192 | 3804 |
if (!typdatum || typdatum->isattr) {
|
4193 | |
sprintf(errormsg, "type %s is not defined", id);
|
|
3805 |
sprintf(errormsg, "type %s is not defined or is an attribute", id);
|
4194 | 3806 |
yyerror(errormsg);
|
4195 | 3807 |
free(id);
|
4196 | 3808 |
return -1;
|
|
4805 | 4417 |
char *id;
|
4806 | 4418 |
level_datum_t *levdatum = 0;
|
4807 | 4419 |
mls_range_t range;
|
4808 | |
ebitmap_t doms, types, negset;
|
|
4420 |
type_set_t doms, types;
|
|
4421 |
ebitmap_node_t *snode, *tnode;
|
4809 | 4422 |
range_trans_t *rt = 0;
|
4810 | 4423 |
unsigned int i, j;
|
4811 | 4424 |
int l, add = 1;
|
|
4833 | 4446 |
return 0;
|
4834 | 4447 |
}
|
4835 | 4448 |
|
4836 | |
ebitmap_init(&doms);
|
4837 | |
ebitmap_init(&types);
|
4838 | |
|
4839 | |
ebitmap_init(&negset);
|
|
4449 |
type_set_init(&doms);
|
|
4450 |
type_set_init(&types);
|
|
4451 |
|
4840 | 4452 |
while ((id = queue_remove(id_queue))) {
|
4841 | |
if (set_types(&doms, &negset, id, &add))
|
|
4453 |
if (set_types(&doms, id, &add, 0))
|
4842 | 4454 |
return -1;
|
4843 | 4455 |
}
|
4844 | |
ebitmap_destroy(&negset);
|
4845 | |
|
4846 | |
ebitmap_init(&negset);
|
|
4456 |
add = 1;
|
4847 | 4457 |
while ((id = queue_remove(id_queue))) {
|
4848 | |
if (set_types(&types, &negset, id, &add))
|
|
4458 |
if (set_types(&types, id, &add, 0))
|
4849 | 4459 |
return -1;
|
4850 | 4460 |
}
|
4851 | |
ebitmap_destroy(&negset);
|
4852 | 4461 |
|
4853 | 4462 |
id = (char *)queue_remove(id_queue);
|
4854 | 4463 |
if (!id) {
|
|
4894 | 4503 |
return -1;
|
4895 | 4504 |
}
|
4896 | 4505 |
|
4897 | |
for (i = ebitmap_startbit(&doms); i < ebitmap_length(&doms); i++) {
|
4898 | |
if (!ebitmap_get_bit(&doms, i))
|
|
4506 |
ebitmap_for_each_bit(&doms.types, snode, i) {
|
|
4507 |
if (!ebitmap_node_get_bit(snode, i))
|
4899 | 4508 |
continue;
|
4900 | |
for (j = ebitmap_startbit(&types); j < ebitmap_length(&types); j++) {
|
4901 | |
if (!ebitmap_get_bit(&types, j))
|
|
4509 |
ebitmap_for_each_bit(&types.types, tnode, j) {
|
|
4510 |
if (!ebitmap_node_get_bit(tnode, j))
|
4902 | 4511 |
continue;
|
4903 | 4512 |
|
4904 | 4513 |
for (rt = policydbp->range_tr; rt; rt = rt->next) {
|
4905 | 4514 |
if (rt->dom == (i + 1) && rt->type == (j + 1)) {
|
4906 | 4515 |
sprintf(errormsg, "duplicate range_transition defined for (%s,%s)",
|
4907 | |
type_val_to_name(i + 1), type_val_to_name(j + 1));
|
|
4516 |
policydbp->p_type_val_to_name[i + 1],
|
|
4517 |
policydbp->p_type_val_to_name[j + 1]);
|
4908 | 4518 |
yyerror(errormsg);
|
4909 | 4519 |
return -1;
|
4910 | 4520 |
}
|
|
4937 | 4547 |
}
|
4938 | 4548 |
}
|
4939 | 4549 |
|
4940 | |
ebitmap_destroy(&doms);
|
4941 | |
ebitmap_destroy(&types);
|
|
4550 |
type_set_destroy(&doms);
|
|
4551 |
type_set_destroy(&types);
|
4942 | 4552 |
ebitmap_destroy(&range.level[0].cat);
|
4943 | 4553 |
ebitmap_destroy(&range.level[1].cat);
|
4944 | 4554 |
return 0;
|