Codebase list checkpolicy / ac0d3ba
Imported Upstream version 1.26 Laurent Bigonville 12 years ago
13 changed file(s) with 3929 addition(s) and 1815 deletion(s). Raw diff Collapse all Expand all
0 1.26 2005-09-06
1 * Updated version for release.
2
3 1.25.12 2005-08-22
4 * Fixed handling of validatetrans constraint expressions.
5 Bug reported by Dan Walsh for checkpolicy -M.
6
7 1.25.11 2005-08-18
8 * Merged use-after-free fix from Serge Hallyn (IBM).
9 Bug found by Coverity.
10
11 1.25.10 2005-08-15
12 * Fixed further memory leaks found by valgrind.
13
14 1.25.9 2005-08-15
15 * Changed checkpolicy to destroy the policydbs prior to exit
16 to allow leak detection.
17 * Fixed several memory leaks found by valgrind.
18
19 1.25.8 2005-08-11
20 * Updated checkpolicy and dispol for the new avtab format.
21 Converted users of ebitmaps to new inline operators.
22 Note: The binary policy format version has been incremented to
23 version 20 as a result of these changes. To build a policy
24 for a kernel that does not yet include these changes, use
25 the -c 19 option to checkpolicy.
26
27 1.25.7 2005-08-11
28 * Merged patch to prohibit use of "self" as a type name from Jason Tang (Tresys).
29
30 1.25.6 2005-08-10
31 * Merged patch to fix dismod compilation from Joshua Brindle (Tresys).
32
33 1.25.5 2005-08-09
34 * Fixed call to hierarchy checking code to pass the right policydb.
35
36 1.25.4 2005-08-02
37 * Merged patch to update dismod for the relocation of the
38 module read/write code from libsemanage to libsepol, and
39 to enable build of test subdirectory from Jason Tang (Tresys).
40
41 1.25.3 2005-07-18
42 * Merged hierarchy check fix from Joshua Brindle (Tresys).
43
44 1.25.2 2005-07-06
45 * Merged loadable module support from Tresys Technology.
46
47 1.25.1 2005-06-24
48 * Merged patch to prohibit the use of * and ~ in type sets
49 (other than in neverallow statements) and in role sets
50 from Joshua Brindle (Tresys).
51
052 1.24 2005-06-20
153 * Updated version for release.
254
00 #
11 # Makefile for building the checkpolicy program
22 #
3 PREFIX ?= ${DESTDIR}/usr
3 PREFIX ?= $(DESTDIR)/usr
44 BINDIR ?= $(PREFIX)/bin
55 MANDIR ?= $(PREFIX)/share/man
6 LIBDIR ?= ${PREFIX}/lib
7 INCLUDEDIR ?= ${PREFIX}/include
8 TARGETS = checkpolicy
6 LIBDIR ?= $(PREFIX)/lib
7 INCLUDEDIR ?= $(PREFIX)/include
8 TARGETS = checkpolicy checkmodule
99
10 CFLAGS = -g -Wall -O2 -pipe
10 CFLAGS ?= -g -Wall -O2 -pipe -fno-strict-aliasing
1111
1212 override CFLAGS += -I. -I${INCLUDEDIR}
1313
14 OBJS += y.tab.o lex.yy.o queue.o checkpolicy.o
14 CHECKOBJS = y.tab.o lex.yy.o queue.o module_compiler.o
15 CHECKPOLOBJS = $(CHECKOBJS) checkpolicy.o
16 CHECKMODOBJS = $(CHECKOBJS) checkmodule.o
1517
16 LIBS=-lfl ${LIBDIR}/libsepol.a
18 LDLIBS=$(LIBDIR)/libsepol.a -lfl
1719
1820 all: $(TARGETS)
21 $(MAKE) -C test
1922
20 checkpolicy: $(OBJS)
21 $(CC) -o $@ $^ $(LIBS)
23 checkpolicy: $(CHECKPOLOBJS)
24
25 checkmodule: $(CHECKMODOBJS)
2226
2327 %.o: %.c
2428 $(CC) $(CFLAGS) -o $@ -c $<
4347
4448 relabel: install
4549 /sbin/restorecon $(BINDIR)/checkpolicy
50 /sbin/restorecon $(BINDIR)/checkmodule
4651
4752 clean:
48 rm -f $(TARGETS) $(OBJS) y.tab.c y.tab.h lex.yy.c
53 -rm -f $(TARGETS) $(CHECKPOLOBJS) $(CHECKMODOBJS) y.tab.c y.tab.h lex.yy.c
54 $(MAKE) -C test clean
4955
0 1.24
0 1.26
0 /*
1 * Authors: Joshua Brindle <jbrindle@tresys.com>
2 * Karl MacMillan <kmacmillan@tresys.com>
3 * Jason Tang <jtang@tresys.com>
4 *
5 *
6 * Copyright (C) 2004-5 Tresys Technology, LLC
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, version 2.
10 */
11
12 #include <getopt.h>
13 #include <unistd.h>
14 #include <stdlib.h>
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include <fcntl.h>
18 #include <stdio.h>
19 #include <errno.h>
20 #include <sys/mman.h>
21
22 #include <sepol/policydb.h>
23 #include <sepol/services.h>
24 #include <sepol/conditional.h>
25 #include <sepol/flask.h>
26 #include <sepol/hierarchy.h>
27
28 #include "queue.h"
29 #include "checkpolicy.h"
30
31 extern char *optarg;
32 extern int optind;
33
34 static sidtab_t sidtab;
35
36 extern policydb_t *policydbp;
37 extern queue_t id_queue;
38 extern unsigned int policydb_errors;
39 extern unsigned long policydb_lineno;
40 extern char source_file[];
41
42 extern FILE *yyin;
43 extern void init_parser(int);
44 extern int yyparse(void);
45 extern void yyrestart(FILE *);
46
47 static char *txtfile = "policy.conf";
48 static char *binfile = "policy";
49
50 unsigned int policy_type = POLICY_BASE;
51 unsigned int policyvers = POLICYDB_VERSION_MAX;
52 unsigned int mlspol = 0;
53
54 static int read_binary_policy(policydb_t *p, char *file, char *progname)
55 {
56 int fd;
57 struct stat sb;
58 void *map;
59 struct policy_file f, *fp;
60
61 fd = open(file, O_RDONLY);
62 if (fd < 0) {
63 fprintf(stderr, "Can't open '%s': %s\n",
64 file, strerror(errno));
65 return -1;
66 }
67 if (fstat(fd, &sb) < 0) {
68 fprintf(stderr, "Can't stat '%s': %s\n",
69 file, strerror(errno));
70 return -1;
71 }
72 map = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
73 if (map == MAP_FAILED) {
74 fprintf(stderr, "Can't map '%s': %s\n",
75 file, strerror(errno));
76 return -1;
77 }
78 f.type = PF_USE_MEMORY;
79 f.data = map;
80 f.len = sb.st_size;
81 fp = &f;
82
83 if (policydb_read(p, fp, 1)) {
84 fprintf(stderr, "%s: error(s) encountered while parsing configuration\n", progname);
85 return -1;
86 }
87
88 /* Check Policy Consistency */
89 if (sepol_mls_enabled()) {
90 if (!mlspol) {
91 fprintf(stderr,"%s: MLS policy, but non-MLS"
92 " is specified\n", progname);
93 return -1;
94 }
95 } else {
96 if (mlspol) {
97 fprintf(stderr,"%s: non-MLS policy, but MLS"
98 " is specified\n", progname);
99 return -1;
100 }
101 }
102 return 0;
103 }
104
105 static int read_source_policy(policydb_t *p, char *file, char *progname)
106 {
107 char error_msg[ERRMSG_LEN];
108
109 yyin = fopen(file, "r");
110 if (!yyin) {
111 fprintf(stderr, "%s: unable to open %s\n", progname,
112 file);
113 return -1;
114 }
115
116 if (policydb_init(p, policy_type) ||
117 ((id_queue = queue_create()) == NULL)) {
118 fprintf(stderr, "%s: out of memory!\n", progname);
119 return -1;
120 }
121
122 init_parser(1);
123 if (yyparse() || policydb_errors) {
124 fprintf(stderr, "%s: error(s) encountered while parsing configuration\n", progname);
125 return -1;
126 }
127 rewind(yyin);
128 init_parser(2);
129 source_file[0] = '\0';
130 yyrestart(yyin);
131 if (yyparse() || policydb_errors) {
132 fprintf(stderr, "%s: error(s) encountered while parsing configuration\n", progname);
133 return -1;
134 }
135 queue_destroy(id_queue);
136
137 if (hierarchy_check_constraints(p, error_msg, sizeof(error_msg))) {
138 fprintf(stderr, "%s\n", error_msg);
139 return -1;
140 }
141
142 if (policydb_errors)
143 return -1;
144
145 fclose(yyin);
146 return 0;
147 }
148
149 static int write_binary_policy(policydb_t *p, char *file, char *progname)
150 {
151 FILE *outfp = NULL;
152 struct policy_file pf;
153 int ret;
154
155 printf("%s: writing binary representation (version %d) to %s\n",
156 progname, policyvers, file);
157
158 outfp = fopen(file, "w");
159 if (!outfp) {
160 perror(file);
161 exit(1);
162 }
163
164 if (sepol_set_policyvers(policy_type, policyvers)) {
165 fprintf(stderr,"%s: incompatible policy (version %d) "
166 "for writing to %s\n", progname,
167 policyvers, file);
168 exit(1);
169 }
170
171 pf.type = PF_USE_STDIO;
172 pf.fp = outfp;
173 ret = policydb_write(p, &pf);
174 if (ret) {
175 fprintf(stderr, "%s: error writing %s\n",
176 progname, file);
177 return -1;
178 }
179 fclose(outfp);
180 return 0;
181 }
182
183 static void usage(char *progname)
184 {
185 printf("usage: %s [-V] [-b] [-m] [-M] [-o FILE] [INPUT]\n",
186 progname);
187 printf("Build base and policy modules.\n");
188 printf("Options:\n");
189 printf(" INPUT build module from INPUT (else read from \"%s\")\n", txtfile);
190 printf(" -V show policy versions created by this program\n");
191 printf(" -b treat input as a binary policy file\n");
192 printf(" -m build a policy module instead of a base module\n");
193 printf(" -M enable MLS policy\n");
194 printf(" -o FILE write module to FILE (else just check syntax)\n");
195 exit(1);
196 }
197
198 int main(int argc, char **argv)
199 {
200 char *file = txtfile, *outfile = NULL;
201 unsigned int binary = 0;
202 int ch;
203 int show_version = 0;
204 policydb_t modpolicydb;
205
206 while ((ch = getopt(argc, argv, "ho:dbVmM")) != EOF) {
207 switch (ch) {
208 case 'h':
209 usage (argv [0]);
210 break;
211 case 'o':
212 outfile = optarg;
213 break;
214 case 'b':
215 binary = 1;
216 file = binfile;
217 break;
218 case 'V':
219 show_version = 1;
220 break;
221 case 'm':
222 policy_type = POLICY_MOD;
223 policyvers = MOD_POLICYDB_VERSION_MAX;
224 break;
225 case 'M':
226 fprintf(stderr, "checkmodule does not currently accept MLS policies\n");
227 exit(1);
228 default:
229 usage(argv[0]);
230 }
231 }
232
233 if (show_version) {
234 printf("%d (compatibility range %d-%d)\n", policyvers,
235 POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX);
236 printf("Module versions %d-%d\n",
237 MOD_POLICYDB_VERSION_MIN, MOD_POLICYDB_VERSION_MAX);
238 exit(0);
239 }
240
241 if (optind != argc) {
242 file = argv[optind++];
243 if (optind != argc)
244 usage(argv[0]);
245 }
246 printf("%s: loading policy configuration from %s\n", argv[0],
247 file);
248
249 /* Set policydb and sidtab used by libsepol service functions
250 to my structures, so that I can directly populate and
251 manipulate them. */
252 sepol_set_policydb(&modpolicydb);
253 sepol_set_sidtab(&sidtab);
254
255 policydbp = &modpolicydb;
256 if (binary) {
257 if (read_binary_policy(policydbp, file, argv[0]) == -1) {
258 exit(1);
259 }
260 } else {
261 if (read_source_policy(policydbp, file, argv[0]) == -1) {
262 exit(1);
263 }
264 }
265
266 if (policydb_load_isids(policydbp, &sidtab))
267 exit(1);
268
269 printf("%s: policy configuration loaded\n", argv[0]);
270
271 if (outfile &&
272 write_binary_policy(policydbp, outfile, argv[0]) == -1) {
273 exit(1);
274 }
275 return 0;
276 }
277
278 /* FLASK */
279
1515 *
1616 * Added IPv6 support.
1717 *
18 * Updated: Joshua Brindle <jbrindle@tresys.com>
19 * Karl MacMillan <kmacmillan@tresys.com>
20 * Jason Tang <jtang@tresys.com>
21 *
22 * Policy Module support.
23 *
1824 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
19 * Copyright (C) 2003 - 2004 Tresys Technology, LLC
25 * Copyright (C) 2003 - 2005 Tresys Technology, LLC
2026 * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
2127 * This program is free software; you can redistribute it and/or modify
2228 * it under the terms of the GNU General Public License as published by
6874 #include <sepol/conditional.h>
6975 #include <sepol/hierarchy.h>
7076 #include <sepol/flask.h>
77 #include <sepol/expand.h>
7178
7279 #include "queue.h"
7380 #include "checkpolicy.h"
8289 extern queue_t id_queue;
8390 extern unsigned int policydb_errors;
8491 extern unsigned long policydb_lineno;
85 extern unsigned long source_lineno;
8692 extern char source_file[];
87 extern unsigned int pass;
8893
8994 extern FILE *yyin;
95 extern void init_parser(int);
9096 extern int yyparse(void);
9197 extern void yyrestart(FILE *);
9298
93 char *txtfile = "policy.conf";
94 char *binfile = "policy";
99 static char *txtfile = "policy.conf";
100 static char *binfile = "policy";
95101
96102 unsigned int policyvers = POLICYDB_VERSION_MAX;
97103 unsigned int mlspol = 0;
143149 return 1;
144150 }
145151
146 return 0;
147 }
148
149 static int type_attr_remove(hashtab_key_t key __attribute__ ((unused)), hashtab_datum_t datum, void *p __attribute__ ((unused)))
150 {
151 type_datum_t *typdatum;
152
153 typdatum = (type_datum_t *) datum;
154 if (typdatum->isattr)
155 return 1;
156152 return 0;
157153 }
158154
288284 cond_av_list_t *cur = list;
289285
290286 while (cur) {
291 if (cur->node->datum.specified & AVTAB_TYPE) {
292 if (avtab_search(&policydbp->te_avtab, &cur->node->key, AVTAB_TYPE)) {
287 if (cur->node->key.specified & AVTAB_TYPE) {
288 if (avtab_search(&policydbp->te_avtab, &cur->node->key)) {
293289 fprintf(stderr, "conditional type rule for (%s, %s : %s) conflicts with entry in base policy; "
294290 "conditional rule discarded.\n", policydbp->p_type_val_to_name[cur->node->key.source_type-1],
295291 policydbp->p_type_val_to_name[cur->node->key.target_type-1],
320316
321317 extern char *av_to_string(uint32_t tclass, sepol_access_vector_t av);
322318
323 void check_assertion_helper(unsigned int stype, unsigned int ttype, ebitmap_t *tclasses,
324 sepol_access_vector_t *avp, unsigned long line)
325 {
326 avtab_key_t avkey;
327 avtab_datum_t *avdatump;
328 unsigned int k;
329
330
331 for (k = ebitmap_startbit(tclasses); k < ebitmap_length(tclasses); k++) {
332 if (!ebitmap_get_bit(tclasses, k))
333 continue;
334 avkey.source_type = stype + 1;
335 avkey.target_type = ttype + 1;
336 avkey.target_class = k + 1;
337 avdatump = avtab_search(&policydb.te_avtab, &avkey, AVTAB_AV);
338 if (!avdatump)
339 continue;
340
341 if ((avdatump->specified & AVTAB_ALLOWED) &&
342 (avtab_allowed(avdatump) & avp[k])) {
343 fprintf(stderr, "assertion on line %ld violated by allow %s %s:%s {%s };\n", line, policydb.p_type_val_to_name[stype], policydb.p_type_val_to_name[ttype], policydb.p_class_val_to_name[k],
344 av_to_string(k+1,
345 avtab_allowed(avdatump) & avp[k]));
346 policydb_errors++;
347 }
348 }
349 }
350
351 void check_assertions(void)
352 {
353 te_assert_t *a, *tmp;
354 unsigned int i, j;
355
356 a = te_assertions;
357 while (a) {
358 for (i = ebitmap_startbit(&a->stypes); i < ebitmap_length(&a->stypes); i++) {
359 if (!ebitmap_get_bit(&a->stypes, i))
360 continue;
361 if (a->self) {
362 check_assertion_helper(i, i, &a->tclasses, a->avp, a->line);
363 }
364 for (j = ebitmap_startbit(&a->ttypes); j < ebitmap_length(&a->ttypes); j++) {
365 if (!ebitmap_get_bit(&a->ttypes, j))
366 continue;
367 check_assertion_helper(i, j, &a->tclasses, a->avp, a->line);
368 }
369 }
370 tmp = a;
371 a = a->next;
372 ebitmap_destroy(&tmp->stypes);
373 ebitmap_destroy(&tmp->ttypes);
374 ebitmap_destroy(&tmp->tclasses);
375 free(tmp->avp);
376 free(tmp);
377 }
378 }
379319
380320 int display_bools()
381321 {
574514 }
575515 }
576516 } else {
577 yyin = fopen(file, "r");
517 policydb_t parse_policy;
518
519 yyin = fopen(file, "r");
578520 if (!yyin) {
579521 fprintf(stderr, "%s: unable to open %s\n", argv[0],
580522 file);
581523 exit(1);
582524 }
583525
584 if (policydb_init(&policydb))
526 /* We build this as a base policy first since that is all the parser understands */
527 if (policydb_init(&parse_policy, POLICY_BASE))
585528 exit(1);
586529
587530 /* Let sepol know if we are dealing with MLS support */
592535 fprintf(stderr, "%s: out of memory\n", argv[0]);
593536 exit(1);
594537 }
595 policydbp = &policydb;
596 policydb_errors = 0;
597 pass = 1;
538 policydbp = &parse_policy;
539 init_parser(1);
598540 if (yyparse() || policydb_errors) {
599541 fprintf(stderr, "%s: error(s) encountered while parsing configuration\n", argv[0]);
600542 exit(1);
601543 }
602544 rewind(yyin);
603 policydb_lineno = 1;
545 init_parser(2);
604546 source_file[0] = '\0';
605 source_lineno = 1;
606547 yyrestart(yyin);
607 pass = 2;
608548 if (yyparse() || policydb_errors) {
609549 fprintf(stderr, "%s: error(s) encountered while parsing configuration\n", argv[0]);
610550 exit(1);
614554 cond_check_type_rules();
615555 cond_optimize_lists(policydb.cond_list);
616556
617 check_assertions();
618557 if (policydb_errors)
619558 exit(1);
620559
621560 if (policyvers >= POLICYDB_VERSION_NLCLASS &&
622 policydb.p_classes.nprim < SECCLASS_NETLINK_DNRT_SOCKET) {
561 parse_policy.p_classes.nprim < SECCLASS_NETLINK_DNRT_SOCKET) {
623562 fprintf(stderr, "%s: policy lacks new netlink classes, unable to generate policy version %d\n", argv[0], policyvers);
624563 exit(1);
625564 }
626565
627 if (hierarchy_check_constraints(&policydb, error_msg, sizeof(error_msg))) {
566 /* as that this is building a non-module policy,
567 always enable the global avrule block */
568 parse_policy.global->branch_list->enabled = 1;
569 parse_policy.global->enabled = parse_policy.global->branch_list;
570 if (expand_module(&parse_policy, &policydb, 0, error_msg, ERRMSG_LEN)) {
571 fprintf(stderr, "Error while expanding policy: %s\n", error_msg);
572 exit(1);
573 }
574 policydb_destroy(&parse_policy);
575 policydbp = &policydb;
576
577 if (hierarchy_check_constraints(policydbp, error_msg, sizeof(error_msg))) {
628578 fprintf(stderr, "%s\n", error_msg);
629579 exit(1);
630580 }
631581
632 /* remove type attributes */
633 hashtab_map_remove_on_error(policydb.p_types.table,
634 type_attr_remove, 0, 0);
635
582 if (check_assertions(policydbp,
583 policydbp->global->branch_list->avrules)) {
584 fprintf(stderr, "Check assertions failed.\n");
585 return -1;
586 }
587
636588 fclose(yyin);
637589 }
638590
650602 exit(1);
651603 }
652604
653 if (sepol_set_policyvers(policyvers)) {
605 if (sepol_set_policyvers(POLICY_KERN, policyvers)) {
654606 fprintf(stderr,"%s: incompatible policy (version %d) "
655607 "for writing to %s\n", argv[0],
656608 policyvers, outfile);
667619 }
668620 fclose(outfp);
669621 }
670 if (!debug)
622 if (!debug) {
623 policydb_destroy(&policydb);
671624 exit(0);
625 }
672626
673627 menu:
674628 printf("\nSelect an option:\n");
+0
-46
checkpolicy.spec less more
0 Summary: SELinux policy compiler
1 Name: checkpolicy
2 Version: 1.24
3 Release: 1
4 License: GPL
5 Group: Development/System
6 Source: http://www.nsa.gov/selinux/archives/%{name}-%{version}.tgz
7 Prefix: %{_prefix}
8 BuildRoot: %{_tmppath}/%{name}-buildroot
9 BuildRequires: byacc flex libsepol-devel
10 Requires: libsepol
11
12 %description
13 Security-enhanced Linux is a patch of the Linux® kernel and a number
14 of utilities with enhanced security functionality designed to add
15 mandatory access controls to Linux. The Security-enhanced Linux
16 kernel contains new architectural components originally developed to
17 improve the security of the Flask operating system. These
18 architectural components provide general support for the enforcement
19 of many kinds of mandatory access control policies, including those
20 based on the concepts of Type Enforcement®, Role-based Access
21 Control, and Multi-level Security.
22
23 This package contains checkpolicy, the SELinux policy compiler.
24 Only required for building policies.
25
26 %prep
27 %setup -q
28
29 %build
30 make LIBDIR="%{_libdir}" CFLAGS="%{optflags}"
31
32 %install
33 rm -rf ${RPM_BUILD_ROOT}
34 mkdir -p ${RPM_BUILD_ROOT}%{_bindir}
35 make DESTDIR="${RPM_BUILD_ROOT}" install
36
37 %clean
38 rm -rf ${RPM_BUILD_ROOT}
39
40 %files
41 %defattr(-,root,root)
42 %{_bindir}/checkpolicy
43 %{_mandir}/man8/checkpolicy.8.gz
44
45 %changelog
0 /* Author : Joshua Brindle <jbrindle@tresys.com>
1 * Karl MacMillan <kmacmillan@tresys.com>
2 * Jason Tang <jtang@tresys.com>
3 * Added support for binary policy modules
4 *
5 * Copyright (C) 2004 - 2005 Tresys Technology, LLC
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, version 2.
9 */
10
11 #include <assert.h>
12 #include <stdarg.h>
13 #include <stdlib.h>
14 #include <string.h>
15
16 #include <sepol/policydb.h>
17 #include <sepol/avrule_block.h>
18 #include <sepol/conditional.h>
19
20 #include "queue.h"
21 #include "module_compiler.h"
22
23 union stack_item_u {
24 avrule_block_t *avrule;
25 cond_list_t *cond_list;
26 };
27
28 typedef struct scope_stack {
29 union stack_item_u u;
30 int type; /* for above union: 1 = avrule block, 2 = conditional */
31 avrule_decl_t *decl; /* if in an avrule block, which
32 * declaration is current */
33 avrule_t *last_avrule;
34 int in_else; /* if in an avrule block, within ELSE branch */
35 struct scope_stack *parent, *child;
36 } scope_stack_t;
37
38 extern policydb_t *policydbp;
39 extern queue_t id_queue;
40 extern int yyerror(char *msg);
41 extern void yyerror2(char *fmt, ...);
42
43 static int push_stack(int stack_type, ...);
44 static void pop_stack(void);
45
46 /* keep track of the last item added to the stack */
47 static scope_stack_t *stack_top = NULL;
48 static avrule_block_t *last_block;
49 static uint32_t next_decl_id = 1;
50
51 int define_policy(int pass, int module_header_given) {
52 char *id;
53
54 if (module_header_given) {
55 if (policydbp->policy_type != POLICY_MOD) {
56 yyerror("Module specification found while not building a policy module.\n");
57 return -1;
58 }
59
60 if (pass == 2) {
61 while ((id = queue_remove(id_queue)) != NULL)
62 free(id);
63 }
64 else {
65 id = (char *) queue_remove(id_queue);
66 if (!id) {
67 yyerror("no module name");
68 return -1;
69 }
70 policydbp->name = id;
71 if ((policydbp->version = queue_remove(id_queue)) == NULL) {
72 if ((policydbp->version = strdup("")) == NULL) {
73 yyerror("Out of memory!");
74 return -1;
75 }
76 }
77 }
78 /* the first declaration within the global avrule
79 block will always have an id of 1 */
80 next_decl_id = 2;
81 }
82 else {
83 if (policydbp->policy_type == POLICY_MOD) {
84 yyerror("Building a policy module, but no module specification found.\n");
85 return -1;
86 }
87 }
88
89 /* reset the scoping stack */
90 while (stack_top != NULL) {
91 pop_stack();
92 }
93 if (push_stack(1, policydbp->global, policydbp->global->branch_list) == -1) {
94 return -1;
95 }
96 last_block = policydbp->global;
97 return 0;
98 }
99
100 /* Given the current parse stack, returns 1 if a declaration would be
101 * allowed here or 0 if not. For example, declarations are not
102 * allowed in conditionals, so if there are any conditionals in the
103 * current scope stack then this would return a 0.
104 */
105 static int is_declaration_allowed(void) {
106 if (stack_top->type != 1 ||
107 stack_top->in_else) {
108 return 0;
109 }
110 return 1;
111 }
112
113 /* Attempt to declare a symbol within the current declaration. If
114 * currently within a non-conditional and in a non-else branch then
115 * insert the symbol, return 0 on success if symbol was undeclared.
116 * For roles and users, it is legal to have multiple declarations; as
117 * such return 1 to indicate that caller must free() the datum because
118 * it was not added. If symbols may not be declared here return -1.
119 * For duplicate declarations return -2. For all else, including out
120 * of memory, return -3. Note that dest_value and datum_value might
121 * not be restricted pointers. */
122 int declare_symbol(uint32_t symbol_type,
123 hashtab_key_t key, hashtab_datum_t datum,
124 uint32_t *dest_value, uint32_t *datum_value) {
125 avrule_decl_t *decl = stack_top->decl;
126 int retval;
127
128 /* first check that symbols may be declared here */
129 if (!is_declaration_allowed()) {
130 return -1;
131 }
132 retval = symtab_insert(policydbp, symbol_type, key, datum,
133 SCOPE_DECL, decl->decl_id,
134 dest_value);
135 if (retval == 1) {
136 /* because C has no polymorphism, make the
137 * [outrageous] assumption that the first field of all
138 * symbol table data is a uint32_t representing its
139 * value */
140 uint32_t *v = (uint32_t *) hashtab_search(policydbp->symtab[symbol_type].table, key);
141 assert(v != NULL);
142 *dest_value = *v;
143 }
144 else if (retval == -2) {
145 return -2;
146 }
147 else if (retval == -1 || retval == -ENOMEM) {
148 return -3;
149 }
150 if (datum_value != NULL) {
151 if (ebitmap_set_bit(decl->declared.scope + symbol_type,
152 *datum_value - 1,
153 1)) {
154 return -3;
155 }
156 }
157 return retval;
158 }
159
160 role_datum_t *declare_role(void)
161 {
162 char *id = queue_remove(id_queue), *dest_id = NULL;
163 role_datum_t *role = NULL, *dest_role = NULL;
164 int retval;
165 uint32_t value;
166
167 if (id == NULL) {
168 yyerror("no role name");
169 return NULL;
170 }
171 if ((role = (role_datum_t *) malloc(sizeof(*role))) == NULL) {
172 yyerror("Out of memory!");
173 free(id);
174 return NULL;
175 }
176 role_datum_init(role);
177
178 retval = declare_symbol(SYM_ROLES, id, (hashtab_datum_t*)role, &value, &value);
179 if (retval == 0) {
180 role->value = value;
181 if ((dest_id = strdup(id)) == NULL) {
182 yyerror("Out of memory!");
183 return NULL;
184 }
185 }
186 else {
187 /* this role was already declared in this module, or error */
188 dest_id = id;
189 role_datum_destroy(role);
190 free(role);
191 }
192 if (retval == 0 || retval == 1) {
193 /* create a new role_datum_t for this decl, if necessary */
194 hashtab_t roles_tab;
195 assert(stack_top->type == 1);
196 if (stack_top->parent == NULL) {
197 /* in parent, so use global symbol table */
198 roles_tab = policydbp->p_roles.table;
199 }
200 else {
201 roles_tab = stack_top->decl->p_roles.table;
202 }
203 dest_role = (role_datum_t *) hashtab_search(roles_tab, dest_id);
204 if (dest_role == NULL) {
205 if ((dest_role = (role_datum_t *) malloc(sizeof(*dest_role))) == NULL) {
206 yyerror("Out of memory!");
207 free(dest_id);
208 return NULL;
209 }
210 role_datum_init(dest_role);
211 dest_role->value = value;
212 if (hashtab_insert(roles_tab, dest_id, dest_role)) {
213 yyerror("Out of memory!");
214 free(dest_id);
215 role_datum_destroy(dest_role);
216 free(dest_role);
217 return NULL;
218 }
219 }
220 else {
221 free(dest_id);
222 }
223 }
224 else {
225 free(dest_id);
226 }
227 switch(retval) {
228 case -3: {
229 yyerror("Out of memory!");
230 return NULL;
231 }
232 case -2: {
233 yyerror("duplicate declaration of role");
234 return NULL;
235 }
236 case -1: {
237 yyerror("could not declare role here");
238 return NULL;
239 }
240 case 0: {
241 ebitmap_set_bit(&role->dominates, role->value - 1, 1);
242 return dest_role;
243 }
244 case 1: {
245 return dest_role; /* role already declared for this block */
246 }
247 default: {
248 assert(0); /* should never get here */
249 }
250 }
251 }
252
253 type_datum_t *declare_type(unsigned char primary, unsigned char isattr) {
254 char *id, *dest_id = NULL;
255 type_datum_t *typdatum, *dest_typdatum = NULL;
256 int retval;
257 uint32_t value = 0;
258
259 id = (char *) queue_remove(id_queue);
260 if (!id) {
261 yyerror("no type/attribute name?");
262 return NULL;
263 }
264 if (strcmp(id, "self") == 0) {
265 yyerror("'self' is a reserved type name and may not be declared.");
266 return NULL;
267 }
268
269 typdatum = (type_datum_t *) malloc(sizeof(type_datum_t));
270 if (!typdatum) {
271 yyerror("Out of memory!");
272 free(id);
273 return NULL;
274 }
275 type_datum_init(typdatum);
276 typdatum->primary = primary;
277 typdatum->isattr = isattr;
278
279 retval = declare_symbol(SYM_TYPES, id, typdatum, &value, &value);
280 if (retval == 0 || retval == 1) {
281 if (typdatum->primary) {
282 typdatum->value = value;
283 }
284 if ((dest_id = strdup(id)) == NULL) {
285 yyerror("Out of memory!");
286 return NULL;
287 }
288 if ((dest_typdatum = get_local_type(dest_id, value)) == NULL) {
289 yyerror("Out of memory!");
290 return NULL;
291 }
292 }
293 else {
294 /* error occurred (can't have duplicate type declarations) */
295 free(id);
296 type_datum_destroy(typdatum);
297 free(typdatum);
298 }
299 switch(retval) {
300 case -3: {
301 yyerror("Out of memory!");
302 return NULL;
303 }
304 case -2: {
305 yyerror2("duplicate declaration of type/attribute");
306 return NULL;
307 }
308 case -1: {
309 yyerror("could not declare attribute here");
310 return NULL;
311 }
312 case 0:
313 case 1: {
314 return dest_typdatum;
315 }
316 default: {
317 assert(0); /* should never get here */
318 }
319 }
320 }
321
322 user_datum_t *declare_user(void) {
323 char *id = queue_remove(id_queue), *dest_id = NULL;
324 user_datum_t *user = NULL, *dest_user = NULL;
325 int retval;
326 uint32_t value = 0;
327
328 if (id == NULL) {
329 yyerror("no user name");
330 return NULL;
331 }
332 if ((user = (user_datum_t *) malloc(sizeof(*user))) == NULL) {
333 yyerror("Out of memory!");
334 free(id);
335 return NULL;
336 }
337 user_datum_init(user);
338
339 retval = declare_symbol(SYM_USERS, id, (hashtab_datum_t*)user, &value, &value);
340
341 if (retval == 0) {
342 user->value = value;
343 if ((dest_id = strdup(id)) == NULL) {
344 yyerror("Out of memory!");
345 return NULL;
346 }
347 }
348 else {
349 /* this user was already declared in this module, or error */
350 dest_id = id;
351 user_datum_destroy(user);
352 free(user);
353 }
354 if (retval == 0 || retval == 1) {
355 /* create a new user_datum_t for this decl, if necessary */
356 hashtab_t users_tab;
357 assert(stack_top->type == 1);
358 if (stack_top->parent == NULL) {
359 /* in parent, so use global symbol table */
360 users_tab = policydbp->p_users.table;
361 }
362 else {
363 users_tab = stack_top->decl->p_users.table;
364 }
365 dest_user = (user_datum_t *) hashtab_search(users_tab, dest_id);
366 if (dest_user == NULL) {
367 if ((dest_user = (user_datum_t *) malloc(sizeof(*dest_user))) == NULL) {
368 yyerror("Out of memory!");
369 free(dest_id);
370 return NULL;
371 }
372 user_datum_init(dest_user);
373 dest_user->value = value;
374 if (hashtab_insert(users_tab, dest_id, dest_user)) {
375 yyerror("Out of memory!");
376 free(dest_id);
377 user_datum_destroy(dest_user);
378 free(dest_user);
379 return NULL;
380 }
381 }
382 else {
383 free(dest_id);
384 }
385 }
386 else {
387 free(dest_id);
388 }
389 switch(retval) {
390 case -3: {
391 yyerror("Out of memory!");
392 return NULL;
393 }
394 case -2: {
395 yyerror("duplicate declaration of user");
396 return NULL;
397 }
398 case -1: {
399 yyerror("could not declare user here");
400 return NULL;
401 }
402 case 0: {
403 return dest_user;
404 }
405 case 1: {
406 return dest_user; /* user already declared for this block */
407 }
408 default: {
409 assert(0); /* should never get here */
410 }
411 }
412 }
413
414 /* Return a type_datum_t for the local avrule_decl with the given ID.
415 * If it does not exist, create one with the same value as 'value'.
416 * This function assumes that the ID is within scope. c.f.,
417 * is_id_in_scope().
418 *
419 * NOTE: this function usurps ownership of id afterwards. The caller
420 * shall not reference it nor free() it afterwards.
421 */
422 type_datum_t *get_local_type(char *id, uint32_t value) {
423 type_datum_t *dest_typdatum;
424 hashtab_t types_tab;
425 assert(stack_top->type == 1);
426 if (stack_top->parent == NULL) {
427 /* in parent, so use global symbol table */
428 types_tab = policydbp->p_types.table;
429 }
430 else {
431 types_tab = stack_top->decl->p_types.table;
432 }
433 if ((dest_typdatum = hashtab_search(types_tab, id)) == NULL) {
434 dest_typdatum = (type_datum_t *) malloc(sizeof(type_datum_t));
435 if (dest_typdatum == NULL) {
436 free(id);
437 return NULL;
438 }
439 type_datum_init(dest_typdatum);
440 dest_typdatum->value = value;
441 if (hashtab_insert(types_tab, id, dest_typdatum)) {
442 free(id);
443 type_datum_destroy(dest_typdatum);
444 free(dest_typdatum);
445 return NULL;
446 }
447
448 } else {
449 free(id);
450 }
451 return dest_typdatum;
452 }
453
454 /* Given the current parse stack, returns 1 if a requirement would be
455 * allowed here or 0 if not. For example, the ELSE branch may never
456 * have its own requirements.
457 */
458 static int is_require_allowed(void) {
459 if (stack_top->type == 1 &&
460 !stack_top->in_else) {
461 return 1;
462 }
463 return 0;
464 }
465
466 /* Attempt to require a symbol within the current scope. If currently
467 * within an optional (and not its else branch), add the symbol to the
468 * required list. Return 0 on success, 1 if caller needs to free()
469 * datum. If symbols may not be declared here return -1. For duplicate
470 * declarations return -2. For all else, including out of memory,
471 * return -3.. Note that dest_value and datum_value might not be
472 * restricted pointers.
473 */
474 int require_symbol(uint32_t symbol_type,
475 hashtab_key_t key, hashtab_datum_t datum,
476 uint32_t *dest_value, uint32_t *datum_value) {
477 avrule_decl_t *decl = stack_top->decl;
478 int retval;
479
480 /* first check that symbols may be required here */
481 if (!is_require_allowed()) {
482 return -1;
483 }
484 retval = symtab_insert(policydbp, symbol_type, key, datum,
485 SCOPE_REQ, decl->decl_id,
486 dest_value);
487 if (retval == 1) {
488 /* because C has no polymorphism, make the
489 * [outrageous] assumption that the first field of all
490 * symbol table data is a uint32_t representing its
491 * value */
492 uint32_t *v = (uint32_t *) hashtab_search(policydbp->symtab[symbol_type].table, key);
493 assert(v != NULL);
494 *dest_value = *v;
495 }
496 else if (retval == -2) {
497 return -2;
498 }
499 else if (retval == -1 || retval == -ENOMEM) {
500 return -3;
501 }
502 if (datum_value != NULL) {
503 if (ebitmap_set_bit(decl->required.scope + symbol_type,
504 *datum_value - 1,
505 1)) {
506 return -3;
507 }
508 }
509 return retval;
510 }
511
512 int add_perm_to_class(uint32_t perm_value, uint32_t class_value) {
513 avrule_decl_t *decl = stack_top->decl;
514 scope_index_t *scope;
515
516 assert(perm_value >= 1);
517 assert(class_value >= 1);
518 scope = &decl->required;
519 if (class_value > scope->class_perms_len) {
520 int i;
521 ebitmap_t *new_map = realloc(scope->class_perms_map,
522 class_value * sizeof(*new_map));
523 if (new_map == NULL) {
524 return -1;
525 }
526 scope->class_perms_map = new_map;
527 for (i = scope->class_perms_len; i < class_value; i++) {
528 ebitmap_init(scope->class_perms_map + i);
529 }
530 scope->class_perms_len = class_value;
531 }
532 if (ebitmap_set_bit(scope->class_perms_map + class_value - 1,
533 perm_value - 1, 1)) {
534 return -1;
535 }
536 return 0;
537 }
538
539 static int perm_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p __attribute__ ((unused)))
540 {
541 if (key)
542 free(key);
543 free(datum);
544 return 0;
545 }
546
547 static void class_datum_destroy(class_datum_t *cladatum) {
548 if (cladatum != NULL) {
549 hashtab_map(cladatum->permissions.table, perm_destroy, NULL);
550 hashtab_destroy(cladatum->permissions.table);
551 free(cladatum);
552 }
553 }
554
555 int require_class(int pass)
556 {
557 char *class_id = queue_remove(id_queue);
558 char *perm_id = NULL;
559 class_datum_t *datum = NULL;
560 perm_datum_t *perm = NULL;
561 int ret, ret2;
562
563 if (pass == 2) {
564 free(class_id);
565 while ((perm_id = queue_remove(id_queue)) != NULL)
566 free(perm_id);
567 return 0;
568 }
569
570 /* first add the class if it is not already there */
571 if (class_id == NULL) {
572 yyerror("no class name for class definition?");
573 return -1;
574 }
575
576 if ((datum = calloc(1, sizeof(*datum))) == NULL ||
577 symtab_init(&datum->permissions, PERM_SYMTAB_SIZE)) {
578 yyerror("Out of memory!");
579 goto cleanup;
580 }
581 ret = require_symbol(SYM_CLASSES, class_id, datum, &datum->value, &datum->value);
582 switch (ret) {
583 case -3: {
584 yyerror("Out of memory!");
585 free(class_id);
586 class_datum_destroy(datum);
587 goto cleanup;
588 }
589 case -2: {
590 yyerror("duplicate declaration of class");
591 free(class_id);
592 class_datum_destroy(datum);
593 goto cleanup;
594 }
595 case -1: {
596 yyerror("could not require class here");
597 free(class_id);
598 class_datum_destroy(datum);
599 goto cleanup;
600 }
601 case 0: {
602 /* a new class was added; reindex everything */
603 if (policydb_index_classes(policydbp)) {
604 yyerror("Out of memory!");
605 goto cleanup;
606 }
607 break;
608 }
609 case 1: {
610 class_datum_destroy(datum);
611 datum = hashtab_search(policydbp->p_classes.table, class_id);
612 assert(datum); /* the class datum should have existed */
613 free(class_id);
614 break;
615 }
616 default: {
617 assert(0); /* should never get here */
618 }
619 }
620
621 /* now add each of the permissions to this class's requirements */
622 while ((perm_id = queue_remove(id_queue)) != NULL) {
623 if ((perm = malloc(sizeof(*perm))) == NULL) {
624 yyerror("Out of memory!");
625 free(perm_id);
626 goto cleanup;
627 }
628 ret2 = hashtab_insert(datum->permissions.table, perm_id, perm);
629 switch (ret2) {
630 case HASHTAB_PRESENT: {
631 perm = hashtab_search(datum->permissions.table, perm_id);
632 assert(perm != NULL); /* reuse existing permission */
633 free(perm_id);
634 perm_id = NULL;
635 break;
636 }
637 case HASHTAB_SUCCESS: {
638 perm->value = ++datum->permissions.nprim;
639 break;
640 }
641 default: {
642 yyerror("Out of memory!");
643 free(perm_id);
644 free(perm);
645 goto cleanup;
646 }
647 }
648 if (add_perm_to_class(perm->value, datum->value) == -1) {
649 yyerror("Out of memory!");
650 free(perm_id);
651 free(perm);
652 goto cleanup;
653 }
654 }
655 return 0;
656 cleanup:
657 return -1;
658 }
659
660
661 int require_role(int pass)
662 {
663 char *id = queue_remove(id_queue);
664 role_datum_t *role = NULL;
665 int retval;
666 if (pass == 2) {
667 free(id);
668 return 0;
669 }
670 if (id == NULL) {
671 yyerror("no role name");
672 return -1;
673 }
674 if ((role = malloc(sizeof (*role))) == NULL) {
675 free(id);
676 yyerror("Out of memory!");
677 return -1;
678 }
679 role_datum_init(role);
680 retval = require_symbol(SYM_ROLES, id, (hashtab_datum_t *) role, &role->value, &role->value);
681 if (retval != 0) {
682 free(id);
683 role_datum_destroy(role);
684 free(role);
685 }
686 switch (retval) {
687 case -3: {
688 yyerror("Out of memory!");
689 return -1;
690 }
691 case -2: {
692 yyerror("duplicate declaration of role");
693 return -1;
694 }
695 case -1: {
696 yyerror("could not require role here");
697 return -1;
698 }
699 case 0: {
700 /* all roles dominate themselves */
701 ebitmap_set_bit(&role->dominates, role->value - 1, 1);
702 return 0;
703 }
704 case 1: {
705 return 0; /* role already required */
706 }
707 default: {
708 assert(0); /* should never get here */
709 }
710 }
711 }
712
713
714 static int require_type_or_attribute(int pass, unsigned char isattr) {
715 char *id = queue_remove(id_queue);
716 type_datum_t *type = NULL;
717 int retval;
718 if (pass == 2) {
719 free(id);
720 return 0;
721 }
722 if (id == NULL) {
723 yyerror("no type name");
724 return -1;
725 }
726 if ((type = malloc(sizeof(*type))) == NULL) {
727 free(id);
728 yyerror("Out of memory!");
729 return -1;
730 }
731 type_datum_init(type);
732 type->primary = 1;
733 type->isattr = isattr;
734 retval = require_symbol(SYM_TYPES, id, (hashtab_datum_t *) type, &type->value, &type->value);
735 if (retval != 0) {
736 free(id);
737 free(type);
738 }
739 switch (retval) {
740 case -3: {
741 yyerror("Out of memory!");
742 return -1;
743 }
744 case -2: {
745 yyerror("duplicate declaration of type/attribute");
746 return -1;
747 }
748 case -1: {
749 yyerror("could not require type/attribute here");
750 return -1;
751 }
752 case 0: {
753 return 0;
754 }
755 case 1: {
756 return 0; /* type already required */
757 }
758 default: {
759 assert(0); /* should never get here */
760 }
761 }
762 }
763
764 int require_type(int pass) {
765 return require_type_or_attribute(pass, 0);
766 }
767
768 int require_attribute(int pass) {
769 return require_type_or_attribute(pass, 1);
770 }
771
772 int require_user(int pass)
773 {
774 char *id = queue_remove(id_queue);
775 user_datum_t *user = NULL;
776 int retval;
777 if (pass == 2) {
778 free(id);
779 return 0;
780 }
781 if (id == NULL) {
782 yyerror("no user name");
783 return -1;
784 }
785 if ((user = malloc(sizeof (*user))) == NULL) {
786 free(id);
787 yyerror("Out of memory!");
788 return -1;
789 }
790 user_datum_init(user);
791 retval = require_symbol(SYM_USERS, id, (hashtab_datum_t *) user, &user->value, &user->value);
792 if (retval != 0) {
793 free(id);
794 user_datum_destroy(user);
795 }
796 switch (retval) {
797 case -3: {
798 yyerror("Out of memory!");
799 return -1;
800 }
801 case -2: {
802 yyerror("duplicate declaration of user");
803 return -1;
804 }
805 case -1: {
806 yyerror("could not require user here");
807 return -1;
808 }
809 case 0: {
810 return 0;
811 }
812 case 1: {
813 return 0; /* user already required */
814 }
815 default: {
816 assert(0); /* should never get here */
817 }
818 }
819 }
820
821 int require_bool(int pass)
822 {
823 char *id = queue_remove(id_queue);
824 cond_bool_datum_t *booldatum = NULL;
825 int retval;
826 if (pass == 2) {
827 free(id);
828 return 0;
829 }
830 if (id == NULL) {
831 yyerror("no boolean name");
832 return -1;
833 }
834 if ((booldatum = calloc(1, sizeof (*booldatum))) == NULL) {
835 cond_destroy_bool(id, booldatum, NULL);
836 yyerror("Out of memory!");
837 return -1;
838 }
839 retval = require_symbol(SYM_BOOLS, id, (hashtab_datum_t *) booldatum, &booldatum->value, &booldatum->value);
840 if (retval != 0) {
841 cond_destroy_bool(id, booldatum, NULL);
842 }
843 switch (retval) {
844 case -3: {
845 yyerror("Out of memory!");
846 return -1;
847 }
848 case -2: {
849 yyerror("duplicate declaration of boolean");
850 return -1;
851 }
852 case -1: {
853 yyerror("could not require boolean here");
854 return -1;
855 }
856 case 0: {
857 return 0;
858 }
859 case 1: {
860 return 0; /* boolean already required */
861 }
862 default: {
863 assert(0); /* should never get here */
864 }
865 }
866 }
867
868 static int is_scope_in_stack(scope_datum_t *scope, scope_stack_t *stack) {
869 int i;
870 if (stack == NULL) {
871 return 0; /* no matching scope found */
872 }
873 if (stack->type == 1) {
874 avrule_decl_t *decl = stack->decl;
875 for (i = 0; i < scope->decl_ids_len; i++) {
876 if (scope->decl_ids[i] == decl->decl_id) {
877 return 1;
878 }
879 }
880 }
881 else {
882 /* note that conditionals can't declare or require
883 * symbols, so skip this level */
884 }
885
886 /* not within scope of this stack, so try its parent */
887 return is_scope_in_stack(scope, stack->parent);
888 }
889
890 int is_id_in_scope(uint32_t symbol_type, hashtab_key_t id) {
891 scope_datum_t *scope = (scope_datum_t *) hashtab_search(policydbp->scope[symbol_type].table, id);
892 if (scope == NULL) {
893 return 1; /* id is not known, so return success */
894 }
895 return is_scope_in_stack(scope, stack_top);
896 }
897
898 static int is_perm_in_scope_index(uint32_t perm_value, uint32_t class_value, scope_index_t *scope) {
899 if (class_value > scope->class_perms_len) {
900 return 1;
901 }
902 if (ebitmap_get_bit(scope->class_perms_map + class_value - 1,
903 perm_value - 1)) {
904 return 1;
905 }
906 return 0;
907 }
908
909 static int is_perm_in_stack(uint32_t perm_value, uint32_t class_value, scope_stack_t *stack) {
910 if (stack == NULL) {
911 return 0; /* no matching scope found */
912 }
913 if (stack->type == 1) {
914 avrule_decl_t *decl = stack->decl;
915 if (is_perm_in_scope_index(perm_value, class_value, &decl->required) ||
916 is_perm_in_scope_index(perm_value, class_value, &decl->declared)) {
917 return 1;
918 }
919 }
920 else {
921 /* note that conditionals can't declare or require
922 * symbols, so skip this level */
923 }
924
925 /* not within scope of this stack, so try its parent */
926 return is_perm_in_stack(perm_value, class_value, stack->parent);
927 }
928
929 int is_perm_in_scope(hashtab_key_t perm_id, hashtab_key_t class_id) {
930 class_datum_t *cladatum = (class_datum_t *) hashtab_search(policydbp->p_classes.table,
931 class_id);
932 perm_datum_t *perdatum;
933 if (cladatum == NULL) {
934 return 1;
935 }
936 perdatum = (perm_datum_t *) hashtab_search(cladatum->permissions.table,
937 perm_id);
938 if (perdatum == NULL) {
939 return 1;
940 }
941 return is_perm_in_stack(perdatum->value, cladatum->value, stack_top);
942 }
943
944 cond_list_t *get_current_cond_list(cond_list_t *cond) {
945 /* FIX ME: do something different here if in a nested
946 * conditional? */
947 avrule_decl_t *decl = stack_top->decl;
948 return get_decl_cond_list(policydbp, decl, cond);
949 }
950
951 /* Append the new conditional node to the existing ones. During
952 * expansion the list will be reversed -- i.e., the last AV rule will
953 * be the first one listed in the policy. This matches the behavior
954 * of the upstream compiler. */
955 void append_cond_list(cond_list_t *cond) {
956 cond_list_t *old_cond = get_current_cond_list(cond);
957 avrule_t *tmp;
958 assert(old_cond != NULL); /* probably out of memory */
959 if (old_cond->avtrue_list == NULL) {
960 old_cond->avtrue_list = cond->avtrue_list;
961 }
962 else {
963 for (tmp = old_cond->avtrue_list; tmp->next != NULL; tmp = tmp->next)
964 ;
965 tmp->next = cond->avtrue_list;
966 }
967 if (old_cond->avfalse_list == NULL) {
968 old_cond->avfalse_list = cond->avfalse_list;
969 }
970 else {
971 for (tmp = old_cond->avfalse_list; tmp->next != NULL; tmp = tmp->next)
972 ;
973 tmp->next = cond->avfalse_list;
974 }
975 }
976
977 void append_avrule(avrule_t *avrule) {
978 avrule_decl_t *decl = stack_top->decl;
979
980 /* currently avrules follow a completely different code path
981 * for handling avrules and compute types
982 * (define_cond_avrule_te_avtab, define_cond_compute_type);
983 * therefore there ought never be a conditional on top of the
984 * scope stack */
985 assert(stack_top->type == 1);
986
987 if (stack_top->last_avrule == NULL) {
988 decl->avrules = avrule;
989 }
990 else {
991 stack_top->last_avrule->next = avrule;
992 }
993 stack_top->last_avrule = avrule;
994 }
995
996 /* this doesn't actually append, but really prepends it */
997 void append_role_trans(role_trans_rule_t *role_tr_rules) {
998 avrule_decl_t *decl = stack_top->decl;
999
1000 /* role transitions are not allowed within conditionals */
1001 assert(stack_top->type == 1);
1002
1003 role_tr_rules->next = decl->role_tr_rules;
1004 decl->role_tr_rules = role_tr_rules;
1005 }
1006
1007 /* this doesn't actually append, but really prepends it */
1008 void append_role_allow(role_allow_rule_t *role_allow_rules) {
1009 avrule_decl_t *decl = stack_top->decl;
1010
1011 /* role allows are not allowed within conditionals */
1012 assert(stack_top->type == 1);
1013
1014 role_allow_rules->next = decl->role_allow_rules;
1015 decl->role_allow_rules = role_allow_rules;
1016 }
1017
1018 int begin_optional(int pass) {
1019 avrule_block_t *block = NULL;
1020 avrule_decl_t *decl;
1021 if (pass == 1) {
1022 /* allocate a new avrule block for this optional block */
1023 if ((block = avrule_block_create()) == NULL ||
1024 (decl = avrule_decl_create(next_decl_id)) == NULL) {
1025 goto cleanup;
1026 }
1027 block->branch_list = decl;
1028 last_block->next = block;
1029 }
1030 else {
1031 /* select the next block from the chain built during pass 1 */
1032 block = last_block->next;
1033 assert(block != NULL &&
1034 block->branch_list != NULL &&
1035 block->branch_list->decl_id == next_decl_id);
1036 decl = block->branch_list;
1037 }
1038 if (push_stack(1, block, decl) == -1) {
1039 goto cleanup;
1040 }
1041 stack_top->last_avrule = NULL;
1042 last_block = block;
1043 next_decl_id++;
1044 return 0;
1045 cleanup:
1046 yyerror("Out of memory!");
1047 avrule_block_destroy(block);
1048 return -1;
1049 }
1050
1051 int end_optional(int pass) {
1052 /* once nested conditionals are allowed, do the stack unfolding here */
1053 pop_stack();
1054 return 0;
1055 }
1056
1057 int begin_optional_else(int pass) {
1058 avrule_decl_t *decl;
1059 assert(stack_top->type == 1 && stack_top->in_else == 0);
1060 if (pass == 1) {
1061 /* allocate a new declaration and add it to the
1062 * current chain */
1063 if ((decl = avrule_decl_create(next_decl_id)) == NULL) {
1064 yyerror("Out of memory!");
1065 return -1;
1066 }
1067 stack_top->decl->next = decl;
1068 }
1069 else {
1070 /* pick the (hopefully last) declaration of this
1071 avrule block, built from pass 1 */
1072 decl = stack_top->decl->next;
1073 assert(decl != NULL &&
1074 decl->next == NULL &&
1075 decl->decl_id == next_decl_id);
1076 }
1077 stack_top->in_else = 1;
1078 stack_top->decl = decl;
1079 stack_top->last_avrule = NULL;
1080 next_decl_id++;
1081 return 0;
1082 }
1083
1084 static int copy_requirements(avrule_decl_t *dest, scope_stack_t *stack) {
1085 int i;
1086 if (stack == NULL) {
1087 return 0;
1088 }
1089 if (stack->type == 1) {
1090 scope_index_t *src_scope = &stack->decl->required;
1091 scope_index_t *dest_scope = &dest->required;
1092 for (i = 0; i < SYM_NUM; i++) {
1093 ebitmap_t *src_bitmap = &src_scope->scope[i];
1094 ebitmap_t *dest_bitmap = &dest_scope->scope[i];
1095 if (ebitmap_union(dest_bitmap, src_bitmap)) {
1096 yyerror("Out of memory!");
1097 return -1;
1098 }
1099 }
1100 /* now copy class permissions */
1101 if (src_scope->class_perms_len > dest_scope->class_perms_len) {
1102 ebitmap_t *new_map = realloc(dest_scope->class_perms_map,
1103 src_scope->class_perms_len * sizeof(*new_map));
1104 if (new_map == NULL) {
1105 yyerror("Out of memory!");
1106 return -1;
1107 }
1108 dest_scope->class_perms_map = new_map;
1109 for (i = dest_scope->class_perms_len; i < src_scope->class_perms_len; i++) {
1110 ebitmap_init(dest_scope->class_perms_map + i);
1111 }
1112 dest_scope->class_perms_len = src_scope->class_perms_len;
1113 }
1114 for (i = 0; i < src_scope->class_perms_len; i++) {
1115 ebitmap_t *src_bitmap = &src_scope->class_perms_map[i];
1116 ebitmap_t *dest_bitmap = &dest_scope->class_perms_map[i];
1117 if (ebitmap_union(dest_bitmap, src_bitmap)) {
1118 yyerror("Out of memory!");
1119 return -1;
1120 }
1121 }
1122 }
1123 return copy_requirements(dest, stack->parent);
1124 }
1125
1126 /* During pass 1, check that at least one thing was required within
1127 * this block, for those places where a REQUIRED is necessary. During
1128 * pass 2, have this block inherit its parents' requirements. Return
1129 * 0 on success, -1 on failure. */
1130 int end_avrule_block(int pass) {
1131 int i, j;
1132 avrule_decl_t *decl = stack_top->decl;
1133 ebitmap_node_t *node;
1134 assert(stack_top->type == 1);
1135 if (pass == 2) {
1136 /* this avrule_decl inherits all of its parents'
1137 * requirements */
1138 if (copy_requirements(decl, stack_top->parent) == -1) {
1139 return -1;
1140 }
1141 return 0;
1142 }
1143 if (!stack_top->in_else) {
1144 /* non-ELSE branches must have at least one thing required */
1145 for (i = 0; i < SYM_NUM; i++) {
1146 ebitmap_t *bitmap = &decl->required.scope[i];
1147 ebitmap_for_each_bit(bitmap, node, j) {
1148 if (ebitmap_node_get_bit(node, j)) {
1149 /* at least one thing was required */
1150 return 0;
1151 }
1152 }
1153 }
1154 /* this av did not require anything, which is an error */
1155 yyerror("This block has no require section.");
1156 return -1;
1157 }
1158 return 0;
1159 }
1160
1161 /* Push a new scope on to the stack and update the 'last' pointer.
1162 * Return 0 on success, -1 if out * of memory. */
1163 static int push_stack(int stack_type, ...) {
1164 scope_stack_t *s = calloc(1, sizeof(*s));
1165 va_list ap;
1166 if (s == NULL) {
1167 return -1;
1168 }
1169 va_start(ap, stack_type);
1170 switch (s->type = stack_type) {
1171 case 1: {
1172 s->u.avrule = va_arg(ap, avrule_block_t *);
1173 s->decl = va_arg(ap, avrule_decl_t *);
1174 break;
1175 }
1176 case 2: {
1177 s->u.cond_list = va_arg(ap, cond_list_t *);
1178 break;
1179 }
1180 default:
1181 /* invalid stack type given */
1182 assert(0);
1183 }
1184 va_end(ap);
1185 s->parent = stack_top;
1186 s->child = NULL;
1187 stack_top = s;
1188 return 0;
1189 }
1190
1191 /* Pop off the most recently added from the stack. Update the 'last'
1192 * pointer. */
1193 static void pop_stack(void) {
1194 scope_stack_t *parent;
1195 assert(stack_top != NULL);
1196 parent = stack_top->parent;
1197 if (parent != NULL) {
1198 parent->child = NULL;
1199 }
1200 free(stack_top);
1201 stack_top = parent;
1202 }
0 /* Author : Joshua Brindle <jbrindle@tresys.com>
1 * Karl MacMillan <kmacmillan@tresys.com>
2 * Jason Tang <jtang@tresys.com>
3 * Added support for binary policy modules
4 *
5 * Copyright (C) 2004 - 2005 Tresys Technology, LLC
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, version 2.
9 */
10
11 #ifndef MODULE_COMPILER_H
12 #define MODULE_COMPILER_H
13
14 #include <sepol/hashtab.h>
15
16 /* Called when checkpolicy begins to parse a policy -- either at the
17 * very beginning for a kernel/base policy, or after the module header
18 * for policy modules. Initialize the memory structures within.
19 * Return 0 on success, -1 on error. */
20 int define_policy(int pass, int module_header_given);
21
22 /* Declare a symbol declaration to the current avrule_decl. Check
23 * that insertion is allowed here and that the symbol does not already
24 * exist. Returns 0 on success, 1 if symbol was already there (caller
25 * needs to free() the datum), -1 if declarations not allowed, -2 for
26 * duplicate declarations, -3 for all else.
27 */
28 int declare_symbol(uint32_t symbol_type,
29 hashtab_key_t key, hashtab_datum_t datum,
30 uint32_t *dest_value, uint32_t *datum_value);
31
32 role_datum_t *declare_role(void);
33 type_datum_t *declare_type(unsigned char primary, unsigned char isattr);
34 user_datum_t *declare_user(void);
35
36 type_datum_t *get_local_type(char *id, uint32_t value);
37
38 /* Add a symbol to the current avrule_block's require section. Note
39 * that a module may not both declare and require the same symbol.
40 * Returns 0 on success, -1 on error. */
41 int require_symbol(uint32_t symbol_type,
42 hashtab_key_t key, hashtab_datum_t datum,
43 uint32_t *dest_value, uint32_t *datum_value);
44
45 /* Enable a permission for a class within the current avrule_decl.
46 * Return 0 on success, -1 if out of memory. */
47 int add_perm_to_class(uint32_t perm_value, uint32_t class_value);
48
49 /* Functions called from REQUIRE blocks. Add the first symbol on the
50 * id_queue to this avrule_decl's scope if not already there.
51 * c.f. require_symbol(). */
52 int require_class(int pass);
53 int require_role(int pass);
54 int require_type(int pass);
55 int require_attribute(int pass);
56 int require_user(int pass);
57 int require_bool(int pass);
58
59 /* Check if an identifier is within the scope of the current
60 * declaration or any of its parents. Return 1 if it is, 0 if not.
61 * If the identifier is not known at all then return 1 (truth). */
62 int is_id_in_scope(uint32_t symbol_type, hashtab_key_t id);
63
64 /* Check if a particular permission is within the scope of the current
65 * declaration or any of its parents. Return 1 if it is, 0 if not.
66 * If the identifier is not known at all then return 1 (truth). */
67 int is_perm_in_scope(hashtab_key_t perm_id, hashtab_key_t class_id);
68
69 /* Search the current avrules block for a conditional with the same
70 * expression as 'cond'. If the conditional does not exist then
71 * create one. Either way, return the conditional. */
72 cond_list_t *get_current_cond_list(cond_list_t *cond);
73
74 /* Append rule to the current avrule_block. */
75 void append_cond_list(cond_list_t *cond);
76 void append_avrule(avrule_t *avrule);
77 void append_role_trans(role_trans_rule_t *role_tr_rules);
78 void append_role_allow(role_allow_rule_t *role_allow_rules);
79
80 /* Create a new optional block and add it to the global policy.
81 * During the second pass resolve the block's requirements. Return 0
82 * on success, -1 on error.
83 */
84 int begin_optional(int pass);
85 int end_optional(int pass);
86
87 /* ELSE blocks are similar to normal blocks with the following two
88 * limitations:
89 * - no declarations are allowed within else branches
90 * - no REQUIRES are allowed; the else branch inherits the parent's
91 * requirements
92 */
93 int begin_optional_else(int pass);
94
95 /* Called whenever existing an avrule block. Check that the block had
96 * a non-empty REQUIRE section. If so pop the block off of the scop
97 * stack and return 0. If not then send an error to yyerror and
98 * return -1. */
99 int end_avrule_block(int pass);
100
101 #endif
1111 *
1212 * Added conditional policy language extensions
1313 *
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 *
1420 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
15 * Copyright (C) 2003 - 2004 Tresys Technology, LLC
21 * Copyright (C) 2003 - 2005 Tresys Technology, LLC
1622 * This program is free software; you can redistribute it and/or modify
1723 * it under the terms of the GNU General Public License as published by
1824 * the Free Software Foundation, version 2.
2228
2329 %{
2430 #include <sys/types.h>
31 #include <assert.h>
32 #include <stdarg.h>
2533 #include <stdint.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
2637 #include <sys/socket.h>
2738 #include <netinet/in.h>
2839 #include <arpa/inet.h>
2940 #include <stdlib.h>
3041
42 #include <sepol/expand.h>
3143 #include <sepol/policydb.h>
3244 #include <sepol/services.h>
3345 #include <sepol/conditional.h>
3547 #include <sepol/hierarchy.h>
3648 #include "queue.h"
3749 #include "checkpolicy.h"
50 #include "module_compiler.h"
3851
3952 /*
4053 * We need the following so we have a valid error return code in yacc
4154 * when we have a parse error for a conditional rule. We can't check
4255 * for NULL (ie 0) because that is a potentially valid return.
4356 */
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
4659
4760 #define TRUE 1
4861 #define FALSE 0
4962
5063 policydb_t *policydbp;
5164 queue_t id_queue = 0;
52 unsigned int pass;
65 static unsigned int pass;
5366 char *curfile = 0;
54 unsigned int curline;
5567
5668 extern unsigned long policydb_lineno;
69 extern unsigned long source_lineno;
70 extern unsigned int policydb_errors;
71 extern unsigned int policyvers;
5772
5873 extern char yytext[];
5974 extern int yylex(void);
6075 extern int yywarn(char *msg);
6176 extern int yyerror(char *msg);
6277
63 static char errormsg[255];
78 #define ERRORMSG_LEN 255
79 static char errormsg[ERRORMSG_LEN + 1] = {0};
6480
6581 static int insert_separator(int push);
6682 static int insert_id(char *id,int push);
87103 static int define_role_allow(void);
88104 static int define_constraint(constraint_expr_t *expr);
89105 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 );
92108 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);
98112 static uintptr_t define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2);
99113 static int define_user(void);
100114 static int parse_security_context(context_struct_t *c);
106120 static int define_netif_context(void);
107121 static int define_ipv4_node_context(unsigned int addr, unsigned int mask);
108122 static int define_ipv6_node_context(void);
123
124 typedef int (* require_func_t)();
125
109126 %}
110127
111128 %union {
112129 unsigned int val;
113130 uintptr_t valptr;
114131 void *ptr;
132 require_func_t require_func;
115133 }
116134
117135 %type <ptr> cond_expr cond_expr_prim cond_pol_list
120138 %type <ptr> role_def roles
121139 %type <valptr> cexpr cexpr_prim op role_mls_op
122140 %type <val> ipv4_addr_def number
141 %type <require_func> require_decl_def
123142
124143 %token PATH
125144 %token CLONE
174193 %token EQUALS
175194 %token NOTEQUAL
176195 %token IPV6_ADDR
196 %token MODULE VERSION_IDENTIFIER REQUIRE OPTIONAL
177197
178198 %left OR
179199 %left XOR
181201 %right NOT
182202 %left EQUALS NOTEQUAL
183203 %%
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; }}
186211 opt_mls te_rbac users opt_constraints
187212 { 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;}}
189214 initial_sid_contexts opt_fs_contexts fs_uses opt_genfs_contexts net_contexts
190215 ;
191216 classes : class_def
277302 ;
278303 te_rbac_decl : te_decl
279304 | rbac_decl
305 | cond_stmt_def
280306 | ';'
281307 ;
282308 rbac_decl : role_type_def
292318 | transition_def
293319 | range_trans_def
294320 | te_avtab_def
295 | cond_stmt_def
296321 ;
297322 attribute_def : ATTRIBUTE identifier ';'
298323 { if (define_attrib()) return -1;}
320345 { if (insert_id("F",0)) return -1; }
321346 ;
322347 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; }}
324349 | 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; }}
326351 | 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; }}
328353 | 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; }}
330355 | IF cond_expr '{' '}' ELSE '{' '}'
331356 /* do nothing */
332357 | IF cond_expr '{' '}'
360385 if ($$ == COND_ERR) return -1; }
361386 ;
362387 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);}
364389 | 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); }
366391 ;
367392 cond_rule_def : cond_transition_def
368393 { $$ = $1; }
370395 { $$ = $1; }
371396 ;
372397 cond_transition_def : TYPE_TRANSITION names names ':' names identifier ';'
373 { $$ = define_cond_compute_type(AVTAB_TRANSITION) ;
398 { $$ = define_cond_compute_type(AVRULE_TRANSITION) ;
374399 if ($$ == COND_ERR) return -1;}
375400 | TYPE_MEMBER names names ':' names identifier ';'
376 { $$ = define_cond_compute_type(AVTAB_MEMBER) ;
401 { $$ = define_cond_compute_type(AVRULE_MEMBER) ;
377402 if ($$ == COND_ERR) return -1;}
378403 | TYPE_CHANGE names names ':' names identifier ';'
379 { $$ = define_cond_compute_type(AVTAB_CHANGE) ;
404 { $$ = define_cond_compute_type(AVRULE_CHANGE) ;
380405 if ($$ == COND_ERR) return -1;}
381406 ;
382407 cond_te_avtab_def : cond_allow_def
389414 { $$ = $1; }
390415 ;
391416 cond_allow_def : ALLOW names names ':' names names ';'
392 { $$ = define_cond_te_avtab(AVTAB_ALLOWED) ;
417 { $$ = define_cond_te_avtab(AVRULE_ALLOWED) ;
393418 if ($$ == COND_ERR) return -1; }
394419 ;
395420 cond_auditallow_def : AUDITALLOW names names ':' names names ';'
396 { $$ = define_cond_te_avtab(AVTAB_AUDITALLOW) ;
421 { $$ = define_cond_te_avtab(AVRULE_AUDITALLOW) ;
397422 if ($$ == COND_ERR) return -1; }
398423 ;
399424 cond_auditdeny_def : AUDITDENY names names ':' names names ';'
400 { $$ = define_cond_te_avtab(AVTAB_AUDITDENY) ;
425 { $$ = define_cond_te_avtab(AVRULE_AUDITDENY) ;
401426 if ($$ == COND_ERR) return -1; }
402427 ;
403428 cond_dontaudit_def : DONTAUDIT names names ':' names names ';'
404 { $$ = define_cond_te_avtab(-AVTAB_AUDITDENY);
429 { $$ = define_cond_te_avtab(AVRULE_DONTAUDIT);
405430 if ($$ == COND_ERR) return -1; }
406431 ;
407432 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;}
409434 | TYPE_MEMBER names names ':' names identifier ';'
410 {if (define_compute_type(AVTAB_MEMBER)) return -1;}
435 {if (define_compute_type(AVRULE_MEMBER)) return -1;}
411436 | TYPE_CHANGE names names ':' names identifier ';'
412 {if (define_compute_type(AVTAB_CHANGE)) return -1;}
437 {if (define_compute_type(AVRULE_CHANGE)) return -1;}
413438 ;
414439 range_trans_def : RANGE_TRANSITION names names mls_range_def ';'
415440 { if (define_range_trans()) return -1; }
421446 | neverallow_def
422447 ;
423448 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; }
425450 ;
426451 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; }
428453 ;
429454 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; }
431456 ;
432457 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; }
434459 ;
435460 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; }
437462 ;
438463 role_type_def : ROLE identifier TYPES names ';'
439464 {if (define_role_types()) return -1;}
465 | ROLE identifier';'
466 {if (define_role_types()) return -1;}
440467 ;
441468 role_dominance : DOMINANCE '{' roles '}'
442469 ;
643670 {if (define_fs_use(SECURITY_FS_USE_TRANS)) return -1;}
644671 ;
645672 opt_genfs_contexts : genfs_contexts
646 |
673 |
647674 ;
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 ;
651678 genfs_context_def : GENFSCON identifier path '-' identifier security_context_def
652679 {if (define_genfs_context(1)) return -1;}
653680 | GENFSCON identifier path '-' '-' {insert_id("-", 0);} security_context_def
761788 ipv6_addr : IPV6_ADDR
762789 { if (insert_id(yytext,0)) return -1; }
763790 ;
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 ;
764861 %%
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
765882 #define DEBUG 1
766883
767884 static int insert_separator(int push)
804921 return 0;
805922 }
806923
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. */
808962 static int id_has_dot(char *id)
809963 {
810964 if (strchr(id, '.') >= id + 1) {
818972 char *id = 0;
819973 class_datum_t *datum = 0;
820974 int ret;
821
975 uint32_t value;
822976
823977 if (pass == 2) {
824978 id = queue_remove(id_queue);
842996 goto bad;
843997 }
844998 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;
8591022 return 0;
8601023
8611024 bad:
9381101 yyerror("no common name for common perm definition?");
9391102 return -1;
9401103 }
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 }
9411111 comdatum = (common_datum_t *) malloc(sizeof(common_datum_t));
9421112 if (!comdatum) {
9431113 yyerror("out of memory");
9441114 goto bad;
9451115 }
9461116 memset(comdatum, 0, sizeof(common_datum_t));
947 comdatum->value = ++policydbp->p_commons.nprim;
9481117 ret = hashtab_insert(policydbp->p_commons.table,
9491118 (hashtab_key_t) id, (hashtab_datum_t) comdatum);
9501119
9561125 yyerror("hash table overflow");
9571126 goto bad;
9581127 }
1128 comdatum->value = ++policydbp->p_commons.nprim;
9591129 if (symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE)) {
9601130 yyerror("out of memory");
9611131 goto bad;
11071277 yyerror("hash table overflow");
11081278 goto bad;
11091279 }
1280 if (add_perm_to_class(perdatum->value, cladatum->value)) {
1281 yyerror("out of memory");
1282 goto bad;
1283 }
11101284 }
11111285
11121286 return 0;
11261300 mls_level_t *level = 0;
11271301 level_datum_t *datum = 0, *aliasdatum = 0;
11281302 int ret;
1303 uint32_t value; /* dummy variable -- its value is never used */
11291304
11301305 if (!mlspol) {
11311306 yyerror("sensitivity definition in non-MLS configuration");
11541329 }
11551330 memset(level, 0, sizeof(mls_level_t));
11561331 level->sens = 0; /* actual value set in define_dominance */
1157 ++policydbp->p_levels.nprim;
11581332 ebitmap_init(&level->cat); /* actual value set in define_level */
11591333
11601334 datum = (level_datum_t *) malloc(sizeof(level_datum_t));
11661340 datum->isalias = FALSE;
11671341 datum->level = level;
11681342
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
11831366 while ((id = queue_remove(id_queue))) {
11841367 if (id_has_dot(id)) {
11851368 yyerror("sensitivity aliases may not contain periods");
11941377 aliasdatum->isalias = TRUE;
11951378 aliasdatum->level = level;
11961379
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 }
12091402 }
12101403
12111404 return 0;
12781471 char *id;
12791472 cat_datum_t *datum = 0, *aliasdatum = 0;
12801473 int ret;
1474 uint32_t value;
12811475
12821476 if (!mlspol) {
12831477 yyerror("category definition in non-MLS configuration");
13061500 }
13071501 memset(datum, 0, sizeof(cat_datum_t));
13081502 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;
13241527
13251528 while ((id = queue_remove(id_queue))) {
13261529 if (id_has_dot(id)) {
13361539 aliasdatum->isalias = TRUE;
13371540 aliasdatum->value = datum->value;
13381541
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 }
13511564 }
13521565
13531566 return 0;
14621675
14631676 static int define_attrib(void)
14641677 {
1465 char *id;
1466 type_datum_t *attr;
1467 int ret;
1468
1469
14701678 if (pass == 2) {
14711679 free(queue_remove(id_queue));
14721680 return 0;
14731681 }
14741682
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 }
15021733 return 0;
1734 cleanup:
1735 free(id);
1736 type_datum_destroy(aliasdatum);
1737 free(aliasdatum);
1738 return -1;
15031739 }
15041740
15051741 static int define_typealias(void)
15061742 {
15071743 char *id;
1508 type_datum_t *t, *aliasdatum;
1509 int ret;
1744 type_datum_t *t;
15101745
15111746 if (pass == 2) {
15121747 while ((id = queue_remove(id_queue)))
15201755 return -1;
15211756 }
15221757
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 }
15231795 t = hashtab_search(policydbp->p_types.table, id);
15241796 if (!t || t->isattr) {
15251797 sprintf(errormsg, "unknown type %s", id);
15271799 free(id);
15281800 return -1;
15291801 }
1802 if ((t = get_local_type(id, t->value)) == NULL) {
1803 yyerror("Out of memory!");
1804 return -1;
1805 }
15301806
15311807 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);
15331810 free(id);
1534 yyerror("type alias identifiers may not contain periods");
15351811 return -1;
15361812 }
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))) {
15921813 attr = hashtab_search(policydbp->p_types.table, id);
1593 if (!attr) {
1814 if (!attr) {
15941815 sprintf(errormsg, "attribute %s is not declared", id);
15951816 /* treat it as a fatal error */
15961817 yyerror(errormsg);
16191840 static int define_type(int alias)
16201841 {
16211842 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;
16251845
16261846 if (pass == 2) {
16271847 while ((id = queue_remove(id_queue)))
16331853 return 0;
16341854 }
16351855
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 }
16971864 }
16981865
16991866 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 }
17001872 attr = hashtab_search(policydbp->p_types.table, id);
17011873 if (!attr) {
17021874 sprintf(errormsg, "attribute %s is not declared", id);
1703 #if 1
1875
17041876 /* treat it as a fatal error */
17051877 yyerror(errormsg);
17061878 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
17271879 } else {
17281880 newattr = 0;
17291881 }
17341886 return -1;
17351887 }
17361888
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 }
17391893
17401894 ebitmap_set_bit(&attr->types, datum->value - 1, TRUE);
17411895 }
17431897 return 0;
17441898 }
17451899
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,
17821904 char *id,
1783 int *add)
1905 int *add,
1906 char starallowed)
17841907 {
17851908 type_datum_t *t;
1786 unsigned int i;
17871909
17881910 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;
17941917 free(id);
1918 *add = 1;
17951919 return 0;
17961920 }
17971921
17981922 if (strcmp(id, "~") == 0) {
1923 if (!starallowed) {
1924 yyerror("~ not allowed in this type of rule");
1925 return -1;
1926 }
17991927 /* 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;
18061929 free(id);
1930 *add = 1;
18071931 return 0;
18081932 }
18091933
18131937 return 0;
18141938 }
18151939
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 }
18161945 t = hashtab_search(policydbp->p_types.table, id);
18171946 if (!t) {
1818 sprintf(errormsg, "unknown type %s", id);
1947 snprintf(errormsg, ERRORMSG_LEN, "unknown type %s", id);
18191948 yyerror(errormsg);
18201949 free(id);
18211950 return -1;
18221951 }
18231952
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 }
18591959 free(id);
18601960 *add = 1;
18611961 return 0;
18621962 }
18631963
1864
1865 static int define_compute_type(int which)
1964 static int define_compute_type_helper(int which, avrule_t **rule)
18661965 {
18671966 char *id;
1868 avtab_key_t avkey;
1869 avtab_datum_t avdatum, *avdatump;
18701967 type_datum_t *datum;
18711968 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;
18762071
18772072 if (pass == 1) {
18782073 while ((id = queue_remove(id_queue)))
18852080 free(id);
18862081 return 0;
18872082 }
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)
20062112 {
20072113 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;
24512115
24522116 if (pass == 1) {
24532117 while ((id = queue_remove(id_queue)))
24562120 free(id);
24572121 while ((id = queue_remove(id_queue)))
24582122 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)))
24602143 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
24692237 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;
24762244 while ((id = queue_remove(id_queue))) {
24772245 if (strcmp(id, "self") == 0) {
2478 self = 1;
2246 avrule->flags |= RULE_SELF;
24792247 continue;
24802248 }
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 }
24852254
24862255 hiclass = 0;
2256 ebitmap_init(&tclasses);
24872257 while ((id = queue_remove(id_queue))) {
24882258 uint32_t classvalue;
24892259
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 }
24902265 cladatum = hashtab_search(policydbp->p_classes.table, id);
24912266 if (!cladatum) {
24922267 sprintf(errormsg, "unknown class %s used in rule", id);
24932268 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 &&
24982273 (cladatum->value >= SECCLASS_NETLINK_ROUTE_SOCKET &&
24992274 cladatum->value <= SECCLASS_NETLINK_DNRT_SOCKET)) {
25002275 sprintf(errormsg, "remapping class %s to netlink_socket "
25112286 free(id);
25122287 }
25132288
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
25212308 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))
25242312 continue;
25252313 cladatum = policydbp->class_val_to_struct[i];
25262314
25272315 if (strcmp(id, "*") == 0) {
25282316 /* set all permissions in the class */
2529 avp[i] = ~0;
2530 continue;
2317 cur_perms->data = ~0U;
2318 goto next;
25312319 }
25322320
25332321 if (strcmp(id, "~") == 0) {
25342322 /* complement the set */
2535 if (which == -AVTAB_AUDITDENY)
2323 if (which == AVRULE_DONTAUDIT)
25362324 yywarn("dontaudit rule with a ~?");
2537 avp[i] = ~avp[i];
2538 continue;
2325 cur_perms->data = ~cur_perms->data;
2326 goto next;
25392327 }
25402328
2541 perdatum = hashtab_search(cladatum->permissions.table,
2542 id);
2329 perdatum = hashtab_search(cladatum->permissions.table, id);
25432330 if (!perdatum) {
25442331 if (cladatum->comdatum) {
25452332 perdatum = hashtab_search(cladatum->comdatum->permissions.table,
25512338 if (!suppress)
25522339 yyerror(errormsg);
25532340 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);
25542350 }
2555
2556 avp[i] |= (1 << (perdatum->value - 1));
2351 next:
2352 cur_perms = cur_perms->next;
25572353 }
25582354
25592355 free(id);
25602356 }
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
26092358 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 }
26112381
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 }
26172387
26182388 static int define_te_avtab(int which)
26192389 {
26202390 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;
26292393
26302394 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 }
26392399 return 0;
26402400 }
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);
27792407 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;
28122408 }
28132409
28142410 static int define_role_types(void)
28152411 {
28162412 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;
28202415
28212416 if (pass == 1) {
28222417 while ((id = queue_remove(id_queue)))
28242419 return 0;
28252420 }
28262421
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 }
28542425 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
28592430
28602431 return 0;
28612432 }
28812452 yyerror("out of memory");
28822453 return NULL;
28832454 }
2884 if (ebitmap_or(&new->types, &r1->types, &r2->types)) {
2455 if (ebitmap_or(&new->types.types, &r1->types.types, &r2->types.types)) {
28852456 yyerror("out of memory");
28862457 return NULL;
28872458 }
28882459 if (!r1->value) {
28892460 /* free intermediate result */
2890 ebitmap_destroy(&r1->types);
2461 type_set_destroy(&r1->types);
28912462 ebitmap_destroy(&r1->dominates);
28922463 free(r1);
28932464 }
28942465 if (!r2->value) {
28952466 /* free intermediate result */
28962467 yyerror("right hand role is temporary?");
2897 ebitmap_destroy(&r2->types);
2468 type_set_destroy(&r2->types);
28982469 ebitmap_destroy(&r2->dominates);
28992470 free(r2);
29002471 }
29062477 {
29072478 role_datum_t *rdp = (role_datum_t *) arg;
29082479 role_datum_t *rdatum = (role_datum_t *) datum;
2480 ebitmap_t *types = NULL;
2481 ebitmap_node_t *node;
29092482 int i;
29102483
29112484 /* Don't bother to process against self role */
29152488 /* If a dominating role found */
29162489 if (ebitmap_get_bit(&(rdatum->dominates), rdp->value - 1))
29172490 {
2491 if (type_set_expand(&rdp->types, types, policydbp, 1))
2492 return -1;
29182493 /* 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))
29232496 ebitmap_set_bit(&rdatum->dominates, i, TRUE);
29242497 }
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);
29302501 }
29312502 }
29322503
29392510 {
29402511 role_datum_t *role;
29412512 char *role_id;
2513 ebitmap_t *types = NULL;
2514 ebitmap_node_t *node;
29422515 unsigned int i;
29432516 int ret;
29442517
29492522 }
29502523
29512524 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 }
29522530 role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
29532531 role_id);
29542532 if (!role) {
29592537 return NULL;
29602538 }
29612539 memset(role, 0, sizeof(role_datum_t));
2962 role->value = ++policydbp->p_roles.nprim;
29632540 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))
29712570 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);
29822574 }
29832575 if (!r->value) {
29842576 /* free intermediate result */
2985 ebitmap_destroy(&r->types);
2577 type_set_destroy(&r->types);
29862578 ebitmap_destroy(&r->dominates);
29872579 free(r);
29882580 }
29942586 dominate_role_recheck, role);
29952587 }
29962588 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,
30012597 char *id)
30022598 {
30032599 role_datum_t *r;
3004 unsigned int i;
30052600
30062601 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);
30102602 free(id);
3011 return 0;
2603 yyerror("* is not allowed for role sets");
2604 return -1;
30122605 }
30132606
30142607 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 }
30222608 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 }
30262617 r = hashtab_search(policydbp->p_roles.table, id);
30272618 if (!r) {
3028 sprintf(errormsg, "unknown role %s", id);
3029 yyerror(errormsg);
2619 yyerror2("unknown role %s", id);
30302620 free(id);
30312621 return -1;
30322622 }
30332623
3034 /* set one role */
3035 ebitmap_set_bit(set, r->value - 1, TRUE);
2624 ebitmap_set_bit(&set->roles, r->value - 1, TRUE);
30362625 free(id);
30372626 return 0;
30382627 }
30422631 {
30432632 char *id;
30442633 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;
30472640 unsigned int i, j;
30482641 int add = 1;
30492642
30572650 return 0;
30582651 }
30592652
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);
30622657
30632658 while ((id = queue_remove(id_queue))) {
30642659 if (set_roles(&roles, id))
30652660 return -1;
30662661 }
3067
3068 ebitmap_init(&negset);
2662 add = 1;
30692663 while ((id = queue_remove(id_queue))) {
3070 if (set_types(&types, &negset, id, &add))
2664 if (set_types(&types, id, &add, 0))
30712665 return -1;
30722666 }
3073 ebitmap_destroy(&negset);
30742667
30752668 id = (char *) queue_remove(id_queue);
30762669 if (!id) {
30772670 yyerror("no new role in transition definition?");
30782671 goto bad;
30792672 }
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 }
30802678 role = hashtab_search(policydbp->p_roles.table, id);
30812679 if (!role) {
30822680 sprintf(errormsg, "unknown role %s used in transition definition", id);
30842682 goto bad;
30852683 }
30862684
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))
30892694 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))
30922697 continue;
30932698
30942699 for (tr = policydbp->role_tr; tr; tr = tr->next) {
30952700 if (tr->role == (i+1) && tr->type == (j+1)) {
30962701 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]);
30982703 yyerror(errormsg);
30992704 goto bad;
31002705 }
31132718 policydbp->role_tr = tr;
31142719 }
31152720 }
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);
31162736
31172737 return 0;
31182738
31242744 static int define_role_allow(void)
31252745 {
31262746 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;
31302748
31312749 if (pass == 1) {
31322750 while ((id = queue_remove(id_queue)))
31362754 return 0;
31372755 }
31382756
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
31422764 while ((id = queue_remove(id_queue))) {
3143 if (set_roles(&roles, id))
2765 if (set_roles(&ra->roles, id))
31442766 return -1;
31452767 }
31462768
31472769
31482770 while ((id = queue_remove(id_queue))) {
3149 if (set_roles(&new_roles, id))
2771 if (set_roles(&ra->new_roles, id))
31502772 return -1;
31512773 }
31522774
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;
31632805 }
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;
31822818 }
31832819
31842820
31892825 class_datum_t *cladatum;
31902826 perm_datum_t *perdatum;
31912827 ebitmap_t classmap;
2828 ebitmap_node_t *enode;
31922829 constraint_expr_t *e;
31932830 unsigned int i;
31942831 int depth;
2832 unsigned char useexpr = 1;
31952833
31962834 if (pass == 1) {
31972835 while ((id = queue_remove(id_queue)))
32422880
32432881 ebitmap_init(&classmap);
32442882 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 }
32452888 cladatum = (class_datum_t *) hashtab_search(policydbp->p_classes.table,
32462889 (hashtab_key_t) id);
32472890 if (!cladatum) {
32632906 return -1;
32642907 }
32652908 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 }
32672919 node->permissions = 0;
32682920
32692921 node->next = cladatum->constraints;
32732925 }
32742926
32752927 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)) {
32782930 cladatum = policydbp->class_val_to_struct[i];
32792931 node = cladatum->constraints;
32802932
33122964 ebitmap_t classmap;
33132965 constraint_expr_t *e;
33142966 int depth;
2967 unsigned char useexpr = 1;
33152968
33162969 if (pass == 1) {
33172970 while ((id = queue_remove(id_queue)))
33563009
33573010 ebitmap_init(&classmap);
33583011 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 }
33593017 cladatum = (class_datum_t *)hashtab_search(policydbp->p_classes.table, (hashtab_key_t)id);
33603018 if (!cladatum) {
33613019 sprintf(errormsg, "class %s is not defined", id);
33773035 return -1;
33783036 }
33793037 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 }
33813044 node->permissions = 0;
33823045
33833046 node->next = cladatum->validatetrans;
34013064 ebitmap_t negset;
34023065 char *id;
34033066 uint32_t val;
3404 int add = 1;
3067 int add = 1;
34053068
34063069 if (pass == 1) {
34073070 if (expr_type == CEXPR_NAMES) {
34113074 return 1; /* any non-NULL value */
34123075 }
34133076
3414 expr = malloc(sizeof(struct constraint_expr));
3415 if (!expr) {
3077 if ((expr = malloc(sizeof(*expr))) == NULL ||
3078 constraint_expr_init(expr) == - 1) {
34163079 yyerror("out of memory");
3080 free(expr);
34173081 return 0;
34183082 }
3419 memset(expr, 0, sizeof(constraint_expr_t));
34203083 expr->expr_type = expr_type;
34213084
34223085 switch (expr_type) {
34293092 }
34303093 if (!e1 || e1->next) {
34313094 yyerror("illegal constraint expression");
3432 free(expr);
3095 constraint_expr_destroy(expr);
34333096 return 0;
34343097 }
34353098 e1->next = expr;
34443107 }
34453108 if (!e1 || e1->next) {
34463109 yyerror("illegal constraint expression");
3447 free(expr);
3110 constraint_expr_destroy(expr);
34483111 return 0;
34493112 }
34503113 e1->next = (struct constraint_expr *) arg2;
34573120 }
34583121 if (!e1 || e1->next) {
34593122 yyerror("illegal constraint expression");
3460 free(expr);
3123 constraint_expr_destroy(expr);
34613124 return 0;
34623125 }
34633126 e1->next = expr;
34673130 expr->op = arg2;
34683131 return (uintptr_t)expr;
34693132 case CEXPR_NAMES:
3133 add = 1;
34703134 expr->attr = arg1;
34713135 expr->op = arg2;
34723136 ebitmap_init(&negset);
34733137 while ((id = (char *) queue_remove(id_queue))) {
34743138 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 }
34753144 user = (user_datum_t *) hashtab_search(policydbp->p_users.table,
34763145 (hashtab_key_t) id);
34773146 if (!user) {
34783147 sprintf(errormsg, "unknown user %s", id);
34793148 yyerror(errormsg);
3480 free(expr);
3149 constraint_expr_destroy(expr);
34813150 return 0;
34823151 }
34833152 val = user->value;
34843153 } 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 }
34853159 role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
34863160 (hashtab_key_t) id);
34873161 if (!role) {
34883162 sprintf(errormsg, "unknown role %s", id);
34893163 yyerror(errormsg);
3490 free(expr);
3164 constraint_expr_destroy(expr);
34913165 return 0;
34923166 }
34933167 val = role->value;
34943168 } 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);
34973171 return 0;
34983172 }
34993173 continue;
35003174 } else {
35013175 yyerror("invalid constraint expression");
3502 free(expr);
3176 constraint_expr_destroy(expr);
35033177 return 0;
35043178 }
35053179 if (ebitmap_set_bit(&expr->names, val - 1, TRUE)) {
35063180 yyerror("out of memory");
35073181 ebitmap_destroy(&expr->names);
3508 free(expr);
3182 constraint_expr_destroy(expr);
35093183 return 0;
35103184 }
35113185 free(id);
35143188 return (uintptr_t)expr;
35153189 default:
35163190 yyerror("invalid constraint expression");
3517 free(expr);
3191 constraint_expr_destroy(expr);
35183192 return 0;
35193193 }
35203194
35233197 return 0;
35243198 }
35253199
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 )
35273201 {
35283202 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;
35323206
35333207 /* expression cannot be NULL */
35343208 if ( !expr) {
35893263 }
35903264
35913265 /* 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
35973271 /* normalize/precompute expression */
3598 if (cond_normalize_expr(policydbp, cn) < 0) {
3272 if (cond_normalize_expr(policydbp, &cn) < 0) {
35993273 yyerror("problem normalizing conditional expression");
36003274 return -1;
36013275 }
36023276
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);
36133371
36143372 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 */
37553373 }
37563374
37573375 static cond_expr_t *
38353453 free(expr);
38363454 return NULL;
38373455 }
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 }
38383462 bool_var = (cond_bool_datum_t *) hashtab_search(policydbp->p_bools.table,
38393463 (hashtab_key_t) id);
38403464 if (!bool_var) {
38543478 }
38553479
38563480
3857 static int set_user_roles(ebitmap_t *set,
3481 static int set_user_roles(role_set_t *set,
38583482 char *id)
38593483 {
38603484 role_datum_t *r;
38613485 unsigned int i;
3486 ebitmap_node_t *node;
38623487
38633488 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);
38673489 free(id);
3868 return 0;
3490 yyerror("* is not allowed in user declarations");
3491 return -1;
38693492 }
38703493
38713494 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 }
38793495 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 }
38833505 r = hashtab_search(policydbp->p_roles.table, id);
38843506 if (!r) {
38853507 sprintf(errormsg, "unknown role %s", id);
38893511 }
38903512
38913513 /* 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);
38953517 }
38963518 free(id);
38973519 return 0;
39633585 {
39643586 char *id;
39653587 user_datum_t *usrdatum;
3966 int ret;
39673588 level_datum_t *levdatum;
39683589 int l;
39693590
39873608 return 0;
39883609 }
39893610
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 }
40173614
40183615 while ((id = queue_remove(id_queue))) {
40193616 if (set_user_roles(&usrdatum->roles, id))
41483745 yyerror("no effective user?");
41493746 goto bad;
41503747 }
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 }
41513753 usrdatum = (user_datum_t *) hashtab_search(policydbp->p_users.table,
41523754 (hashtab_key_t) id);
41533755 if (!usrdatum) {
41673769 yyerror("no role name for sid context definition?");
41683770 return -1;
41693771 }
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 }
41703777 role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
41713778 (hashtab_key_t) id);
41723779 if (!role) {
41873794 yyerror("no type name for sid context definition?");
41883795 return -1;
41893796 }
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 }
41903802 typdatum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
41913803 (hashtab_key_t) id);
41923804 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);
41943806 yyerror(errormsg);
41953807 free(id);
41963808 return -1;
48054417 char *id;
48064418 level_datum_t *levdatum = 0;
48074419 mls_range_t range;
4808 ebitmap_t doms, types, negset;
4420 type_set_t doms, types;
4421 ebitmap_node_t *snode, *tnode;
48094422 range_trans_t *rt = 0;
48104423 unsigned int i, j;
48114424 int l, add = 1;
48334446 return 0;
48344447 }
48354448
4836 ebitmap_init(&doms);
4837 ebitmap_init(&types);
4838
4839 ebitmap_init(&negset);
4449 type_set_init(&doms);
4450 type_set_init(&types);
4451
48404452 while ((id = queue_remove(id_queue))) {
4841 if (set_types(&doms, &negset, id, &add))
4453 if (set_types(&doms, id, &add, 0))
48424454 return -1;
48434455 }
4844 ebitmap_destroy(&negset);
4845
4846 ebitmap_init(&negset);
4456 add = 1;
48474457 while ((id = queue_remove(id_queue))) {
4848 if (set_types(&types, &negset, id, &add))
4458 if (set_types(&types, id, &add, 0))
48494459 return -1;
48504460 }
4851 ebitmap_destroy(&negset);
48524461
48534462 id = (char *)queue_remove(id_queue);
48544463 if (!id) {
48944503 return -1;
48954504 }
48964505
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))
48994508 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))
49024511 continue;
49034512
49044513 for (rt = policydbp->range_tr; rt; rt = rt->next) {
49054514 if (rt->dom == (i + 1) && rt->type == (j + 1)) {
49064515 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]);
49084518 yyerror(errormsg);
49094519 return -1;
49104520 }
49374547 }
49384548 }
49394549
4940 ebitmap_destroy(&doms);
4941 ebitmap_destroy(&types);
4550 type_set_destroy(&doms);
4551 type_set_destroy(&types);
49424552 ebitmap_destroy(&range.level[0].cat);
49434553 ebitmap_destroy(&range.level[1].cat);
49444554 return 0;
66 *
77 * Added conditional policy language extensions
88 *
9 * Copyright (C) 2003 Tresys Technology, LLC
9 * Jason Tang <jtang@tresys.com>
10 *
11 * Added support for binary policy modules
12 *
13 * Copyright (C) 2003-5 Tresys Technology, LLC
1014 * This program is free software; you can redistribute it and/or modify
1115 * it under the terms of the GNU General Public License as published by
1216 * the Free Software Foundation, version 2.
1822 #include <sys/types.h>
1923 #include <stdint.h>
2024 #include <string.h>
25
26 typedef int (* require_func_t)();
2127
2228 #include "y.tab.h"
2329
3743 letter [A-Za-z]
3844 digit [0-9]
3945 hexval [0-9A-Fa-f]
46 version [0-9]+(\.[A-Za-z0-9_.]*)?
47
4048 %%
4149 \n.* { strncpy(linebuf[lno], yytext+1, 255);
4250 linebuf[lno][254] = 0;
122130 target { return(TARGET); }
123131 SAMEUSER |
124132 sameuser { return(SAMEUSER);}
133 module|MODULE { return(MODULE); }
134 require|REQUIRE { return(REQUIRE); }
135 optional|OPTIONAL { return(OPTIONAL); }
125136 OR |
126137 or { return(OR);}
127138 AND |
193204 {letter}({letter}|{digit}|_|"."|"-")* { return(USER_IDENTIFIER); }
194205 {digit}{digit}* { return(NUMBER); }
195206 {hexval}{0,4}":"{hexval}{0,4}":"({hexval}|":"|".")* { return(IPV6_ADDR); }
207 {version}/([ \t\f]*;) { return(VERSION_IDENTIFIER); }
196208 #line[ ]1[ ]\"[^\n]*\" { source_lineno = 1; strncpy(source_file, yytext+9, 255); source_file[strlen(source_file)-1] = '\0'; }
197209 #line[ ]{digit}{digit}* { source_lineno = atoi(yytext+6)-1; }
198210 #[^\n]* { /* delete comments */ }
00 #
11 # Makefile for building the dispol program
22 #
3 PREFIX=/usr/local/selinux/
3 PREFIX ?= $(DESTDIR)/usr
44 BINDIR=$(PREFIX)/bin
5 LIBDIR=$(PREFIX)/lib
6 INCLUDEDIR ?= $(PREFIX)/include
57
6 CFLAGS = -g -Wall -O2 -pipe
7 #CFLAGS = -g -Wall -O2 -pipe
8 override CFLAGS += -I. -I.. -I../include
8 CFLAGS ?= -g -Wall -O2 -pipe
9 override CFLAGS += -I$(INCLUDEDIR)
910
10 OBJS = dispol.o
11 LDLIBS=-lfl -lselinux $(LIBDIR)/libsepol.a -L$(LIBDIR)
1112
12 LIBS=-lfl /usr/lib/libsepol.a
13 all: dispol dismod
1314
14 all: dispol
15 dispol: dispol.o
1516
16 dispol: $(OBJS)
17 $(CC) -o $@ $^ $(LIBS)
18
19 %.o: ../%.c
20 $(CC) $(CFLAGS) -o $@ -c $<
17 dismod: dismod.o
2118
2219 clean:
23 rm -f dispol *.o
24
20 -rm -f dispol dismod *.o
0
1 /* Authors: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com>
2 *
3 * Copyright (C) 2003,2004,2005 Tresys Technology, LLC
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, version 2.
7 */
8
9 /*
10 * dismod.c
11 *
12 * Test program to the contents of a binary policy in text
13 * form.
14 *
15 * dismod binary_mod_file
16 */
17
18 #include <getopt.h>
19 #include <assert.h>
20 #include <sys/stat.h>
21 #include <sys/types.h>
22 #include <sys/mman.h>
23 #include <errno.h>
24 #include <stdio.h>
25 #include <fcntl.h>
26 #include <stdlib.h>
27 #include <unistd.h>
28
29 #include <sepol/policydb.h>
30 #include <sepol/services.h>
31 #include <sepol/conditional.h>
32 #include <sepol/flask.h>
33 #include <sepol/link.h>
34 #include <sepol/module.h>
35
36 #include <byteswap.h>
37 #include <endian.h>
38
39 #if __BYTE_ORDER == __LITTLE_ENDIAN
40 #define le32_to_cpu(x) (x)
41 #else
42 #define le32_to_cpu(x) bswap_32(x)
43 #endif
44
45 static policydb_t policydb;
46 extern unsigned int ss_initialized;
47
48 int policyvers = MOD_POLICYDB_VERSION_BASE;
49
50 static const char *symbol_labels[9] = {
51 "commons",
52 "classes", "roles ", "types ", "users ", "bools ",
53 "levels ", "cats ", "attribs"
54 };
55
56 void usage(char *progname)
57 {
58 printf("usage: %s binary_pol_file\n\n", progname);
59 exit(1);
60 }
61
62 /* borrowed from checkpolicy.c */
63 static int find_perm(hashtab_key_t key, hashtab_datum_t datum, void *p)
64 {
65 unsigned int *valuep;
66 perm_datum_t *perdatum;
67
68 valuep = (unsigned int *) p;
69 perdatum = (perm_datum_t *) datum;
70
71 if (*valuep == perdatum->value)
72 return (int) key;
73
74 return 0;
75 }
76
77 static void render_access_mask(uint32_t mask, uint32_t class, policydb_t *p, FILE *fp)
78 {
79 unsigned int i;
80 class_datum_t *cladatum;
81 char *perm;
82 cladatum = p->class_val_to_struct[class - 1];
83 fprintf(fp, "{");
84 for (i = 1; i <= sizeof(mask) * 8; i++) {
85 if (mask & (1 << (i - 1))) {
86 perm = (char *) hashtab_map(cladatum->permissions.table,
87 find_perm, &i);
88
89 if (!perm && cladatum->comdatum) {
90 perm = (char *) hashtab_map(cladatum->comdatum->permissions.table,
91 find_perm, &i);
92 }
93 if (perm)
94 fprintf(fp, " %s", perm);
95 }
96 }
97 fprintf(fp, " }");
98 }
99
100 static void render_access_bitmap(ebitmap_t *map, uint32_t class, policydb_t *p, FILE *fp)
101 {
102 unsigned int i;
103 uint32_t perm_value;
104 class_datum_t *cladatum;
105 char *perm;
106 cladatum = p->class_val_to_struct[class - 1];
107 fprintf(fp, "{");
108 for (i = ebitmap_startbit(map); i < ebitmap_length(map); i++) {
109 if (ebitmap_get_bit(map, i)) {
110 perm_value = i + 1;
111 perm = (char *) hashtab_map(cladatum->permissions.table,
112 find_perm, &perm_value);
113
114 if (!perm && cladatum->comdatum) {
115 perm = (char *) hashtab_map(cladatum->comdatum->permissions.table,
116 find_perm, &perm_value);
117 }
118 if (perm)
119 fprintf(fp, " %s", perm);
120 }
121 }
122 fprintf(fp, " }");
123 }
124
125 static void display_id(policydb_t *p, FILE *fp, uint32_t symbol_type, uint32_t symbol_value, char *prefix) {
126 char *id = p->sym_val_to_name[symbol_type][symbol_value];
127 scope_datum_t *scope = (scope_datum_t *) hashtab_search(p->scope[symbol_type].table, id);
128 assert(scope != NULL);
129 if (scope->scope == SCOPE_REQ) {
130 fprintf(fp, " [%s%s]", prefix, id);
131 }
132 else {
133 fprintf(fp, " %s%s", prefix, id);
134 }
135 }
136
137 int display_type_set(type_set_t *set, uint32_t flags, policydb_t *policy, FILE *fp)
138 {
139 int i, num_types;
140
141 if (set->flags & TYPE_STAR) {
142 fprintf(fp, " * ");
143 return 0;
144 } else if (set->flags & TYPE_COMP) {
145 fprintf(fp, " ~");
146 }
147
148 num_types = 0;
149 if (flags & RULE_SELF) {
150 num_types++;
151 }
152
153 for (i = ebitmap_startbit(&set->types); i < ebitmap_length(&set->types); i++) {
154 if (!ebitmap_get_bit(&set->types, i))
155 continue;
156 num_types++;
157 if (num_types > 1)
158 break;
159 }
160
161 if (num_types <= 1) {
162 for (i = ebitmap_startbit(&set->negset); i < ebitmap_length(&set->negset); i++) {
163 if (!ebitmap_get_bit(&set->negset, i))
164 continue;
165 num_types++;
166 if (num_types > 1)
167 break;
168 }
169 }
170
171 if (num_types > 1)
172 fprintf(fp, "{");
173
174 for (i = ebitmap_startbit(&set->types); i < ebitmap_length(&set->types); i++) {
175 if (!ebitmap_get_bit(&set->types, i))
176 continue;
177 display_id(policy, fp, SYM_TYPES, i, "");
178 }
179
180
181 for (i = ebitmap_startbit(&set->negset); i < ebitmap_length(&set->negset); i++) {
182 if (!ebitmap_get_bit(&set->negset, i))
183 continue;
184 display_id(policy, fp, SYM_TYPES, i, "-");
185 }
186
187
188 if (flags & RULE_SELF) {
189 fprintf(fp, " self");
190 }
191
192
193 if (num_types > 1)
194 fprintf(fp, " }");
195
196
197 return 0;
198 }
199
200 int display_mod_role_set(role_set_t *roles, policydb_t *p, FILE *fp)
201 {
202 int i, num = 0;
203
204 if (roles->flags & ROLE_STAR) {
205 fprintf(fp, " * ");
206 return 0;
207 } else if (roles->flags & ROLE_COMP) {
208 fprintf(fp, " ~");
209 }
210
211 for (i = ebitmap_startbit(&roles->roles); i < ebitmap_length(&roles->roles); i++) {
212 if (!ebitmap_get_bit(&roles->roles, i))
213 continue;
214 num++;
215 if (num > 1) {
216 fprintf(fp, "{");
217 break;
218 }
219 }
220
221 for (i = ebitmap_startbit(&roles->roles); i < ebitmap_length(&roles->roles); i++) {
222 if (ebitmap_get_bit(&roles->roles, i))
223 display_id(p, fp, SYM_ROLES, i, "");
224 }
225
226 if (num > 1)
227 fprintf(fp, " }");
228
229 return 0;
230
231 }
232
233
234 /* 'what' values for this function */
235 #define RENDER_UNCONDITIONAL 0x0001 /* render all regardless of enabled state */
236 #define RENDER_ENABLED 0x0002
237 #define RENDER_DISABLED 0x0004
238 #define RENDER_CONDITIONAL (RENDER_ENABLED|RENDER_DISABLED)
239
240 int display_avrule(avrule_t *avrule, uint32_t what, policydb_t *policy, FILE *fp)
241 {
242 class_perm_node_t *cur;
243 int num_classes;
244
245 if (avrule == NULL) {
246 fprintf(fp, " <empty>\n");
247 return 0;
248 }
249 if( avrule->specified & AVRULE_AV) {
250 if(avrule->specified & AVRULE_ALLOWED) {
251 fprintf(fp, " allow");
252 }
253 if(avrule->specified & AVRULE_AUDITALLOW) {
254 fprintf(fp, " auditallow ");
255 }
256 if(avrule->specified & AVRULE_DONTAUDIT) {
257 fprintf(fp, " dontaudit");
258 }
259 } else if( avrule->specified & AVRULE_TYPE){
260 if(avrule->specified & AVRULE_TRANSITION) {
261 fprintf(fp, " type_transition");
262 }
263 if(avrule->specified & AVRULE_MEMBER) {
264 fprintf(fp, " type_member");
265 }
266 if(avrule->specified & AVRULE_CHANGE) {
267 fprintf(fp, " type_change");
268 }
269 } else if (avrule->specified & AVRULE_NEVERALLOW) {
270 fprintf(fp, " neverallow");
271 } else {
272 fprintf(fp, " ERROR: no valid rule type specified\n");
273 return -1;
274 }
275
276 if (display_type_set(&avrule->stypes, 0, policy, fp))
277 return -1;
278
279 if (display_type_set(&avrule->ttypes, avrule->flags, policy, fp))
280 return -1;
281
282 fprintf(fp, " :");
283 cur = avrule->perms;
284 num_classes = 0;
285 while (cur) {
286 num_classes++;
287 if (num_classes > 1)
288 break;
289 cur = cur->next;
290 }
291
292 if (num_classes > 1)
293 fprintf(fp, " {");
294
295 cur = avrule->perms;
296 while (cur) {
297 display_id(policy, fp, SYM_CLASSES, cur->class - 1, "");
298 cur = cur->next;
299 }
300
301 if (num_classes > 1)
302 fprintf(fp, " }");
303 fprintf(fp, " ");
304
305 if( avrule->specified & AVRULE_AV) {
306 render_access_mask(avrule->perms->data, avrule->perms->class, policy, fp);
307 } else if ( avrule->specified & AVRULE_TYPE) {
308 display_id(policy, fp, SYM_TYPES, avrule->perms->data - 1, "");
309 }
310
311 fprintf(fp, ";\n");
312
313 return 0;
314 }
315
316 int display_type_callback(hashtab_key_t key, hashtab_datum_t datum, void *data)
317 {
318 type_datum_t *type;
319 FILE *fp;
320 int i, first_attrib = 1;
321
322 type = (type_datum_t *)datum;
323 fp = (FILE *)data;
324
325 if (type->primary) {
326 display_id(&policydb, fp, SYM_TYPES, type->value - 1, "");
327 fprintf(fp, " [%d]: ", type->value);
328 }
329 else {
330 /* as that aliases have no value of their own and that
331 * they can never be required by a module, use this
332 * alternative way of displaying a name */
333 fprintf(fp, " %s [%d]: ", (char *) key, type->value);
334 }
335 if (type->isattr) {
336 fprintf(fp, "attribute for types");
337 for (i = ebitmap_startbit(&type->types); i < ebitmap_length(&type->types); i++) {
338 if (!ebitmap_get_bit(&type->types, i))
339 continue;
340 if (first_attrib) {
341 first_attrib = 0;
342 }
343 else {
344 fprintf(fp, ",");
345 }
346 display_id(&policydb, fp, SYM_TYPES, i, "");
347 }
348 } else if (type->primary) {
349 fprintf(fp, "type");
350 } else {
351 fprintf(fp, "alias for type");
352 display_id(&policydb, fp, SYM_TYPES, type->value - 1, "");
353 }
354 fprintf(fp, "\n");
355
356 return 0;
357 }
358
359 int display_types(policydb_t *p, FILE *fp)
360 {
361 if (hashtab_map(p->p_types.table, display_type_callback, fp))
362 return -1;
363 return 0;
364 }
365
366 int display_users(policydb_t *p, FILE *fp)
367 {
368 int i, j;
369 ebitmap_t *bitmap;
370 for (i = 0; i < p->p_users.nprim; i++) {
371 display_id(p, fp, SYM_USERS, i, "");
372 fprintf(fp, ":");
373 bitmap = &(p->user_val_to_struct[i]->roles.roles);
374 for (j = ebitmap_startbit(bitmap); j < ebitmap_length(bitmap); j++) {
375 if (ebitmap_get_bit (bitmap, j)) {
376 display_id(p, fp, SYM_ROLES, j, "");
377 }
378 }
379 fprintf (fp, "\n");
380 }
381 return 0;
382 }
383
384 int display_bools(policydb_t *p, FILE *fp)
385 {
386 int i;
387
388 for (i = 0; i < p->p_bools.nprim; i++) {
389 display_id(p, fp, SYM_BOOLS, i, "");
390 fprintf(fp, " : %d\n", p->bool_val_to_struct[i]->state);
391 }
392 return 0;
393 }
394
395 void display_expr(policydb_t *p, cond_expr_t *exp, FILE *fp)
396 {
397
398 cond_expr_t *cur;
399 for (cur = exp; cur != NULL; cur = cur->next) {
400 switch (cur->expr_type) {
401 case COND_BOOL:
402 fprintf(fp, "%s ", p->p_bool_val_to_name[cur->bool - 1]);
403 break;
404 case COND_NOT:
405 fprintf(fp, "! ");
406 break;
407 case COND_OR:
408 fprintf(fp, "|| ");
409 break;
410 case COND_AND:
411 fprintf(fp, "&& ");
412 break;
413 case COND_XOR:
414 fprintf(fp, "^ ");
415 break;
416 case COND_EQ:
417 fprintf(fp, "== ");
418 break;
419 case COND_NEQ:
420 fprintf(fp, "!= ");
421 break;
422 default:
423 fprintf(fp, "error!");
424 break;
425 }
426 }
427 }
428
429 void display_policycon(policydb_t *p, FILE *fp)
430 {
431 #if 0
432 int i;
433 ocontext_t *cur;
434 char *name;
435
436 for (i = 0; i < POLICYCON_NUM; i++) {
437 fprintf(fp, "%s:", symbol_labels[i]);
438 for(cur = p->policycon[i].head; cur != NULL; cur = cur->next) {
439 if (*(cur->u.name) == '\0') {
440 name = "{default}";
441 }
442 else {
443 name = cur->u.name;
444 }
445 fprintf(fp, "\n%16s - %s:%s:%s", name, p->p_user_val_to_name[cur->context[0].user -1],
446 p->p_role_val_to_name[cur->context[0].role -1],
447 p->p_type_val_to_name[cur->context[0].type -1]);
448 }
449 fprintf(fp, "\n");
450 }
451 #endif
452 }
453
454 void display_initial_sids(policydb_t *p, FILE *fp)
455 {
456 ocontext_t *cur;
457 char *user, *role, *type;
458
459 fprintf (fp, "Initial SIDs:\n");
460 for (cur = p->ocontexts [OCON_ISID]; cur != NULL; cur = cur->next) {
461 user = p->p_user_val_to_name [cur->context [0].user - 1];
462 role = p->p_role_val_to_name [cur->context [0].role - 1];
463 type = p->p_type_val_to_name [cur->context [0].type - 1];
464 fprintf(fp, "\t%s: sid %d, context %s:%s:%s\n",
465 cur->u.name, cur->sid [0], user, role, type);
466 }
467 #if 0
468 fprintf (fp, "Policy Initial SIDs:\n");
469 for (cur = p->ocontexts [OCON_POLICYISID]; cur != NULL; cur = cur->next) {
470 user = p->p_user_val_to_name [cur->context [0].user - 1];
471 role = p->p_role_val_to_name [cur->context [0].role - 1];
472 type = p->p_type_val_to_name [cur->context [0].type - 1];
473 fprintf(fp, "\t%s: sid %d, context %s:%s:%s\n",
474 cur->u.name, cur->sid [0], user, role, type);
475 }
476 #endif
477 }
478
479 void display_role_trans(role_trans_rule_t *tr, policydb_t *p, FILE *fp)
480 {
481 for (; tr; tr = tr->next) {
482 fprintf(fp, "role transition ");
483 display_mod_role_set(&tr->roles, p, fp);
484 display_type_set(&tr->types, 0, p, fp);
485 display_id(p, fp, SYM_ROLES, tr->new_role - 1, " :");
486 fprintf(fp, "\n");
487 }
488 }
489
490 void display_role_allow(role_allow_rule_t *ra, policydb_t *p, FILE *fp)
491 {
492 for (; ra; ra = ra->next) {
493 fprintf(fp, "role allow ");
494 display_mod_role_set(&ra->roles, p, fp);
495 display_mod_role_set(&ra->new_roles, p, fp);
496 fprintf(fp, "\n");
497 }
498 }
499
500 int role_display_callback(hashtab_key_t key, hashtab_datum_t datum, void *data)
501 {
502 char *id;
503 role_datum_t *role;
504 FILE *fp;
505
506 id = key;
507 role = (role_datum_t*)datum;
508 fp = (FILE*)data;
509
510 fprintf(fp, "role:");
511 display_id(&policydb, fp, SYM_ROLES, role->value - 1, "");
512 fprintf(fp, " types: ");
513 display_type_set(&role->types, 0, &policydb, fp);
514 fprintf(fp, "\n");
515
516 return 0;
517 }
518
519
520 static int display_scope_index(scope_index_t *indices, policydb_t *p, FILE *out_fp) {
521 int i;
522 for (i = 0; i < SYM_NUM; i++) {
523 int any_found = 0, j;
524 fprintf(out_fp, "%s:", symbol_labels[i]);
525 for (j = ebitmap_startbit(&indices->scope[i]);
526 j < ebitmap_length(&indices->scope[i]);
527 j++) {
528 if (ebitmap_get_bit(&indices->scope[i], j)) {
529 any_found = 1;
530 fprintf(out_fp, " %s", p->sym_val_to_name[i][j]);
531 if (i == SYM_CLASSES) {
532 if (j < indices->class_perms_len) {
533 render_access_bitmap(indices->class_perms_map + j, j + 1, p, out_fp);
534 }
535 else {
536 fprintf(out_fp, "<no perms known>");
537 }
538 }
539 }
540 }
541 if (!any_found) {
542 fprintf(out_fp, " <empty>");
543 }
544 fprintf(out_fp, "\n");
545 }
546 return 0;
547 }
548
549
550 #if 0
551 int display_cond_expressions(policydb_t *p, FILE *fp)
552 {
553 cond_node_t *cur;
554 cond_av_list_t *av_cur;
555 for (cur = p->cond_list; cur != NULL; cur = cur->next) {
556 fprintf(fp, "expression: ");
557 display_expr(p, cur->expr, fp);
558 fprintf(fp, "current state: %d\n", cur->cur_state);
559 fprintf(fp, "True list:\n");
560 for (av_cur = cur->true_list; av_cur != NULL; av_cur = av_cur->next) {
561 fprintf(fp, "\t");
562 render_av_rule(&av_cur->node->key, &av_cur->node->datum,
563 RENDER_CONDITIONAL, p, fp);
564 }
565 fprintf(fp, "False list:\n");
566 for (av_cur = cur->false_list; av_cur != NULL; av_cur = av_cur->next) {
567 fprintf(fp, "\t");
568 render_av_rule(&av_cur->node->key, &av_cur->node->datum,
569 RENDER_CONDITIONAL, p, fp);
570 }
571 }
572 return 0;
573 }
574
575 int change_bool(char *name, int state, policydb_t *p, FILE *fp)
576 {
577 cond_bool_datum_t *bool;
578
579 bool = hashtab_search(p->p_bools.table, name);
580 if (bool == NULL) {
581 fprintf(fp, "Could not find bool %s\n", name);
582 return -1;
583 }
584 bool->state = state;
585 evaluate_conds(p);
586 return 0;
587 }
588 #endif
589
590 int display_avdecl(avrule_decl_t *decl, int field, uint32_t what, policydb_t *policy, FILE *out_fp) {
591 fprintf(out_fp, "decl %u:%s\n", decl->decl_id, (decl->enabled ? " [enabled]" : ""));
592 switch (field) {
593 case 0: {
594 cond_list_t *cond = decl->cond_list;
595 avrule_t *avrule;
596 while (cond) {
597 fprintf(out_fp, "expression: ");
598 display_expr(&policydb, cond->expr, out_fp);
599 fprintf(out_fp, "current state: %d\n", cond->cur_state);
600 fprintf(out_fp, "True list:\n");
601 avrule = cond->avtrue_list;
602 while (avrule) {
603 display_avrule(avrule, RENDER_UNCONDITIONAL, &policydb, out_fp);
604 avrule = avrule->next;
605 }
606 fprintf(out_fp, "False list:\n");
607 avrule = cond->avfalse_list;
608 while (avrule) {
609 display_avrule(avrule, RENDER_UNCONDITIONAL, &policydb, out_fp);
610 avrule = avrule->next;
611 }
612 cond = cond->next;
613 }
614 break;
615 }
616 case 1: {
617 avrule_t *avrule = decl->avrules;
618 if (avrule == NULL) {
619 fprintf(out_fp, " <empty>\n");
620 }
621 while (avrule != NULL) {
622 if (display_avrule(avrule, what, policy, out_fp)) {
623 return -1;
624 }
625 avrule = avrule->next;
626 }
627 break;
628 }
629 case 2: { /* role_type_node */
630 break;
631 }
632 case 3: {
633 display_role_trans(decl->role_tr_rules, policy, out_fp);
634 break;
635 }
636 case 4: {
637 display_role_allow(decl->role_allow_rules, policy, out_fp);
638 break;
639 }
640 case 5: {
641 if (display_scope_index(&decl->required, policy, out_fp)) {
642 return -1;
643 }
644 break;
645 }
646 case 6: {
647 if (display_scope_index(&decl->declared, policy, out_fp)) {
648 return -1;
649 }
650 break;
651 }
652 default: {
653 assert(0);
654 }
655 }
656 return 0; /* should never get here */
657 }
658
659 int display_avblock(int field, uint32_t what, policydb_t *policy, FILE *out_fp) {
660 avrule_block_t *block = policydb.global;
661 while (block != NULL) {
662 fprintf(out_fp, "--- begin avrule block ---\n");
663 avrule_decl_t *decl = block->branch_list;
664 while (decl != NULL) {
665 if (display_avdecl(decl, field, what, policy, out_fp)) {
666 return -1;
667 }
668 decl = decl->next;
669 }
670 block = block->next;
671 }
672 return 0;
673 }
674
675 static int read_policy(char *filename, policydb_t *policy) {
676 FILE *in_fp;
677 struct policy_file f;
678 int retval;
679 uint32_t buf[1];
680
681 if ((in_fp = fopen(filename, "rb")) == NULL) {
682 fprintf(stderr, "Can't open '%s': %s\n",
683 filename, strerror(errno));
684 exit(1);
685 }
686 f.type = PF_USE_STDIO;
687 f.fp = in_fp;
688
689 /* peek at the first byte. if they are indicative of a
690 package use the package reader, otherwise use the normal
691 policy reader */
692 if (fread(buf, sizeof(uint32_t), 1, in_fp) != 1) {
693 fprintf(stderr, "Could not read from policy.\n");
694 exit(1);
695 }
696 rewind(in_fp);
697 if (le32_to_cpu(buf[0]) == SEPOL_MODULE_PACKAGE_MAGIC) {
698 sepol_module_package_t package;
699 package.policy = policy;
700 package.file_contexts = NULL;
701 retval = sepol_module_package_read(&package, &f, 1);
702 free(package.file_contexts);
703 }
704 else {
705 retval = policydb_read(policy, &f, 1);
706 }
707 fclose(in_fp);
708 return retval;
709 }
710
711 static void link_module(policydb_t *base, FILE *out_fp) {
712 char module_name[80] = {0};
713 char error_buf[128] = {0};
714 int ret;
715 policydb_t module, *mods = &module;
716
717 if (base->policy_type != POLICY_BASE) {
718 printf("Can only link if initial file was a base policy.\n");
719 return;
720 }
721 printf("\nModule filename: ");
722 fgets(module_name, sizeof(module_name), stdin);
723 module_name[strlen(module_name)-1] = '\0'; /* remove LF */
724 if (module_name[0] == '\0') {
725 return;
726 }
727
728 /* read the binary policy */
729 fprintf(out_fp, "Reading module...\n");
730 if (read_policy(module_name, mods)) {
731 fprintf(stderr, "%s: error(s) encountered while loading policy\n", module_name);
732 exit(1);
733 }
734 if (module.policy_type != POLICY_MOD) {
735 fprintf(stderr, "This file is not a loadable policy module.\n");
736 exit(1);
737 }
738 if (policydb_index_classes(&module) ||
739 policydb_index_others(&module, 0)) {
740 fprintf(stderr, "Could not index module.\n");
741 exit(1);
742 }
743 ret = link_modules(base, &mods, 1, 0, error_buf, sizeof(error_buf));
744 if (ret != 0) {
745 printf("Link failed (error %d): %s\n", ret, error_buf);
746 printf("(You will probably need to restart dismod.)\n");
747 }
748 policydb_destroy(&module);
749 return;
750 }
751
752 int menu() {
753 printf("\nSelect a command:\n");
754 printf("1) display unconditional AVTAB\n");
755 printf("2) display conditional AVTAB\n");
756 printf("3) display users\n");
757 printf("4) display bools\n");
758 printf("5) display roles\n");
759 printf("6) display types, attributes, and aliases\n");
760 printf("7) display role transitions\n");
761 printf("8) display role allows\n");
762 printf("9) Display policycon\n");
763 printf("0) Display initial SIDs\n");
764 printf("\n");
765 printf("a) Display avrule requirements\n");
766 printf("b) Display avrule declarations\n");
767 printf("l) Link in a module\n");
768 printf("\n");
769 printf("f) set output file\n");
770 printf("m) display menu\n");
771 printf("q) quit\n");
772 return 0;
773 }
774
775
776 int main(int argc, char **argv)
777 {
778 FILE *out_fp = stdout;
779 char ans[81], OutfileName[121];
780
781 if(argc != 2)
782 usage(argv[0]);
783
784 /* read the binary policy */
785 fprintf(out_fp, "Reading policy...\n");
786 if (read_policy(argv[1], &policydb)) {
787 fprintf(stderr, "%s: error(s) encountered while loading policy\n", argv[0]);
788 exit(1);
789 }
790
791 if (policydb.policy_type != POLICY_BASE &&
792 policydb.policy_type != POLICY_MOD) {
793 fprintf(stderr, "This file is neither a base nor loadable policy module.\n");
794 exit(1);
795 }
796
797 if (policydb_index_classes(&policydb)) {
798 fprintf(stderr, "Error indexing classes\n");
799 exit(1);
800 }
801
802 if (policydb_index_others(&policydb, 1)) {
803 fprintf(stderr, "Error indexing others\n");
804 exit(1);
805 }
806
807 if (policydb.policy_type == POLICY_BASE) {
808 printf("Binary base policy file loaded.\n\n");
809 }
810 else {
811 printf("Binary policy module file loaded.\n");
812 printf("Module name: %s\n", policydb.name);
813 printf("Module version: %s\n", policydb.version);
814 printf("\n");
815 }
816
817 menu();
818 for(;;) {
819 printf("\nCommand (\'m\' for menu): ");
820 fgets(ans, sizeof(ans), stdin);
821 switch(ans[0]) {
822
823 case '1': {
824 fprintf(out_fp, "unconditional avtab:\n");
825 display_avblock(1, RENDER_UNCONDITIONAL, &policydb, out_fp);
826 break;
827 }
828 case '2':
829 fprintf(out_fp, "conditional avtab:\n");
830 display_avblock(0, RENDER_UNCONDITIONAL, &policydb, out_fp);
831 break;
832 case '3':
833 display_users(&policydb, out_fp);
834 break;
835 case '4':
836 display_bools(&policydb, out_fp);
837 break;
838 case '5':
839 if (hashtab_map(policydb.p_roles.table, role_display_callback, out_fp))
840 exit(1);
841 break;
842 case '6':
843 if (display_types(&policydb, out_fp)) {
844 fprintf(stderr, "Error displaying types\n");
845 exit(1);
846 }
847 break;
848 case '7':
849 fprintf(out_fp, "role transitions:\n");
850 display_avblock(3, 0, &policydb, out_fp);
851 break;
852 case '8':
853 fprintf(out_fp, "role allows:\n");
854 display_avblock(4, 0, &policydb, out_fp);
855 break;
856 case '9':
857 display_policycon(&policydb, out_fp);
858 break;
859 case '0':
860 display_initial_sids(&policydb, out_fp);
861 break;
862 case 'a':
863 fprintf(out_fp, "avrule block requirements:\n");
864 display_avblock(5, 0, &policydb, out_fp);
865 break;
866 case 'b':
867 fprintf(out_fp, "avrule block declarations:\n");
868 display_avblock(6, 0, &policydb, out_fp);
869 break;
870 case 'f':
871 printf("\nFilename for output (<CR> for screen output): ");
872 fgets(OutfileName, sizeof(OutfileName), stdin);
873 OutfileName[strlen(OutfileName)-1] = '\0'; /* fix_string (remove LF) */
874 if (strlen(OutfileName) == 0)
875 out_fp = stdout;
876 else if ((out_fp = fopen(OutfileName, "w")) == NULL) {
877 fprintf (stderr, "Cannot open output file %s\n", OutfileName);
878 out_fp = stdout;
879 }
880 if (out_fp != stdout)
881 printf("\nOutput to file: %s\n", OutfileName);
882 break;
883 case 'l':
884 link_module(&policydb, out_fp);
885 break;
886 case 'q':
887 policydb_destroy(&policydb);
888 exit(0);
889 break;
890 case 'm':
891 menu();
892 break;
893 default:
894 printf("\nInvalid choice\n");
895 menu();
896 break;
897
898 }
899 }
900 exit(EXIT_SUCCESS);
901 }
902
903
2020 #include <sepol/avtab.h>
2121 #include <sepol/services.h>
2222 #include <sepol/conditional.h>
23 #include <sepol/expand.h>
2324 #include <getopt.h>
2425 #include <assert.h>
2526 #include <unistd.h>
3940 exit(1);
4041 }
4142
42 /* borrowed from avtab.c */
43 #define HASH_BITS 15
44 #define HASH_BUCKETS (1 << HASH_BITS)
45 #define HASH_MASK (HASH_BUCKETS-1)
46
4743 /* borrowed from checkpolicy.c */
4844 static int find_perm(hashtab_key_t key, hashtab_datum_t datum, void *p)
4945 {
9187
9288 int render_key(avtab_key_t *key, policydb_t *p, FILE *fp)
9389 {
94 fprintf(fp, "%s %s : %s ", p->p_type_val_to_name[key->source_type - 1],
95 p->p_type_val_to_name[key->target_type - 1],
96 p->p_class_val_to_name[key->target_class - 1]);
90 char *stype, *ttype, *tclass;
91 stype = p->p_type_val_to_name[key->source_type - 1];
92 ttype = p->p_type_val_to_name[key->target_type - 1];
93 tclass = p->p_class_val_to_name[key->target_class - 1];
94 if (stype && ttype)
95 fprintf(fp, "%s %s : %s ", stype, ttype, tclass);
96 else if (stype)
97 fprintf(fp, "%s %u : %s ", stype, key->target_type, tclass);
98 else if (ttype)
99 fprintf(fp, "%u %s : %s ", key->source_type, ttype, tclass);
100 else
101 fprintf(fp, "%u %u : %s ", key->source_type, key->target_type, tclass);
97102 return 0;
98103 }
99104
107112 {
108113 if(!(what & RENDER_UNCONDITIONAL)) {
109114 if(what != RENDER_CONDITIONAL &&
110 (((what & RENDER_ENABLED) && !(datum->specified & AVTAB_ENABLED)) ||
111 ((what & RENDER_DISABLED) && (datum->specified & AVTAB_ENABLED)))) {
115 (((what & RENDER_ENABLED) && !(key->specified & AVTAB_ENABLED)) ||
116 ((what & RENDER_DISABLED) && (key->specified & AVTAB_ENABLED)))) {
112117 return 0; /* doesn't match selection criteria */
113118 }
114119 }
115120
116121 if(!(what & RENDER_UNCONDITIONAL)) {
117 if(datum->specified & AVTAB_ENABLED)
122 if(key->specified & AVTAB_ENABLED)
118123 fprintf(fp, "[enabled] ");
119 else if(!(datum->specified & AVTAB_ENABLED))
124 else if(!(key->specified & AVTAB_ENABLED))
120125 fprintf(fp, "[disabled] ");
121126 }
122127
123 if( datum->specified & AVTAB_AV) {
124 if(datum->specified & AVTAB_ALLOWED) {
128 if( key->specified & AVTAB_AV) {
129 if(key->specified & AVTAB_ALLOWED) {
125130 fprintf(fp, "allow ");
126131 render_key(key, p, fp);
127 render_access_mask(avtab_allowed(datum),key, p, fp);
128 fprintf(fp, ";\n");
129 }
130 if(datum->specified & AVTAB_AUDITALLOW) {
132 render_access_mask(datum->data,key, p, fp);
133 fprintf(fp, ";\n");
134 }
135 if(key->specified & AVTAB_AUDITALLOW) {
131136 fprintf(fp, "auditallow ");
132137 render_key(key, p, fp);
133 render_access_mask(avtab_auditallow(datum),key, p, fp);
134 fprintf(fp, ";\n");
135 }
136 if(datum->specified & AVTAB_AUDITDENY) {
138 render_access_mask(datum->data,key, p, fp);
139 fprintf(fp, ";\n");
140 }
141 if(key->specified & AVTAB_AUDITDENY) {
137142 fprintf(fp, "dontaudit ");
138143 render_key(key, p, fp);
139144 /* We inverse the mask for dontaudit since the mask is internally stored
140145 * as a auditdeny mask */
141 render_access_mask(~avtab_auditdeny(datum),key, p, fp);
142 fprintf(fp, ";\n");
143 }
144 }
145 else if( datum->specified & AVTAB_TYPE){
146 if(datum->specified & AVTAB_TRANSITION) {
146 render_access_mask(~datum->data,key, p, fp);
147 fprintf(fp, ";\n");
148 }
149 }
150 else if( key->specified & AVTAB_TYPE){
151 if(key->specified & AVTAB_TRANSITION) {
147152 fprintf(fp, "type_transition ");
148153 render_key(key, p, fp);
149 render_type(avtab_transition(datum), p, fp);
150 fprintf(fp, ";\n");
151 }
152 if(datum->specified & AVTAB_MEMBER) {
154 render_type(datum->data, p, fp);
155 fprintf(fp, ";\n");
156 }
157 if(key->specified & AVTAB_MEMBER) {
153158 fprintf(fp, "type_member ");
154159 render_key(key, p, fp);
155 render_type(avtab_member(datum), p, fp);
156 fprintf(fp, ";\n");
157 }
158 if(datum->specified & AVTAB_CHANGE) {
160 render_type(datum->data, p, fp);
161 fprintf(fp, ";\n");
162 }
163 if(key->specified & AVTAB_CHANGE) {
159164 fprintf(fp, "type_change ");
160165 render_key(key, p, fp);
161 render_type(avtab_change(datum), p, fp);
166 render_type(datum->data, p, fp);
162167 fprintf(fp, ";\n");
163168 }
164169 }
171176
172177 int display_avtab(avtab_t *a, uint32_t what, policydb_t *p, FILE *fp)
173178 {
174 int i;
179 int i, rc;
175180 avtab_ptr_t cur;
176
181 avtab_t expa;
182
183 if (avtab_init(&expa))
184 goto oom;
185 if (expand_avtab(p, a, &expa)) {
186 avtab_destroy(&expa);
187 goto oom;
188 }
189
190 /* hmm...should have used avtab_map. */
177191 for (i = 0; i < AVTAB_SIZE; i++) {
178 for (cur = a->htable[i]; cur; cur = cur->next) {
192 for (cur = expa.htable[i]; cur; cur = cur->next) {
179193 render_av_rule(&cur->key, &cur->datum, what, p, fp);
180194 }
181195 }
196 avtab_destroy(&expa);
182197 fprintf(fp, "\n");
183198 return 0;
199 oom:
200 fprintf(stderr, "out of memory\n");
201 return 1;
184202 }
185203
186204 int display_bools(policydb_t *p, FILE *fp)
231249 int display_cond_expressions(policydb_t *p, FILE *fp)
232250 {
233251 cond_node_t *cur;
234 cond_av_list_t *av_cur;
252 cond_av_list_t *av_cur, *expl = NULL;
253 avtab_t expa;
254
255
235256 for (cur = p->cond_list; cur != NULL; cur = cur->next) {
236257 fprintf(fp, "expression: ");
237258 display_expr(p, cur->expr, fp);
238259 fprintf(fp, "current state: %d\n", cur->cur_state);
239260 fprintf(fp, "True list:\n");
240 for (av_cur = cur->true_list; av_cur != NULL; av_cur = av_cur->next) {
261 if (avtab_init(&expa))
262 goto oom;
263 if (expand_cond_av_list(p, cur->true_list, &expl, &expa)) {
264 avtab_destroy(&expa);
265 goto oom;
266 }
267 for (av_cur = expl; av_cur != NULL; av_cur = av_cur->next) {
241268 fprintf(fp, "\t");
242269 render_av_rule(&av_cur->node->key, &av_cur->node->datum,
243270 RENDER_CONDITIONAL, p, fp);
244271 }
272 cond_av_list_destroy(expl);
273 avtab_destroy(&expa);
245274 fprintf(fp, "False list:\n");
246 for (av_cur = cur->false_list; av_cur != NULL; av_cur = av_cur->next) {
275 if (avtab_init(&expa))
276 goto oom;
277 if (expand_cond_av_list(p, cur->false_list, &expl, &expa)) {
278 avtab_destroy(&expa);
279 goto oom;
280 }
281 for (av_cur = expl; av_cur != NULL; av_cur = av_cur->next) {
247282 fprintf(fp, "\t");
248283 render_av_rule(&av_cur->node->key, &av_cur->node->datum,
249284 RENDER_CONDITIONAL, p, fp);
250285 }
251 }
252 return 0;
286 cond_av_list_destroy(expl);
287 avtab_destroy(&expa);
288 }
289 return 0;
290
291 oom:
292 fprintf(stderr, "out of memory\n");
293 return 1;
253294 }
254295
255296 int change_bool(char *name, int state, policydb_t *p, FILE *fp)