• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /* Author : Stephen Smalley, <sds@tycho.nsa.gov> */
3 
4 /*
5  * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com>
6  *
7  *	Support for enhanced MLS infrastructure.
8  *
9  * Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com>
10  *
11  * 	Added conditional policy language extensions
12  *
13  * Updated: Red Hat, Inc.  James Morris <jmorris@redhat.com>
14  *      Fine-grained netlink support
15  *      IPv6 support
16  *      Code cleanup
17  *
18  * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
19  * Copyright (C) 2003 - 2005 Tresys Technology, LLC
20  * Copyright (C) 2003 - 2007 Red Hat, Inc.
21  * Copyright (C) 2017 Mellanox Technologies Inc.
22  *
23  *  This library is free software; you can redistribute it and/or
24  *  modify it under the terms of the GNU Lesser General Public
25  *  License as published by the Free Software Foundation; either
26  *  version 2.1 of the License, or (at your option) any later version.
27  *
28  *  This library is distributed in the hope that it will be useful,
29  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
30  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
31  *  Lesser General Public License for more details.
32  *
33  *  You should have received a copy of the GNU Lesser General Public
34  *  License along with this library; if not, write to the Free Software
35  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
36  */
37 
38 /* FLASK */
39 
40 /*
41  * Implementation of the policy database.
42  */
43 
44 #include <assert.h>
45 #include <stdlib.h>
46 
47 #include <sepol/policydb/policydb.h>
48 #include <sepol/policydb/expand.h>
49 #include <sepol/policydb/conditional.h>
50 #include <sepol/policydb/avrule_block.h>
51 #include <sepol/policydb/util.h>
52 
53 #include "kernel_to_common.h"
54 #include "private.h"
55 #include "debug.h"
56 #include "mls.h"
57 #include "policydb_validate.h"
58 
59 #define POLICYDB_TARGET_SZ   ARRAY_SIZE(policydb_target_strings)
60 const char * const policydb_target_strings[] = { POLICYDB_STRING, POLICYDB_XEN_STRING };
61 
62 /* These need to be updated if SYM_NUM or OCON_NUM changes */
63 static const struct policydb_compat_info policydb_compat[] = {
64 	{
65 	 .type = POLICY_KERN,
66 	 .version = POLICYDB_VERSION_BOUNDARY,
67 	 .sym_num = SYM_NUM,
68 	 .ocon_num = OCON_XEN_PCIDEVICE + 1,
69 	 .target_platform = SEPOL_TARGET_XEN,
70 	 },
71 	{
72 	 .type = POLICY_KERN,
73 	 .version = POLICYDB_VERSION_XEN_DEVICETREE,
74 	 .sym_num = SYM_NUM,
75 	 .ocon_num = OCON_XEN_DEVICETREE + 1,
76 	 .target_platform = SEPOL_TARGET_XEN,
77 	 },
78 	{
79 	 .type = POLICY_KERN,
80 	 .version = POLICYDB_VERSION_BASE,
81 	 .sym_num = SYM_NUM - 3,
82 	 .ocon_num = OCON_FSUSE + 1,
83 	 .target_platform = SEPOL_TARGET_SELINUX,
84 	 },
85 	{
86 	 .type = POLICY_KERN,
87 	 .version = POLICYDB_VERSION_BOOL,
88 	 .sym_num = SYM_NUM - 2,
89 	 .ocon_num = OCON_FSUSE + 1,
90 	 .target_platform = SEPOL_TARGET_SELINUX,
91 	 },
92 	{
93 	 .type = POLICY_KERN,
94 	 .version = POLICYDB_VERSION_IPV6,
95 	 .sym_num = SYM_NUM - 2,
96 	 .ocon_num = OCON_NODE6 + 1,
97 	 .target_platform = SEPOL_TARGET_SELINUX,
98 	 },
99 	{
100 	 .type = POLICY_KERN,
101 	 .version = POLICYDB_VERSION_NLCLASS,
102 	 .sym_num = SYM_NUM - 2,
103 	 .ocon_num = OCON_NODE6 + 1,
104 	 .target_platform = SEPOL_TARGET_SELINUX,
105 	 },
106 	{
107 	 .type = POLICY_KERN,
108 	 .version = POLICYDB_VERSION_MLS,
109 	 .sym_num = SYM_NUM,
110 	 .ocon_num = OCON_NODE6 + 1,
111 	 .target_platform = SEPOL_TARGET_SELINUX,
112 	 },
113 	{
114 	 .type = POLICY_KERN,
115 	 .version = POLICYDB_VERSION_AVTAB,
116 	 .sym_num = SYM_NUM,
117 	 .ocon_num = OCON_NODE6 + 1,
118 	 .target_platform = SEPOL_TARGET_SELINUX,
119 	 },
120 	{
121 	 .type = POLICY_KERN,
122 	 .version = POLICYDB_VERSION_RANGETRANS,
123 	 .sym_num = SYM_NUM,
124 	 .ocon_num = OCON_NODE6 + 1,
125 	 .target_platform = SEPOL_TARGET_SELINUX,
126 	 },
127 	{
128 	 .type = POLICY_KERN,
129 	 .version = POLICYDB_VERSION_POLCAP,
130 	 .sym_num = SYM_NUM,
131 	 .ocon_num = OCON_NODE6 + 1,
132 	 .target_platform = SEPOL_TARGET_SELINUX,
133 	 },
134 	{
135 	 .type = POLICY_KERN,
136 	 .version = POLICYDB_VERSION_PERMISSIVE,
137 	 .sym_num = SYM_NUM,
138 	 .ocon_num = OCON_NODE6 + 1,
139 	 .target_platform = SEPOL_TARGET_SELINUX,
140 	 },
141         {
142 	 .type = POLICY_KERN,
143 	 .version = POLICYDB_VERSION_BOUNDARY,
144 	 .sym_num = SYM_NUM,
145 	 .ocon_num = OCON_NODE6 + 1,
146 	 .target_platform = SEPOL_TARGET_SELINUX,
147 	},
148 	{
149 	 .type = POLICY_KERN,
150 	 .version = POLICYDB_VERSION_FILENAME_TRANS,
151 	 .sym_num = SYM_NUM,
152 	 .ocon_num = OCON_NODE6 + 1,
153 	 .target_platform = SEPOL_TARGET_SELINUX,
154 	},
155 	{
156 	 .type = POLICY_KERN,
157 	 .version = POLICYDB_VERSION_ROLETRANS,
158 	 .sym_num = SYM_NUM,
159 	 .ocon_num = OCON_NODE6 + 1,
160 	 .target_platform = SEPOL_TARGET_SELINUX,
161 	},
162 	{
163 	 .type = POLICY_KERN,
164 	 .version = POLICYDB_VERSION_NEW_OBJECT_DEFAULTS,
165 	 .sym_num = SYM_NUM,
166 	 .ocon_num = OCON_NODE6 + 1,
167 	 .target_platform = SEPOL_TARGET_SELINUX,
168 	},
169 	{
170 	 .type = POLICY_KERN,
171 	 .version = POLICYDB_VERSION_DEFAULT_TYPE,
172 	 .sym_num = SYM_NUM,
173 	 .ocon_num = OCON_NODE6 + 1,
174 	 .target_platform = SEPOL_TARGET_SELINUX,
175 	},
176 	{
177 	 .type = POLICY_KERN,
178 	 .version = POLICYDB_VERSION_CONSTRAINT_NAMES,
179 	 .sym_num = SYM_NUM,
180 	 .ocon_num = OCON_NODE6 + 1,
181 	 .target_platform = SEPOL_TARGET_SELINUX,
182 	},
183 	{
184 	 .type = POLICY_KERN,
185 	 .version = POLICYDB_VERSION_XPERMS_IOCTL,
186 	 .sym_num = SYM_NUM,
187 	 .ocon_num = OCON_NODE6 + 1,
188 	 .target_platform = SEPOL_TARGET_SELINUX,
189 	},
190 	{
191 	 .type = POLICY_KERN,
192 	 .version = POLICYDB_VERSION_INFINIBAND,
193 	 .sym_num = SYM_NUM,
194 	 .ocon_num = OCON_IBENDPORT + 1,
195 	 .target_platform = SEPOL_TARGET_SELINUX,
196 	},
197 	{
198 	 .type = POLICY_KERN,
199 	 .version = POLICYDB_VERSION_GLBLUB,
200 	 .sym_num = SYM_NUM,
201 	 .ocon_num = OCON_IBENDPORT + 1,
202 	 .target_platform = SEPOL_TARGET_SELINUX,
203 	},
204 	{
205 	 .type = POLICY_KERN,
206 	 .version = POLICYDB_VERSION_COMP_FTRANS,
207 	 .sym_num = SYM_NUM,
208 	 .ocon_num = OCON_IBENDPORT + 1,
209 	 .target_platform = SEPOL_TARGET_SELINUX,
210 	},
211 	{
212 	 .type = POLICY_BASE,
213 	 .version = MOD_POLICYDB_VERSION_BASE,
214 	 .sym_num = SYM_NUM,
215 	 .ocon_num = OCON_NODE6 + 1,
216 	 .target_platform = SEPOL_TARGET_SELINUX,
217 	 },
218 	{
219 	 .type = POLICY_BASE,
220 	 .version = MOD_POLICYDB_VERSION_MLS,
221 	 .sym_num = SYM_NUM,
222 	 .ocon_num = OCON_NODE6 + 1,
223 	 .target_platform = SEPOL_TARGET_SELINUX,
224 	 },
225 	{
226 	 .type = POLICY_BASE,
227 	 .version = MOD_POLICYDB_VERSION_MLS_USERS,
228 	 .sym_num = SYM_NUM,
229 	 .ocon_num = OCON_NODE6 + 1,
230 	 .target_platform = SEPOL_TARGET_SELINUX,
231 	 },
232 	{
233 	 .type = POLICY_BASE,
234 	 .version = MOD_POLICYDB_VERSION_POLCAP,
235 	 .sym_num = SYM_NUM,
236 	 .ocon_num = OCON_NODE6 + 1,
237 	 .target_platform = SEPOL_TARGET_SELINUX,
238 	 },
239 	{
240 	 .type = POLICY_BASE,
241 	 .version = MOD_POLICYDB_VERSION_PERMISSIVE,
242 	 .sym_num = SYM_NUM,
243 	 .ocon_num = OCON_NODE6 + 1,
244 	 .target_platform = SEPOL_TARGET_SELINUX,
245 	 },
246 	{
247 	 .type = POLICY_BASE,
248 	 .version = MOD_POLICYDB_VERSION_BOUNDARY,
249 	 .sym_num = SYM_NUM,
250 	 .ocon_num = OCON_NODE6 + 1,
251 	 .target_platform = SEPOL_TARGET_SELINUX,
252 	},
253 	{
254 	 .type = POLICY_BASE,
255 	 .version = MOD_POLICYDB_VERSION_BOUNDARY_ALIAS,
256 	 .sym_num = SYM_NUM,
257 	 .ocon_num = OCON_NODE6 + 1,
258 	 .target_platform = SEPOL_TARGET_SELINUX,
259 	},
260 	{
261 	 .type = POLICY_BASE,
262 	 .version = MOD_POLICYDB_VERSION_FILENAME_TRANS,
263 	 .sym_num = SYM_NUM,
264 	 .ocon_num = OCON_NODE6 + 1,
265 	 .target_platform = SEPOL_TARGET_SELINUX,
266 	},
267 	{
268 	 .type = POLICY_BASE,
269 	 .version = MOD_POLICYDB_VERSION_ROLETRANS,
270 	 .sym_num = SYM_NUM,
271 	 .ocon_num = OCON_NODE6 + 1,
272 	 .target_platform = SEPOL_TARGET_SELINUX,
273 	},
274 	{
275 	 .type = POLICY_BASE,
276 	 .version = MOD_POLICYDB_VERSION_ROLEATTRIB,
277 	 .sym_num = SYM_NUM,
278 	 .ocon_num = OCON_NODE6 + 1,
279 	 .target_platform = SEPOL_TARGET_SELINUX,
280 	},
281 	{
282 	 .type = POLICY_BASE,
283 	 .version = MOD_POLICYDB_VERSION_TUNABLE_SEP,
284 	 .sym_num = SYM_NUM,
285 	 .ocon_num = OCON_NODE6 + 1,
286 	 .target_platform = SEPOL_TARGET_SELINUX,
287 	},
288 	{
289 	 .type = POLICY_BASE,
290 	 .version = MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS,
291 	 .sym_num = SYM_NUM,
292 	 .ocon_num = OCON_NODE6 + 1,
293 	 .target_platform = SEPOL_TARGET_SELINUX,
294 	},
295 	{
296 	 .type = POLICY_BASE,
297 	 .version = MOD_POLICYDB_VERSION_DEFAULT_TYPE,
298 	 .sym_num = SYM_NUM,
299 	 .ocon_num = OCON_NODE6 + 1,
300 	 .target_platform = SEPOL_TARGET_SELINUX,
301 	},
302 	{
303 	 .type = POLICY_BASE,
304 	 .version = MOD_POLICYDB_VERSION_CONSTRAINT_NAMES,
305 	 .sym_num = SYM_NUM,
306 	 .ocon_num = OCON_NODE6 + 1,
307 	 .target_platform = SEPOL_TARGET_SELINUX,
308 	},
309 	{
310 	 .type = POLICY_BASE,
311 	 .version = MOD_POLICYDB_VERSION_XPERMS_IOCTL,
312 	 .sym_num = SYM_NUM,
313 	 .ocon_num = OCON_NODE6 + 1,
314 	 .target_platform = SEPOL_TARGET_SELINUX,
315 	},
316 	{
317 	 .type = POLICY_BASE,
318 	 .version = MOD_POLICYDB_VERSION_INFINIBAND,
319 	 .sym_num = SYM_NUM,
320 	 .ocon_num = OCON_IBENDPORT + 1,
321 	 .target_platform = SEPOL_TARGET_SELINUX,
322 	},
323 	{
324 	 .type = POLICY_BASE,
325 	 .version = MOD_POLICYDB_VERSION_GLBLUB,
326 	 .sym_num = SYM_NUM,
327 	 .ocon_num = OCON_IBENDPORT + 1,
328 	 .target_platform = SEPOL_TARGET_SELINUX,
329 	},
330 	{
331 	 .type = POLICY_MOD,
332 	 .version = MOD_POLICYDB_VERSION_BASE,
333 	 .sym_num = SYM_NUM,
334 	 .ocon_num = 0,
335 	 .target_platform = SEPOL_TARGET_SELINUX,
336 	 },
337 	{
338 	 .type = POLICY_MOD,
339 	 .version = MOD_POLICYDB_VERSION_MLS,
340 	 .sym_num = SYM_NUM,
341 	 .ocon_num = 0,
342 	 .target_platform = SEPOL_TARGET_SELINUX,
343 	 },
344 	{
345 	 .type = POLICY_MOD,
346 	 .version = MOD_POLICYDB_VERSION_MLS_USERS,
347 	 .sym_num = SYM_NUM,
348 	 .ocon_num = 0,
349 	 .target_platform = SEPOL_TARGET_SELINUX,
350 	 },
351 	{
352 	 .type = POLICY_MOD,
353 	 .version = MOD_POLICYDB_VERSION_POLCAP,
354 	 .sym_num = SYM_NUM,
355 	 .ocon_num = 0,
356 	 .target_platform = SEPOL_TARGET_SELINUX,
357 	 },
358 	{
359 	 .type = POLICY_MOD,
360 	 .version = MOD_POLICYDB_VERSION_PERMISSIVE,
361 	 .sym_num = SYM_NUM,
362 	 .ocon_num = 0,
363 	 .target_platform = SEPOL_TARGET_SELINUX,
364 	 },
365 	{
366 	 .type = POLICY_MOD,
367 	 .version = MOD_POLICYDB_VERSION_BOUNDARY,
368 	 .sym_num = SYM_NUM,
369 	 .ocon_num = 0,
370 	 .target_platform = SEPOL_TARGET_SELINUX,
371 	},
372 	{
373 	 .type = POLICY_MOD,
374 	 .version = MOD_POLICYDB_VERSION_BOUNDARY_ALIAS,
375 	 .sym_num = SYM_NUM,
376 	 .ocon_num = 0,
377 	 .target_platform = SEPOL_TARGET_SELINUX,
378 	},
379 	{
380 	 .type = POLICY_MOD,
381 	 .version = MOD_POLICYDB_VERSION_FILENAME_TRANS,
382 	 .sym_num = SYM_NUM,
383 	 .ocon_num = 0,
384 	 .target_platform = SEPOL_TARGET_SELINUX,
385 	},
386 	{
387 	 .type = POLICY_MOD,
388 	 .version = MOD_POLICYDB_VERSION_ROLETRANS,
389 	 .sym_num = SYM_NUM,
390 	 .ocon_num = 0,
391 	 .target_platform = SEPOL_TARGET_SELINUX,
392 	},
393 	{
394 	 .type = POLICY_MOD,
395 	 .version = MOD_POLICYDB_VERSION_ROLEATTRIB,
396 	 .sym_num = SYM_NUM,
397 	 .ocon_num = 0,
398 	 .target_platform = SEPOL_TARGET_SELINUX,
399 	},
400 	{
401 	 .type = POLICY_MOD,
402 	 .version = MOD_POLICYDB_VERSION_TUNABLE_SEP,
403 	 .sym_num = SYM_NUM,
404 	 .ocon_num = 0,
405 	 .target_platform = SEPOL_TARGET_SELINUX,
406 	},
407 	{
408 	 .type = POLICY_MOD,
409 	 .version = MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS,
410 	 .sym_num = SYM_NUM,
411 	 .ocon_num = 0,
412 	 .target_platform = SEPOL_TARGET_SELINUX,
413 	},
414 	{
415 	 .type = POLICY_MOD,
416 	 .version = MOD_POLICYDB_VERSION_DEFAULT_TYPE,
417 	 .sym_num = SYM_NUM,
418 	 .ocon_num = 0,
419 	 .target_platform = SEPOL_TARGET_SELINUX,
420 	},
421 	{
422 	 .type = POLICY_MOD,
423 	 .version = MOD_POLICYDB_VERSION_CONSTRAINT_NAMES,
424 	 .sym_num = SYM_NUM,
425 	 .ocon_num = 0,
426 	 .target_platform = SEPOL_TARGET_SELINUX,
427 	},
428 	{
429 	 .type = POLICY_MOD,
430 	 .version = MOD_POLICYDB_VERSION_XPERMS_IOCTL,
431 	 .sym_num = SYM_NUM,
432 	 .ocon_num = 0,
433 	 .target_platform = SEPOL_TARGET_SELINUX,
434 	},
435 	{
436 	 .type = POLICY_MOD,
437 	 .version = MOD_POLICYDB_VERSION_INFINIBAND,
438 	 .sym_num = SYM_NUM,
439 	 .ocon_num = 0,
440 	 .target_platform = SEPOL_TARGET_SELINUX,
441 	},
442 	{
443 	 .type = POLICY_MOD,
444 	 .version = MOD_POLICYDB_VERSION_GLBLUB,
445 	 .sym_num = SYM_NUM,
446 	 .ocon_num = 0,
447 	 .target_platform = SEPOL_TARGET_SELINUX,
448 	},
449 
450 };
451 
452 #if 0
453 static char *symtab_name[SYM_NUM] = {
454 	"common prefixes",
455 	"classes",
456 	"roles",
457 	"types",
458 	"users",
459 	"bools" mls_symtab_names cond_symtab_names
460 };
461 #endif
462 
463 static const unsigned int symtab_sizes[SYM_NUM] = {
464 	2,
465 	32,
466 	16,
467 	512,
468 	128,
469 	16,
470 	16,
471 	16,
472 };
473 
policydb_lookup_compat(unsigned int version,unsigned int type,unsigned int target_platform)474 const struct policydb_compat_info *policydb_lookup_compat(unsigned int version,
475 						          unsigned int type,
476 						          unsigned int target_platform)
477 {
478 	unsigned int i;
479 	const struct policydb_compat_info *info = NULL;
480 
481 	for (i = 0; i < sizeof(policydb_compat) / sizeof(*info); i++) {
482 		if (policydb_compat[i].version == version &&
483 		    policydb_compat[i].type == type &&
484 		    policydb_compat[i].target_platform == target_platform) {
485 			info = &policydb_compat[i];
486 			break;
487 		}
488 	}
489 	return info;
490 }
491 
type_set_init(type_set_t * x)492 void type_set_init(type_set_t * x)
493 {
494 	memset(x, 0, sizeof(type_set_t));
495 	ebitmap_init(&x->types);
496 	ebitmap_init(&x->negset);
497 }
498 
type_set_destroy(type_set_t * x)499 void type_set_destroy(type_set_t * x)
500 {
501 	if (x != NULL) {
502 		ebitmap_destroy(&x->types);
503 		ebitmap_destroy(&x->negset);
504 	}
505 }
506 
role_set_init(role_set_t * x)507 void role_set_init(role_set_t * x)
508 {
509 	memset(x, 0, sizeof(role_set_t));
510 	ebitmap_init(&x->roles);
511 }
512 
role_set_destroy(role_set_t * x)513 void role_set_destroy(role_set_t * x)
514 {
515 	ebitmap_destroy(&x->roles);
516 }
517 
role_datum_init(role_datum_t * x)518 void role_datum_init(role_datum_t * x)
519 {
520 	memset(x, 0, sizeof(role_datum_t));
521 	ebitmap_init(&x->dominates);
522 	type_set_init(&x->types);
523 	ebitmap_init(&x->cache);
524 	ebitmap_init(&x->roles);
525 }
526 
role_datum_destroy(role_datum_t * x)527 void role_datum_destroy(role_datum_t * x)
528 {
529 	if (x != NULL) {
530 		ebitmap_destroy(&x->dominates);
531 		type_set_destroy(&x->types);
532 		ebitmap_destroy(&x->cache);
533 		ebitmap_destroy(&x->roles);
534 	}
535 }
536 
type_datum_init(type_datum_t * x)537 void type_datum_init(type_datum_t * x)
538 {
539 	memset(x, 0, sizeof(*x));
540 	ebitmap_init(&x->types);
541 }
542 
type_datum_destroy(type_datum_t * x)543 void type_datum_destroy(type_datum_t * x)
544 {
545 	if (x != NULL) {
546 		ebitmap_destroy(&x->types);
547 	}
548 }
549 
user_datum_init(user_datum_t * x)550 void user_datum_init(user_datum_t * x)
551 {
552 	memset(x, 0, sizeof(user_datum_t));
553 	role_set_init(&x->roles);
554 	mls_semantic_range_init(&x->range);
555 	mls_semantic_level_init(&x->dfltlevel);
556 	ebitmap_init(&x->cache);
557 	mls_range_init(&x->exp_range);
558 	mls_level_init(&x->exp_dfltlevel);
559 }
560 
user_datum_destroy(user_datum_t * x)561 void user_datum_destroy(user_datum_t * x)
562 {
563 	if (x != NULL) {
564 		role_set_destroy(&x->roles);
565 		mls_semantic_range_destroy(&x->range);
566 		mls_semantic_level_destroy(&x->dfltlevel);
567 		ebitmap_destroy(&x->cache);
568 		mls_range_destroy(&x->exp_range);
569 		mls_level_destroy(&x->exp_dfltlevel);
570 	}
571 }
572 
level_datum_init(level_datum_t * x)573 void level_datum_init(level_datum_t * x)
574 {
575 	memset(x, 0, sizeof(level_datum_t));
576 }
577 
level_datum_destroy(level_datum_t * x)578 void level_datum_destroy(level_datum_t * x __attribute__ ((unused)))
579 {
580 	/* the mls_level_t referenced by the level_datum is managed
581 	 * separately for now, so there is nothing to destroy */
582 	return;
583 }
584 
cat_datum_init(cat_datum_t * x)585 void cat_datum_init(cat_datum_t * x)
586 {
587 	memset(x, 0, sizeof(cat_datum_t));
588 }
589 
cat_datum_destroy(cat_datum_t * x)590 void cat_datum_destroy(cat_datum_t * x __attribute__ ((unused)))
591 {
592 	/* it's currently a simple struct - really nothing to destroy */
593 	return;
594 }
595 
class_perm_node_init(class_perm_node_t * x)596 void class_perm_node_init(class_perm_node_t * x)
597 {
598 	memset(x, 0, sizeof(class_perm_node_t));
599 }
600 
avrule_init(avrule_t * x)601 void avrule_init(avrule_t * x)
602 {
603 	memset(x, 0, sizeof(avrule_t));
604 	type_set_init(&x->stypes);
605 	type_set_init(&x->ttypes);
606 }
607 
avrule_destroy(avrule_t * x)608 void avrule_destroy(avrule_t * x)
609 {
610 	class_perm_node_t *cur, *next;
611 
612 	if (x == NULL) {
613 		return;
614 	}
615 	type_set_destroy(&x->stypes);
616 	type_set_destroy(&x->ttypes);
617 
618 	free(x->source_filename);
619 
620 	next = x->perms;
621 	while (next) {
622 		cur = next;
623 		next = cur->next;
624 		free(cur);
625 	}
626 
627 	free(x->xperms);
628 }
629 
role_trans_rule_init(role_trans_rule_t * x)630 void role_trans_rule_init(role_trans_rule_t * x)
631 {
632 	memset(x, 0, sizeof(*x));
633 	role_set_init(&x->roles);
634 	type_set_init(&x->types);
635 	ebitmap_init(&x->classes);
636 }
637 
role_trans_rule_destroy(role_trans_rule_t * x)638 static void role_trans_rule_destroy(role_trans_rule_t * x)
639 {
640 	if (x != NULL) {
641 		role_set_destroy(&x->roles);
642 		type_set_destroy(&x->types);
643 		ebitmap_destroy(&x->classes);
644 	}
645 }
646 
role_trans_rule_list_destroy(role_trans_rule_t * x)647 void role_trans_rule_list_destroy(role_trans_rule_t * x)
648 {
649 	while (x != NULL) {
650 		role_trans_rule_t *next = x->next;
651 		role_trans_rule_destroy(x);
652 		free(x);
653 		x = next;
654 	}
655 }
656 
filename_trans_rule_init(filename_trans_rule_t * x)657 void filename_trans_rule_init(filename_trans_rule_t * x)
658 {
659 	memset(x, 0, sizeof(*x));
660 	type_set_init(&x->stypes);
661 	type_set_init(&x->ttypes);
662 }
663 
filename_trans_rule_destroy(filename_trans_rule_t * x)664 static void filename_trans_rule_destroy(filename_trans_rule_t * x)
665 {
666 	if (!x)
667 		return;
668 	type_set_destroy(&x->stypes);
669 	type_set_destroy(&x->ttypes);
670 	free(x->name);
671 }
672 
filename_trans_rule_list_destroy(filename_trans_rule_t * x)673 void filename_trans_rule_list_destroy(filename_trans_rule_t * x)
674 {
675 	filename_trans_rule_t *next;
676 	while (x) {
677 		next = x->next;
678 		filename_trans_rule_destroy(x);
679 		free(x);
680 		x = next;
681 	}
682 }
683 
role_allow_rule_init(role_allow_rule_t * x)684 void role_allow_rule_init(role_allow_rule_t * x)
685 {
686 	memset(x, 0, sizeof(role_allow_rule_t));
687 	role_set_init(&x->roles);
688 	role_set_init(&x->new_roles);
689 }
690 
role_allow_rule_destroy(role_allow_rule_t * x)691 void role_allow_rule_destroy(role_allow_rule_t * x)
692 {
693 	role_set_destroy(&x->roles);
694 	role_set_destroy(&x->new_roles);
695 }
696 
role_allow_rule_list_destroy(role_allow_rule_t * x)697 void role_allow_rule_list_destroy(role_allow_rule_t * x)
698 {
699 	while (x != NULL) {
700 		role_allow_rule_t *next = x->next;
701 		role_allow_rule_destroy(x);
702 		free(x);
703 		x = next;
704 	}
705 }
706 
range_trans_rule_init(range_trans_rule_t * x)707 void range_trans_rule_init(range_trans_rule_t * x)
708 {
709 	type_set_init(&x->stypes);
710 	type_set_init(&x->ttypes);
711 	ebitmap_init(&x->tclasses);
712 	mls_semantic_range_init(&x->trange);
713 	x->next = NULL;
714 }
715 
range_trans_rule_destroy(range_trans_rule_t * x)716 void range_trans_rule_destroy(range_trans_rule_t * x)
717 {
718 	type_set_destroy(&x->stypes);
719 	type_set_destroy(&x->ttypes);
720 	ebitmap_destroy(&x->tclasses);
721 	mls_semantic_range_destroy(&x->trange);
722 }
723 
range_trans_rule_list_destroy(range_trans_rule_t * x)724 void range_trans_rule_list_destroy(range_trans_rule_t * x)
725 {
726 	while (x != NULL) {
727 		range_trans_rule_t *next = x->next;
728 		range_trans_rule_destroy(x);
729 		free(x);
730 		x = next;
731 	}
732 }
733 
avrule_list_destroy(avrule_t * x)734 void avrule_list_destroy(avrule_t * x)
735 {
736 	avrule_t *next, *cur;
737 
738 	if (!x)
739 		return;
740 
741 	next = x;
742 	while (next) {
743 		cur = next;
744 		next = next->next;
745 		avrule_destroy(cur);
746 		free(cur);
747 	}
748 }
749 
750 /*
751  * Initialize the role table by implicitly adding role 'object_r'.  If
752  * the policy is a module, set object_r's scope to be SCOPE_REQ,
753  * otherwise set it to SCOPE_DECL.
754  */
roles_init(policydb_t * p)755 static int roles_init(policydb_t * p)
756 {
757 	char *key = 0;
758 	int rc;
759 	role_datum_t *role;
760 
761 	role = calloc(1, sizeof(role_datum_t));
762 	if (!role) {
763 		rc = -ENOMEM;
764 		goto out;
765 	}
766 	key = malloc(strlen(OBJECT_R) + 1);
767 	if (!key) {
768 		rc = -ENOMEM;
769 		goto out_free_role;
770 	}
771 	strcpy(key, OBJECT_R);
772 	rc = symtab_insert(p, SYM_ROLES, key, role,
773 			   (p->policy_type ==
774 			    POLICY_MOD ? SCOPE_REQ : SCOPE_DECL), 1,
775 			   &role->s.value);
776 	if (rc)
777 		goto out_free_key;
778 	if (role->s.value != OBJECT_R_VAL) {
779 		rc = -EINVAL;
780 		goto out_free_role;
781 	}
782       out:
783 	return rc;
784 
785       out_free_key:
786 	free(key);
787       out_free_role:
788 	free(role);
789 	goto out;
790 }
791 
792 ignore_unsigned_overflow_
793 static inline unsigned long
partial_name_hash(unsigned long c,unsigned long prevhash)794 partial_name_hash(unsigned long c, unsigned long prevhash)
795 {
796 	return (prevhash + (c << 4) + (c >> 4)) * 11;
797 }
798 
filenametr_hash(hashtab_t h,const_hashtab_key_t k)799 static unsigned int filenametr_hash(hashtab_t h, const_hashtab_key_t k)
800 {
801 	const filename_trans_key_t *ft = (const filename_trans_key_t *)k;
802 	unsigned long hash;
803 	unsigned int byte_num;
804 	unsigned char focus;
805 
806 	hash = ft->ttype ^ ft->tclass;
807 
808 	byte_num = 0;
809 	while ((focus = ft->name[byte_num++]))
810 		hash = partial_name_hash(focus, hash);
811 	return hash & (h->size - 1);
812 }
813 
filenametr_cmp(hashtab_t h,const_hashtab_key_t k1,const_hashtab_key_t k2)814 static int filenametr_cmp(hashtab_t h __attribute__ ((unused)),
815 			  const_hashtab_key_t k1, const_hashtab_key_t k2)
816 {
817 	const filename_trans_key_t *ft1 = (const filename_trans_key_t *)k1;
818 	const filename_trans_key_t *ft2 = (const filename_trans_key_t *)k2;
819 	int v;
820 
821 	v = spaceship_cmp(ft1->ttype, ft2->ttype);
822 	if (v)
823 		return v;
824 
825 	v = spaceship_cmp(ft1->tclass, ft2->tclass);
826 	if (v)
827 		return v;
828 
829 	return strcmp(ft1->name, ft2->name);
830 
831 }
832 
rangetr_hash(hashtab_t h,const_hashtab_key_t k)833 static unsigned int rangetr_hash(hashtab_t h, const_hashtab_key_t k)
834 {
835 	const struct range_trans *key = (const struct range_trans *)k;
836 	return (key->source_type + (key->target_type << 3) +
837 		(key->target_class << 5)) & (h->size - 1);
838 }
839 
rangetr_cmp(hashtab_t h,const_hashtab_key_t k1,const_hashtab_key_t k2)840 static int rangetr_cmp(hashtab_t h __attribute__ ((unused)),
841 		       const_hashtab_key_t k1, const_hashtab_key_t k2)
842 {
843 	const struct range_trans *key1 = (const struct range_trans *)k1;
844 	const struct range_trans *key2 = (const struct range_trans *)k2;
845 	int v;
846 
847 	v = spaceship_cmp(key1->source_type, key2->source_type);
848 	if (v)
849 		return v;
850 
851 	v = spaceship_cmp(key1->target_type, key2->target_type);
852 	if (v)
853 		return v;
854 
855 	v = spaceship_cmp(key1->target_class, key2->target_class);
856 
857 	return v;
858 }
859 
860 /*
861  * Initialize a policy database structure.
862  */
policydb_init(policydb_t * p)863 int policydb_init(policydb_t * p)
864 {
865 	int i, rc;
866 
867 	memset(p, 0, sizeof(policydb_t));
868 
869 	for (i = 0; i < SYM_NUM; i++) {
870 		p->sym_val_to_name[i] = NULL;
871 		rc = symtab_init(&p->symtab[i], symtab_sizes[i]);
872 		if (rc)
873 			goto err;
874 	}
875 
876 	/* initialize the module stuff */
877 	for (i = 0; i < SYM_NUM; i++) {
878 		if (symtab_init(&p->scope[i], symtab_sizes[i])) {
879 			goto err;
880 		}
881 	}
882 	if ((p->global = avrule_block_create()) == NULL ||
883 	    (p->global->branch_list = avrule_decl_create(1)) == NULL) {
884 		goto err;
885 	}
886 	p->decl_val_to_struct = NULL;
887 
888 	rc = avtab_init(&p->te_avtab);
889 	if (rc)
890 		goto err;
891 
892 	rc = roles_init(p);
893 	if (rc)
894 		goto err;
895 
896 	rc = cond_policydb_init(p);
897 	if (rc)
898 		goto err;
899 
900 	p->filename_trans = hashtab_create(filenametr_hash, filenametr_cmp, (1 << 10));
901 	if (!p->filename_trans) {
902 		rc = -ENOMEM;
903 		goto err;
904 	}
905 
906 	p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256);
907 	if (!p->range_tr) {
908 		rc = -ENOMEM;
909 		goto err;
910 	}
911 
912 	ebitmap_init(&p->policycaps);
913 	ebitmap_init(&p->permissive_map);
914 
915 	return 0;
916 err:
917 	hashtab_destroy(p->filename_trans);
918 	hashtab_destroy(p->range_tr);
919 	for (i = 0; i < SYM_NUM; i++) {
920 		hashtab_destroy(p->symtab[i].table);
921 		hashtab_destroy(p->scope[i].table);
922 	}
923 	avrule_block_list_destroy(p->global);
924 	return rc;
925 }
926 
policydb_role_cache(hashtab_key_t key,hashtab_datum_t datum,void * arg)927 int policydb_role_cache(hashtab_key_t key
928 			__attribute__ ((unused)), hashtab_datum_t datum,
929 			void *arg)
930 {
931 	policydb_t *p;
932 	role_datum_t *role;
933 
934 	role = (role_datum_t *) datum;
935 	p = (policydb_t *) arg;
936 
937 	ebitmap_destroy(&role->cache);
938 	if (type_set_expand(&role->types, &role->cache, p, 1)) {
939 		return -1;
940 	}
941 
942 	return 0;
943 }
944 
policydb_user_cache(hashtab_key_t key,hashtab_datum_t datum,void * arg)945 int policydb_user_cache(hashtab_key_t key
946 			__attribute__ ((unused)), hashtab_datum_t datum,
947 			void *arg)
948 {
949 	policydb_t *p;
950 	user_datum_t *user;
951 
952 	user = (user_datum_t *) datum;
953 	p = (policydb_t *) arg;
954 
955 	ebitmap_destroy(&user->cache);
956 	if (role_set_expand(&user->roles, &user->cache, p, NULL, NULL)) {
957 		return -1;
958 	}
959 
960 	/* we do not expand user's MLS info in kernel policies because the
961 	 * semantic representation is not present and we do not expand user's
962 	 * MLS info in module policies because all of the necessary mls
963 	 * information is not present */
964 	if (p->policy_type != POLICY_KERN && p->policy_type != POLICY_MOD) {
965 		mls_range_destroy(&user->exp_range);
966 		if (mls_semantic_range_expand(&user->range,
967 					      &user->exp_range, p, NULL)) {
968 			return -1;
969 		}
970 
971 		mls_level_destroy(&user->exp_dfltlevel);
972 		if (mls_semantic_level_expand(&user->dfltlevel,
973 					      &user->exp_dfltlevel, p, NULL)) {
974 			return -1;
975 		}
976 	}
977 
978 	return 0;
979 }
980 
981 /*
982  * The following *_index functions are used to
983  * define the val_to_name and val_to_struct arrays
984  * in a policy database structure.  The val_to_name
985  * arrays are used when converting security context
986  * structures into string representations.  The
987  * val_to_struct arrays are used when the attributes
988  * of a class, role, or user are needed.
989  */
990 
common_index(hashtab_key_t key,hashtab_datum_t datum,void * datap)991 static int common_index(hashtab_key_t key, hashtab_datum_t datum, void *datap)
992 {
993 	policydb_t *p;
994 	common_datum_t *comdatum;
995 
996 	comdatum = (common_datum_t *) datum;
997 	p = (policydb_t *) datap;
998 	if (!value_isvalid(comdatum->s.value, p->p_commons.nprim))
999 		return -EINVAL;
1000 	if (p->p_common_val_to_name[comdatum->s.value - 1] != NULL)
1001 		return -EINVAL;
1002 	p->p_common_val_to_name[comdatum->s.value - 1] = (char *)key;
1003 
1004 	return 0;
1005 }
1006 
class_index(hashtab_key_t key,hashtab_datum_t datum,void * datap)1007 static int class_index(hashtab_key_t key, hashtab_datum_t datum, void *datap)
1008 {
1009 	policydb_t *p;
1010 	class_datum_t *cladatum;
1011 
1012 	cladatum = (class_datum_t *) datum;
1013 	p = (policydb_t *) datap;
1014 	if (!value_isvalid(cladatum->s.value, p->p_classes.nprim))
1015 		return -EINVAL;
1016 	if (p->p_class_val_to_name[cladatum->s.value - 1] != NULL)
1017 		return -EINVAL;
1018 	p->p_class_val_to_name[cladatum->s.value - 1] = (char *)key;
1019 	p->class_val_to_struct[cladatum->s.value - 1] = cladatum;
1020 
1021 	return 0;
1022 }
1023 
role_index(hashtab_key_t key,hashtab_datum_t datum,void * datap)1024 static int role_index(hashtab_key_t key, hashtab_datum_t datum, void *datap)
1025 {
1026 	policydb_t *p;
1027 	role_datum_t *role;
1028 
1029 	role = (role_datum_t *) datum;
1030 	p = (policydb_t *) datap;
1031 	if (!value_isvalid(role->s.value, p->p_roles.nprim))
1032 		return -EINVAL;
1033 	if (p->p_role_val_to_name[role->s.value - 1] != NULL)
1034 		return -EINVAL;
1035 	p->p_role_val_to_name[role->s.value - 1] = (char *)key;
1036 	p->role_val_to_struct[role->s.value - 1] = role;
1037 
1038 	return 0;
1039 }
1040 
type_index(hashtab_key_t key,hashtab_datum_t datum,void * datap)1041 static int type_index(hashtab_key_t key, hashtab_datum_t datum, void *datap)
1042 {
1043 	policydb_t *p;
1044 	type_datum_t *typdatum;
1045 
1046 	typdatum = (type_datum_t *) datum;
1047 	p = (policydb_t *) datap;
1048 
1049 	if (typdatum->primary) {
1050 		if (!value_isvalid(typdatum->s.value, p->p_types.nprim))
1051 			return -EINVAL;
1052 		if (p->p_type_val_to_name[typdatum->s.value - 1] != NULL)
1053 			return -EINVAL;
1054 		p->p_type_val_to_name[typdatum->s.value - 1] = (char *)key;
1055 		p->type_val_to_struct[typdatum->s.value - 1] = typdatum;
1056 	}
1057 
1058 	return 0;
1059 }
1060 
user_index(hashtab_key_t key,hashtab_datum_t datum,void * datap)1061 static int user_index(hashtab_key_t key, hashtab_datum_t datum, void *datap)
1062 {
1063 	policydb_t *p;
1064 	user_datum_t *usrdatum;
1065 
1066 	usrdatum = (user_datum_t *) datum;
1067 	p = (policydb_t *) datap;
1068 
1069 	if (!value_isvalid(usrdatum->s.value, p->p_users.nprim))
1070 		return -EINVAL;
1071 	if (p->p_user_val_to_name[usrdatum->s.value - 1] != NULL)
1072 		return -EINVAL;
1073 	p->p_user_val_to_name[usrdatum->s.value - 1] = (char *)key;
1074 	p->user_val_to_struct[usrdatum->s.value - 1] = usrdatum;
1075 
1076 	return 0;
1077 }
1078 
sens_index(hashtab_key_t key,hashtab_datum_t datum,void * datap)1079 static int sens_index(hashtab_key_t key, hashtab_datum_t datum, void *datap)
1080 {
1081 	policydb_t *p;
1082 	level_datum_t *levdatum;
1083 
1084 	levdatum = (level_datum_t *) datum;
1085 	p = (policydb_t *) datap;
1086 
1087 	if (!levdatum->isalias) {
1088 		if (!value_isvalid(levdatum->level->sens, p->p_levels.nprim))
1089 			return -EINVAL;
1090 		if (p->p_sens_val_to_name[levdatum->level->sens - 1] != NULL)
1091 			return -EINVAL;
1092 		p->p_sens_val_to_name[levdatum->level->sens - 1] = (char *)key;
1093 	}
1094 
1095 	return 0;
1096 }
1097 
cat_index(hashtab_key_t key,hashtab_datum_t datum,void * datap)1098 static int cat_index(hashtab_key_t key, hashtab_datum_t datum, void *datap)
1099 {
1100 	policydb_t *p;
1101 	cat_datum_t *catdatum;
1102 
1103 	catdatum = (cat_datum_t *) datum;
1104 	p = (policydb_t *) datap;
1105 
1106 	if (!catdatum->isalias) {
1107 		if (!value_isvalid(catdatum->s.value, p->p_cats.nprim))
1108 			return -EINVAL;
1109 		if (p->p_cat_val_to_name[catdatum->s.value - 1] != NULL)
1110 			return -EINVAL;
1111 		p->p_cat_val_to_name[catdatum->s.value - 1] = (char *)key;
1112 	}
1113 
1114 	return 0;
1115 }
1116 
1117 static int (*index_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum,
1118 				void *datap) = {
1119 common_index, class_index, role_index, type_index, user_index,
1120 	    cond_index_bool, sens_index, cat_index,};
1121 
1122 /*
1123  * Define the common val_to_name array and the class
1124  * val_to_name and val_to_struct arrays in a policy
1125  * database structure.
1126  */
policydb_index_classes(policydb_t * p)1127 int policydb_index_classes(policydb_t * p)
1128 {
1129 	free(p->p_common_val_to_name);
1130 	p->p_common_val_to_name = (char **)
1131 	    calloc(p->p_commons.nprim, sizeof(char *));
1132 	if (!p->p_common_val_to_name)
1133 		return -1;
1134 
1135 	if (hashtab_map(p->p_commons.table, common_index, p))
1136 		return -1;
1137 
1138 	free(p->class_val_to_struct);
1139 	p->class_val_to_struct = (class_datum_t **)
1140 	    calloc(p->p_classes.nprim, sizeof(class_datum_t *));
1141 	if (!p->class_val_to_struct)
1142 		return -1;
1143 
1144 	free(p->p_class_val_to_name);
1145 	p->p_class_val_to_name = (char **)
1146 	    calloc(p->p_classes.nprim, sizeof(char *));
1147 	if (!p->p_class_val_to_name)
1148 		return -1;
1149 
1150 	if (hashtab_map(p->p_classes.table, class_index, p))
1151 		return -1;
1152 
1153 	return 0;
1154 }
1155 
policydb_index_bools(policydb_t * p)1156 int policydb_index_bools(policydb_t * p)
1157 {
1158 
1159 	if (cond_init_bool_indexes(p) == -1)
1160 		return -1;
1161 	p->p_bool_val_to_name = (char **)
1162 	    calloc(p->p_bools.nprim, sizeof(char *));
1163 	if (!p->p_bool_val_to_name)
1164 		return -1;
1165 	if (hashtab_map(p->p_bools.table, cond_index_bool, p))
1166 		return -1;
1167 	return 0;
1168 }
1169 
policydb_index_decls(sepol_handle_t * handle,policydb_t * p)1170 static int policydb_index_decls(sepol_handle_t * handle, policydb_t * p)
1171 {
1172 	avrule_block_t *curblock;
1173 	avrule_decl_t *decl;
1174 	unsigned int num_decls = 0;
1175 
1176 	free(p->decl_val_to_struct);
1177 
1178 	for (curblock = p->global; curblock != NULL; curblock = curblock->next) {
1179 		for (decl = curblock->branch_list; decl != NULL;
1180 		     decl = decl->next) {
1181 			num_decls++;
1182 		}
1183 	}
1184 
1185 	p->decl_val_to_struct =
1186 	    calloc(num_decls, sizeof(*(p->decl_val_to_struct)));
1187 	if (!p->decl_val_to_struct) {
1188 		return -1;
1189 	}
1190 
1191 	for (curblock = p->global; curblock != NULL; curblock = curblock->next) {
1192 		for (decl = curblock->branch_list; decl != NULL;
1193 		     decl = decl->next) {
1194 			if (!value_isvalid(decl->decl_id, num_decls)) {
1195 				ERR(handle, "invalid decl ID %u", decl->decl_id);
1196 				return -1;
1197 			}
1198 			if (p->decl_val_to_struct[decl->decl_id - 1] != NULL) {
1199 				ERR(handle, "duplicated decl ID %u", decl->decl_id);
1200 				return -1;
1201 			}
1202 			p->decl_val_to_struct[decl->decl_id - 1] = decl;
1203 		}
1204 	}
1205 
1206 	return 0;
1207 }
1208 
1209 /*
1210  * Define the other val_to_name and val_to_struct arrays
1211  * in a policy database structure.
1212  */
policydb_index_others(sepol_handle_t * handle,policydb_t * p,unsigned verbose)1213 int policydb_index_others(sepol_handle_t * handle,
1214 			  policydb_t * p, unsigned verbose)
1215 {
1216 	int i;
1217 
1218 	if (verbose) {
1219 		INFO(handle,
1220 		     "security:  %d users, %d roles, %d types, %d bools",
1221 		     p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim,
1222 		     p->p_bools.nprim);
1223 
1224 		if (p->mls)
1225 			INFO(handle, "security: %d sens, %d cats",
1226 			     p->p_levels.nprim, p->p_cats.nprim);
1227 
1228 		INFO(handle, "security:  %d classes, %d rules, %d cond rules",
1229 		     p->p_classes.nprim, p->te_avtab.nel, p->te_cond_avtab.nel);
1230 	}
1231 #if 0
1232 	avtab_hash_eval(&p->te_avtab, "rules");
1233 	for (i = 0; i < SYM_NUM; i++)
1234 		hashtab_hash_eval(p->symtab[i].table, symtab_name[i]);
1235 #endif
1236 
1237 	free(p->role_val_to_struct);
1238 	p->role_val_to_struct = (role_datum_t **)
1239 	    calloc(p->p_roles.nprim, sizeof(role_datum_t *));
1240 	if (!p->role_val_to_struct)
1241 		return -1;
1242 
1243 	free(p->user_val_to_struct);
1244 	p->user_val_to_struct = (user_datum_t **)
1245 	    calloc(p->p_users.nprim, sizeof(user_datum_t *));
1246 	if (!p->user_val_to_struct)
1247 		return -1;
1248 
1249 	free(p->type_val_to_struct);
1250 	p->type_val_to_struct = (type_datum_t **)
1251 	    calloc(p->p_types.nprim, sizeof(type_datum_t *));
1252 	if (!p->type_val_to_struct)
1253 		return -1;
1254 
1255 	cond_init_bool_indexes(p);
1256 
1257 	for (i = SYM_ROLES; i < SYM_NUM; i++) {
1258 		free(p->sym_val_to_name[i]);
1259 		p->sym_val_to_name[i] = NULL;
1260 		if (p->symtab[i].nprim) {
1261 			p->sym_val_to_name[i] = (char **)
1262 			    calloc(p->symtab[i].nprim, sizeof(char *));
1263 			if (!p->sym_val_to_name[i])
1264 				return -1;
1265 			if (hashtab_map(p->symtab[i].table, index_f[i], p))
1266 				return -1;
1267 		}
1268 	}
1269 
1270 	/* This pre-expands the roles and users for context validity checking */
1271 	if (hashtab_map(p->p_roles.table, policydb_role_cache, p))
1272 		return -1;
1273 
1274 	if (hashtab_map(p->p_users.table, policydb_user_cache, p))
1275 		return -1;
1276 
1277 	return 0;
1278 }
1279 
1280 /*
1281  * The following *_destroy functions are used to
1282  * free any memory allocated for each kind of
1283  * symbol data in the policy database.
1284  */
1285 
perm_destroy(hashtab_key_t key,hashtab_datum_t datum,void * p)1286 static int perm_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
1287 			__attribute__ ((unused)))
1288 {
1289 	if (key)
1290 		free(key);
1291 	free(datum);
1292 	return 0;
1293 }
1294 
common_destroy(hashtab_key_t key,hashtab_datum_t datum,void * p)1295 static int common_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
1296 			  __attribute__ ((unused)))
1297 {
1298 	common_datum_t *comdatum;
1299 
1300 	if (key)
1301 		free(key);
1302 	comdatum = (common_datum_t *) datum;
1303 	(void)hashtab_map(comdatum->permissions.table, perm_destroy, 0);
1304 	hashtab_destroy(comdatum->permissions.table);
1305 	free(datum);
1306 	return 0;
1307 }
1308 
class_destroy(hashtab_key_t key,hashtab_datum_t datum,void * p)1309 static int class_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
1310 			 __attribute__ ((unused)))
1311 {
1312 	class_datum_t *cladatum;
1313 	constraint_node_t *constraint, *ctemp;
1314 
1315 	if (key)
1316 		free(key);
1317 	cladatum = (class_datum_t *) datum;
1318 	if (cladatum == NULL) {
1319 		return 0;
1320 	}
1321 	(void)hashtab_map(cladatum->permissions.table, perm_destroy, 0);
1322 	hashtab_destroy(cladatum->permissions.table);
1323 	constraint = cladatum->constraints;
1324 	while (constraint) {
1325 		constraint_expr_destroy(constraint->expr);
1326 		ctemp = constraint;
1327 		constraint = constraint->next;
1328 		free(ctemp);
1329 	}
1330 
1331 	constraint = cladatum->validatetrans;
1332 	while (constraint) {
1333 		constraint_expr_destroy(constraint->expr);
1334 		ctemp = constraint;
1335 		constraint = constraint->next;
1336 		free(ctemp);
1337 	}
1338 
1339 	if (cladatum->comkey)
1340 		free(cladatum->comkey);
1341 	free(datum);
1342 	return 0;
1343 }
1344 
role_destroy(hashtab_key_t key,hashtab_datum_t datum,void * p)1345 static int role_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
1346 			__attribute__ ((unused)))
1347 {
1348 	free(key);
1349 	role_datum_destroy((role_datum_t *) datum);
1350 	free(datum);
1351 	return 0;
1352 }
1353 
type_destroy(hashtab_key_t key,hashtab_datum_t datum,void * p)1354 static int type_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
1355 			__attribute__ ((unused)))
1356 {
1357 	free(key);
1358 	type_datum_destroy((type_datum_t *) datum);
1359 	free(datum);
1360 	return 0;
1361 }
1362 
user_destroy(hashtab_key_t key,hashtab_datum_t datum,void * p)1363 static int user_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
1364 			__attribute__ ((unused)))
1365 {
1366 	free(key);
1367 	user_datum_destroy((user_datum_t *) datum);
1368 	free(datum);
1369 	return 0;
1370 }
1371 
sens_destroy(hashtab_key_t key,hashtab_datum_t datum,void * p)1372 static int sens_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
1373 			__attribute__ ((unused)))
1374 {
1375 	level_datum_t *levdatum;
1376 
1377 	if (key)
1378 		free(key);
1379 	levdatum = (level_datum_t *) datum;
1380 	mls_level_destroy(levdatum->level);
1381 	free(levdatum->level);
1382 	level_datum_destroy(levdatum);
1383 	free(levdatum);
1384 	return 0;
1385 }
1386 
cat_destroy(hashtab_key_t key,hashtab_datum_t datum,void * p)1387 static int cat_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
1388 		       __attribute__ ((unused)))
1389 {
1390 	if (key)
1391 		free(key);
1392 	cat_datum_destroy((cat_datum_t *) datum);
1393 	free(datum);
1394 	return 0;
1395 }
1396 
1397 static int (*destroy_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum,
1398 				  void *datap) = {
1399 common_destroy, class_destroy, role_destroy, type_destroy, user_destroy,
1400 	    cond_destroy_bool, sens_destroy, cat_destroy,};
1401 
filenametr_destroy(hashtab_key_t key,hashtab_datum_t datum,void * p)1402 static int filenametr_destroy(hashtab_key_t key, hashtab_datum_t datum,
1403 			      void *p __attribute__ ((unused)))
1404 {
1405 	filename_trans_key_t *ft = (filename_trans_key_t *)key;
1406 	filename_trans_datum_t *fd = datum, *next;
1407 
1408 	free(ft->name);
1409 	free(key);
1410 	do {
1411 		next = fd->next;
1412 		ebitmap_destroy(&fd->stypes);
1413 		free(fd);
1414 		fd = next;
1415 	} while (fd);
1416 	return 0;
1417 }
1418 
range_tr_destroy(hashtab_key_t key,hashtab_datum_t datum,void * p)1419 static int range_tr_destroy(hashtab_key_t key, hashtab_datum_t datum,
1420 			    void *p __attribute__ ((unused)))
1421 {
1422 	struct mls_range *rt = (struct mls_range *)datum;
1423 	free(key);
1424 	ebitmap_destroy(&rt->level[0].cat);
1425 	ebitmap_destroy(&rt->level[1].cat);
1426 	free(datum);
1427 	return 0;
1428 }
1429 
ocontext_selinux_free(ocontext_t ** ocontexts)1430 static void ocontext_selinux_free(ocontext_t **ocontexts)
1431 {
1432 	ocontext_t *c, *ctmp;
1433 	int i;
1434 
1435 	for (i = 0; i < OCON_NUM; i++) {
1436 		c = ocontexts[i];
1437 		while (c) {
1438 			ctmp = c;
1439 			c = c->next;
1440 			context_destroy(&ctmp->context[0]);
1441 			context_destroy(&ctmp->context[1]);
1442 			if (i == OCON_ISID || i == OCON_FS || i == OCON_NETIF
1443 				|| i == OCON_FSUSE)
1444 				free(ctmp->u.name);
1445 			else if (i == OCON_IBENDPORT)
1446 				free(ctmp->u.ibendport.dev_name);
1447 			free(ctmp);
1448 		}
1449 	}
1450 }
1451 
ocontext_xen_free(ocontext_t ** ocontexts)1452 static void ocontext_xen_free(ocontext_t **ocontexts)
1453 {
1454 	ocontext_t *c, *ctmp;
1455 	int i;
1456 
1457 	for (i = 0; i < OCON_NUM; i++) {
1458 		c = ocontexts[i];
1459 		while (c) {
1460 			ctmp = c;
1461 			c = c->next;
1462 			context_destroy(&ctmp->context[0]);
1463 			context_destroy(&ctmp->context[1]);
1464 			if (i == OCON_ISID || i == OCON_XEN_DEVICETREE)
1465 				free(ctmp->u.name);
1466 			free(ctmp);
1467 		}
1468 	}
1469 }
1470 
1471 /*
1472  * Free any memory allocated by a policy database structure.
1473  */
policydb_destroy(policydb_t * p)1474 void policydb_destroy(policydb_t * p)
1475 {
1476 	ocontext_t *c, *ctmp;
1477 	genfs_t *g, *gtmp;
1478 	unsigned int i;
1479 	role_allow_t *ra, *lra = NULL;
1480 	role_trans_t *tr, *ltr = NULL;
1481 
1482 	if (!p)
1483 		return;
1484 
1485 	ebitmap_destroy(&p->policycaps);
1486 
1487 	ebitmap_destroy(&p->permissive_map);
1488 
1489 	symtabs_destroy(p->symtab);
1490 
1491 	for (i = 0; i < SYM_NUM; i++) {
1492 		if (p->sym_val_to_name[i])
1493 			free(p->sym_val_to_name[i]);
1494 	}
1495 
1496 	if (p->class_val_to_struct)
1497 		free(p->class_val_to_struct);
1498 	if (p->role_val_to_struct)
1499 		free(p->role_val_to_struct);
1500 	if (p->user_val_to_struct)
1501 		free(p->user_val_to_struct);
1502 	if (p->type_val_to_struct)
1503 		free(p->type_val_to_struct);
1504 	free(p->decl_val_to_struct);
1505 
1506 	for (i = 0; i < SYM_NUM; i++) {
1507 		(void)hashtab_map(p->scope[i].table, scope_destroy, 0);
1508 		hashtab_destroy(p->scope[i].table);
1509 	}
1510 	avrule_block_list_destroy(p->global);
1511 	free(p->name);
1512 	free(p->version);
1513 
1514 	avtab_destroy(&p->te_avtab);
1515 
1516 	if (p->target_platform == SEPOL_TARGET_SELINUX)
1517 		ocontext_selinux_free(p->ocontexts);
1518 	else if (p->target_platform == SEPOL_TARGET_XEN)
1519 		ocontext_xen_free(p->ocontexts);
1520 
1521 	g = p->genfs;
1522 	while (g) {
1523 		free(g->fstype);
1524 		c = g->head;
1525 		while (c) {
1526 			ctmp = c;
1527 			c = c->next;
1528 			context_destroy(&ctmp->context[0]);
1529 			free(ctmp->u.name);
1530 			free(ctmp);
1531 		}
1532 		gtmp = g;
1533 		g = g->next;
1534 		free(gtmp);
1535 	}
1536 	cond_policydb_destroy(p);
1537 
1538 	for (tr = p->role_tr; tr; tr = tr->next) {
1539 		if (ltr)
1540 			free(ltr);
1541 		ltr = tr;
1542 	}
1543 	if (ltr)
1544 		free(ltr);
1545 
1546 	for (ra = p->role_allow; ra; ra = ra->next) {
1547 		if (lra)
1548 			free(lra);
1549 		lra = ra;
1550 	}
1551 	if (lra)
1552 		free(lra);
1553 
1554 	hashtab_map(p->filename_trans, filenametr_destroy, NULL);
1555 	hashtab_destroy(p->filename_trans);
1556 
1557 	hashtab_map(p->range_tr, range_tr_destroy, NULL);
1558 	hashtab_destroy(p->range_tr);
1559 
1560 	if (p->type_attr_map) {
1561 		for (i = 0; i < p->p_types.nprim; i++) {
1562 			ebitmap_destroy(&p->type_attr_map[i]);
1563 		}
1564 		free(p->type_attr_map);
1565 	}
1566 
1567 	if (p->attr_type_map) {
1568 		for (i = 0; i < p->p_types.nprim; i++) {
1569 			ebitmap_destroy(&p->attr_type_map[i]);
1570 		}
1571 		free(p->attr_type_map);
1572 	}
1573 
1574 	return;
1575 }
1576 
symtabs_destroy(symtab_t * symtab)1577 void symtabs_destroy(symtab_t * symtab)
1578 {
1579 	int i;
1580 	for (i = 0; i < SYM_NUM; i++) {
1581 		(void)hashtab_map(symtab[i].table, destroy_f[i], 0);
1582 		hashtab_destroy(symtab[i].table);
1583 	}
1584 }
1585 
scope_destroy(hashtab_key_t key,hashtab_datum_t datum,void * p)1586 int scope_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
1587 		  __attribute__ ((unused)))
1588 {
1589 	scope_datum_t *cur = (scope_datum_t *) datum;
1590 	free(key);
1591 	if (cur != NULL) {
1592 		free(cur->decl_ids);
1593 	}
1594 	free(cur);
1595 	return 0;
1596 }
1597 
1598 /*
1599  * Load the initial SIDs specified in a policy database
1600  * structure into a SID table.
1601  */
policydb_load_isids(policydb_t * p,sidtab_t * s)1602 int policydb_load_isids(policydb_t * p, sidtab_t * s)
1603 {
1604 	ocontext_t *head, *c;
1605 
1606 	if (sepol_sidtab_init(s)) {
1607 		ERR(NULL, "out of memory on SID table init");
1608 		return -1;
1609 	}
1610 
1611 	head = p->ocontexts[OCON_ISID];
1612 	for (c = head; c; c = c->next) {
1613 		if (sepol_sidtab_insert(s, c->sid[0], &c->context[0])) {
1614 			ERR(NULL, "unable to load initial SID %s", c->u.name);
1615 			return -1;
1616 		}
1617 	}
1618 
1619 	return 0;
1620 }
1621 
1622 /* Declare a symbol for a certain avrule_block context.  Insert it
1623  * into a symbol table for a policy.  This function will handle
1624  * inserting the appropriate scope information in addition to
1625  * inserting the symbol into the hash table.
1626  *
1627  * arguments:
1628  *   policydb_t *pol       module policy to modify
1629  *   uint32_t sym          the symbole table for insertion (SYM_*)
1630  *   hashtab_key_t key     the key for the symbol - not cloned
1631  *   hashtab_datum_t data  the data for the symbol - not cloned
1632  *   scope                 scope of this symbol, either SCOPE_REQ or SCOPE_DECL
1633  *   avrule_decl_id        identifier for this symbol's encapsulating declaration
1634  *   value (out)           assigned value to the symbol (if value is not NULL)
1635  *
1636  * returns:
1637  *   0                     success
1638  *   1                     success, but symbol already existed as a requirement
1639  *                         (datum was not inserted and needs to be free()d)
1640  *   -1                    general error
1641  *   -2                    scope conflicted
1642  *   -ENOMEM               memory error
1643  *   error codes from hashtab_insert
1644  */
symtab_insert(policydb_t * pol,uint32_t sym,hashtab_key_t key,hashtab_datum_t datum,uint32_t scope,uint32_t avrule_decl_id,uint32_t * value)1645 int symtab_insert(policydb_t * pol, uint32_t sym,
1646 		  hashtab_key_t key, hashtab_datum_t datum,
1647 		  uint32_t scope, uint32_t avrule_decl_id, uint32_t * value)
1648 {
1649 	int rc, retval = 0;
1650 	unsigned int i;
1651 	scope_datum_t *scope_datum;
1652 
1653 	/* check if the symbol is already there.  multiple
1654 	 * declarations of non-roles/non-users are illegal, but
1655 	 * multiple requires are allowed. */
1656 
1657 	/* FIX ME - the failures after the hashtab_insert will leave
1658 	 * the policy in a inconsistent state. */
1659 	rc = hashtab_insert(pol->symtab[sym].table, key, datum);
1660 	if (rc == SEPOL_OK) {
1661 		/* if no value is passed in the symbol is not primary
1662 		 * (i.e. aliases) */
1663 		if (value)
1664 			*value = ++pol->symtab[sym].nprim;
1665 	} else if (rc == SEPOL_EEXIST) {
1666 		retval = 1;	/* symbol not added -- need to free() later */
1667 	} else {
1668 		return rc;
1669 	}
1670 
1671 	/* get existing scope information; if there is not one then
1672 	 * create it */
1673 	scope_datum =
1674 	    (scope_datum_t *) hashtab_search(pol->scope[sym].table, key);
1675 	if (scope_datum == NULL) {
1676 		hashtab_key_t key2 = strdup((char *)key);
1677 		if (!key2)
1678 			return -ENOMEM;
1679 		if ((scope_datum = malloc(sizeof(*scope_datum))) == NULL) {
1680 			free(key2);
1681 			return -ENOMEM;
1682 		}
1683 		scope_datum->scope = scope;
1684 		scope_datum->decl_ids = NULL;
1685 		scope_datum->decl_ids_len = 0;
1686 		if ((rc =
1687 		     hashtab_insert(pol->scope[sym].table, key2,
1688 				    scope_datum)) != 0) {
1689 			free(key2);
1690 			free(scope_datum);
1691 			return rc;
1692 		}
1693 	} else if (scope_datum->scope == SCOPE_DECL && scope == SCOPE_DECL) {
1694 		/* disallow multiple declarations for non-roles/users */
1695 		if (sym != SYM_ROLES && sym != SYM_USERS) {
1696 			return -2;
1697 		}
1698 		/* Further confine that a role attribute can't have the same
1699 		 * name as another regular role, and a role attribute can't
1700 		 * be declared more than once. */
1701 		if (sym == SYM_ROLES) {
1702 			role_datum_t *base_role;
1703 			role_datum_t *cur_role = (role_datum_t *)datum;
1704 
1705 			base_role = (role_datum_t *)
1706 					hashtab_search(pol->symtab[sym].table,
1707 						       key);
1708 			assert(base_role != NULL);
1709 
1710 			if (!((base_role->flavor == ROLE_ROLE) &&
1711 			    (cur_role->flavor == ROLE_ROLE))) {
1712 				/* Only regular roles are allowed to have
1713 				 * multiple declarations. */
1714 				return -2;
1715 			}
1716 		}
1717 	} else if (scope_datum->scope == SCOPE_REQ && scope == SCOPE_DECL) {
1718 		scope_datum->scope = SCOPE_DECL;
1719 	}
1720 
1721 	/* search through the pre-existing list to avoid adding duplicates */
1722 	for (i = 0; i < scope_datum->decl_ids_len; i++) {
1723 		if (scope_datum->decl_ids[i] == avrule_decl_id) {
1724 			/* already there, so don't modify its scope */
1725 			return retval;
1726 		}
1727 	}
1728 
1729 	if (add_i_to_a(avrule_decl_id,
1730 		       &scope_datum->decl_ids_len,
1731 		       &scope_datum->decl_ids) == -1) {
1732 		return -ENOMEM;
1733 	}
1734 
1735 	if (scope_datum->scope == SCOPE_DECL && scope == SCOPE_REQ) {
1736 		/* Need to keep the decl at the end of the list */
1737 		uint32_t len, tmp;
1738 		len = scope_datum->decl_ids_len;
1739 		if (len < 2) {
1740 			/* This should be impossible here */
1741 			return -1;
1742 		}
1743 		tmp = scope_datum->decl_ids[len-2];
1744 		scope_datum->decl_ids[len-2] = scope_datum->decl_ids[len-1];
1745 		scope_datum->decl_ids[len-1] = tmp;
1746 	}
1747 
1748 	return retval;
1749 }
1750 
type_set_or(type_set_t * dst,const type_set_t * a,const type_set_t * b)1751 static int type_set_or(type_set_t * dst, const type_set_t * a, const type_set_t * b)
1752 {
1753 	type_set_init(dst);
1754 
1755 	if (ebitmap_or(&dst->types, &a->types, &b->types)) {
1756 		return -1;
1757 	}
1758 	if (ebitmap_or(&dst->negset, &a->negset, &b->negset)) {
1759 		return -1;
1760 	}
1761 
1762 	dst->flags |= a->flags;
1763 	dst->flags |= b->flags;
1764 
1765 	return 0;
1766 }
1767 
type_set_cpy(type_set_t * dst,const type_set_t * src)1768 int type_set_cpy(type_set_t * dst, const type_set_t * src)
1769 {
1770 	type_set_init(dst);
1771 
1772 	dst->flags = src->flags;
1773 	if (ebitmap_cpy(&dst->types, &src->types))
1774 		return -1;
1775 	if (ebitmap_cpy(&dst->negset, &src->negset))
1776 		return -1;
1777 
1778 	return 0;
1779 }
1780 
type_set_or_eq(type_set_t * dst,const type_set_t * other)1781 int type_set_or_eq(type_set_t * dst, const type_set_t * other)
1782 {
1783 	int ret;
1784 	type_set_t tmp;
1785 
1786 	if (type_set_or(&tmp, dst, other))
1787 		return -1;
1788 	type_set_destroy(dst);
1789 	ret = type_set_cpy(dst, &tmp);
1790 	type_set_destroy(&tmp);
1791 
1792 	return ret;
1793 }
1794 
1795 /***********************************************************************/
1796 /* everything below is for policy reads */
1797 
1798 /* The following are read functions for module structures */
1799 
role_set_read(role_set_t * r,struct policy_file * fp)1800 static int role_set_read(role_set_t * r, struct policy_file *fp)
1801 {
1802 	uint32_t buf[1];
1803 	int rc;
1804 
1805 	if (ebitmap_read(&r->roles, fp))
1806 		return -1;
1807 	rc = next_entry(buf, fp, sizeof(uint32_t));
1808 	if (rc < 0)
1809 		return -1;
1810 	r->flags = le32_to_cpu(buf[0]);
1811 
1812 	return 0;
1813 }
1814 
type_set_read(type_set_t * t,struct policy_file * fp)1815 static int type_set_read(type_set_t * t, struct policy_file *fp)
1816 {
1817 	uint32_t buf[1];
1818 	int rc;
1819 
1820 	if (ebitmap_read(&t->types, fp))
1821 		return -1;
1822 	if (ebitmap_read(&t->negset, fp))
1823 		return -1;
1824 
1825 	rc = next_entry(buf, fp, sizeof(uint32_t));
1826 	if (rc < 0)
1827 		return -1;
1828 	t->flags = le32_to_cpu(buf[0]);
1829 
1830 	return 0;
1831 }
1832 
1833 /*
1834  * Read a MLS range structure from a policydb binary
1835  * representation file.
1836  */
mls_read_range_helper(mls_range_t * r,struct policy_file * fp)1837 static int mls_read_range_helper(mls_range_t * r, struct policy_file *fp)
1838 {
1839 	uint32_t buf[2], items;
1840 	int rc;
1841 
1842 	rc = next_entry(buf, fp, sizeof(uint32_t));
1843 	if (rc < 0)
1844 		goto out;
1845 
1846 	items = le32_to_cpu(buf[0]);
1847 	if (items > ARRAY_SIZE(buf)) {
1848 		ERR(fp->handle, "range overflow");
1849 		rc = -EINVAL;
1850 		goto out;
1851 	}
1852 	rc = next_entry(buf, fp, sizeof(uint32_t) * items);
1853 	if (rc < 0) {
1854 		ERR(fp->handle, "truncated range");
1855 		goto out;
1856 	}
1857 	r->level[0].sens = le32_to_cpu(buf[0]);
1858 	if (items > 1)
1859 		r->level[1].sens = le32_to_cpu(buf[1]);
1860 	else
1861 		r->level[1].sens = r->level[0].sens;
1862 
1863 	rc = ebitmap_read(&r->level[0].cat, fp);
1864 	if (rc) {
1865 		ERR(fp->handle, "error reading low categories");
1866 		goto out;
1867 	}
1868 	if (items > 1) {
1869 		rc = ebitmap_read(&r->level[1].cat, fp);
1870 		if (rc) {
1871 			ERR(fp->handle, "error reading high categories");
1872 			goto bad_high;
1873 		}
1874 	} else {
1875 		rc = ebitmap_cpy(&r->level[1].cat, &r->level[0].cat);
1876 		if (rc) {
1877 			ERR(fp->handle, "out of memory");
1878 			goto bad_high;
1879 		}
1880 	}
1881 
1882 	rc = 0;
1883       out:
1884 	return rc;
1885       bad_high:
1886 	ebitmap_destroy(&r->level[0].cat);
1887 	goto out;
1888 }
1889 
1890 /*
1891  * Read a semantic MLS level structure from a policydb binary
1892  * representation file.
1893  */
mls_read_semantic_level_helper(mls_semantic_level_t * l,struct policy_file * fp)1894 static int mls_read_semantic_level_helper(mls_semantic_level_t * l,
1895 					  struct policy_file *fp)
1896 {
1897 	uint32_t buf[2], ncat;
1898 	unsigned int i;
1899 	mls_semantic_cat_t *cat;
1900 	int rc;
1901 
1902 	mls_semantic_level_init(l);
1903 
1904 	rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
1905 	if (rc < 0) {
1906 		ERR(fp->handle, "truncated level");
1907 		goto bad;
1908 	}
1909 	l->sens = le32_to_cpu(buf[0]);
1910 
1911 	ncat = le32_to_cpu(buf[1]);
1912 	for (i = 0; i < ncat; i++) {
1913 		cat = (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t));
1914 		if (!cat) {
1915 			ERR(fp->handle, "out of memory");
1916 			goto bad;
1917 		}
1918 
1919 		mls_semantic_cat_init(cat);
1920 		cat->next = l->cat;
1921 		l->cat = cat;
1922 
1923 		rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
1924 		if (rc < 0) {
1925 			ERR(fp->handle, "error reading level categories");
1926 			goto bad;
1927 		}
1928 		cat->low = le32_to_cpu(buf[0]);
1929 		cat->high = le32_to_cpu(buf[1]);
1930 	}
1931 
1932 	return 0;
1933 
1934       bad:
1935 	return -EINVAL;
1936 }
1937 
1938 /*
1939  * Read a semantic MLS range structure from a policydb binary
1940  * representation file.
1941  */
mls_read_semantic_range_helper(mls_semantic_range_t * r,struct policy_file * fp)1942 static int mls_read_semantic_range_helper(mls_semantic_range_t * r,
1943 					  struct policy_file *fp)
1944 {
1945 	int rc;
1946 
1947 	rc = mls_read_semantic_level_helper(&r->level[0], fp);
1948 	if (rc)
1949 		return rc;
1950 
1951 	rc = mls_read_semantic_level_helper(&r->level[1], fp);
1952 
1953 	return rc;
1954 }
1955 
mls_level_to_semantic(mls_level_t * l,mls_semantic_level_t * sl)1956 static int mls_level_to_semantic(mls_level_t * l, mls_semantic_level_t * sl)
1957 {
1958 	unsigned int i;
1959 	ebitmap_node_t *cnode;
1960 	mls_semantic_cat_t *open_cat = NULL;
1961 
1962 	mls_semantic_level_init(sl);
1963 	sl->sens = l->sens;
1964 	ebitmap_for_each_bit(&l->cat, cnode, i) {
1965 		if (ebitmap_node_get_bit(cnode, i)) {
1966 			if (open_cat)
1967 				continue;
1968 			open_cat = (mls_semantic_cat_t *)
1969 			    malloc(sizeof(mls_semantic_cat_t));
1970 			if (!open_cat)
1971 				return -1;
1972 
1973 			mls_semantic_cat_init(open_cat);
1974 			open_cat->low = i + 1;
1975 			open_cat->next = sl->cat;
1976 			sl->cat = open_cat;
1977 		} else {
1978 			if (!open_cat)
1979 				continue;
1980 			open_cat->high = i;
1981 			open_cat = NULL;
1982 		}
1983 	}
1984 	if (open_cat)
1985 		open_cat->high = i;
1986 
1987 	return 0;
1988 }
1989 
mls_range_to_semantic(mls_range_t * r,mls_semantic_range_t * sr)1990 static int mls_range_to_semantic(mls_range_t * r, mls_semantic_range_t * sr)
1991 {
1992 	if (mls_level_to_semantic(&r->level[0], &sr->level[0]))
1993 		return -1;
1994 
1995 	if (mls_level_to_semantic(&r->level[1], &sr->level[1]))
1996 		return -1;
1997 
1998 	return 0;
1999 }
2000 
2001 /*
2002  * Read and validate a security context structure
2003  * from a policydb binary representation file.
2004  */
context_read_and_validate(context_struct_t * c,policydb_t * p,struct policy_file * fp)2005 static int context_read_and_validate(context_struct_t * c,
2006 				     policydb_t * p, struct policy_file *fp)
2007 {
2008 	uint32_t buf[3];
2009 	int rc;
2010 
2011 	rc = next_entry(buf, fp, sizeof(uint32_t) * 3);
2012 	if (rc < 0) {
2013 		ERR(fp->handle, "context truncated");
2014 		return -1;
2015 	}
2016 	c->user = le32_to_cpu(buf[0]);
2017 	c->role = le32_to_cpu(buf[1]);
2018 	c->type = le32_to_cpu(buf[2]);
2019 	if ((p->policy_type == POLICY_KERN
2020 	     && p->policyvers >= POLICYDB_VERSION_MLS)
2021 	    || (p->policy_type == POLICY_BASE
2022 		&& p->policyvers >= MOD_POLICYDB_VERSION_MLS)) {
2023 		if (mls_read_range_helper(&c->range, fp)) {
2024 			ERR(fp->handle, "error reading MLS range "
2025 			    "of context");
2026 			return -1;
2027 		}
2028 	}
2029 
2030 	if (!policydb_context_isvalid(p, c)) {
2031 		ERR(fp->handle, "invalid security context");
2032 		context_destroy(c);
2033 		return -1;
2034 	}
2035 	return 0;
2036 }
2037 
2038 /*
2039  * The following *_read functions are used to
2040  * read the symbol data from a policy database
2041  * binary representation file.
2042  */
2043 
perm_read(policydb_t * p,hashtab_t h,struct policy_file * fp,uint32_t nprim)2044 static int perm_read(policydb_t * p
2045 		     __attribute__ ((unused)), hashtab_t h,
2046 		     struct policy_file *fp, uint32_t nprim)
2047 {
2048 	char *key = 0;
2049 	perm_datum_t *perdatum;
2050 	uint32_t buf[2];
2051 	size_t len;
2052 	int rc;
2053 
2054 	perdatum = calloc(1, sizeof(perm_datum_t));
2055 	if (!perdatum)
2056 		return -1;
2057 
2058 	rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
2059 	if (rc < 0)
2060 		goto bad;
2061 
2062 	len = le32_to_cpu(buf[0]);
2063 	if(str_read(&key, fp, len))
2064 		goto bad;
2065 
2066 	perdatum->s.value = le32_to_cpu(buf[1]);
2067 	if (!value_isvalid(perdatum->s.value, nprim))
2068 		goto bad;
2069 
2070 	if (hashtab_insert(h, key, perdatum))
2071 		goto bad;
2072 
2073 	return 0;
2074 
2075       bad:
2076 	perm_destroy(key, perdatum, NULL);
2077 	return -1;
2078 }
2079 
common_read(policydb_t * p,hashtab_t h,struct policy_file * fp)2080 static int common_read(policydb_t * p, hashtab_t h, struct policy_file *fp)
2081 {
2082 	char *key = 0;
2083 	common_datum_t *comdatum;
2084 	uint32_t buf[4];
2085 	size_t len, nel;
2086 	unsigned int i;
2087 	int rc;
2088 
2089 	comdatum = calloc(1, sizeof(common_datum_t));
2090 	if (!comdatum)
2091 		return -1;
2092 
2093 	rc = next_entry(buf, fp, sizeof(uint32_t) * 4);
2094 	if (rc < 0)
2095 		goto bad;
2096 
2097 	len = le32_to_cpu(buf[0]);
2098 	if (zero_or_saturated(len))
2099 		goto bad;
2100 
2101 	comdatum->s.value = le32_to_cpu(buf[1]);
2102 
2103 	if (symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE))
2104 		goto bad;
2105 	comdatum->permissions.nprim = le32_to_cpu(buf[2]);
2106 	nel = le32_to_cpu(buf[3]);
2107 
2108 	key = malloc(len + 1);
2109 	if (!key)
2110 		goto bad;
2111 	rc = next_entry(key, fp, len);
2112 	if (rc < 0)
2113 		goto bad;
2114 	key[len] = 0;
2115 
2116 	for (i = 0; i < nel; i++) {
2117 		if (perm_read(p, comdatum->permissions.table, fp, comdatum->permissions.nprim))
2118 			goto bad;
2119 	}
2120 
2121 	if (hashtab_insert(h, key, comdatum))
2122 		goto bad;
2123 
2124 	return 0;
2125 
2126       bad:
2127 	common_destroy(key, comdatum, NULL);
2128 	return -1;
2129 }
2130 
read_cons_helper(policydb_t * p,constraint_node_t ** nodep,unsigned int ncons,int allowxtarget,struct policy_file * fp)2131 static int read_cons_helper(policydb_t * p, constraint_node_t ** nodep,
2132 			    unsigned int ncons,
2133 			    int allowxtarget, struct policy_file *fp)
2134 {
2135 	constraint_node_t *c, *lc;
2136 	constraint_expr_t *e, *le;
2137 	uint32_t buf[3];
2138 	size_t nexpr;
2139 	unsigned int i, j;
2140 	int rc, depth;
2141 
2142 	lc = NULL;
2143 	for (i = 0; i < ncons; i++) {
2144 		c = calloc(1, sizeof(constraint_node_t));
2145 		if (!c)
2146 			return -1;
2147 
2148 		if (lc)
2149 			lc->next = c;
2150 		else
2151 			*nodep = c;
2152 
2153 		rc = next_entry(buf, fp, (sizeof(uint32_t) * 2));
2154 		if (rc < 0)
2155 			return -1;
2156 		c->permissions = le32_to_cpu(buf[0]);
2157 		nexpr = le32_to_cpu(buf[1]);
2158 		le = NULL;
2159 		depth = -1;
2160 		for (j = 0; j < nexpr; j++) {
2161 			e = malloc(sizeof(constraint_expr_t));
2162 			if (!e)
2163 				return -1;
2164 			if (constraint_expr_init(e) == -1) {
2165 				free(e);
2166 				return -1;
2167 			}
2168 			if (le) {
2169 				le->next = e;
2170 			} else {
2171 				c->expr = e;
2172 			}
2173 
2174 			rc = next_entry(buf, fp, (sizeof(uint32_t) * 3));
2175 			if (rc < 0)
2176 				return -1;
2177 			e->expr_type = le32_to_cpu(buf[0]);
2178 			e->attr = le32_to_cpu(buf[1]);
2179 			e->op = le32_to_cpu(buf[2]);
2180 
2181 			switch (e->expr_type) {
2182 			case CEXPR_NOT:
2183 				if (depth < 0)
2184 					return -1;
2185 				break;
2186 			case CEXPR_AND:
2187 			case CEXPR_OR:
2188 				if (depth < 1)
2189 					return -1;
2190 				depth--;
2191 				break;
2192 			case CEXPR_ATTR:
2193 				if (depth == (CEXPR_MAXDEPTH - 1))
2194 					return -1;
2195 				depth++;
2196 				break;
2197 			case CEXPR_NAMES:
2198 				if (!allowxtarget && (e->attr & CEXPR_XTARGET))
2199 					return -1;
2200 				if (depth == (CEXPR_MAXDEPTH - 1))
2201 					return -1;
2202 				depth++;
2203 				if (ebitmap_read(&e->names, fp))
2204 					return -1;
2205 				if (p->policy_type != POLICY_KERN &&
2206 				    type_set_read(e->type_names, fp))
2207 					return -1;
2208 				else if (p->policy_type == POLICY_KERN &&
2209 					 p->policyvers >= POLICYDB_VERSION_CONSTRAINT_NAMES &&
2210 					 type_set_read(e->type_names, fp))
2211 					return -1;
2212 				break;
2213 			default:
2214 				return -1;
2215 			}
2216 			le = e;
2217 		}
2218 		if (depth != 0)
2219 			return -1;
2220 		lc = c;
2221 	}
2222 
2223 	return 0;
2224 }
2225 
class_read(policydb_t * p,hashtab_t h,struct policy_file * fp)2226 static int class_read(policydb_t * p, hashtab_t h, struct policy_file *fp)
2227 {
2228 	char *key = 0;
2229 	class_datum_t *cladatum;
2230 	uint32_t buf[6];
2231 	size_t len, len2, ncons, nel;
2232 	unsigned int i;
2233 	int rc;
2234 
2235 	cladatum = (class_datum_t *) calloc(1, sizeof(class_datum_t));
2236 	if (!cladatum)
2237 		return -1;
2238 
2239 	rc = next_entry(buf, fp, sizeof(uint32_t) * 6);
2240 	if (rc < 0)
2241 		goto bad;
2242 
2243 	len = le32_to_cpu(buf[0]);
2244 	if (zero_or_saturated(len))
2245 		goto bad;
2246 	len2 = le32_to_cpu(buf[1]);
2247 	if (is_saturated(len2))
2248 		goto bad;
2249 	cladatum->s.value = le32_to_cpu(buf[2]);
2250 
2251 	if (symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE))
2252 		goto bad;
2253 	cladatum->permissions.nprim = le32_to_cpu(buf[3]);
2254 	nel = le32_to_cpu(buf[4]);
2255 
2256 	ncons = le32_to_cpu(buf[5]);
2257 
2258 	key = malloc(len + 1);
2259 	if (!key)
2260 		goto bad;
2261 	rc = next_entry(key, fp, len);
2262 	if (rc < 0)
2263 		goto bad;
2264 	key[len] = 0;
2265 
2266 	if (len2) {
2267 		cladatum->comkey = malloc(len2 + 1);
2268 		if (!cladatum->comkey)
2269 			goto bad;
2270 		rc = next_entry(cladatum->comkey, fp, len2);
2271 		if (rc < 0)
2272 			goto bad;
2273 		cladatum->comkey[len2] = 0;
2274 
2275 		cladatum->comdatum = hashtab_search(p->p_commons.table,
2276 						    cladatum->comkey);
2277 		if (!cladatum->comdatum) {
2278 			ERR(fp->handle, "unknown common %s", cladatum->comkey);
2279 			goto bad;
2280 		}
2281 	}
2282 	for (i = 0; i < nel; i++) {
2283 		if (perm_read(p, cladatum->permissions.table, fp, cladatum->permissions.nprim))
2284 			goto bad;
2285 	}
2286 
2287 	if (read_cons_helper(p, &cladatum->constraints, ncons, 0, fp))
2288 		goto bad;
2289 
2290 	if ((p->policy_type == POLICY_KERN
2291 	     && p->policyvers >= POLICYDB_VERSION_VALIDATETRANS)
2292 	    || (p->policy_type == POLICY_BASE
2293 		&& p->policyvers >= MOD_POLICYDB_VERSION_VALIDATETRANS)) {
2294 		/* grab the validatetrans rules */
2295 		rc = next_entry(buf, fp, sizeof(uint32_t));
2296 		if (rc < 0)
2297 			goto bad;
2298 		ncons = le32_to_cpu(buf[0]);
2299 		if (read_cons_helper(p, &cladatum->validatetrans, ncons, 1, fp))
2300 			goto bad;
2301 	}
2302 
2303 	if ((p->policy_type == POLICY_KERN &&
2304 	     p->policyvers >= POLICYDB_VERSION_NEW_OBJECT_DEFAULTS) ||
2305 	    (p->policy_type == POLICY_BASE &&
2306 	     p->policyvers >= MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS)) {
2307 		rc = next_entry(buf, fp, sizeof(uint32_t) * 3);
2308 		if (rc < 0)
2309 			goto bad;
2310 		cladatum->default_user = le32_to_cpu(buf[0]);
2311 		cladatum->default_role = le32_to_cpu(buf[1]);
2312 		cladatum->default_range = le32_to_cpu(buf[2]);
2313 	}
2314 
2315 	if ((p->policy_type == POLICY_KERN &&
2316 	     p->policyvers >= POLICYDB_VERSION_DEFAULT_TYPE) ||
2317 	    (p->policy_type == POLICY_BASE &&
2318 	     p->policyvers >= MOD_POLICYDB_VERSION_DEFAULT_TYPE)) {
2319 		rc = next_entry(buf, fp, sizeof(uint32_t));
2320 		if (rc < 0)
2321 			goto bad;
2322 		cladatum->default_type = le32_to_cpu(buf[0]);
2323 	}
2324 
2325 	if (hashtab_insert(h, key, cladatum))
2326 		goto bad;
2327 
2328 	return 0;
2329 
2330       bad:
2331 	class_destroy(key, cladatum, NULL);
2332 	return -1;
2333 }
2334 
role_read(policydb_t * p,hashtab_t h,struct policy_file * fp)2335 static int role_read(policydb_t * p, hashtab_t h, struct policy_file *fp)
2336 {
2337 	char *key = 0;
2338 	role_datum_t *role;
2339 	uint32_t buf[3];
2340 	size_t len;
2341 	int rc, to_read = 2;
2342 
2343 	role = calloc(1, sizeof(role_datum_t));
2344 	if (!role)
2345 		return -1;
2346 
2347 	if (policydb_has_boundary_feature(p))
2348 		to_read = 3;
2349 
2350 	rc = next_entry(buf, fp, sizeof(uint32_t) * to_read);
2351 	if (rc < 0)
2352 		goto bad;
2353 
2354 	len = le32_to_cpu(buf[0]);
2355 	if (zero_or_saturated(len))
2356 		goto bad;
2357 
2358 	role->s.value = le32_to_cpu(buf[1]);
2359 	if (policydb_has_boundary_feature(p))
2360 		role->bounds = le32_to_cpu(buf[2]);
2361 
2362 	key = malloc(len + 1);
2363 	if (!key)
2364 		goto bad;
2365 	rc = next_entry(key, fp, len);
2366 	if (rc < 0)
2367 		goto bad;
2368 	key[len] = 0;
2369 
2370 	if (ebitmap_read(&role->dominates, fp))
2371 		goto bad;
2372 
2373 	if (p->policy_type == POLICY_KERN) {
2374 		if (ebitmap_read(&role->types.types, fp))
2375 			goto bad;
2376 	} else {
2377 		if (type_set_read(&role->types, fp))
2378 			goto bad;
2379 	}
2380 
2381 	if (p->policy_type != POLICY_KERN &&
2382 	    p->policyvers >= MOD_POLICYDB_VERSION_ROLEATTRIB) {
2383 		rc = next_entry(buf, fp, sizeof(uint32_t));
2384 		if (rc < 0)
2385 			goto bad;
2386 
2387 		role->flavor = le32_to_cpu(buf[0]);
2388 
2389 		if (ebitmap_read(&role->roles, fp))
2390 			goto bad;
2391 	}
2392 
2393 	if (strcmp(key, OBJECT_R) == 0) {
2394 		if (role->s.value != OBJECT_R_VAL) {
2395 			ERR(fp->handle, "role %s has wrong value %d",
2396 			    OBJECT_R, role->s.value);
2397 			role_destroy(key, role, NULL);
2398 			return -1;
2399 		}
2400 		role_destroy(key, role, NULL);
2401 		return 0;
2402 	}
2403 
2404 	if (hashtab_insert(h, key, role))
2405 		goto bad;
2406 
2407 	return 0;
2408 
2409       bad:
2410 	role_destroy(key, role, NULL);
2411 	return -1;
2412 }
2413 
type_read(policydb_t * p,hashtab_t h,struct policy_file * fp)2414 static int type_read(policydb_t * p, hashtab_t h, struct policy_file *fp)
2415 {
2416 	char *key = 0;
2417 	type_datum_t *typdatum;
2418 	uint32_t buf[5];
2419 	size_t len;
2420 	int rc, to_read;
2421 	int pos = 0;
2422 
2423 	typdatum = calloc(1, sizeof(type_datum_t));
2424 	if (!typdatum)
2425 		return -1;
2426 
2427 	if (policydb_has_boundary_feature(p)) {
2428 		if (p->policy_type != POLICY_KERN
2429 		    && p->policyvers >= MOD_POLICYDB_VERSION_BOUNDARY_ALIAS)
2430 			to_read = 5;
2431 		else
2432 			to_read = 4;
2433 	}
2434 	else if (p->policy_type == POLICY_KERN)
2435 		to_read = 3;
2436 	else if (p->policyvers >= MOD_POLICYDB_VERSION_PERMISSIVE)
2437 		to_read = 5;
2438 	else
2439 		to_read = 4;
2440 
2441 	rc = next_entry(buf, fp, sizeof(uint32_t) * to_read);
2442 	if (rc < 0)
2443 		goto bad;
2444 
2445 	len = le32_to_cpu(buf[pos]);
2446 	if (zero_or_saturated(len))
2447 		goto bad;
2448 
2449 	typdatum->s.value = le32_to_cpu(buf[++pos]);
2450 	if (policydb_has_boundary_feature(p)) {
2451 		uint32_t properties;
2452 
2453 		if (p->policy_type != POLICY_KERN
2454 		    && p->policyvers >= MOD_POLICYDB_VERSION_BOUNDARY_ALIAS) {
2455 			typdatum->primary = le32_to_cpu(buf[++pos]);
2456 			properties = le32_to_cpu(buf[++pos]);
2457 		}
2458 		else {
2459 			properties = le32_to_cpu(buf[++pos]);
2460 
2461 			if (properties & TYPEDATUM_PROPERTY_PRIMARY)
2462 				typdatum->primary = 1;
2463 		}
2464 
2465 		if (properties & TYPEDATUM_PROPERTY_ATTRIBUTE)
2466 			typdatum->flavor = TYPE_ATTRIB;
2467 		if (properties & TYPEDATUM_PROPERTY_ALIAS
2468 		    && p->policy_type != POLICY_KERN)
2469 			typdatum->flavor = TYPE_ALIAS;
2470 		if (properties & TYPEDATUM_PROPERTY_PERMISSIVE
2471 		    && p->policy_type != POLICY_KERN)
2472 			typdatum->flags |= TYPE_FLAGS_PERMISSIVE;
2473 
2474 		typdatum->bounds = le32_to_cpu(buf[++pos]);
2475 	} else {
2476 		typdatum->primary = le32_to_cpu(buf[++pos]);
2477 		if (p->policy_type != POLICY_KERN) {
2478 			typdatum->flavor = le32_to_cpu(buf[++pos]);
2479 			if (p->policyvers >= MOD_POLICYDB_VERSION_PERMISSIVE)
2480 				typdatum->flags = le32_to_cpu(buf[++pos]);
2481 		}
2482 	}
2483 
2484 	if (p->policy_type != POLICY_KERN) {
2485 		if (ebitmap_read(&typdatum->types, fp))
2486 			goto bad;
2487 	}
2488 
2489 	key = malloc(len + 1);
2490 	if (!key)
2491 		goto bad;
2492 	rc = next_entry(key, fp, len);
2493 	if (rc < 0)
2494 		goto bad;
2495 	key[len] = 0;
2496 
2497 	if (hashtab_insert(h, key, typdatum))
2498 		goto bad;
2499 
2500 	return 0;
2501 
2502       bad:
2503 	type_destroy(key, typdatum, NULL);
2504 	return -1;
2505 }
2506 
role_trans_read(policydb_t * p,struct policy_file * fp)2507 static int role_trans_read(policydb_t *p, struct policy_file *fp)
2508 {
2509 	role_trans_t **t = &p->role_tr;
2510 	unsigned int i;
2511 	uint32_t buf[3], nel;
2512 	role_trans_t *tr, *ltr;
2513 	int rc;
2514 	int new_roletr = (p->policy_type == POLICY_KERN &&
2515 			  p->policyvers >= POLICYDB_VERSION_ROLETRANS);
2516 
2517 	rc = next_entry(buf, fp, sizeof(uint32_t));
2518 	if (rc < 0)
2519 		return -1;
2520 	nel = le32_to_cpu(buf[0]);
2521 	ltr = NULL;
2522 	for (i = 0; i < nel; i++) {
2523 		tr = calloc(1, sizeof(struct role_trans));
2524 		if (!tr) {
2525 			return -1;
2526 		}
2527 		if (ltr) {
2528 			ltr->next = tr;
2529 		} else {
2530 			*t = tr;
2531 		}
2532 		rc = next_entry(buf, fp, sizeof(uint32_t) * 3);
2533 		if (rc < 0)
2534 			return -1;
2535 		tr->role = le32_to_cpu(buf[0]);
2536 		tr->type = le32_to_cpu(buf[1]);
2537 		tr->new_role = le32_to_cpu(buf[2]);
2538 		if (new_roletr) {
2539 			rc = next_entry(buf, fp, sizeof(uint32_t));
2540 			if (rc < 0)
2541 				return -1;
2542 			tr->tclass = le32_to_cpu(buf[0]);
2543 		} else
2544 			tr->tclass = p->process_class;
2545 		ltr = tr;
2546 	}
2547 	return 0;
2548 }
2549 
role_allow_read(role_allow_t ** r,struct policy_file * fp)2550 static int role_allow_read(role_allow_t ** r, struct policy_file *fp)
2551 {
2552 	unsigned int i;
2553 	uint32_t buf[2], nel;
2554 	role_allow_t *ra, *lra;
2555 	int rc;
2556 
2557 	rc = next_entry(buf, fp, sizeof(uint32_t));
2558 	if (rc < 0)
2559 		return -1;
2560 	nel = le32_to_cpu(buf[0]);
2561 	lra = NULL;
2562 	for (i = 0; i < nel; i++) {
2563 		ra = calloc(1, sizeof(struct role_allow));
2564 		if (!ra) {
2565 			return -1;
2566 		}
2567 		if (lra) {
2568 			lra->next = ra;
2569 		} else {
2570 			*r = ra;
2571 		}
2572 		rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
2573 		if (rc < 0)
2574 			return -1;
2575 		ra->role = le32_to_cpu(buf[0]);
2576 		ra->new_role = le32_to_cpu(buf[1]);
2577 		lra = ra;
2578 	}
2579 	return 0;
2580 }
2581 
policydb_filetrans_insert(policydb_t * p,uint32_t stype,uint32_t ttype,uint32_t tclass,const char * name,char ** name_alloc,uint32_t otype,uint32_t * present_otype)2582 int policydb_filetrans_insert(policydb_t *p, uint32_t stype, uint32_t ttype,
2583 			      uint32_t tclass, const char *name,
2584 			      char **name_alloc, uint32_t otype,
2585 			      uint32_t *present_otype)
2586 {
2587 	filename_trans_key_t *ft, key;
2588 	filename_trans_datum_t *datum, *last;
2589 
2590 	key.ttype = ttype;
2591 	key.tclass = tclass;
2592 	key.name = (char *)name;
2593 
2594 	last = NULL;
2595 	datum = hashtab_search(p->filename_trans, (hashtab_key_t)&key);
2596 	while (datum) {
2597 		if (ebitmap_get_bit(&datum->stypes, stype - 1)) {
2598 			if (present_otype)
2599 				*present_otype = datum->otype;
2600 			return SEPOL_EEXIST;
2601 		}
2602 		if (datum->otype == otype)
2603 			break;
2604 		last = datum;
2605 		datum = datum->next;
2606 	}
2607 	if (!datum) {
2608 		datum = malloc(sizeof(*datum));
2609 		if (!datum)
2610 			return SEPOL_ENOMEM;
2611 
2612 		ebitmap_init(&datum->stypes);
2613 		datum->otype = otype;
2614 		datum->next = NULL;
2615 
2616 		if (last) {
2617 			last->next = datum;
2618 		} else {
2619 			char *name_dup;
2620 
2621 			if (name_alloc) {
2622 				name_dup = *name_alloc;
2623 				*name_alloc = NULL;
2624 			} else {
2625 				name_dup = strdup(name);
2626 				if (!name_dup) {
2627 					free(datum);
2628 					return SEPOL_ENOMEM;
2629 				}
2630 			}
2631 
2632 			ft = malloc(sizeof(*ft));
2633 			if (!ft) {
2634 				free(name_dup);
2635 				free(datum);
2636 				return SEPOL_ENOMEM;
2637 			}
2638 
2639 			ft->ttype = ttype;
2640 			ft->tclass = tclass;
2641 			ft->name = name_dup;
2642 
2643 			if (hashtab_insert(p->filename_trans, (hashtab_key_t)ft,
2644 					   (hashtab_datum_t)datum)) {
2645 				free(name_dup);
2646 				free(datum);
2647 				free(ft);
2648 				return SEPOL_ENOMEM;
2649 			}
2650 		}
2651 	}
2652 
2653 	p->filename_trans_count++;
2654 	return ebitmap_set_bit(&datum->stypes, stype - 1, 1);
2655 }
2656 
filename_trans_read_one_compat(policydb_t * p,struct policy_file * fp)2657 static int filename_trans_read_one_compat(policydb_t *p, struct policy_file *fp)
2658 {
2659 	uint32_t buf[4], len, stype, ttype, tclass, otype;
2660 	char *name = NULL;
2661 	int rc;
2662 
2663 	rc = next_entry(buf, fp, sizeof(uint32_t));
2664 	if (rc < 0)
2665 		return -1;
2666 	len = le32_to_cpu(buf[0]);
2667 	if (zero_or_saturated(len))
2668 		return -1;
2669 
2670 	name = calloc(len + 1, sizeof(*name));
2671 	if (!name)
2672 		return -1;
2673 
2674 	rc = next_entry(name, fp, len);
2675 	if (rc < 0)
2676 		goto err;
2677 
2678 	rc = next_entry(buf, fp, sizeof(uint32_t) * 4);
2679 	if (rc < 0)
2680 		goto err;
2681 
2682 	stype  = le32_to_cpu(buf[0]);
2683 	ttype  = le32_to_cpu(buf[1]);
2684 	tclass = le32_to_cpu(buf[2]);
2685 	otype  = le32_to_cpu(buf[3]);
2686 
2687 	rc = policydb_filetrans_insert(p, stype, ttype, tclass, name, &name,
2688 				       otype, NULL);
2689 	if (rc) {
2690 		if (rc != SEPOL_EEXIST)
2691 			goto err;
2692 		/*
2693 		 * Some old policies were wrongly generated with
2694 		 * duplicate filename transition rules.  For backward
2695 		 * compatibility, do not reject such policies, just
2696 		 * ignore the duplicate.
2697 		 */
2698 	}
2699 	free(name);
2700 	return 0;
2701 err:
2702 	free(name);
2703 	return -1;
2704 }
2705 
filename_trans_check_datum(filename_trans_datum_t * datum)2706 static int filename_trans_check_datum(filename_trans_datum_t *datum)
2707 {
2708 	ebitmap_t stypes, otypes;
2709 	int rc = -1;
2710 
2711 	ebitmap_init(&stypes);
2712 	ebitmap_init(&otypes);
2713 
2714 	while (datum) {
2715 		if (ebitmap_get_bit(&otypes, datum->otype))
2716 			goto out;
2717 
2718 		if (ebitmap_set_bit(&otypes, datum->otype, 1))
2719 			goto out;
2720 
2721 		if (ebitmap_match_any(&stypes, &datum->stypes))
2722 			goto out;
2723 
2724 		if (ebitmap_union(&stypes, &datum->stypes))
2725 			goto out;
2726 
2727 		datum = datum->next;
2728 	}
2729 	rc = 0;
2730 out:
2731 	ebitmap_destroy(&stypes);
2732 	ebitmap_destroy(&otypes);
2733 	return rc;
2734 }
2735 
filename_trans_read_one(policydb_t * p,struct policy_file * fp)2736 static int filename_trans_read_one(policydb_t *p, struct policy_file *fp)
2737 {
2738 	filename_trans_key_t *ft = NULL;
2739 	filename_trans_datum_t **dst, *datum, *first = NULL;
2740 	unsigned int i;
2741 	uint32_t buf[3], len, ttype, tclass, ndatum;
2742 	char *name = NULL;
2743 	int rc;
2744 
2745 	rc = next_entry(buf, fp, sizeof(uint32_t));
2746 	if (rc < 0)
2747 		return -1;
2748 	len = le32_to_cpu(buf[0]);
2749 	if (zero_or_saturated(len))
2750 		return -1;
2751 
2752 	name = calloc(len + 1, sizeof(*name));
2753 	if (!name)
2754 		return -1;
2755 
2756 	rc = next_entry(name, fp, len);
2757 	if (rc < 0)
2758 		goto err;
2759 
2760 	rc = next_entry(buf, fp, sizeof(uint32_t) * 3);
2761 	if (rc < 0)
2762 		goto err;
2763 
2764 	ttype = le32_to_cpu(buf[0]);
2765 	tclass = le32_to_cpu(buf[1]);
2766 	ndatum = le32_to_cpu(buf[2]);
2767 	if (ndatum == 0)
2768 		goto err;
2769 
2770 	dst = &first;
2771 	for (i = 0; i < ndatum; i++) {
2772 		datum = malloc(sizeof(*datum));
2773 		if (!datum)
2774 			goto err;
2775 
2776 		*dst = datum;
2777 
2778 		/* ebitmap_read() will at least init the bitmap */
2779 		rc = ebitmap_read(&datum->stypes, fp);
2780 		if (rc < 0)
2781 			goto err;
2782 
2783 		rc = next_entry(buf, fp, sizeof(uint32_t));
2784 		if (rc < 0)
2785 			goto err;
2786 
2787 		datum->otype = le32_to_cpu(buf[0]);
2788 
2789 		p->filename_trans_count += ebitmap_cardinality(&datum->stypes);
2790 
2791 		dst = &datum->next;
2792 	}
2793 	*dst = NULL;
2794 
2795 	if (ndatum > 1 && filename_trans_check_datum(first))
2796 		goto err;
2797 
2798 	ft = malloc(sizeof(*ft));
2799 	if (!ft)
2800 		goto err;
2801 
2802 	ft->ttype = ttype;
2803 	ft->tclass = tclass;
2804 	ft->name = name;
2805 
2806 	rc = hashtab_insert(p->filename_trans, (hashtab_key_t)ft,
2807 			    (hashtab_datum_t)first);
2808 	if (rc)
2809 		goto err;
2810 
2811 	return 0;
2812 err:
2813 	free(ft);
2814 	free(name);
2815 	while (first) {
2816 		datum = first;
2817 		first = first->next;
2818 
2819 		ebitmap_destroy(&datum->stypes);
2820 		free(datum);
2821 	}
2822 	return -1;
2823 }
2824 
filename_trans_read(policydb_t * p,struct policy_file * fp)2825 static int filename_trans_read(policydb_t *p, struct policy_file *fp)
2826 {
2827 	unsigned int i;
2828 	uint32_t buf[1], nel;
2829 	int rc;
2830 
2831 	rc = next_entry(buf, fp, sizeof(uint32_t));
2832 	if (rc < 0)
2833 		return -1;
2834 	nel = le32_to_cpu(buf[0]);
2835 
2836 	if (p->policyvers < POLICYDB_VERSION_COMP_FTRANS) {
2837 		for (i = 0; i < nel; i++) {
2838 			rc = filename_trans_read_one_compat(p, fp);
2839 			if (rc < 0)
2840 				return -1;
2841 		}
2842 	} else {
2843 		for (i = 0; i < nel; i++) {
2844 			rc = filename_trans_read_one(p, fp);
2845 			if (rc < 0)
2846 				return -1;
2847 		}
2848 	}
2849 	return 0;
2850 }
2851 
ocontext_read_xen(const struct policydb_compat_info * info,policydb_t * p,struct policy_file * fp)2852 static int ocontext_read_xen(const struct policydb_compat_info *info,
2853 	policydb_t *p, struct policy_file *fp)
2854 {
2855 	unsigned int i, j;
2856 	size_t nel, len;
2857 	ocontext_t *l, *c;
2858 	uint32_t buf[8];
2859 	int rc;
2860 
2861 	for (i = 0; i < info->ocon_num; i++) {
2862 		rc = next_entry(buf, fp, sizeof(uint32_t));
2863 		if (rc < 0)
2864 			return -1;
2865 		nel = le32_to_cpu(buf[0]);
2866 		l = NULL;
2867 		for (j = 0; j < nel; j++) {
2868 			c = calloc(1, sizeof(ocontext_t));
2869 			if (!c)
2870 				return -1;
2871 			if (l)
2872 				l->next = c;
2873 			else
2874 				p->ocontexts[i] = c;
2875 			l = c;
2876 			switch (i) {
2877 			case OCON_XEN_ISID:
2878 				rc = next_entry(buf, fp, sizeof(uint32_t));
2879 				if (rc < 0)
2880 					return -1;
2881 				c->sid[0] = le32_to_cpu(buf[0]);
2882 				if (context_read_and_validate
2883 				    (&c->context[0], p, fp))
2884 					return -1;
2885 				break;
2886 			case OCON_XEN_PIRQ:
2887 				rc = next_entry(buf, fp, sizeof(uint32_t));
2888 				if (rc < 0)
2889 					return -1;
2890 				c->u.pirq = le32_to_cpu(buf[0]);
2891 				if (context_read_and_validate
2892 				    (&c->context[0], p, fp))
2893 					return -1;
2894 				break;
2895 			case OCON_XEN_IOPORT:
2896 				rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
2897 				if (rc < 0)
2898 					return -1;
2899 				c->u.ioport.low_ioport = le32_to_cpu(buf[0]);
2900 				c->u.ioport.high_ioport = le32_to_cpu(buf[1]);
2901 				if (context_read_and_validate
2902 				    (&c->context[0], p, fp))
2903 					return -1;
2904 				break;
2905 			case OCON_XEN_IOMEM:
2906 				if (p->policyvers >= POLICYDB_VERSION_XEN_DEVICETREE) {
2907 					uint64_t b64[2];
2908 					rc = next_entry(b64, fp, sizeof(uint64_t) * 2);
2909 					if (rc < 0)
2910 						return -1;
2911 					c->u.iomem.low_iomem = le64_to_cpu(b64[0]);
2912 					c->u.iomem.high_iomem = le64_to_cpu(b64[1]);
2913 				} else {
2914 					rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
2915 					if (rc < 0)
2916 						return -1;
2917 					c->u.iomem.low_iomem = le32_to_cpu(buf[0]);
2918 					c->u.iomem.high_iomem = le32_to_cpu(buf[1]);
2919 				}
2920 				if (context_read_and_validate
2921 				    (&c->context[0], p, fp))
2922 					return -1;
2923 				break;
2924 			case OCON_XEN_PCIDEVICE:
2925 				rc = next_entry(buf, fp, sizeof(uint32_t));
2926 				if (rc < 0)
2927 					return -1;
2928 				c->u.device = le32_to_cpu(buf[0]);
2929 				if (context_read_and_validate
2930 				    (&c->context[0], p, fp))
2931 					return -1;
2932 				break;
2933 			case OCON_XEN_DEVICETREE:
2934 				rc = next_entry(buf, fp, sizeof(uint32_t));
2935 				if (rc < 0)
2936 					return -1;
2937 				len = le32_to_cpu(buf[0]);
2938 				if (zero_or_saturated(len))
2939 					return -1;
2940 
2941 				c->u.name = malloc(len + 1);
2942 				if (!c->u.name)
2943 					return -1;
2944 				rc = next_entry(c->u.name, fp, len);
2945 				if (rc < 0)
2946 					return -1;
2947 				c->u.name[len] = 0;
2948 				if (context_read_and_validate
2949 				    (&c->context[0], p, fp))
2950 					return -1;
2951 				break;
2952 			default:
2953 				/* should never get here */
2954 				ERR(fp->handle, "Unknown Xen ocontext");
2955 				return -1;
2956 			}
2957 		}
2958 	}
2959 	return 0;
2960 }
ocontext_read_selinux(const struct policydb_compat_info * info,policydb_t * p,struct policy_file * fp)2961 static int ocontext_read_selinux(const struct policydb_compat_info *info,
2962 			 policydb_t * p, struct policy_file *fp)
2963 {
2964 	unsigned int i, j;
2965 	size_t nel, len;
2966 	ocontext_t *l, *c;
2967 	uint32_t buf[8];
2968 	int rc;
2969 
2970 	for (i = 0; i < info->ocon_num; i++) {
2971 		rc = next_entry(buf, fp, sizeof(uint32_t));
2972 		if (rc < 0)
2973 			return -1;
2974 		nel = le32_to_cpu(buf[0]);
2975 		l = NULL;
2976 		for (j = 0; j < nel; j++) {
2977 			c = calloc(1, sizeof(ocontext_t));
2978 			if (!c) {
2979 				return -1;
2980 			}
2981 			if (l) {
2982 				l->next = c;
2983 			} else {
2984 				p->ocontexts[i] = c;
2985 			}
2986 			l = c;
2987 			switch (i) {
2988 			case OCON_ISID:
2989 				rc = next_entry(buf, fp, sizeof(uint32_t));
2990 				if (rc < 0)
2991 					return -1;
2992 				c->sid[0] = le32_to_cpu(buf[0]);
2993 				if (context_read_and_validate
2994 				    (&c->context[0], p, fp))
2995 					return -1;
2996 				break;
2997 			case OCON_FS:
2998 			case OCON_NETIF:
2999 				rc = next_entry(buf, fp, sizeof(uint32_t));
3000 				if (rc < 0)
3001 					return -1;
3002 				len = le32_to_cpu(buf[0]);
3003 				if (zero_or_saturated(len) || len > 63)
3004 					return -1;
3005 				c->u.name = malloc(len + 1);
3006 				if (!c->u.name)
3007 					return -1;
3008 				rc = next_entry(c->u.name, fp, len);
3009 				if (rc < 0)
3010 					return -1;
3011 				c->u.name[len] = 0;
3012 				if (context_read_and_validate
3013 				    (&c->context[0], p, fp))
3014 					return -1;
3015 				if (context_read_and_validate
3016 				    (&c->context[1], p, fp))
3017 					return -1;
3018 				break;
3019 			case OCON_IBPKEY: {
3020 				uint32_t pkey_lo, pkey_hi;
3021 
3022 				rc = next_entry(buf, fp, sizeof(uint32_t) * 4);
3023 				if (rc < 0)
3024 					return -1;
3025 
3026 				pkey_lo = le32_to_cpu(buf[2]);
3027 				pkey_hi = le32_to_cpu(buf[3]);
3028 
3029 				if (pkey_lo > UINT16_MAX || pkey_hi > UINT16_MAX)
3030 					return -1;
3031 
3032 				c->u.ibpkey.low_pkey  = pkey_lo;
3033 				c->u.ibpkey.high_pkey = pkey_hi;
3034 
3035 				/* we want c->u.ibpkey.subnet_prefix in network
3036 				 * (big-endian) order, just memcpy it */
3037 				memcpy(&c->u.ibpkey.subnet_prefix, buf,
3038 				       sizeof(c->u.ibpkey.subnet_prefix));
3039 
3040 				if (context_read_and_validate
3041 				    (&c->context[0], p, fp))
3042 					return -1;
3043 				break;
3044 			}
3045 			case OCON_IBENDPORT: {
3046 				uint32_t port;
3047 
3048 				rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
3049 				if (rc < 0)
3050 					return -1;
3051 				len = le32_to_cpu(buf[0]);
3052 				if (len == 0 || len > IB_DEVICE_NAME_MAX - 1)
3053 					return -1;
3054 
3055 				port = le32_to_cpu(buf[1]);
3056 				if (port > UINT8_MAX || port == 0)
3057 					return -1;
3058 
3059 				c->u.ibendport.dev_name = malloc(len + 1);
3060 				if (!c->u.ibendport.dev_name)
3061 					return -1;
3062 				rc = next_entry(c->u.ibendport.dev_name, fp, len);
3063 				if (rc < 0)
3064 					return -1;
3065 				c->u.ibendport.dev_name[len] = 0;
3066 				c->u.ibendport.port = port;
3067 				if (context_read_and_validate
3068 				    (&c->context[0], p, fp))
3069 					return -1;
3070 				break;
3071 			}
3072 			case OCON_PORT:
3073 				rc = next_entry(buf, fp, sizeof(uint32_t) * 3);
3074 				if (rc < 0)
3075 					return -1;
3076 				c->u.port.protocol = le32_to_cpu(buf[0]);
3077 				c->u.port.low_port = le32_to_cpu(buf[1]);
3078 				c->u.port.high_port = le32_to_cpu(buf[2]);
3079 				if (context_read_and_validate
3080 				    (&c->context[0], p, fp))
3081 					return -1;
3082 				break;
3083 			case OCON_NODE:
3084 				rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
3085 				if (rc < 0)
3086 					return -1;
3087 				c->u.node.addr = buf[0]; /* network order */
3088 				c->u.node.mask = buf[1]; /* network order */
3089 				if (context_read_and_validate
3090 				    (&c->context[0], p, fp))
3091 					return -1;
3092 				break;
3093 			case OCON_FSUSE:
3094 				rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
3095 				if (rc < 0)
3096 					return -1;
3097 				c->v.behavior = le32_to_cpu(buf[0]);
3098 				len = le32_to_cpu(buf[1]);
3099 				if (zero_or_saturated(len))
3100 					return -1;
3101 				c->u.name = malloc(len + 1);
3102 				if (!c->u.name)
3103 					return -1;
3104 				rc = next_entry(c->u.name, fp, len);
3105 				if (rc < 0)
3106 					return -1;
3107 				c->u.name[len] = 0;
3108 				if (context_read_and_validate
3109 				    (&c->context[0], p, fp))
3110 					return -1;
3111 				break;
3112 			case OCON_NODE6:{
3113 				int k;
3114 
3115 				rc = next_entry(buf, fp, sizeof(uint32_t) * 8);
3116 				if (rc < 0)
3117 					return -1;
3118 				for (k = 0; k < 4; k++)
3119 					 /* network order */
3120 					c->u.node6.addr[k] = buf[k];
3121 				for (k = 0; k < 4; k++)
3122 					/* network order */
3123 					c->u.node6.mask[k] = buf[k + 4];
3124 				if (context_read_and_validate
3125 				    (&c->context[0], p, fp))
3126 					return -1;
3127 				break;
3128 				}
3129 			default:{
3130 				ERR(fp->handle, "Unknown SELinux ocontext");
3131 				return -1;
3132 				}
3133 			}
3134 		}
3135 	}
3136 	return 0;
3137 }
3138 
ocontext_read(const struct policydb_compat_info * info,policydb_t * p,struct policy_file * fp)3139 static int ocontext_read(const struct policydb_compat_info *info,
3140 	policydb_t *p, struct policy_file *fp)
3141 {
3142 	int rc = -1;
3143 	switch (p->target_platform) {
3144 	case SEPOL_TARGET_SELINUX:
3145 		rc = ocontext_read_selinux(info, p, fp);
3146 		break;
3147 	case SEPOL_TARGET_XEN:
3148 		rc = ocontext_read_xen(info, p, fp);
3149 		break;
3150 	default:
3151 		ERR(fp->handle, "Unknown target");
3152 	}
3153 	return rc;
3154 }
3155 
genfs_read(policydb_t * p,struct policy_file * fp)3156 static int genfs_read(policydb_t * p, struct policy_file *fp)
3157 {
3158 	uint32_t buf[1];
3159 	size_t nel, nel2, len, len2;
3160 	genfs_t *genfs_p, *newgenfs, *genfs;
3161 	size_t i, j;
3162 	ocontext_t *l, *c, *newc = NULL;
3163 	int rc;
3164 
3165 	rc = next_entry(buf, fp, sizeof(uint32_t));
3166 	if (rc < 0)
3167 		goto bad;
3168 	nel = le32_to_cpu(buf[0]);
3169 	genfs_p = NULL;
3170 	for (i = 0; i < nel; i++) {
3171 		rc = next_entry(buf, fp, sizeof(uint32_t));
3172 		if (rc < 0)
3173 			goto bad;
3174 		len = le32_to_cpu(buf[0]);
3175 		if (zero_or_saturated(len))
3176 			goto bad;
3177 		newgenfs = calloc(1, sizeof(genfs_t));
3178 		if (!newgenfs)
3179 			goto bad;
3180 		newgenfs->fstype = malloc(len + 1);
3181 		if (!newgenfs->fstype) {
3182 			free(newgenfs);
3183 			goto bad;
3184 		}
3185 		rc = next_entry(newgenfs->fstype, fp, len);
3186 		if (rc < 0) {
3187 			free(newgenfs->fstype);
3188 			free(newgenfs);
3189 			goto bad;
3190 		}
3191 		newgenfs->fstype[len] = 0;
3192 		for (genfs_p = NULL, genfs = p->genfs; genfs;
3193 		     genfs_p = genfs, genfs = genfs->next) {
3194 			if (strcmp(newgenfs->fstype, genfs->fstype) == 0) {
3195 				ERR(fp->handle, "dup genfs fstype %s",
3196 				    newgenfs->fstype);
3197 				free(newgenfs->fstype);
3198 				free(newgenfs);
3199 				goto bad;
3200 			}
3201 			if (strcmp(newgenfs->fstype, genfs->fstype) < 0)
3202 				break;
3203 		}
3204 		newgenfs->next = genfs;
3205 		if (genfs_p)
3206 			genfs_p->next = newgenfs;
3207 		else
3208 			p->genfs = newgenfs;
3209 		rc = next_entry(buf, fp, sizeof(uint32_t));
3210 		if (rc < 0)
3211 			goto bad;
3212 		nel2 = le32_to_cpu(buf[0]);
3213 		for (j = 0; j < nel2; j++) {
3214 			newc = calloc(1, sizeof(ocontext_t));
3215 			if (!newc) {
3216 				goto bad;
3217 			}
3218 			rc = next_entry(buf, fp, sizeof(uint32_t));
3219 			if (rc < 0)
3220 				goto bad;
3221 			len = le32_to_cpu(buf[0]);
3222 			if (zero_or_saturated(len))
3223 				goto bad;
3224 			newc->u.name = malloc(len + 1);
3225 			if (!newc->u.name) {
3226 				goto bad;
3227 			}
3228 			rc = next_entry(newc->u.name, fp, len);
3229 			if (rc < 0)
3230 				goto bad;
3231 			newc->u.name[len] = 0;
3232 			rc = next_entry(buf, fp, sizeof(uint32_t));
3233 			if (rc < 0)
3234 				goto bad;
3235 			newc->v.sclass = le32_to_cpu(buf[0]);
3236 			if (context_read_and_validate(&newc->context[0], p, fp))
3237 				goto bad;
3238 			for (l = NULL, c = newgenfs->head; c;
3239 			     l = c, c = c->next) {
3240 				if (!strcmp(newc->u.name, c->u.name) &&
3241 				    (!c->v.sclass || !newc->v.sclass ||
3242 				     newc->v.sclass == c->v.sclass)) {
3243 					ERR(fp->handle, "dup genfs entry "
3244 					    "(%s,%s)", newgenfs->fstype,
3245 					    c->u.name);
3246 					goto bad;
3247 				}
3248 				len = strlen(newc->u.name);
3249 				len2 = strlen(c->u.name);
3250 				if (len > len2)
3251 					break;
3252 			}
3253 			newc->next = c;
3254 			if (l)
3255 				l->next = newc;
3256 			else
3257 				newgenfs->head = newc;
3258 			/* clear newc after a new owner has the pointer */
3259 			newc = NULL;
3260 		}
3261 	}
3262 
3263 	return 0;
3264 
3265       bad:
3266 	if (newc) {
3267 		context_destroy(&newc->context[0]);
3268 		context_destroy(&newc->context[1]);
3269 		free(newc->u.name);
3270 		free(newc);
3271 	}
3272 	return -1;
3273 }
3274 
3275 /*
3276  * Read a MLS level structure from a policydb binary
3277  * representation file.
3278  */
mls_read_level(mls_level_t * lp,struct policy_file * fp)3279 static int mls_read_level(mls_level_t * lp, struct policy_file *fp)
3280 {
3281 	uint32_t buf[1];
3282 	int rc;
3283 
3284 	mls_level_init(lp);
3285 
3286 	rc = next_entry(buf, fp, sizeof(uint32_t));
3287 	if (rc < 0) {
3288 		ERR(fp->handle, "truncated level");
3289 		goto bad;
3290 	}
3291 	lp->sens = le32_to_cpu(buf[0]);
3292 
3293 	if (ebitmap_read(&lp->cat, fp)) {
3294 		ERR(fp->handle, "error reading level categories");
3295 		goto bad;
3296 	}
3297 	return 0;
3298 
3299       bad:
3300 	return -EINVAL;
3301 }
3302 
user_read(policydb_t * p,hashtab_t h,struct policy_file * fp)3303 static int user_read(policydb_t * p, hashtab_t h, struct policy_file *fp)
3304 {
3305 	char *key = 0;
3306 	user_datum_t *usrdatum;
3307 	uint32_t buf[3];
3308 	size_t len;
3309 	int rc, to_read = 2;
3310 
3311 	usrdatum = calloc(1, sizeof(user_datum_t));
3312 	if (!usrdatum)
3313 		return -1;
3314 
3315 	if (policydb_has_boundary_feature(p))
3316 		to_read = 3;
3317 
3318 	rc = next_entry(buf, fp, sizeof(uint32_t) * to_read);
3319 	if (rc < 0)
3320 		goto bad;
3321 
3322 	len = le32_to_cpu(buf[0]);
3323 	if (zero_or_saturated(len))
3324 		goto bad;
3325 
3326 	usrdatum->s.value = le32_to_cpu(buf[1]);
3327 	if (policydb_has_boundary_feature(p))
3328 		usrdatum->bounds = le32_to_cpu(buf[2]);
3329 
3330 	key = malloc(len + 1);
3331 	if (!key)
3332 		goto bad;
3333 	rc = next_entry(key, fp, len);
3334 	if (rc < 0)
3335 		goto bad;
3336 	key[len] = 0;
3337 
3338 	if (p->policy_type == POLICY_KERN) {
3339 		if (ebitmap_read(&usrdatum->roles.roles, fp))
3340 			goto bad;
3341 	} else {
3342 		if (role_set_read(&usrdatum->roles, fp))
3343 			goto bad;
3344 	}
3345 
3346 	/* users were not allowed in mls modules before version
3347 	 * MOD_POLICYDB_VERSION_MLS_USERS, but they could have been
3348 	 * required - the mls fields will be empty.  user declarations in
3349 	 * non-mls modules will also have empty mls fields */
3350 	if ((p->policy_type == POLICY_KERN
3351 	     && p->policyvers >= POLICYDB_VERSION_MLS)
3352 	    || (p->policy_type == POLICY_MOD
3353 		&& p->policyvers >= MOD_POLICYDB_VERSION_MLS
3354 		&& p->policyvers < MOD_POLICYDB_VERSION_MLS_USERS)
3355 	    || (p->policy_type == POLICY_BASE
3356 		&& p->policyvers >= MOD_POLICYDB_VERSION_MLS
3357 		&& p->policyvers < MOD_POLICYDB_VERSION_MLS_USERS)) {
3358 		if (mls_read_range_helper(&usrdatum->exp_range, fp))
3359 			goto bad;
3360 		if (mls_read_level(&usrdatum->exp_dfltlevel, fp))
3361 			goto bad;
3362 		if (p->policy_type != POLICY_KERN) {
3363 			if (mls_range_to_semantic(&usrdatum->exp_range,
3364 						  &usrdatum->range))
3365 				goto bad;
3366 			if (mls_level_to_semantic(&usrdatum->exp_dfltlevel,
3367 						  &usrdatum->dfltlevel))
3368 				goto bad;
3369 		}
3370 	} else if ((p->policy_type == POLICY_MOD
3371 		    && p->policyvers >= MOD_POLICYDB_VERSION_MLS_USERS)
3372 		   || (p->policy_type == POLICY_BASE
3373 		       && p->policyvers >= MOD_POLICYDB_VERSION_MLS_USERS)) {
3374 		if (mls_read_semantic_range_helper(&usrdatum->range, fp))
3375 			goto bad;
3376 		if (mls_read_semantic_level_helper(&usrdatum->dfltlevel, fp))
3377 			goto bad;
3378 	}
3379 
3380 	if (hashtab_insert(h, key, usrdatum))
3381 		goto bad;
3382 
3383 	return 0;
3384 
3385       bad:
3386 	user_destroy(key, usrdatum, NULL);
3387 	return -1;
3388 }
3389 
sens_read(policydb_t * p,hashtab_t h,struct policy_file * fp)3390 static int sens_read(policydb_t * p
3391 		     __attribute__ ((unused)), hashtab_t h,
3392 		     struct policy_file *fp)
3393 {
3394 	char *key = 0;
3395 	level_datum_t *levdatum;
3396 	uint32_t buf[2], len;
3397 	int rc;
3398 
3399 	levdatum = malloc(sizeof(level_datum_t));
3400 	if (!levdatum)
3401 		return -1;
3402 	level_datum_init(levdatum);
3403 
3404 	rc = next_entry(buf, fp, (sizeof(uint32_t) * 2));
3405 	if (rc < 0)
3406 		goto bad;
3407 
3408 	len = le32_to_cpu(buf[0]);
3409 	if (zero_or_saturated(len))
3410 		goto bad;
3411 
3412 	levdatum->isalias = le32_to_cpu(buf[1]);
3413 
3414 	key = malloc(len + 1);
3415 	if (!key)
3416 		goto bad;
3417 	rc = next_entry(key, fp, len);
3418 	if (rc < 0)
3419 		goto bad;
3420 	key[len] = 0;
3421 
3422 	levdatum->level = malloc(sizeof(mls_level_t));
3423 	if (!levdatum->level || mls_read_level(levdatum->level, fp))
3424 		goto bad;
3425 
3426 	if (hashtab_insert(h, key, levdatum))
3427 		goto bad;
3428 
3429 	return 0;
3430 
3431       bad:
3432 	sens_destroy(key, levdatum, NULL);
3433 	return -1;
3434 }
3435 
cat_read(policydb_t * p,hashtab_t h,struct policy_file * fp)3436 static int cat_read(policydb_t * p
3437 		    __attribute__ ((unused)), hashtab_t h,
3438 		    struct policy_file *fp)
3439 {
3440 	char *key = 0;
3441 	cat_datum_t *catdatum;
3442 	uint32_t buf[3], len;
3443 	int rc;
3444 
3445 	catdatum = malloc(sizeof(cat_datum_t));
3446 	if (!catdatum)
3447 		return -1;
3448 	cat_datum_init(catdatum);
3449 
3450 	rc = next_entry(buf, fp, (sizeof(uint32_t) * 3));
3451 	if (rc < 0)
3452 		goto bad;
3453 
3454 	len = le32_to_cpu(buf[0]);
3455 	if(zero_or_saturated(len))
3456 		goto bad;
3457 
3458 	catdatum->s.value = le32_to_cpu(buf[1]);
3459 	catdatum->isalias = le32_to_cpu(buf[2]);
3460 
3461 	key = malloc(len + 1);
3462 	if (!key)
3463 		goto bad;
3464 	rc = next_entry(key, fp, len);
3465 	if (rc < 0)
3466 		goto bad;
3467 	key[len] = 0;
3468 
3469 	if (hashtab_insert(h, key, catdatum))
3470 		goto bad;
3471 
3472 	return 0;
3473 
3474       bad:
3475 	cat_destroy(key, catdatum, NULL);
3476 	return -1;
3477 }
3478 
3479 static int (*read_f[SYM_NUM]) (policydb_t * p, hashtab_t h,
3480 			       struct policy_file * fp) = {
3481 common_read, class_read, role_read, type_read, user_read,
3482 	    cond_read_bool, sens_read, cat_read,};
3483 
3484 /************** module reading functions below **************/
3485 
avrule_read(policydb_t * p,struct policy_file * fp)3486 static avrule_t *avrule_read(policydb_t * p, struct policy_file *fp)
3487 {
3488 	unsigned int i;
3489 	uint32_t buf[2], len;
3490 	class_perm_node_t *cur, *tail = NULL;
3491 	avrule_t *avrule;
3492 	int rc;
3493 
3494 	avrule = (avrule_t *) malloc(sizeof(avrule_t));
3495 	if (!avrule)
3496 		return NULL;
3497 
3498 	avrule_init(avrule);
3499 
3500 	rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
3501 	if (rc < 0)
3502 		goto bad;
3503 
3504 	avrule->specified = le32_to_cpu(buf[0]);
3505 	avrule->flags = le32_to_cpu(buf[1]);
3506 
3507 	if (type_set_read(&avrule->stypes, fp))
3508 		goto bad;
3509 
3510 	if (type_set_read(&avrule->ttypes, fp))
3511 		goto bad;
3512 
3513 	rc = next_entry(buf, fp, sizeof(uint32_t));
3514 	if (rc < 0)
3515 		goto bad;
3516 	len = le32_to_cpu(buf[0]);
3517 
3518 	for (i = 0; i < len; i++) {
3519 		cur = (class_perm_node_t *) malloc(sizeof(class_perm_node_t));
3520 		if (!cur)
3521 			goto bad;
3522 		class_perm_node_init(cur);
3523 
3524 		rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
3525 		if (rc < 0) {
3526 			free(cur);
3527 			goto bad;
3528 		}
3529 
3530 		cur->tclass = le32_to_cpu(buf[0]);
3531 		cur->data = le32_to_cpu(buf[1]);
3532 
3533 		if (!tail) {
3534 			avrule->perms = cur;
3535 		} else {
3536 			tail->next = cur;
3537 		}
3538 		tail = cur;
3539 	}
3540 
3541 	if (avrule->specified & AVRULE_XPERMS) {
3542 		uint8_t buf8;
3543 		size_t nel = ARRAY_SIZE(avrule->xperms->perms);
3544 		uint32_t buf32[nel];
3545 
3546 		if (p->policyvers < MOD_POLICYDB_VERSION_XPERMS_IOCTL) {
3547 			ERR(fp->handle,
3548 			    "module policy version %u does not support ioctl"
3549 			    " extended permissions rules and one was specified",
3550 			    p->policyvers);
3551 			goto bad;
3552 		}
3553 
3554 		if (p->target_platform != SEPOL_TARGET_SELINUX) {
3555 			ERR(fp->handle,
3556 			    "Target platform %s does not support ioctl"
3557 			    " extended permissions rules and one was specified",
3558 			    policydb_target_strings[p->target_platform]);
3559 			goto bad;
3560 		}
3561 
3562 		avrule->xperms = calloc(1, sizeof(*avrule->xperms));
3563 		if (!avrule->xperms)
3564 			goto bad;
3565 
3566 		rc = next_entry(&buf8, fp, sizeof(uint8_t));
3567 		if (rc < 0) {
3568 			ERR(fp->handle, "truncated entry");
3569 			goto bad;
3570 		}
3571 		avrule->xperms->specified = buf8;
3572 		rc = next_entry(&buf8, fp, sizeof(uint8_t));
3573 		if (rc < 0) {
3574 			ERR(fp->handle, "truncated entry");
3575 			goto bad;
3576 		}
3577 		avrule->xperms->driver = buf8;
3578 		rc = next_entry(buf32, fp, sizeof(uint32_t)*nel);
3579 		if (rc < 0) {
3580 			ERR(fp->handle, "truncated entry");
3581 			goto bad;
3582 		}
3583 		for (i = 0; i < nel; i++)
3584 			avrule->xperms->perms[i] = le32_to_cpu(buf32[i]);
3585 	}
3586 
3587 	return avrule;
3588       bad:
3589 	if (avrule) {
3590 		avrule_destroy(avrule);
3591 		free(avrule);
3592 	}
3593 	return NULL;
3594 }
3595 
range_read(policydb_t * p,struct policy_file * fp)3596 static int range_read(policydb_t * p, struct policy_file *fp)
3597 {
3598 	uint32_t buf[2], nel;
3599 	range_trans_t *rt = NULL;
3600 	struct mls_range *r = NULL;
3601 	range_trans_rule_t *rtr = NULL, *lrtr = NULL;
3602 	unsigned int i;
3603 	int new_rangetr = (p->policy_type == POLICY_KERN &&
3604 			   p->policyvers >= POLICYDB_VERSION_RANGETRANS);
3605 	int rc;
3606 
3607 	rc = next_entry(buf, fp, sizeof(uint32_t));
3608 	if (rc < 0)
3609 		return -1;
3610 	nel = le32_to_cpu(buf[0]);
3611 	for (i = 0; i < nel; i++) {
3612 		rt = calloc(1, sizeof(range_trans_t));
3613 		if (!rt)
3614 			return -1;
3615 		rc = next_entry(buf, fp, (sizeof(uint32_t) * 2));
3616 		if (rc < 0)
3617 			goto err;
3618 		rt->source_type = le32_to_cpu(buf[0]);
3619 		if (!value_isvalid(rt->source_type, p->p_types.nprim))
3620 			goto err;
3621 		rt->target_type = le32_to_cpu(buf[1]);
3622 		if (!value_isvalid(rt->target_type, p->p_types.nprim))
3623 			goto err;
3624 		if (new_rangetr) {
3625 			rc = next_entry(buf, fp, (sizeof(uint32_t)));
3626 			if (rc < 0)
3627 				goto err;
3628 			rt->target_class = le32_to_cpu(buf[0]);
3629 			if (!value_isvalid(rt->target_class, p->p_classes.nprim))
3630 				goto err;
3631 		} else
3632 			rt->target_class = p->process_class;
3633 		r = calloc(1, sizeof(*r));
3634 		if (!r)
3635 			goto err;
3636 		if (mls_read_range_helper(r, fp))
3637 			goto err;
3638 
3639 		if (p->policy_type == POLICY_KERN) {
3640 			rc = hashtab_insert(p->range_tr, (hashtab_key_t)rt, r);
3641 			if (rc)
3642 				goto err;
3643 			rt = NULL;
3644 			r = NULL;
3645 			continue;
3646 		}
3647 
3648 		/* Module policy: convert to range_trans_rule and discard. */
3649 		rtr = malloc(sizeof(range_trans_rule_t));
3650 		if (!rtr)
3651 			goto err;
3652 		range_trans_rule_init(rtr);
3653 
3654 		if (ebitmap_set_bit(&rtr->stypes.types, rt->source_type - 1, 1))
3655 			goto err;
3656 
3657 		if (ebitmap_set_bit(&rtr->ttypes.types, rt->target_type - 1, 1))
3658 			goto err;
3659 
3660 		if (ebitmap_set_bit(&rtr->tclasses, rt->target_class - 1, 1))
3661 			goto err;
3662 
3663 		if (mls_range_to_semantic(r, &rtr->trange))
3664 			goto err;
3665 
3666 		if (lrtr)
3667 			lrtr->next = rtr;
3668 		else
3669 			p->global->enabled->range_tr_rules = rtr;
3670 
3671 		free(rt);
3672 		rt = NULL;
3673 		free(r);
3674 		r = NULL;
3675 		lrtr = rtr;
3676 	}
3677 
3678 	return 0;
3679 err:
3680 	free(rt);
3681 	if (r) {
3682 		mls_range_destroy(r);
3683 		free(r);
3684 	}
3685 	if (rtr) {
3686 		range_trans_rule_destroy(rtr);
3687 		free(rtr);
3688 	}
3689 	return -1;
3690 }
3691 
avrule_read_list(policydb_t * p,avrule_t ** avrules,struct policy_file * fp)3692 int avrule_read_list(policydb_t * p, avrule_t ** avrules,
3693 		     struct policy_file *fp)
3694 {
3695 	unsigned int i;
3696 	avrule_t *cur, *tail;
3697 	uint32_t buf[1], len;
3698 	int rc;
3699 
3700 	*avrules = tail = NULL;
3701 
3702 	rc = next_entry(buf, fp, sizeof(uint32_t));
3703 	if (rc < 0) {
3704 		return -1;
3705 	}
3706 	len = le32_to_cpu(buf[0]);
3707 
3708 	for (i = 0; i < len; i++) {
3709 		cur = avrule_read(p, fp);
3710 		if (!cur) {
3711 			return -1;
3712 		}
3713 
3714 		if (!tail) {
3715 			*avrules = cur;
3716 		} else {
3717 			tail->next = cur;
3718 		}
3719 		tail = cur;
3720 	}
3721 
3722 	return 0;
3723 }
3724 
role_trans_rule_read(policydb_t * p,role_trans_rule_t ** r,struct policy_file * fp)3725 static int role_trans_rule_read(policydb_t *p, role_trans_rule_t ** r,
3726 				struct policy_file *fp)
3727 {
3728 	uint32_t buf[1], nel;
3729 	unsigned int i;
3730 	role_trans_rule_t *tr, *ltr;
3731 	int rc;
3732 
3733 	rc = next_entry(buf, fp, sizeof(uint32_t));
3734 	if (rc < 0)
3735 		return -1;
3736 	nel = le32_to_cpu(buf[0]);
3737 	ltr = NULL;
3738 	for (i = 0; i < nel; i++) {
3739 		tr = malloc(sizeof(role_trans_rule_t));
3740 		if (!tr) {
3741 			return -1;
3742 		}
3743 		role_trans_rule_init(tr);
3744 
3745 		if (ltr) {
3746 			ltr->next = tr;
3747 		} else {
3748 			*r = tr;
3749 		}
3750 
3751 		if (role_set_read(&tr->roles, fp))
3752 			return -1;
3753 
3754 		if (type_set_read(&tr->types, fp))
3755 			return -1;
3756 
3757 		if (p->policyvers >= MOD_POLICYDB_VERSION_ROLETRANS) {
3758 			if (ebitmap_read(&tr->classes, fp))
3759 				return -1;
3760 		} else {
3761 			if (!p->process_class)
3762 				return -1;
3763 			if (ebitmap_set_bit(&tr->classes, p->process_class - 1, 1))
3764 				return -1;
3765 		}
3766 
3767 		rc = next_entry(buf, fp, sizeof(uint32_t));
3768 		if (rc < 0)
3769 			return -1;
3770 		tr->new_role = le32_to_cpu(buf[0]);
3771 		ltr = tr;
3772 	}
3773 
3774 	return 0;
3775 }
3776 
role_allow_rule_read(role_allow_rule_t ** r,struct policy_file * fp)3777 static int role_allow_rule_read(role_allow_rule_t ** r, struct policy_file *fp)
3778 {
3779 	unsigned int i;
3780 	uint32_t buf[1], nel;
3781 	role_allow_rule_t *ra, *lra;
3782 	int rc;
3783 
3784 	rc = next_entry(buf, fp, sizeof(uint32_t));
3785 	if (rc < 0)
3786 		return -1;
3787 	nel = le32_to_cpu(buf[0]);
3788 	lra = NULL;
3789 	for (i = 0; i < nel; i++) {
3790 		ra = malloc(sizeof(role_allow_rule_t));
3791 		if (!ra) {
3792 			return -1;
3793 		}
3794 		role_allow_rule_init(ra);
3795 
3796 		if (lra) {
3797 			lra->next = ra;
3798 		} else {
3799 			*r = ra;
3800 		}
3801 
3802 		if (role_set_read(&ra->roles, fp))
3803 			return -1;
3804 
3805 		if (role_set_read(&ra->new_roles, fp))
3806 			return -1;
3807 
3808 		lra = ra;
3809 	}
3810 	return 0;
3811 }
3812 
filename_trans_rule_read(filename_trans_rule_t ** r,struct policy_file * fp)3813 static int filename_trans_rule_read(filename_trans_rule_t ** r, struct policy_file *fp)
3814 {
3815 	uint32_t buf[2], nel;
3816 	unsigned int i, len;
3817 	filename_trans_rule_t *ftr, *lftr;
3818 	int rc;
3819 
3820 	rc = next_entry(buf, fp, sizeof(uint32_t));
3821 	if (rc < 0)
3822 		return -1;
3823 	nel = le32_to_cpu(buf[0]);
3824 	lftr = NULL;
3825 	for (i = 0; i < nel; i++) {
3826 		ftr = malloc(sizeof(*ftr));
3827 		if (!ftr)
3828 			return -1;
3829 
3830 		filename_trans_rule_init(ftr);
3831 
3832 		if (lftr)
3833 			lftr->next = ftr;
3834 		else
3835 			*r = ftr;
3836 		lftr = ftr;
3837 
3838 		rc = next_entry(buf, fp, sizeof(uint32_t));
3839 		if (rc < 0)
3840 			return -1;
3841 
3842 		len = le32_to_cpu(buf[0]);
3843 		if (zero_or_saturated(len))
3844 			return -1;
3845 
3846 		ftr->name = malloc(len + 1);
3847 		if (!ftr->name)
3848 			return -1;
3849 
3850 		rc = next_entry(ftr->name, fp, len);
3851 		if (rc)
3852 			return -1;
3853 		ftr->name[len] = 0;
3854 
3855 		if (type_set_read(&ftr->stypes, fp))
3856 			return -1;
3857 
3858 		if (type_set_read(&ftr->ttypes, fp))
3859 			return -1;
3860 
3861 		rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
3862 		if (rc < 0)
3863 			return -1;
3864 		ftr->tclass = le32_to_cpu(buf[0]);
3865 		ftr->otype = le32_to_cpu(buf[1]);
3866 	}
3867 
3868 	return 0;
3869 }
3870 
range_trans_rule_read(range_trans_rule_t ** r,struct policy_file * fp)3871 static int range_trans_rule_read(range_trans_rule_t ** r,
3872 				 struct policy_file *fp)
3873 {
3874 	uint32_t buf[1], nel;
3875 	unsigned int i;
3876 	range_trans_rule_t *rt, *lrt = NULL;
3877 	int rc;
3878 
3879 	rc = next_entry(buf, fp, sizeof(uint32_t));
3880 	if (rc < 0)
3881 		return -1;
3882 	nel = le32_to_cpu(buf[0]);
3883 	for (i = 0; i < nel; i++) {
3884 		rt = malloc(sizeof(range_trans_rule_t));
3885 		if (!rt) {
3886 			return -1;
3887 		}
3888 		range_trans_rule_init(rt);
3889 
3890 		if (lrt)
3891 			lrt->next = rt;
3892 		else
3893 			*r = rt;
3894 
3895 		if (type_set_read(&rt->stypes, fp))
3896 			return -1;
3897 
3898 		if (type_set_read(&rt->ttypes, fp))
3899 			return -1;
3900 
3901 		if (ebitmap_read(&rt->tclasses, fp))
3902 			return -1;
3903 
3904 		if (mls_read_semantic_range_helper(&rt->trange, fp))
3905 			return -1;
3906 
3907 		lrt = rt;
3908 	}
3909 
3910 	return 0;
3911 }
3912 
scope_index_read(scope_index_t * scope_index,unsigned int num_scope_syms,struct policy_file * fp)3913 static int scope_index_read(scope_index_t * scope_index,
3914 			    unsigned int num_scope_syms, struct policy_file *fp)
3915 {
3916 	unsigned int i;
3917 	uint32_t buf[1];
3918 	int rc;
3919 
3920 	for (i = 0; i < num_scope_syms; i++) {
3921 		if (ebitmap_read(scope_index->scope + i, fp) < 0) {
3922 			return -1;
3923 		}
3924 	}
3925 	rc = next_entry(buf, fp, sizeof(uint32_t));
3926 	if (rc < 0)
3927 		return -1;
3928 	scope_index->class_perms_len = le32_to_cpu(buf[0]);
3929 	if (scope_index->class_perms_len == 0) {
3930 		scope_index->class_perms_map = NULL;
3931 		return 0;
3932 	}
3933 	if ((scope_index->class_perms_map =
3934 	     calloc(scope_index->class_perms_len,
3935 		    sizeof(*scope_index->class_perms_map))) == NULL) {
3936 		return -1;
3937 	}
3938 	for (i = 0; i < scope_index->class_perms_len; i++) {
3939 		if (ebitmap_read(scope_index->class_perms_map + i, fp) < 0) {
3940 			return -1;
3941 		}
3942 	}
3943 	return 0;
3944 }
3945 
avrule_decl_read(policydb_t * p,avrule_decl_t * decl,unsigned int num_scope_syms,struct policy_file * fp)3946 static int avrule_decl_read(policydb_t * p, avrule_decl_t * decl,
3947 			    unsigned int num_scope_syms, struct policy_file *fp)
3948 {
3949 	uint32_t buf[2], nprim, nel;
3950 	unsigned int i, j;
3951 	int rc;
3952 
3953 	rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
3954 	if (rc < 0)
3955 		return -1;
3956 	decl->decl_id = le32_to_cpu(buf[0]);
3957 	decl->enabled = le32_to_cpu(buf[1]);
3958 	if (cond_read_list(p, &decl->cond_list, fp) == -1 ||
3959 	    avrule_read_list(p, &decl->avrules, fp) == -1 ||
3960 	    role_trans_rule_read(p, &decl->role_tr_rules, fp) == -1 ||
3961 	    role_allow_rule_read(&decl->role_allow_rules, fp) == -1) {
3962 		return -1;
3963 	}
3964 
3965 	if (p->policyvers >= MOD_POLICYDB_VERSION_FILENAME_TRANS &&
3966 	    filename_trans_rule_read(&decl->filename_trans_rules, fp))
3967 		return -1;
3968 
3969 	if (p->policyvers >= MOD_POLICYDB_VERSION_RANGETRANS &&
3970 	    range_trans_rule_read(&decl->range_tr_rules, fp) == -1) {
3971 		return -1;
3972 	}
3973 	if (scope_index_read(&decl->required, num_scope_syms, fp) == -1 ||
3974 	    scope_index_read(&decl->declared, num_scope_syms, fp) == -1) {
3975 		return -1;
3976 	}
3977 
3978 	for (i = 0; i < num_scope_syms; i++) {
3979 		rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
3980 		if (rc < 0)
3981 			return -1;
3982 		nprim = le32_to_cpu(buf[0]);
3983 		nel = le32_to_cpu(buf[1]);
3984 		for (j = 0; j < nel; j++) {
3985 			if (read_f[i] (p, decl->symtab[i].table, fp)) {
3986 				return -1;
3987 			}
3988 		}
3989 		decl->symtab[i].nprim = nprim;
3990 	}
3991 	return 0;
3992 }
3993 
avrule_block_read(policydb_t * p,avrule_block_t ** block,unsigned int num_scope_syms,struct policy_file * fp)3994 static int avrule_block_read(policydb_t * p,
3995 			     avrule_block_t ** block,
3996 			     unsigned int num_scope_syms,
3997 			     struct policy_file *fp)
3998 {
3999 	avrule_block_t *last_block = NULL, *curblock;
4000 	uint32_t buf[1], num_blocks, nel;
4001 	int rc;
4002 
4003 	assert(*block == NULL);
4004 
4005 	rc = next_entry(buf, fp, sizeof(uint32_t));
4006 	if (rc < 0)
4007 		return -1;
4008 	num_blocks = le32_to_cpu(buf[0]);
4009 	nel = num_blocks;
4010 	while (num_blocks > 0) {
4011 		avrule_decl_t *last_decl = NULL, *curdecl;
4012 		uint32_t num_decls;
4013 		if ((curblock = calloc(1, sizeof(*curblock))) == NULL) {
4014 			return -1;
4015 		}
4016 		rc = next_entry(buf, fp, sizeof(uint32_t));
4017 		if (rc < 0) {
4018 			free(curblock);
4019 			return -1;
4020 		}
4021 		/* if this is the first block its non-optional, else its optional */
4022 		if (num_blocks != nel)
4023 			curblock->flags |= AVRULE_OPTIONAL;
4024 
4025 		num_decls = le32_to_cpu(buf[0]);
4026 		while (num_decls > 0) {
4027 			if ((curdecl = avrule_decl_create(0)) == NULL) {
4028 				avrule_block_destroy(curblock);
4029 				return -1;
4030 			}
4031 			if (avrule_decl_read(p, curdecl, num_scope_syms, fp) ==
4032 			    -1) {
4033 				avrule_decl_destroy(curdecl);
4034 				avrule_block_destroy(curblock);
4035 				return -1;
4036 			}
4037 			if (curdecl->enabled) {
4038 				if (curblock->enabled != NULL) {
4039 					/* probably a corrupt file */
4040 					avrule_decl_destroy(curdecl);
4041 					avrule_block_destroy(curblock);
4042 					return -1;
4043 				}
4044 				curblock->enabled = curdecl;
4045 			}
4046 			/* one must be careful to reconstruct the
4047 			 * decl chain in its correct order */
4048 			if (curblock->branch_list == NULL) {
4049 				curblock->branch_list = curdecl;
4050 			} else {
4051 				assert(last_decl);
4052 				last_decl->next = curdecl;
4053 			}
4054 			last_decl = curdecl;
4055 			num_decls--;
4056 		}
4057 
4058 		if (*block == NULL) {
4059 			*block = curblock;
4060 		} else {
4061 			assert(last_block);
4062 			last_block->next = curblock;
4063 		}
4064 		last_block = curblock;
4065 
4066 		num_blocks--;
4067 	}
4068 
4069 	return 0;
4070 }
4071 
scope_read(policydb_t * p,int symnum,struct policy_file * fp)4072 static int scope_read(policydb_t * p, int symnum, struct policy_file *fp)
4073 {
4074 	scope_datum_t *scope = NULL;
4075 	uint32_t buf[2];
4076 	char *key = NULL;
4077 	size_t key_len;
4078 	unsigned int i;
4079 	hashtab_t h = p->scope[symnum].table;
4080 	int rc;
4081 
4082 	rc = next_entry(buf, fp, sizeof(uint32_t));
4083 	if (rc < 0)
4084 		goto cleanup;
4085 	key_len = le32_to_cpu(buf[0]);
4086 	if (zero_or_saturated(key_len))
4087 		goto cleanup;
4088 	key = malloc(key_len + 1);
4089 	if (!key)
4090 		goto cleanup;
4091 	rc = next_entry(key, fp, key_len);
4092 	if (rc < 0)
4093 		goto cleanup;
4094 	key[key_len] = '\0';
4095 
4096 	/* ensure that there already exists a symbol with this key */
4097 	if (hashtab_search(p->symtab[symnum].table, key) == NULL) {
4098 		goto cleanup;
4099 	}
4100 
4101 	if ((scope = calloc(1, sizeof(*scope))) == NULL) {
4102 		goto cleanup;
4103 	}
4104 	rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
4105 	if (rc < 0)
4106 		goto cleanup;
4107 	scope->scope = le32_to_cpu(buf[0]);
4108 	scope->decl_ids_len = le32_to_cpu(buf[1]);
4109 	if (scope->decl_ids_len == 0) {
4110 		ERR(fp->handle, "invalid scope with no declaration");
4111 		goto cleanup;
4112 	}
4113 	if ((scope->decl_ids =
4114 	     malloc(scope->decl_ids_len * sizeof(uint32_t))) == NULL) {
4115 		goto cleanup;
4116 	}
4117 	rc = next_entry(scope->decl_ids, fp, sizeof(uint32_t) * scope->decl_ids_len);
4118 	if (rc < 0)
4119 		goto cleanup;
4120 	for (i = 0; i < scope->decl_ids_len; i++) {
4121 		scope->decl_ids[i] = le32_to_cpu(scope->decl_ids[i]);
4122 	}
4123 
4124 	if (strcmp(key, "object_r") == 0 && h == p->p_roles_scope.table) {
4125 		/* object_r was already added to this table in roles_init() */
4126 		scope_destroy(key, scope, NULL);
4127 	} else {
4128 		if (hashtab_insert(h, key, scope)) {
4129 			goto cleanup;
4130 		}
4131 	}
4132 
4133 	return 0;
4134 
4135       cleanup:
4136 	scope_destroy(key, scope, NULL);
4137 	return -1;
4138 }
4139 
policydb_string_to_security_class(struct policydb * policydb,const char * class_name)4140 static sepol_security_class_t policydb_string_to_security_class(
4141 	struct policydb *policydb,
4142 	const char *class_name)
4143 {
4144 	class_datum_t *tclass_datum;
4145 
4146 	tclass_datum = hashtab_search(policydb->p_classes.table,
4147 				      (hashtab_key_t) class_name);
4148 	if (!tclass_datum)
4149 		return 0;
4150 	return tclass_datum->s.value;
4151 }
4152 
policydb_string_to_av_perm(struct policydb * policydb,sepol_security_class_t tclass,const char * perm_name)4153 static sepol_access_vector_t policydb_string_to_av_perm(
4154 	struct policydb *policydb,
4155 	sepol_security_class_t tclass,
4156 	const char *perm_name)
4157 {
4158 	class_datum_t *tclass_datum;
4159 	perm_datum_t *perm_datum;
4160 
4161 	if (!tclass || tclass > policydb->p_classes.nprim)
4162 		return 0;
4163 	tclass_datum = policydb->class_val_to_struct[tclass - 1];
4164 
4165 	perm_datum = (perm_datum_t *)
4166 			hashtab_search(tclass_datum->permissions.table,
4167 			(hashtab_key_t)perm_name);
4168 	if (perm_datum != NULL)
4169 		return UINT32_C(1) << (perm_datum->s.value - 1);
4170 
4171 	if (tclass_datum->comdatum == NULL)
4172 		return 0;
4173 
4174 	perm_datum = (perm_datum_t *)
4175 			hashtab_search(tclass_datum->comdatum->permissions.table,
4176 			(hashtab_key_t)perm_name);
4177 
4178 	if (perm_datum != NULL)
4179 		return UINT32_C(1) << (perm_datum->s.value - 1);
4180 
4181 	return 0;
4182 }
4183 
4184 
4185 /*
4186  * Read the configuration data from a policy database binary
4187  * representation file into a policy database structure.
4188  */
policydb_read(policydb_t * p,struct policy_file * fp,unsigned verbose)4189 int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose)
4190 {
4191 
4192 	unsigned int i, j, r_policyvers;
4193 	uint32_t buf[5];
4194 	size_t len, nprim, nel;
4195 	char *policydb_str;
4196 	const struct policydb_compat_info *info;
4197 	unsigned int policy_type, bufindex;
4198 	ebitmap_node_t *tnode;
4199 	int rc;
4200 
4201 	/* Read the magic number and string length. */
4202 	rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
4203 	if (rc < 0)
4204 		return POLICYDB_ERROR;
4205 	for (i = 0; i < 2; i++)
4206 		buf[i] = le32_to_cpu(buf[i]);
4207 
4208 	if (buf[0] == POLICYDB_MAGIC) {
4209 		policy_type = POLICY_KERN;
4210 	} else if (buf[0] == POLICYDB_MOD_MAGIC) {
4211 		policy_type = POLICY_MOD;
4212 	} else {
4213 		ERR(fp->handle, "policydb magic number %#08x does not "
4214 		    "match expected magic number %#08x or %#08x",
4215 		    buf[0], POLICYDB_MAGIC, POLICYDB_MOD_MAGIC);
4216 		return POLICYDB_ERROR;
4217 	}
4218 
4219 	len = buf[1];
4220 	if (len == 0 || len > POLICYDB_STRING_MAX_LENGTH) {
4221 		ERR(fp->handle, "policydb string length %s ", len ? "too long" : "zero");
4222 		return POLICYDB_ERROR;
4223 	}
4224 
4225 	policydb_str = malloc(len + 1);
4226 	if (!policydb_str) {
4227 		ERR(fp->handle, "unable to allocate memory for policydb "
4228 		    "string of length %zu", len);
4229 		return POLICYDB_ERROR;
4230 	}
4231 	rc = next_entry(policydb_str, fp, len);
4232 	if (rc < 0) {
4233 		ERR(fp->handle, "truncated policydb string identifier");
4234 		free(policydb_str);
4235 		return POLICYDB_ERROR;
4236 	}
4237 	policydb_str[len] = 0;
4238 
4239 	if (policy_type == POLICY_KERN) {
4240 		for (i = 0; i < POLICYDB_TARGET_SZ; i++) {
4241 			if ((strcmp(policydb_str, policydb_target_strings[i])
4242 				== 0)) {
4243 				policydb_set_target_platform(p, i);
4244 				break;
4245 			}
4246 		}
4247 
4248 		if (i == POLICYDB_TARGET_SZ) {
4249 			ERR(fp->handle, "cannot find a valid target for policy "
4250 				"string %s", policydb_str);
4251 			free(policydb_str);
4252 			return POLICYDB_ERROR;
4253 		}
4254 	} else {
4255 		if (strcmp(policydb_str, POLICYDB_MOD_STRING)) {
4256 			ERR(fp->handle, "invalid string identifier %s",
4257 				policydb_str);
4258 			free(policydb_str);
4259 			return POLICYDB_ERROR;
4260 		}
4261 	}
4262 
4263 	/* Done with policydb_str. */
4264 	free(policydb_str);
4265 	policydb_str = NULL;
4266 
4267 	/* Read the version, config, and table sizes (and policy type if it's a module). */
4268 	if (policy_type == POLICY_KERN)
4269 		nel = 4;
4270 	else
4271 		nel = 5;
4272 
4273 	rc = next_entry(buf, fp, sizeof(uint32_t) * nel);
4274 	if (rc < 0)
4275 		return POLICYDB_ERROR;
4276 	for (i = 0; i < nel; i++)
4277 		buf[i] = le32_to_cpu(buf[i]);
4278 
4279 	bufindex = 0;
4280 
4281 	if (policy_type == POLICY_MOD) {
4282 		/* We know it's a module but not whether it's a base
4283 		   module or regular binary policy module.  buf[0]
4284 		   tells us which. */
4285 		policy_type = buf[bufindex];
4286 		if (policy_type != POLICY_MOD && policy_type != POLICY_BASE) {
4287 			ERR(fp->handle, "unknown module type: %#08x",
4288 			    policy_type);
4289 			return POLICYDB_ERROR;
4290 		}
4291 		bufindex++;
4292 	}
4293 
4294 	r_policyvers = buf[bufindex];
4295 	if (policy_type == POLICY_KERN) {
4296 		if (r_policyvers < POLICYDB_VERSION_MIN ||
4297 		    r_policyvers > POLICYDB_VERSION_MAX) {
4298 			ERR(fp->handle, "policydb version %d does not match "
4299 			    "my version range %d-%d", buf[bufindex],
4300 			    POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX);
4301 			return POLICYDB_ERROR;
4302 		}
4303 	} else if (policy_type == POLICY_BASE || policy_type == POLICY_MOD) {
4304 		if (r_policyvers < MOD_POLICYDB_VERSION_MIN ||
4305 		    r_policyvers > MOD_POLICYDB_VERSION_MAX) {
4306 			ERR(fp->handle, "policydb module version %d does "
4307 			    "not match my version range %d-%d",
4308 			    buf[bufindex], MOD_POLICYDB_VERSION_MIN,
4309 			    MOD_POLICYDB_VERSION_MAX);
4310 			return POLICYDB_ERROR;
4311 		}
4312 	} else {
4313 		assert(0);
4314 	}
4315 	bufindex++;
4316 
4317 	/* Set the policy type and version from the read values. */
4318 	p->policy_type = policy_type;
4319 	p->policyvers = r_policyvers;
4320 
4321 	if (buf[bufindex] & POLICYDB_CONFIG_MLS) {
4322 		p->mls = 1;
4323 	} else {
4324 		p->mls = 0;
4325 	}
4326 
4327 	p->handle_unknown = buf[bufindex] & POLICYDB_CONFIG_UNKNOWN_MASK;
4328 
4329 	bufindex++;
4330 
4331 	info = policydb_lookup_compat(r_policyvers, policy_type,
4332 					p->target_platform);
4333 	if (!info) {
4334 		ERR(fp->handle, "unable to find policy compat info "
4335 		    "for version %d", r_policyvers);
4336 		goto bad;
4337 	}
4338 
4339 	if (buf[bufindex] != info->sym_num
4340 	    || buf[bufindex + 1] != info->ocon_num) {
4341 		ERR(fp->handle,
4342 		    "policydb table sizes (%d,%d) do not " "match mine (%d,%d)",
4343 		    buf[bufindex], buf[bufindex + 1], info->sym_num,
4344 		    info->ocon_num);
4345 		goto bad;
4346 	}
4347 
4348 	if (p->policy_type == POLICY_MOD) {
4349 		/* Get the module name and version */
4350 		if ((rc = next_entry(buf, fp, sizeof(uint32_t))) < 0) {
4351 			goto bad;
4352 		}
4353 		len = le32_to_cpu(buf[0]);
4354 		if (zero_or_saturated(len))
4355 			goto bad;
4356 		if ((p->name = malloc(len + 1)) == NULL) {
4357 			goto bad;
4358 		}
4359 		if ((rc = next_entry(p->name, fp, len)) < 0) {
4360 			goto bad;
4361 		}
4362 		p->name[len] = '\0';
4363 		if ((rc = next_entry(buf, fp, sizeof(uint32_t))) < 0) {
4364 			goto bad;
4365 		}
4366 		len = le32_to_cpu(buf[0]);
4367 		if (zero_or_saturated(len))
4368 			goto bad;
4369 		if ((p->version = malloc(len + 1)) == NULL) {
4370 			goto bad;
4371 		}
4372 		if ((rc = next_entry(p->version, fp, len)) < 0) {
4373 			goto bad;
4374 		}
4375 		p->version[len] = '\0';
4376 	}
4377 
4378 	if ((p->policyvers >= POLICYDB_VERSION_POLCAP &&
4379 	     p->policy_type == POLICY_KERN) ||
4380 	    (p->policyvers >= MOD_POLICYDB_VERSION_POLCAP &&
4381 	     p->policy_type == POLICY_BASE) ||
4382 	    (p->policyvers >= MOD_POLICYDB_VERSION_POLCAP &&
4383 	     p->policy_type == POLICY_MOD)) {
4384 		if (ebitmap_read(&p->policycaps, fp))
4385 			goto bad;
4386 	}
4387 
4388 	if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE &&
4389 	    p->policy_type == POLICY_KERN) {
4390 		if (ebitmap_read(&p->permissive_map, fp))
4391 			goto bad;
4392 	}
4393 
4394 	for (i = 0; i < info->sym_num; i++) {
4395 		rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
4396 		if (rc < 0)
4397 			goto bad;
4398 		nprim = le32_to_cpu(buf[0]);
4399 		nel = le32_to_cpu(buf[1]);
4400 		if (nel && !nprim) {
4401 			ERR(fp->handle, "unexpected items in symbol table with no symbol");
4402 			goto bad;
4403 		}
4404 		for (j = 0; j < nel; j++) {
4405 			if (read_f[i] (p, p->symtab[i].table, fp))
4406 				goto bad;
4407 		}
4408 
4409 		p->symtab[i].nprim = nprim;
4410 	}
4411 
4412 	switch (p->target_platform) {
4413 	case SEPOL_TARGET_SELINUX:
4414 		p->process_class = policydb_string_to_security_class(p, "process");
4415 		p->dir_class = policydb_string_to_security_class(p, "dir");
4416 		break;
4417 	case SEPOL_TARGET_XEN:
4418 		p->process_class = policydb_string_to_security_class(p, "domain");
4419 		break;
4420 	default:
4421 		break;
4422 	}
4423 
4424 	if (policy_type == POLICY_KERN) {
4425 		if (avtab_read(&p->te_avtab, fp, r_policyvers))
4426 			goto bad;
4427 		if (r_policyvers >= POLICYDB_VERSION_BOOL)
4428 			if (cond_read_list(p, &p->cond_list, fp))
4429 				goto bad;
4430 		if (role_trans_read(p, fp))
4431 			goto bad;
4432 		if (role_allow_read(&p->role_allow, fp))
4433 			goto bad;
4434 		if (r_policyvers >= POLICYDB_VERSION_FILENAME_TRANS &&
4435 		    filename_trans_read(p, fp))
4436 			goto bad;
4437 	} else {
4438 		/* first read the AV rule blocks, then the scope tables */
4439 		avrule_block_destroy(p->global);
4440 		p->global = NULL;
4441 		if (avrule_block_read(p, &p->global, info->sym_num, fp) == -1) {
4442 			goto bad;
4443 		}
4444 		if (p->global == NULL) {
4445 			ERR(fp->handle, "no avrule block in policy");
4446 			goto bad;
4447 		}
4448 		for (i = 0; i < info->sym_num; i++) {
4449 			if ((rc = next_entry(buf, fp, sizeof(uint32_t))) < 0) {
4450 				goto bad;
4451 			}
4452 			nel = le32_to_cpu(buf[0]);
4453 			for (j = 0; j < nel; j++) {
4454 				if (scope_read(p, i, fp))
4455 					goto bad;
4456 			}
4457 		}
4458 
4459 	}
4460 
4461 	if (policydb_index_decls(fp->handle, p))
4462 		goto bad;
4463 
4464 	if (policydb_index_classes(p))
4465 		goto bad;
4466 
4467 	switch (p->target_platform) {
4468 	case SEPOL_TARGET_SELINUX:
4469 		/* fall through */
4470 	case SEPOL_TARGET_XEN:
4471 		p->process_trans = policydb_string_to_av_perm(p, p->process_class,
4472 							      "transition");
4473 		p->process_trans_dyntrans = p->process_trans |
4474 			policydb_string_to_av_perm(p, p->process_class,
4475 						   "dyntransition");
4476 		break;
4477 	default:
4478 		break;
4479 	}
4480 
4481 	if (policydb_index_others(fp->handle, p, verbose))
4482 		goto bad;
4483 
4484 	if (ocontext_read(info, p, fp) == -1) {
4485 		goto bad;
4486 	}
4487 
4488 	if (genfs_read(p, fp) == -1) {
4489 		goto bad;
4490 	}
4491 
4492 	if ((p->policy_type == POLICY_KERN
4493 	     && p->policyvers >= POLICYDB_VERSION_MLS)
4494 	    || (p->policy_type == POLICY_BASE
4495 		&& p->policyvers >= MOD_POLICYDB_VERSION_MLS
4496 		&& p->policyvers < MOD_POLICYDB_VERSION_RANGETRANS)) {
4497 		if (range_read(p, fp)) {
4498 			goto bad;
4499 		}
4500 	}
4501 
4502 	if (policy_type == POLICY_KERN) {
4503 		p->type_attr_map = malloc(p->p_types.nprim * sizeof(ebitmap_t));
4504 		p->attr_type_map = malloc(p->p_types.nprim * sizeof(ebitmap_t));
4505 		if (!p->type_attr_map || !p->attr_type_map)
4506 			goto bad;
4507 		for (i = 0; i < p->p_types.nprim; i++) {
4508 			ebitmap_init(&p->type_attr_map[i]);
4509 			ebitmap_init(&p->attr_type_map[i]);
4510 		}
4511 		for (i = 0; i < p->p_types.nprim; i++) {
4512 			if (r_policyvers >= POLICYDB_VERSION_AVTAB) {
4513 				if (ebitmap_read(&p->type_attr_map[i], fp))
4514 					goto bad;
4515 				ebitmap_for_each_positive_bit(&p->type_attr_map[i],
4516 							 tnode, j) {
4517 					if (i == j)
4518 						continue;
4519 
4520 					if (j >= p->p_types.nprim)
4521 						goto bad;
4522 
4523 					if (ebitmap_set_bit
4524 					    (&p->attr_type_map[j], i, 1))
4525 						goto bad;
4526 				}
4527 			}
4528 			/* add the type itself as the degenerate case */
4529 			if (ebitmap_set_bit(&p->type_attr_map[i], i, 1))
4530 				goto bad;
4531 			if (p->type_val_to_struct[i] && p->type_val_to_struct[i]->flavor != TYPE_ATTRIB) {
4532 				if (ebitmap_set_bit(&p->attr_type_map[i], i, 1))
4533 					goto bad;
4534 			}
4535 		}
4536 	}
4537 
4538 	if (validate_policydb(fp->handle, p))
4539 		goto bad;
4540 
4541 	return POLICYDB_SUCCESS;
4542       bad:
4543 	return POLICYDB_ERROR;
4544 }
4545 
policydb_reindex_users(policydb_t * p)4546 int policydb_reindex_users(policydb_t * p)
4547 {
4548 	unsigned int i = SYM_USERS;
4549 
4550 	if (p->user_val_to_struct)
4551 		free(p->user_val_to_struct);
4552 	if (p->sym_val_to_name[i])
4553 		free(p->sym_val_to_name[i]);
4554 
4555 	p->user_val_to_struct = (user_datum_t **)
4556 	    calloc(p->p_users.nprim, sizeof(user_datum_t *));
4557 	if (!p->user_val_to_struct)
4558 		return -1;
4559 
4560 	p->sym_val_to_name[i] = (char **)
4561 	    calloc(p->symtab[i].nprim, sizeof(char *));
4562 	if (!p->sym_val_to_name[i])
4563 		return -1;
4564 
4565 	if (hashtab_map(p->symtab[i].table, index_f[i], p))
4566 		return -1;
4567 
4568 	/* Expand user roles for context validity checking */
4569 	if (hashtab_map(p->p_users.table, policydb_user_cache, p))
4570 		return -1;
4571 
4572 	return 0;
4573 }
4574 
policy_file_init(policy_file_t * pf)4575 void policy_file_init(policy_file_t *pf)
4576 {
4577 	memset(pf, 0, sizeof(policy_file_t));
4578 }
4579 
policydb_set_target_platform(policydb_t * p,int platform)4580 int policydb_set_target_platform(policydb_t *p, int platform)
4581 {
4582 	if (platform == SEPOL_TARGET_SELINUX)
4583 		p->target_platform = SEPOL_TARGET_SELINUX;
4584 	else if (platform == SEPOL_TARGET_XEN)
4585 		p->target_platform = SEPOL_TARGET_XEN;
4586 	else
4587 		return -1;
4588 
4589 	return 0;
4590 }
4591 
policydb_sort_ocontexts(policydb_t * p)4592 int policydb_sort_ocontexts(policydb_t *p)
4593 {
4594 	return sort_ocontexts(p);
4595 }
4596