blob: b18895302555618f02ee0d03590bc2e04ee3d1c6 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * Implementation of the policy database.
3 *
4 * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
5 */
6
7/*
8 * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com>
9 *
10 * Support for enhanced MLS infrastructure.
11 *
12 * Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com>
13 *
14 * Added conditional policy language extensions
15 *
16 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
17 * Copyright (C) 2003 - 2004 Tresys Technology, LLC
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation, version 2.
21 */
22
23#include <linux/kernel.h>
24#include <linux/slab.h>
25#include <linux/string.h>
26#include <linux/errno.h>
27#include "security.h"
28
29#include "policydb.h"
30#include "conditional.h"
31#include "mls.h"
32
33#define _DEBUG_HASHES
34
35#ifdef DEBUG_HASHES
36static char *symtab_name[SYM_NUM] = {
37 "common prefixes",
38 "classes",
39 "roles",
40 "types",
41 "users",
42 "bools",
43 "levels",
44 "categories",
45};
46#endif
47
48int selinux_mls_enabled = 0;
49
50static unsigned int symtab_sizes[SYM_NUM] = {
51 2,
52 32,
53 16,
54 512,
55 128,
56 16,
57 16,
58 16,
59};
60
61struct policydb_compat_info {
62 int version;
63 int sym_num;
64 int ocon_num;
65};
66
67/* These need to be updated if SYM_NUM or OCON_NUM changes */
68static struct policydb_compat_info policydb_compat[] = {
69 {
70 .version = POLICYDB_VERSION_BASE,
71 .sym_num = SYM_NUM - 3,
72 .ocon_num = OCON_NUM - 1,
73 },
74 {
75 .version = POLICYDB_VERSION_BOOL,
76 .sym_num = SYM_NUM - 2,
77 .ocon_num = OCON_NUM - 1,
78 },
79 {
80 .version = POLICYDB_VERSION_IPV6,
81 .sym_num = SYM_NUM - 2,
82 .ocon_num = OCON_NUM,
83 },
84 {
85 .version = POLICYDB_VERSION_NLCLASS,
86 .sym_num = SYM_NUM - 2,
87 .ocon_num = OCON_NUM,
88 },
89 {
90 .version = POLICYDB_VERSION_MLS,
91 .sym_num = SYM_NUM,
92 .ocon_num = OCON_NUM,
93 },
Stephen Smalley782ebb92005-09-03 15:55:16 -070094 {
95 .version = POLICYDB_VERSION_AVTAB,
96 .sym_num = SYM_NUM,
97 .ocon_num = OCON_NUM,
98 },
Darrel Goeddelf3f87712006-09-25 23:31:59 -070099 {
100 .version = POLICYDB_VERSION_RANGETRANS,
101 .sym_num = SYM_NUM,
102 .ocon_num = OCON_NUM,
103 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104};
105
106static struct policydb_compat_info *policydb_lookup_compat(int version)
107{
108 int i;
109 struct policydb_compat_info *info = NULL;
110
Tobias Klauser32725ad2006-01-06 00:11:23 -0800111 for (i = 0; i < ARRAY_SIZE(policydb_compat); i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112 if (policydb_compat[i].version == version) {
113 info = &policydb_compat[i];
114 break;
115 }
116 }
117 return info;
118}
119
120/*
121 * Initialize the role table.
122 */
123static int roles_init(struct policydb *p)
124{
125 char *key = NULL;
126 int rc;
127 struct role_datum *role;
128
James Morris89d155e2005-10-30 14:59:21 -0800129 role = kzalloc(sizeof(*role), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130 if (!role) {
131 rc = -ENOMEM;
132 goto out;
133 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134 role->value = ++p->p_roles.nprim;
135 if (role->value != OBJECT_R_VAL) {
136 rc = -EINVAL;
137 goto out_free_role;
138 }
139 key = kmalloc(strlen(OBJECT_R)+1,GFP_KERNEL);
140 if (!key) {
141 rc = -ENOMEM;
142 goto out_free_role;
143 }
144 strcpy(key, OBJECT_R);
145 rc = hashtab_insert(p->p_roles.table, key, role);
146 if (rc)
147 goto out_free_key;
148out:
149 return rc;
150
151out_free_key:
152 kfree(key);
153out_free_role:
154 kfree(role);
155 goto out;
156}
157
158/*
159 * Initialize a policy database structure.
160 */
161static int policydb_init(struct policydb *p)
162{
163 int i, rc;
164
165 memset(p, 0, sizeof(*p));
166
167 for (i = 0; i < SYM_NUM; i++) {
168 rc = symtab_init(&p->symtab[i], symtab_sizes[i]);
169 if (rc)
170 goto out_free_symtab;
171 }
172
173 rc = avtab_init(&p->te_avtab);
174 if (rc)
175 goto out_free_symtab;
176
177 rc = roles_init(p);
178 if (rc)
179 goto out_free_avtab;
180
181 rc = cond_policydb_init(p);
182 if (rc)
183 goto out_free_avtab;
184
185out:
186 return rc;
187
188out_free_avtab:
189 avtab_destroy(&p->te_avtab);
190
191out_free_symtab:
192 for (i = 0; i < SYM_NUM; i++)
193 hashtab_destroy(p->symtab[i].table);
194 goto out;
195}
196
197/*
198 * The following *_index functions are used to
199 * define the val_to_name and val_to_struct arrays
200 * in a policy database structure. The val_to_name
201 * arrays are used when converting security context
202 * structures into string representations. The
203 * val_to_struct arrays are used when the attributes
204 * of a class, role, or user are needed.
205 */
206
207static int common_index(void *key, void *datum, void *datap)
208{
209 struct policydb *p;
210 struct common_datum *comdatum;
211
212 comdatum = datum;
213 p = datap;
214 if (!comdatum->value || comdatum->value > p->p_commons.nprim)
215 return -EINVAL;
216 p->p_common_val_to_name[comdatum->value - 1] = key;
217 return 0;
218}
219
220static int class_index(void *key, void *datum, void *datap)
221{
222 struct policydb *p;
223 struct class_datum *cladatum;
224
225 cladatum = datum;
226 p = datap;
227 if (!cladatum->value || cladatum->value > p->p_classes.nprim)
228 return -EINVAL;
229 p->p_class_val_to_name[cladatum->value - 1] = key;
230 p->class_val_to_struct[cladatum->value - 1] = cladatum;
231 return 0;
232}
233
234static int role_index(void *key, void *datum, void *datap)
235{
236 struct policydb *p;
237 struct role_datum *role;
238
239 role = datum;
240 p = datap;
241 if (!role->value || role->value > p->p_roles.nprim)
242 return -EINVAL;
243 p->p_role_val_to_name[role->value - 1] = key;
244 p->role_val_to_struct[role->value - 1] = role;
245 return 0;
246}
247
248static int type_index(void *key, void *datum, void *datap)
249{
250 struct policydb *p;
251 struct type_datum *typdatum;
252
253 typdatum = datum;
254 p = datap;
255
256 if (typdatum->primary) {
257 if (!typdatum->value || typdatum->value > p->p_types.nprim)
258 return -EINVAL;
259 p->p_type_val_to_name[typdatum->value - 1] = key;
260 }
261
262 return 0;
263}
264
265static int user_index(void *key, void *datum, void *datap)
266{
267 struct policydb *p;
268 struct user_datum *usrdatum;
269
270 usrdatum = datum;
271 p = datap;
272 if (!usrdatum->value || usrdatum->value > p->p_users.nprim)
273 return -EINVAL;
274 p->p_user_val_to_name[usrdatum->value - 1] = key;
275 p->user_val_to_struct[usrdatum->value - 1] = usrdatum;
276 return 0;
277}
278
279static int sens_index(void *key, void *datum, void *datap)
280{
281 struct policydb *p;
282 struct level_datum *levdatum;
283
284 levdatum = datum;
285 p = datap;
286
287 if (!levdatum->isalias) {
288 if (!levdatum->level->sens ||
289 levdatum->level->sens > p->p_levels.nprim)
290 return -EINVAL;
291 p->p_sens_val_to_name[levdatum->level->sens - 1] = key;
292 }
293
294 return 0;
295}
296
297static int cat_index(void *key, void *datum, void *datap)
298{
299 struct policydb *p;
300 struct cat_datum *catdatum;
301
302 catdatum = datum;
303 p = datap;
304
305 if (!catdatum->isalias) {
306 if (!catdatum->value || catdatum->value > p->p_cats.nprim)
307 return -EINVAL;
308 p->p_cat_val_to_name[catdatum->value - 1] = key;
309 }
310
311 return 0;
312}
313
314static int (*index_f[SYM_NUM]) (void *key, void *datum, void *datap) =
315{
316 common_index,
317 class_index,
318 role_index,
319 type_index,
320 user_index,
321 cond_index_bool,
322 sens_index,
323 cat_index,
324};
325
326/*
327 * Define the common val_to_name array and the class
328 * val_to_name and val_to_struct arrays in a policy
329 * database structure.
330 *
331 * Caller must clean up upon failure.
332 */
333static int policydb_index_classes(struct policydb *p)
334{
335 int rc;
336
337 p->p_common_val_to_name =
338 kmalloc(p->p_commons.nprim * sizeof(char *), GFP_KERNEL);
339 if (!p->p_common_val_to_name) {
340 rc = -ENOMEM;
341 goto out;
342 }
343
344 rc = hashtab_map(p->p_commons.table, common_index, p);
345 if (rc)
346 goto out;
347
348 p->class_val_to_struct =
349 kmalloc(p->p_classes.nprim * sizeof(*(p->class_val_to_struct)), GFP_KERNEL);
350 if (!p->class_val_to_struct) {
351 rc = -ENOMEM;
352 goto out;
353 }
354
355 p->p_class_val_to_name =
356 kmalloc(p->p_classes.nprim * sizeof(char *), GFP_KERNEL);
357 if (!p->p_class_val_to_name) {
358 rc = -ENOMEM;
359 goto out;
360 }
361
362 rc = hashtab_map(p->p_classes.table, class_index, p);
363out:
364 return rc;
365}
366
367#ifdef DEBUG_HASHES
368static void symtab_hash_eval(struct symtab *s)
369{
370 int i;
371
372 for (i = 0; i < SYM_NUM; i++) {
373 struct hashtab *h = s[i].table;
374 struct hashtab_info info;
375
376 hashtab_stat(h, &info);
377 printk(KERN_INFO "%s: %d entries and %d/%d buckets used, "
378 "longest chain length %d\n", symtab_name[i], h->nel,
379 info.slots_used, h->size, info.max_chain_len);
380 }
381}
382#endif
383
384/*
385 * Define the other val_to_name and val_to_struct arrays
386 * in a policy database structure.
387 *
388 * Caller must clean up on failure.
389 */
390static int policydb_index_others(struct policydb *p)
391{
392 int i, rc = 0;
393
394 printk(KERN_INFO "security: %d users, %d roles, %d types, %d bools",
395 p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim);
396 if (selinux_mls_enabled)
397 printk(", %d sens, %d cats", p->p_levels.nprim,
398 p->p_cats.nprim);
399 printk("\n");
400
401 printk(KERN_INFO "security: %d classes, %d rules\n",
402 p->p_classes.nprim, p->te_avtab.nel);
403
404#ifdef DEBUG_HASHES
405 avtab_hash_eval(&p->te_avtab, "rules");
406 symtab_hash_eval(p->symtab);
407#endif
408
409 p->role_val_to_struct =
410 kmalloc(p->p_roles.nprim * sizeof(*(p->role_val_to_struct)),
411 GFP_KERNEL);
412 if (!p->role_val_to_struct) {
413 rc = -ENOMEM;
414 goto out;
415 }
416
417 p->user_val_to_struct =
418 kmalloc(p->p_users.nprim * sizeof(*(p->user_val_to_struct)),
419 GFP_KERNEL);
420 if (!p->user_val_to_struct) {
421 rc = -ENOMEM;
422 goto out;
423 }
424
425 if (cond_init_bool_indexes(p)) {
426 rc = -ENOMEM;
427 goto out;
428 }
429
430 for (i = SYM_ROLES; i < SYM_NUM; i++) {
431 p->sym_val_to_name[i] =
432 kmalloc(p->symtab[i].nprim * sizeof(char *), GFP_KERNEL);
433 if (!p->sym_val_to_name[i]) {
434 rc = -ENOMEM;
435 goto out;
436 }
437 rc = hashtab_map(p->symtab[i].table, index_f[i], p);
438 if (rc)
439 goto out;
440 }
441
442out:
443 return rc;
444}
445
446/*
447 * The following *_destroy functions are used to
448 * free any memory allocated for each kind of
449 * symbol data in the policy database.
450 */
451
452static int perm_destroy(void *key, void *datum, void *p)
453{
454 kfree(key);
455 kfree(datum);
456 return 0;
457}
458
459static int common_destroy(void *key, void *datum, void *p)
460{
461 struct common_datum *comdatum;
462
463 kfree(key);
464 comdatum = datum;
465 hashtab_map(comdatum->permissions.table, perm_destroy, NULL);
466 hashtab_destroy(comdatum->permissions.table);
467 kfree(datum);
468 return 0;
469}
470
471static int class_destroy(void *key, void *datum, void *p)
472{
473 struct class_datum *cladatum;
474 struct constraint_node *constraint, *ctemp;
475 struct constraint_expr *e, *etmp;
476
477 kfree(key);
478 cladatum = datum;
479 hashtab_map(cladatum->permissions.table, perm_destroy, NULL);
480 hashtab_destroy(cladatum->permissions.table);
481 constraint = cladatum->constraints;
482 while (constraint) {
483 e = constraint->expr;
484 while (e) {
485 ebitmap_destroy(&e->names);
486 etmp = e;
487 e = e->next;
488 kfree(etmp);
489 }
490 ctemp = constraint;
491 constraint = constraint->next;
492 kfree(ctemp);
493 }
494
495 constraint = cladatum->validatetrans;
496 while (constraint) {
497 e = constraint->expr;
498 while (e) {
499 ebitmap_destroy(&e->names);
500 etmp = e;
501 e = e->next;
502 kfree(etmp);
503 }
504 ctemp = constraint;
505 constraint = constraint->next;
506 kfree(ctemp);
507 }
508
509 kfree(cladatum->comkey);
510 kfree(datum);
511 return 0;
512}
513
514static int role_destroy(void *key, void *datum, void *p)
515{
516 struct role_datum *role;
517
518 kfree(key);
519 role = datum;
520 ebitmap_destroy(&role->dominates);
521 ebitmap_destroy(&role->types);
522 kfree(datum);
523 return 0;
524}
525
526static int type_destroy(void *key, void *datum, void *p)
527{
528 kfree(key);
529 kfree(datum);
530 return 0;
531}
532
533static int user_destroy(void *key, void *datum, void *p)
534{
535 struct user_datum *usrdatum;
536
537 kfree(key);
538 usrdatum = datum;
539 ebitmap_destroy(&usrdatum->roles);
540 ebitmap_destroy(&usrdatum->range.level[0].cat);
541 ebitmap_destroy(&usrdatum->range.level[1].cat);
542 ebitmap_destroy(&usrdatum->dfltlevel.cat);
543 kfree(datum);
544 return 0;
545}
546
547static int sens_destroy(void *key, void *datum, void *p)
548{
549 struct level_datum *levdatum;
550
551 kfree(key);
552 levdatum = datum;
553 ebitmap_destroy(&levdatum->level->cat);
554 kfree(levdatum->level);
555 kfree(datum);
556 return 0;
557}
558
559static int cat_destroy(void *key, void *datum, void *p)
560{
561 kfree(key);
562 kfree(datum);
563 return 0;
564}
565
566static int (*destroy_f[SYM_NUM]) (void *key, void *datum, void *datap) =
567{
568 common_destroy,
569 class_destroy,
570 role_destroy,
571 type_destroy,
572 user_destroy,
573 cond_destroy_bool,
574 sens_destroy,
575 cat_destroy,
576};
577
578static void ocontext_destroy(struct ocontext *c, int i)
579{
580 context_destroy(&c->context[0]);
581 context_destroy(&c->context[1]);
582 if (i == OCON_ISID || i == OCON_FS ||
583 i == OCON_NETIF || i == OCON_FSUSE)
584 kfree(c->u.name);
585 kfree(c);
586}
587
588/*
589 * Free any memory allocated by a policy database structure.
590 */
591void policydb_destroy(struct policydb *p)
592{
593 struct ocontext *c, *ctmp;
594 struct genfs *g, *gtmp;
595 int i;
Stephen Smalley782ebb92005-09-03 15:55:16 -0700596 struct role_allow *ra, *lra = NULL;
597 struct role_trans *tr, *ltr = NULL;
598 struct range_trans *rt, *lrt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599
600 for (i = 0; i < SYM_NUM; i++) {
601 hashtab_map(p->symtab[i].table, destroy_f[i], NULL);
602 hashtab_destroy(p->symtab[i].table);
603 }
604
Jesper Juhl9a5f04b2005-06-25 14:58:51 -0700605 for (i = 0; i < SYM_NUM; i++)
606 kfree(p->sym_val_to_name[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607
Jesper Juhl9a5f04b2005-06-25 14:58:51 -0700608 kfree(p->class_val_to_struct);
609 kfree(p->role_val_to_struct);
610 kfree(p->user_val_to_struct);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700611
612 avtab_destroy(&p->te_avtab);
613
614 for (i = 0; i < OCON_NUM; i++) {
615 c = p->ocontexts[i];
616 while (c) {
617 ctmp = c;
618 c = c->next;
619 ocontext_destroy(ctmp,i);
620 }
621 }
622
623 g = p->genfs;
624 while (g) {
625 kfree(g->fstype);
626 c = g->head;
627 while (c) {
628 ctmp = c;
629 c = c->next;
630 ocontext_destroy(ctmp,OCON_FSUSE);
631 }
632 gtmp = g;
633 g = g->next;
634 kfree(gtmp);
635 }
636
637 cond_policydb_destroy(p);
638
Stephen Smalley782ebb92005-09-03 15:55:16 -0700639 for (tr = p->role_tr; tr; tr = tr->next) {
Jesper Juhla7f988b2005-11-07 01:01:35 -0800640 kfree(ltr);
Stephen Smalley782ebb92005-09-03 15:55:16 -0700641 ltr = tr;
642 }
Jesper Juhla7f988b2005-11-07 01:01:35 -0800643 kfree(ltr);
Stephen Smalley782ebb92005-09-03 15:55:16 -0700644
645 for (ra = p->role_allow; ra; ra = ra -> next) {
Jesper Juhla7f988b2005-11-07 01:01:35 -0800646 kfree(lra);
Stephen Smalley782ebb92005-09-03 15:55:16 -0700647 lra = ra;
648 }
Jesper Juhla7f988b2005-11-07 01:01:35 -0800649 kfree(lra);
Stephen Smalley782ebb92005-09-03 15:55:16 -0700650
651 for (rt = p->range_tr; rt; rt = rt -> next) {
Darrel Goeddelddccef32006-07-30 03:03:17 -0700652 if (lrt) {
Darrel Goeddelf3f87712006-09-25 23:31:59 -0700653 ebitmap_destroy(&lrt->target_range.level[0].cat);
654 ebitmap_destroy(&lrt->target_range.level[1].cat);
Darrel Goeddelddccef32006-07-30 03:03:17 -0700655 kfree(lrt);
656 }
Stephen Smalley782ebb92005-09-03 15:55:16 -0700657 lrt = rt;
658 }
Darrel Goeddelddccef32006-07-30 03:03:17 -0700659 if (lrt) {
Darrel Goeddelf3f87712006-09-25 23:31:59 -0700660 ebitmap_destroy(&lrt->target_range.level[0].cat);
661 ebitmap_destroy(&lrt->target_range.level[1].cat);
Darrel Goeddelddccef32006-07-30 03:03:17 -0700662 kfree(lrt);
663 }
Stephen Smalley782ebb92005-09-03 15:55:16 -0700664
Stephen Smalley282c1f52005-10-23 12:57:15 -0700665 if (p->type_attr_map) {
666 for (i = 0; i < p->p_types.nprim; i++)
667 ebitmap_destroy(&p->type_attr_map[i]);
668 }
Stephen Smalley782ebb92005-09-03 15:55:16 -0700669 kfree(p->type_attr_map);
670
Linus Torvalds1da177e2005-04-16 15:20:36 -0700671 return;
672}
673
674/*
675 * Load the initial SIDs specified in a policy database
676 * structure into a SID table.
677 */
678int policydb_load_isids(struct policydb *p, struct sidtab *s)
679{
680 struct ocontext *head, *c;
681 int rc;
682
683 rc = sidtab_init(s);
684 if (rc) {
685 printk(KERN_ERR "security: out of memory on SID table init\n");
686 goto out;
687 }
688
689 head = p->ocontexts[OCON_ISID];
690 for (c = head; c; c = c->next) {
691 if (!c->context[0].user) {
692 printk(KERN_ERR "security: SID %s was never "
693 "defined.\n", c->u.name);
694 rc = -EINVAL;
695 goto out;
696 }
697 if (sidtab_insert(s, c->sid[0], &c->context[0])) {
698 printk(KERN_ERR "security: unable to load initial "
699 "SID %s.\n", c->u.name);
700 rc = -EINVAL;
701 goto out;
702 }
703 }
704out:
705 return rc;
706}
707
708/*
709 * Return 1 if the fields in the security context
710 * structure `c' are valid. Return 0 otherwise.
711 */
712int policydb_context_isvalid(struct policydb *p, struct context *c)
713{
714 struct role_datum *role;
715 struct user_datum *usrdatum;
716
717 if (!c->role || c->role > p->p_roles.nprim)
718 return 0;
719
720 if (!c->user || c->user > p->p_users.nprim)
721 return 0;
722
723 if (!c->type || c->type > p->p_types.nprim)
724 return 0;
725
726 if (c->role != OBJECT_R_VAL) {
727 /*
728 * Role must be authorized for the type.
729 */
730 role = p->role_val_to_struct[c->role - 1];
731 if (!ebitmap_get_bit(&role->types,
732 c->type - 1))
733 /* role may not be associated with type */
734 return 0;
735
736 /*
737 * User must be authorized for the role.
738 */
739 usrdatum = p->user_val_to_struct[c->user - 1];
740 if (!usrdatum)
741 return 0;
742
743 if (!ebitmap_get_bit(&usrdatum->roles,
744 c->role - 1))
745 /* user may not be associated with role */
746 return 0;
747 }
748
749 if (!mls_context_isvalid(p, c))
750 return 0;
751
752 return 1;
753}
754
755/*
756 * Read a MLS range structure from a policydb binary
757 * representation file.
758 */
759static int mls_read_range_helper(struct mls_range *r, void *fp)
760{
Alexey Dobriyanb5bf6c52005-09-03 15:55:17 -0700761 __le32 buf[2];
762 u32 items;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763 int rc;
764
765 rc = next_entry(buf, fp, sizeof(u32));
766 if (rc < 0)
767 goto out;
768
769 items = le32_to_cpu(buf[0]);
770 if (items > ARRAY_SIZE(buf)) {
771 printk(KERN_ERR "security: mls: range overflow\n");
772 rc = -EINVAL;
773 goto out;
774 }
775 rc = next_entry(buf, fp, sizeof(u32) * items);
776 if (rc < 0) {
777 printk(KERN_ERR "security: mls: truncated range\n");
778 goto out;
779 }
780 r->level[0].sens = le32_to_cpu(buf[0]);
781 if (items > 1)
782 r->level[1].sens = le32_to_cpu(buf[1]);
783 else
784 r->level[1].sens = r->level[0].sens;
785
786 rc = ebitmap_read(&r->level[0].cat, fp);
787 if (rc) {
788 printk(KERN_ERR "security: mls: error reading low "
789 "categories\n");
790 goto out;
791 }
792 if (items > 1) {
793 rc = ebitmap_read(&r->level[1].cat, fp);
794 if (rc) {
795 printk(KERN_ERR "security: mls: error reading high "
796 "categories\n");
797 goto bad_high;
798 }
799 } else {
800 rc = ebitmap_cpy(&r->level[1].cat, &r->level[0].cat);
801 if (rc) {
802 printk(KERN_ERR "security: mls: out of memory\n");
803 goto bad_high;
804 }
805 }
806
807 rc = 0;
808out:
809 return rc;
810bad_high:
811 ebitmap_destroy(&r->level[0].cat);
812 goto out;
813}
814
815/*
816 * Read and validate a security context structure
817 * from a policydb binary representation file.
818 */
819static int context_read_and_validate(struct context *c,
820 struct policydb *p,
821 void *fp)
822{
Alexey Dobriyanb5bf6c52005-09-03 15:55:17 -0700823 __le32 buf[3];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824 int rc;
825
826 rc = next_entry(buf, fp, sizeof buf);
827 if (rc < 0) {
828 printk(KERN_ERR "security: context truncated\n");
829 goto out;
830 }
831 c->user = le32_to_cpu(buf[0]);
832 c->role = le32_to_cpu(buf[1]);
833 c->type = le32_to_cpu(buf[2]);
834 if (p->policyvers >= POLICYDB_VERSION_MLS) {
835 if (mls_read_range_helper(&c->range, fp)) {
836 printk(KERN_ERR "security: error reading MLS range of "
837 "context\n");
838 rc = -EINVAL;
839 goto out;
840 }
841 }
842
843 if (!policydb_context_isvalid(p, c)) {
844 printk(KERN_ERR "security: invalid security context\n");
845 context_destroy(c);
846 rc = -EINVAL;
847 }
848out:
849 return rc;
850}
851
852/*
853 * The following *_read functions are used to
854 * read the symbol data from a policy database
855 * binary representation file.
856 */
857
858static int perm_read(struct policydb *p, struct hashtab *h, void *fp)
859{
860 char *key = NULL;
861 struct perm_datum *perdatum;
862 int rc;
Alexey Dobriyanb5bf6c52005-09-03 15:55:17 -0700863 __le32 buf[2];
864 u32 len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700865
James Morris89d155e2005-10-30 14:59:21 -0800866 perdatum = kzalloc(sizeof(*perdatum), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700867 if (!perdatum) {
868 rc = -ENOMEM;
869 goto out;
870 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871
872 rc = next_entry(buf, fp, sizeof buf);
873 if (rc < 0)
874 goto bad;
875
876 len = le32_to_cpu(buf[0]);
877 perdatum->value = le32_to_cpu(buf[1]);
878
879 key = kmalloc(len + 1,GFP_KERNEL);
880 if (!key) {
881 rc = -ENOMEM;
882 goto bad;
883 }
884 rc = next_entry(key, fp, len);
885 if (rc < 0)
886 goto bad;
887 key[len] = 0;
888
889 rc = hashtab_insert(h, key, perdatum);
890 if (rc)
891 goto bad;
892out:
893 return rc;
894bad:
895 perm_destroy(key, perdatum, NULL);
896 goto out;
897}
898
899static int common_read(struct policydb *p, struct hashtab *h, void *fp)
900{
901 char *key = NULL;
902 struct common_datum *comdatum;
Alexey Dobriyanb5bf6c52005-09-03 15:55:17 -0700903 __le32 buf[4];
904 u32 len, nel;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700905 int i, rc;
906
James Morris89d155e2005-10-30 14:59:21 -0800907 comdatum = kzalloc(sizeof(*comdatum), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700908 if (!comdatum) {
909 rc = -ENOMEM;
910 goto out;
911 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700912
913 rc = next_entry(buf, fp, sizeof buf);
914 if (rc < 0)
915 goto bad;
916
917 len = le32_to_cpu(buf[0]);
918 comdatum->value = le32_to_cpu(buf[1]);
919
920 rc = symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE);
921 if (rc)
922 goto bad;
923 comdatum->permissions.nprim = le32_to_cpu(buf[2]);
924 nel = le32_to_cpu(buf[3]);
925
926 key = kmalloc(len + 1,GFP_KERNEL);
927 if (!key) {
928 rc = -ENOMEM;
929 goto bad;
930 }
931 rc = next_entry(key, fp, len);
932 if (rc < 0)
933 goto bad;
934 key[len] = 0;
935
936 for (i = 0; i < nel; i++) {
937 rc = perm_read(p, comdatum->permissions.table, fp);
938 if (rc)
939 goto bad;
940 }
941
942 rc = hashtab_insert(h, key, comdatum);
943 if (rc)
944 goto bad;
945out:
946 return rc;
947bad:
948 common_destroy(key, comdatum, NULL);
949 goto out;
950}
951
952static int read_cons_helper(struct constraint_node **nodep, int ncons,
953 int allowxtarget, void *fp)
954{
955 struct constraint_node *c, *lc;
956 struct constraint_expr *e, *le;
Alexey Dobriyanb5bf6c52005-09-03 15:55:17 -0700957 __le32 buf[3];
958 u32 nexpr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700959 int rc, i, j, depth;
960
961 lc = NULL;
962 for (i = 0; i < ncons; i++) {
James Morris89d155e2005-10-30 14:59:21 -0800963 c = kzalloc(sizeof(*c), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700964 if (!c)
965 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700966
967 if (lc) {
968 lc->next = c;
969 } else {
970 *nodep = c;
971 }
972
973 rc = next_entry(buf, fp, (sizeof(u32) * 2));
974 if (rc < 0)
975 return rc;
976 c->permissions = le32_to_cpu(buf[0]);
977 nexpr = le32_to_cpu(buf[1]);
978 le = NULL;
979 depth = -1;
980 for (j = 0; j < nexpr; j++) {
James Morris89d155e2005-10-30 14:59:21 -0800981 e = kzalloc(sizeof(*e), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700982 if (!e)
983 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700984
985 if (le) {
986 le->next = e;
987 } else {
988 c->expr = e;
989 }
990
991 rc = next_entry(buf, fp, (sizeof(u32) * 3));
992 if (rc < 0)
993 return rc;
994 e->expr_type = le32_to_cpu(buf[0]);
995 e->attr = le32_to_cpu(buf[1]);
996 e->op = le32_to_cpu(buf[2]);
997
998 switch (e->expr_type) {
999 case CEXPR_NOT:
1000 if (depth < 0)
1001 return -EINVAL;
1002 break;
1003 case CEXPR_AND:
1004 case CEXPR_OR:
1005 if (depth < 1)
1006 return -EINVAL;
1007 depth--;
1008 break;
1009 case CEXPR_ATTR:
1010 if (depth == (CEXPR_MAXDEPTH - 1))
1011 return -EINVAL;
1012 depth++;
1013 break;
1014 case CEXPR_NAMES:
1015 if (!allowxtarget && (e->attr & CEXPR_XTARGET))
1016 return -EINVAL;
1017 if (depth == (CEXPR_MAXDEPTH - 1))
1018 return -EINVAL;
1019 depth++;
1020 if (ebitmap_read(&e->names, fp))
1021 return -EINVAL;
1022 break;
1023 default:
1024 return -EINVAL;
1025 }
1026 le = e;
1027 }
1028 if (depth != 0)
1029 return -EINVAL;
1030 lc = c;
1031 }
1032
1033 return 0;
1034}
1035
1036static int class_read(struct policydb *p, struct hashtab *h, void *fp)
1037{
1038 char *key = NULL;
1039 struct class_datum *cladatum;
Alexey Dobriyanb5bf6c52005-09-03 15:55:17 -07001040 __le32 buf[6];
1041 u32 len, len2, ncons, nel;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042 int i, rc;
1043
James Morris89d155e2005-10-30 14:59:21 -08001044 cladatum = kzalloc(sizeof(*cladatum), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045 if (!cladatum) {
1046 rc = -ENOMEM;
1047 goto out;
1048 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049
1050 rc = next_entry(buf, fp, sizeof(u32)*6);
1051 if (rc < 0)
1052 goto bad;
1053
1054 len = le32_to_cpu(buf[0]);
1055 len2 = le32_to_cpu(buf[1]);
1056 cladatum->value = le32_to_cpu(buf[2]);
1057
1058 rc = symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE);
1059 if (rc)
1060 goto bad;
1061 cladatum->permissions.nprim = le32_to_cpu(buf[3]);
1062 nel = le32_to_cpu(buf[4]);
1063
1064 ncons = le32_to_cpu(buf[5]);
1065
1066 key = kmalloc(len + 1,GFP_KERNEL);
1067 if (!key) {
1068 rc = -ENOMEM;
1069 goto bad;
1070 }
1071 rc = next_entry(key, fp, len);
1072 if (rc < 0)
1073 goto bad;
1074 key[len] = 0;
1075
1076 if (len2) {
1077 cladatum->comkey = kmalloc(len2 + 1,GFP_KERNEL);
1078 if (!cladatum->comkey) {
1079 rc = -ENOMEM;
1080 goto bad;
1081 }
1082 rc = next_entry(cladatum->comkey, fp, len2);
1083 if (rc < 0)
1084 goto bad;
1085 cladatum->comkey[len2] = 0;
1086
1087 cladatum->comdatum = hashtab_search(p->p_commons.table,
1088 cladatum->comkey);
1089 if (!cladatum->comdatum) {
1090 printk(KERN_ERR "security: unknown common %s\n",
1091 cladatum->comkey);
1092 rc = -EINVAL;
1093 goto bad;
1094 }
1095 }
1096 for (i = 0; i < nel; i++) {
1097 rc = perm_read(p, cladatum->permissions.table, fp);
1098 if (rc)
1099 goto bad;
1100 }
1101
1102 rc = read_cons_helper(&cladatum->constraints, ncons, 0, fp);
1103 if (rc)
1104 goto bad;
1105
1106 if (p->policyvers >= POLICYDB_VERSION_VALIDATETRANS) {
1107 /* grab the validatetrans rules */
1108 rc = next_entry(buf, fp, sizeof(u32));
1109 if (rc < 0)
1110 goto bad;
1111 ncons = le32_to_cpu(buf[0]);
1112 rc = read_cons_helper(&cladatum->validatetrans, ncons, 1, fp);
1113 if (rc)
1114 goto bad;
1115 }
1116
1117 rc = hashtab_insert(h, key, cladatum);
1118 if (rc)
1119 goto bad;
1120
1121 rc = 0;
1122out:
1123 return rc;
1124bad:
1125 class_destroy(key, cladatum, NULL);
1126 goto out;
1127}
1128
1129static int role_read(struct policydb *p, struct hashtab *h, void *fp)
1130{
1131 char *key = NULL;
1132 struct role_datum *role;
1133 int rc;
Alexey Dobriyanb5bf6c52005-09-03 15:55:17 -07001134 __le32 buf[2];
1135 u32 len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001136
James Morris89d155e2005-10-30 14:59:21 -08001137 role = kzalloc(sizeof(*role), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001138 if (!role) {
1139 rc = -ENOMEM;
1140 goto out;
1141 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001142
1143 rc = next_entry(buf, fp, sizeof buf);
1144 if (rc < 0)
1145 goto bad;
1146
1147 len = le32_to_cpu(buf[0]);
1148 role->value = le32_to_cpu(buf[1]);
1149
1150 key = kmalloc(len + 1,GFP_KERNEL);
1151 if (!key) {
1152 rc = -ENOMEM;
1153 goto bad;
1154 }
1155 rc = next_entry(key, fp, len);
1156 if (rc < 0)
1157 goto bad;
1158 key[len] = 0;
1159
1160 rc = ebitmap_read(&role->dominates, fp);
1161 if (rc)
1162 goto bad;
1163
1164 rc = ebitmap_read(&role->types, fp);
1165 if (rc)
1166 goto bad;
1167
1168 if (strcmp(key, OBJECT_R) == 0) {
1169 if (role->value != OBJECT_R_VAL) {
1170 printk(KERN_ERR "Role %s has wrong value %d\n",
1171 OBJECT_R, role->value);
1172 rc = -EINVAL;
1173 goto bad;
1174 }
1175 rc = 0;
1176 goto bad;
1177 }
1178
1179 rc = hashtab_insert(h, key, role);
1180 if (rc)
1181 goto bad;
1182out:
1183 return rc;
1184bad:
1185 role_destroy(key, role, NULL);
1186 goto out;
1187}
1188
1189static int type_read(struct policydb *p, struct hashtab *h, void *fp)
1190{
1191 char *key = NULL;
1192 struct type_datum *typdatum;
1193 int rc;
Alexey Dobriyanb5bf6c52005-09-03 15:55:17 -07001194 __le32 buf[3];
1195 u32 len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001196
James Morris89d155e2005-10-30 14:59:21 -08001197 typdatum = kzalloc(sizeof(*typdatum),GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001198 if (!typdatum) {
1199 rc = -ENOMEM;
1200 return rc;
1201 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001202
1203 rc = next_entry(buf, fp, sizeof buf);
1204 if (rc < 0)
1205 goto bad;
1206
1207 len = le32_to_cpu(buf[0]);
1208 typdatum->value = le32_to_cpu(buf[1]);
1209 typdatum->primary = le32_to_cpu(buf[2]);
1210
1211 key = kmalloc(len + 1,GFP_KERNEL);
1212 if (!key) {
1213 rc = -ENOMEM;
1214 goto bad;
1215 }
1216 rc = next_entry(key, fp, len);
1217 if (rc < 0)
1218 goto bad;
1219 key[len] = 0;
1220
1221 rc = hashtab_insert(h, key, typdatum);
1222 if (rc)
1223 goto bad;
1224out:
1225 return rc;
1226bad:
1227 type_destroy(key, typdatum, NULL);
1228 goto out;
1229}
1230
1231
1232/*
1233 * Read a MLS level structure from a policydb binary
1234 * representation file.
1235 */
1236static int mls_read_level(struct mls_level *lp, void *fp)
1237{
Alexey Dobriyanb5bf6c52005-09-03 15:55:17 -07001238 __le32 buf[1];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001239 int rc;
1240
1241 memset(lp, 0, sizeof(*lp));
1242
1243 rc = next_entry(buf, fp, sizeof buf);
1244 if (rc < 0) {
1245 printk(KERN_ERR "security: mls: truncated level\n");
1246 goto bad;
1247 }
1248 lp->sens = le32_to_cpu(buf[0]);
1249
1250 if (ebitmap_read(&lp->cat, fp)) {
1251 printk(KERN_ERR "security: mls: error reading level "
1252 "categories\n");
1253 goto bad;
1254 }
1255 return 0;
1256
1257bad:
1258 return -EINVAL;
1259}
1260
1261static int user_read(struct policydb *p, struct hashtab *h, void *fp)
1262{
1263 char *key = NULL;
1264 struct user_datum *usrdatum;
1265 int rc;
Alexey Dobriyanb5bf6c52005-09-03 15:55:17 -07001266 __le32 buf[2];
1267 u32 len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001268
James Morris89d155e2005-10-30 14:59:21 -08001269 usrdatum = kzalloc(sizeof(*usrdatum), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001270 if (!usrdatum) {
1271 rc = -ENOMEM;
1272 goto out;
1273 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001274
1275 rc = next_entry(buf, fp, sizeof buf);
1276 if (rc < 0)
1277 goto bad;
1278
1279 len = le32_to_cpu(buf[0]);
1280 usrdatum->value = le32_to_cpu(buf[1]);
1281
1282 key = kmalloc(len + 1,GFP_KERNEL);
1283 if (!key) {
1284 rc = -ENOMEM;
1285 goto bad;
1286 }
1287 rc = next_entry(key, fp, len);
1288 if (rc < 0)
1289 goto bad;
1290 key[len] = 0;
1291
1292 rc = ebitmap_read(&usrdatum->roles, fp);
1293 if (rc)
1294 goto bad;
1295
1296 if (p->policyvers >= POLICYDB_VERSION_MLS) {
1297 rc = mls_read_range_helper(&usrdatum->range, fp);
1298 if (rc)
1299 goto bad;
1300 rc = mls_read_level(&usrdatum->dfltlevel, fp);
1301 if (rc)
1302 goto bad;
1303 }
1304
1305 rc = hashtab_insert(h, key, usrdatum);
1306 if (rc)
1307 goto bad;
1308out:
1309 return rc;
1310bad:
1311 user_destroy(key, usrdatum, NULL);
1312 goto out;
1313}
1314
1315static int sens_read(struct policydb *p, struct hashtab *h, void *fp)
1316{
1317 char *key = NULL;
1318 struct level_datum *levdatum;
1319 int rc;
Alexey Dobriyanb5bf6c52005-09-03 15:55:17 -07001320 __le32 buf[2];
1321 u32 len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001322
James Morris89d155e2005-10-30 14:59:21 -08001323 levdatum = kzalloc(sizeof(*levdatum), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001324 if (!levdatum) {
1325 rc = -ENOMEM;
1326 goto out;
1327 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001328
1329 rc = next_entry(buf, fp, sizeof buf);
1330 if (rc < 0)
1331 goto bad;
1332
1333 len = le32_to_cpu(buf[0]);
1334 levdatum->isalias = le32_to_cpu(buf[1]);
1335
1336 key = kmalloc(len + 1,GFP_ATOMIC);
1337 if (!key) {
1338 rc = -ENOMEM;
1339 goto bad;
1340 }
1341 rc = next_entry(key, fp, len);
1342 if (rc < 0)
1343 goto bad;
1344 key[len] = 0;
1345
1346 levdatum->level = kmalloc(sizeof(struct mls_level), GFP_ATOMIC);
1347 if (!levdatum->level) {
1348 rc = -ENOMEM;
1349 goto bad;
1350 }
1351 if (mls_read_level(levdatum->level, fp)) {
1352 rc = -EINVAL;
1353 goto bad;
1354 }
1355
1356 rc = hashtab_insert(h, key, levdatum);
1357 if (rc)
1358 goto bad;
1359out:
1360 return rc;
1361bad:
1362 sens_destroy(key, levdatum, NULL);
1363 goto out;
1364}
1365
1366static int cat_read(struct policydb *p, struct hashtab *h, void *fp)
1367{
1368 char *key = NULL;
1369 struct cat_datum *catdatum;
1370 int rc;
Alexey Dobriyanb5bf6c52005-09-03 15:55:17 -07001371 __le32 buf[3];
1372 u32 len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001373
James Morris89d155e2005-10-30 14:59:21 -08001374 catdatum = kzalloc(sizeof(*catdatum), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001375 if (!catdatum) {
1376 rc = -ENOMEM;
1377 goto out;
1378 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001379
1380 rc = next_entry(buf, fp, sizeof buf);
1381 if (rc < 0)
1382 goto bad;
1383
1384 len = le32_to_cpu(buf[0]);
1385 catdatum->value = le32_to_cpu(buf[1]);
1386 catdatum->isalias = le32_to_cpu(buf[2]);
1387
1388 key = kmalloc(len + 1,GFP_ATOMIC);
1389 if (!key) {
1390 rc = -ENOMEM;
1391 goto bad;
1392 }
1393 rc = next_entry(key, fp, len);
1394 if (rc < 0)
1395 goto bad;
1396 key[len] = 0;
1397
1398 rc = hashtab_insert(h, key, catdatum);
1399 if (rc)
1400 goto bad;
1401out:
1402 return rc;
1403
1404bad:
1405 cat_destroy(key, catdatum, NULL);
1406 goto out;
1407}
1408
1409static int (*read_f[SYM_NUM]) (struct policydb *p, struct hashtab *h, void *fp) =
1410{
1411 common_read,
1412 class_read,
1413 role_read,
1414 type_read,
1415 user_read,
1416 cond_read_bool,
1417 sens_read,
1418 cat_read,
1419};
1420
1421extern int ss_initialized;
1422
1423/*
1424 * Read the configuration data from a policy database binary
1425 * representation file into a policy database structure.
1426 */
1427int policydb_read(struct policydb *p, void *fp)
1428{
1429 struct role_allow *ra, *lra;
1430 struct role_trans *tr, *ltr;
1431 struct ocontext *l, *c, *newc;
1432 struct genfs *genfs_p, *genfs, *newgenfs;
1433 int i, j, rc;
Alexey Dobriyanb5bf6c52005-09-03 15:55:17 -07001434 __le32 buf[8];
1435 u32 len, len2, config, nprim, nel, nel2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001436 char *policydb_str;
1437 struct policydb_compat_info *info;
1438 struct range_trans *rt, *lrt;
1439
1440 config = 0;
1441
1442 rc = policydb_init(p);
1443 if (rc)
1444 goto out;
1445
1446 /* Read the magic number and string length. */
1447 rc = next_entry(buf, fp, sizeof(u32)* 2);
1448 if (rc < 0)
1449 goto bad;
1450
Alexey Dobriyanb5bf6c52005-09-03 15:55:17 -07001451 if (le32_to_cpu(buf[0]) != POLICYDB_MAGIC) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001452 printk(KERN_ERR "security: policydb magic number 0x%x does "
1453 "not match expected magic number 0x%x\n",
Alexey Dobriyanb5bf6c52005-09-03 15:55:17 -07001454 le32_to_cpu(buf[0]), POLICYDB_MAGIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001455 goto bad;
1456 }
1457
Alexey Dobriyanb5bf6c52005-09-03 15:55:17 -07001458 len = le32_to_cpu(buf[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001459 if (len != strlen(POLICYDB_STRING)) {
1460 printk(KERN_ERR "security: policydb string length %d does not "
1461 "match expected length %Zu\n",
1462 len, strlen(POLICYDB_STRING));
1463 goto bad;
1464 }
1465 policydb_str = kmalloc(len + 1,GFP_KERNEL);
1466 if (!policydb_str) {
1467 printk(KERN_ERR "security: unable to allocate memory for policydb "
1468 "string of length %d\n", len);
1469 rc = -ENOMEM;
1470 goto bad;
1471 }
1472 rc = next_entry(policydb_str, fp, len);
1473 if (rc < 0) {
1474 printk(KERN_ERR "security: truncated policydb string identifier\n");
1475 kfree(policydb_str);
1476 goto bad;
1477 }
1478 policydb_str[len] = 0;
1479 if (strcmp(policydb_str, POLICYDB_STRING)) {
1480 printk(KERN_ERR "security: policydb string %s does not match "
1481 "my string %s\n", policydb_str, POLICYDB_STRING);
1482 kfree(policydb_str);
1483 goto bad;
1484 }
1485 /* Done with policydb_str. */
1486 kfree(policydb_str);
1487 policydb_str = NULL;
1488
1489 /* Read the version, config, and table sizes. */
1490 rc = next_entry(buf, fp, sizeof(u32)*4);
1491 if (rc < 0)
1492 goto bad;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001493
Alexey Dobriyanb5bf6c52005-09-03 15:55:17 -07001494 p->policyvers = le32_to_cpu(buf[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001495 if (p->policyvers < POLICYDB_VERSION_MIN ||
1496 p->policyvers > POLICYDB_VERSION_MAX) {
1497 printk(KERN_ERR "security: policydb version %d does not match "
1498 "my version range %d-%d\n",
Alexey Dobriyanb5bf6c52005-09-03 15:55:17 -07001499 le32_to_cpu(buf[0]), POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001500 goto bad;
1501 }
1502
Alexey Dobriyanb5bf6c52005-09-03 15:55:17 -07001503 if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001504 if (ss_initialized && !selinux_mls_enabled) {
1505 printk(KERN_ERR "Cannot switch between non-MLS and MLS "
1506 "policies\n");
1507 goto bad;
1508 }
1509 selinux_mls_enabled = 1;
1510 config |= POLICYDB_CONFIG_MLS;
1511
1512 if (p->policyvers < POLICYDB_VERSION_MLS) {
1513 printk(KERN_ERR "security policydb version %d (MLS) "
1514 "not backwards compatible\n", p->policyvers);
1515 goto bad;
1516 }
1517 } else {
1518 if (ss_initialized && selinux_mls_enabled) {
1519 printk(KERN_ERR "Cannot switch between MLS and non-MLS "
1520 "policies\n");
1521 goto bad;
1522 }
1523 }
1524
1525 info = policydb_lookup_compat(p->policyvers);
1526 if (!info) {
1527 printk(KERN_ERR "security: unable to find policy compat info "
1528 "for version %d\n", p->policyvers);
1529 goto bad;
1530 }
1531
Alexey Dobriyanb5bf6c52005-09-03 15:55:17 -07001532 if (le32_to_cpu(buf[2]) != info->sym_num ||
1533 le32_to_cpu(buf[3]) != info->ocon_num) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534 printk(KERN_ERR "security: policydb table sizes (%d,%d) do "
Alexey Dobriyanb5bf6c52005-09-03 15:55:17 -07001535 "not match mine (%d,%d)\n", le32_to_cpu(buf[2]),
1536 le32_to_cpu(buf[3]),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001537 info->sym_num, info->ocon_num);
1538 goto bad;
1539 }
1540
1541 for (i = 0; i < info->sym_num; i++) {
1542 rc = next_entry(buf, fp, sizeof(u32)*2);
1543 if (rc < 0)
1544 goto bad;
1545 nprim = le32_to_cpu(buf[0]);
1546 nel = le32_to_cpu(buf[1]);
1547 for (j = 0; j < nel; j++) {
1548 rc = read_f[i](p, p->symtab[i].table, fp);
1549 if (rc)
1550 goto bad;
1551 }
1552
1553 p->symtab[i].nprim = nprim;
1554 }
1555
Stephen Smalley782ebb92005-09-03 15:55:16 -07001556 rc = avtab_read(&p->te_avtab, fp, p->policyvers);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001557 if (rc)
1558 goto bad;
1559
1560 if (p->policyvers >= POLICYDB_VERSION_BOOL) {
1561 rc = cond_read_list(p, fp);
1562 if (rc)
1563 goto bad;
1564 }
1565
1566 rc = next_entry(buf, fp, sizeof(u32));
1567 if (rc < 0)
1568 goto bad;
1569 nel = le32_to_cpu(buf[0]);
1570 ltr = NULL;
1571 for (i = 0; i < nel; i++) {
James Morris89d155e2005-10-30 14:59:21 -08001572 tr = kzalloc(sizeof(*tr), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001573 if (!tr) {
1574 rc = -ENOMEM;
1575 goto bad;
1576 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577 if (ltr) {
1578 ltr->next = tr;
1579 } else {
1580 p->role_tr = tr;
1581 }
1582 rc = next_entry(buf, fp, sizeof(u32)*3);
1583 if (rc < 0)
1584 goto bad;
1585 tr->role = le32_to_cpu(buf[0]);
1586 tr->type = le32_to_cpu(buf[1]);
1587 tr->new_role = le32_to_cpu(buf[2]);
1588 ltr = tr;
1589 }
1590
1591 rc = next_entry(buf, fp, sizeof(u32));
1592 if (rc < 0)
1593 goto bad;
1594 nel = le32_to_cpu(buf[0]);
1595 lra = NULL;
1596 for (i = 0; i < nel; i++) {
James Morris89d155e2005-10-30 14:59:21 -08001597 ra = kzalloc(sizeof(*ra), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598 if (!ra) {
1599 rc = -ENOMEM;
1600 goto bad;
1601 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001602 if (lra) {
1603 lra->next = ra;
1604 } else {
1605 p->role_allow = ra;
1606 }
1607 rc = next_entry(buf, fp, sizeof(u32)*2);
1608 if (rc < 0)
1609 goto bad;
1610 ra->role = le32_to_cpu(buf[0]);
1611 ra->new_role = le32_to_cpu(buf[1]);
1612 lra = ra;
1613 }
1614
1615 rc = policydb_index_classes(p);
1616 if (rc)
1617 goto bad;
1618
1619 rc = policydb_index_others(p);
1620 if (rc)
1621 goto bad;
1622
1623 for (i = 0; i < info->ocon_num; i++) {
1624 rc = next_entry(buf, fp, sizeof(u32));
1625 if (rc < 0)
1626 goto bad;
1627 nel = le32_to_cpu(buf[0]);
1628 l = NULL;
1629 for (j = 0; j < nel; j++) {
James Morris89d155e2005-10-30 14:59:21 -08001630 c = kzalloc(sizeof(*c), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001631 if (!c) {
1632 rc = -ENOMEM;
1633 goto bad;
1634 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001635 if (l) {
1636 l->next = c;
1637 } else {
1638 p->ocontexts[i] = c;
1639 }
1640 l = c;
1641 rc = -EINVAL;
1642 switch (i) {
1643 case OCON_ISID:
1644 rc = next_entry(buf, fp, sizeof(u32));
1645 if (rc < 0)
1646 goto bad;
1647 c->sid[0] = le32_to_cpu(buf[0]);
1648 rc = context_read_and_validate(&c->context[0], p, fp);
1649 if (rc)
1650 goto bad;
1651 break;
1652 case OCON_FS:
1653 case OCON_NETIF:
1654 rc = next_entry(buf, fp, sizeof(u32));
1655 if (rc < 0)
1656 goto bad;
1657 len = le32_to_cpu(buf[0]);
1658 c->u.name = kmalloc(len + 1,GFP_KERNEL);
1659 if (!c->u.name) {
1660 rc = -ENOMEM;
1661 goto bad;
1662 }
1663 rc = next_entry(c->u.name, fp, len);
1664 if (rc < 0)
1665 goto bad;
1666 c->u.name[len] = 0;
1667 rc = context_read_and_validate(&c->context[0], p, fp);
1668 if (rc)
1669 goto bad;
1670 rc = context_read_and_validate(&c->context[1], p, fp);
1671 if (rc)
1672 goto bad;
1673 break;
1674 case OCON_PORT:
1675 rc = next_entry(buf, fp, sizeof(u32)*3);
1676 if (rc < 0)
1677 goto bad;
1678 c->u.port.protocol = le32_to_cpu(buf[0]);
1679 c->u.port.low_port = le32_to_cpu(buf[1]);
1680 c->u.port.high_port = le32_to_cpu(buf[2]);
1681 rc = context_read_and_validate(&c->context[0], p, fp);
1682 if (rc)
1683 goto bad;
1684 break;
1685 case OCON_NODE:
1686 rc = next_entry(buf, fp, sizeof(u32)* 2);
1687 if (rc < 0)
1688 goto bad;
1689 c->u.node.addr = le32_to_cpu(buf[0]);
1690 c->u.node.mask = le32_to_cpu(buf[1]);
1691 rc = context_read_and_validate(&c->context[0], p, fp);
1692 if (rc)
1693 goto bad;
1694 break;
1695 case OCON_FSUSE:
1696 rc = next_entry(buf, fp, sizeof(u32)*2);
1697 if (rc < 0)
1698 goto bad;
1699 c->v.behavior = le32_to_cpu(buf[0]);
1700 if (c->v.behavior > SECURITY_FS_USE_NONE)
1701 goto bad;
1702 len = le32_to_cpu(buf[1]);
1703 c->u.name = kmalloc(len + 1,GFP_KERNEL);
1704 if (!c->u.name) {
1705 rc = -ENOMEM;
1706 goto bad;
1707 }
1708 rc = next_entry(c->u.name, fp, len);
1709 if (rc < 0)
1710 goto bad;
1711 c->u.name[len] = 0;
1712 rc = context_read_and_validate(&c->context[0], p, fp);
1713 if (rc)
1714 goto bad;
1715 break;
1716 case OCON_NODE6: {
1717 int k;
1718
1719 rc = next_entry(buf, fp, sizeof(u32) * 8);
1720 if (rc < 0)
1721 goto bad;
1722 for (k = 0; k < 4; k++)
1723 c->u.node6.addr[k] = le32_to_cpu(buf[k]);
1724 for (k = 0; k < 4; k++)
1725 c->u.node6.mask[k] = le32_to_cpu(buf[k+4]);
1726 if (context_read_and_validate(&c->context[0], p, fp))
1727 goto bad;
1728 break;
1729 }
1730 }
1731 }
1732 }
1733
1734 rc = next_entry(buf, fp, sizeof(u32));
1735 if (rc < 0)
1736 goto bad;
1737 nel = le32_to_cpu(buf[0]);
1738 genfs_p = NULL;
1739 rc = -EINVAL;
1740 for (i = 0; i < nel; i++) {
1741 rc = next_entry(buf, fp, sizeof(u32));
1742 if (rc < 0)
1743 goto bad;
1744 len = le32_to_cpu(buf[0]);
James Morris89d155e2005-10-30 14:59:21 -08001745 newgenfs = kzalloc(sizeof(*newgenfs), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001746 if (!newgenfs) {
1747 rc = -ENOMEM;
1748 goto bad;
1749 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001750
1751 newgenfs->fstype = kmalloc(len + 1,GFP_KERNEL);
1752 if (!newgenfs->fstype) {
1753 rc = -ENOMEM;
1754 kfree(newgenfs);
1755 goto bad;
1756 }
1757 rc = next_entry(newgenfs->fstype, fp, len);
1758 if (rc < 0) {
1759 kfree(newgenfs->fstype);
1760 kfree(newgenfs);
1761 goto bad;
1762 }
1763 newgenfs->fstype[len] = 0;
1764 for (genfs_p = NULL, genfs = p->genfs; genfs;
1765 genfs_p = genfs, genfs = genfs->next) {
1766 if (strcmp(newgenfs->fstype, genfs->fstype) == 0) {
1767 printk(KERN_ERR "security: dup genfs "
1768 "fstype %s\n", newgenfs->fstype);
1769 kfree(newgenfs->fstype);
1770 kfree(newgenfs);
1771 goto bad;
1772 }
1773 if (strcmp(newgenfs->fstype, genfs->fstype) < 0)
1774 break;
1775 }
1776 newgenfs->next = genfs;
1777 if (genfs_p)
1778 genfs_p->next = newgenfs;
1779 else
1780 p->genfs = newgenfs;
1781 rc = next_entry(buf, fp, sizeof(u32));
1782 if (rc < 0)
1783 goto bad;
1784 nel2 = le32_to_cpu(buf[0]);
1785 for (j = 0; j < nel2; j++) {
1786 rc = next_entry(buf, fp, sizeof(u32));
1787 if (rc < 0)
1788 goto bad;
1789 len = le32_to_cpu(buf[0]);
1790
James Morris89d155e2005-10-30 14:59:21 -08001791 newc = kzalloc(sizeof(*newc), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792 if (!newc) {
1793 rc = -ENOMEM;
1794 goto bad;
1795 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001796
1797 newc->u.name = kmalloc(len + 1,GFP_KERNEL);
1798 if (!newc->u.name) {
1799 rc = -ENOMEM;
1800 goto bad_newc;
1801 }
1802 rc = next_entry(newc->u.name, fp, len);
1803 if (rc < 0)
1804 goto bad_newc;
1805 newc->u.name[len] = 0;
1806 rc = next_entry(buf, fp, sizeof(u32));
1807 if (rc < 0)
1808 goto bad_newc;
1809 newc->v.sclass = le32_to_cpu(buf[0]);
1810 if (context_read_and_validate(&newc->context[0], p, fp))
1811 goto bad_newc;
1812 for (l = NULL, c = newgenfs->head; c;
1813 l = c, c = c->next) {
1814 if (!strcmp(newc->u.name, c->u.name) &&
1815 (!c->v.sclass || !newc->v.sclass ||
1816 newc->v.sclass == c->v.sclass)) {
1817 printk(KERN_ERR "security: dup genfs "
1818 "entry (%s,%s)\n",
1819 newgenfs->fstype, c->u.name);
1820 goto bad_newc;
1821 }
1822 len = strlen(newc->u.name);
1823 len2 = strlen(c->u.name);
1824 if (len > len2)
1825 break;
1826 }
1827
1828 newc->next = c;
1829 if (l)
1830 l->next = newc;
1831 else
1832 newgenfs->head = newc;
1833 }
1834 }
1835
1836 if (p->policyvers >= POLICYDB_VERSION_MLS) {
Darrel Goeddelf3f87712006-09-25 23:31:59 -07001837 int new_rangetr = p->policyvers >= POLICYDB_VERSION_RANGETRANS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001838 rc = next_entry(buf, fp, sizeof(u32));
1839 if (rc < 0)
1840 goto bad;
1841 nel = le32_to_cpu(buf[0]);
1842 lrt = NULL;
1843 for (i = 0; i < nel; i++) {
James Morris89d155e2005-10-30 14:59:21 -08001844 rt = kzalloc(sizeof(*rt), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845 if (!rt) {
1846 rc = -ENOMEM;
1847 goto bad;
1848 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001849 if (lrt)
1850 lrt->next = rt;
1851 else
1852 p->range_tr = rt;
1853 rc = next_entry(buf, fp, (sizeof(u32) * 2));
1854 if (rc < 0)
1855 goto bad;
Darrel Goeddelf3f87712006-09-25 23:31:59 -07001856 rt->source_type = le32_to_cpu(buf[0]);
1857 rt->target_type = le32_to_cpu(buf[1]);
1858 if (new_rangetr) {
1859 rc = next_entry(buf, fp, sizeof(u32));
1860 if (rc < 0)
1861 goto bad;
1862 rt->target_class = le32_to_cpu(buf[0]);
1863 } else
1864 rt->target_class = SECCLASS_PROCESS;
1865 rc = mls_read_range_helper(&rt->target_range, fp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001866 if (rc)
1867 goto bad;
1868 lrt = rt;
1869 }
1870 }
1871
Stephen Smalley782ebb92005-09-03 15:55:16 -07001872 p->type_attr_map = kmalloc(p->p_types.nprim*sizeof(struct ebitmap), GFP_KERNEL);
1873 if (!p->type_attr_map)
1874 goto bad;
1875
1876 for (i = 0; i < p->p_types.nprim; i++) {
1877 ebitmap_init(&p->type_attr_map[i]);
1878 if (p->policyvers >= POLICYDB_VERSION_AVTAB) {
1879 if (ebitmap_read(&p->type_attr_map[i], fp))
1880 goto bad;
1881 }
1882 /* add the type itself as the degenerate case */
1883 if (ebitmap_set_bit(&p->type_attr_map[i], i, 1))
1884 goto bad;
1885 }
1886
Linus Torvalds1da177e2005-04-16 15:20:36 -07001887 rc = 0;
1888out:
1889 return rc;
1890bad_newc:
1891 ocontext_destroy(newc,OCON_FSUSE);
1892bad:
1893 if (!rc)
1894 rc = -EINVAL;
1895 policydb_destroy(p);
1896 goto out;
1897}