2
/* Author : Stephen Smalley, <sds@epoch.ncsc.mil> */
4
/* Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com>
6
* Added conditional policy language extensions
8
* Copyright (C) 2003 - 2004 Tresys Technology, LLC
9
* This program is free software; you can redistribute it and/or modify
10
* it under the terms of the GNU General Public License as published by
11
* the Free Software Foundation, version 2.
18
#include "conditional.h"
20
int ebitmap_write(ebitmap_t * e, FILE * fp)
23
__u32 buf[32], bit, count;
27
buf[0] = cpu_to_le32(MAPSIZE);
28
buf[1] = cpu_to_le32(e->highbit);
31
for (n = e->node; n; n = n->next)
33
buf[2] = cpu_to_le32(count);
35
items = fwrite(buf, sizeof(__u32), 3, fp);
39
for (n = e->node; n; n = n->next) {
40
bit = cpu_to_le32(n->startbit);
41
items = fwrite(&bit, sizeof(__u32), 1, fp);
44
map = cpu_to_le64(n->map);
45
items = fwrite(&map, sizeof(__u64), 1, fp);
54
int avtab_write_item(avtab_ptr_t cur, FILE *fp)
59
items = 1; /* item 0 is used for the item count */
60
buf[items++] = cpu_to_le32(cur->key.source_type);
61
buf[items++] = cpu_to_le32(cur->key.target_type);
62
buf[items++] = cpu_to_le32(cur->key.target_class);
63
buf[items++] = cpu_to_le32(cur->datum.specified);
64
if (!(cur->datum.specified & (AVTAB_AV | AVTAB_TYPE))) {
65
printf("security: avtab: null entry\n");
68
if ((cur->datum.specified & AVTAB_AV) &&
69
(cur->datum.specified & AVTAB_TYPE)) {
70
printf("security: avtab: entry has both access vectors and types\n");
73
if (cur->datum.specified & AVTAB_AV) {
74
if (cur->datum.specified & AVTAB_ALLOWED)
75
buf[items++] = cpu_to_le32(avtab_allowed(&cur->datum));
76
if (cur->datum.specified & AVTAB_AUDITDENY)
77
buf[items++] = cpu_to_le32(avtab_auditdeny(&cur->datum));
78
if (cur->datum.specified & AVTAB_AUDITALLOW)
79
buf[items++] = cpu_to_le32(avtab_auditallow(&cur->datum));
81
if (cur->datum.specified & AVTAB_TRANSITION)
82
buf[items++] = cpu_to_le32(avtab_transition(&cur->datum));
83
if (cur->datum.specified & AVTAB_CHANGE)
84
buf[items++] = cpu_to_le32(avtab_change(&cur->datum));
85
if (cur->datum.specified & AVTAB_MEMBER)
86
buf[items++] = cpu_to_le32(avtab_member(&cur->datum));
88
buf[0] = cpu_to_le32(items - 1);
90
items2 = fwrite(buf, sizeof(__u32), items, fp);
96
int avtab_write(avtab_t * a, FILE * fp)
103
nel = cpu_to_le32(a->nel);
104
items = fwrite(&nel, sizeof(__u32), 1, fp);
108
for (i = 0; i < AVTAB_SIZE; i++) {
109
for (cur = a->htable[i]; cur; cur = cur->next) {
110
if (avtab_write_item(cur, fp))
118
#ifdef CONFIG_SECURITY_SELINUX_MLS
120
* Write a MLS level structure to a policydb binary
121
* representation file.
123
int mls_write_level(mls_level_t * l,
129
sens = cpu_to_le32(l->sens);
130
items = fwrite(&sens, sizeof(__u32), 1, fp);
134
if (ebitmap_write(&l->cat, fp))
142
* Write a MLS range structure to a policydb binary
143
* representation file.
145
static int mls_write_range_helper(mls_range_t * r,
149
size_t items, items2;
152
rel = mls_level_relation(r->level[1], r->level[0]);
154
items = 1; /* item 0 is used for the item count */
155
buf[items++] = cpu_to_le32(r->level[0].sens);
156
if (rel != MLS_RELATION_EQ)
157
buf[items++] = cpu_to_le32(r->level[1].sens);
158
buf[0] = cpu_to_le32(items - 1);
160
items2 = fwrite(buf, sizeof(__u32), items, fp);
164
if (ebitmap_write(&r->level[0].cat, fp))
166
if (rel != MLS_RELATION_EQ)
167
if (ebitmap_write(&r->level[1].cat, fp))
173
int mls_write_range(context_struct_t * c,
176
return mls_write_range_helper(&c->range, fp);
181
* Write a MLS perms structure to a policydb binary
182
* representation file.
184
int mls_write_class(class_datum_t * cladatum,
187
mls_perms_t *p = &cladatum->mlsperms;
189
size_t items, items2;
192
buf[items++] = cpu_to_le32(p->read);
193
buf[items++] = cpu_to_le32(p->readby);
194
buf[items++] = cpu_to_le32(p->write);
195
buf[items++] = cpu_to_le32(p->writeby);
196
items2 = fwrite(buf, sizeof(__u32), items, fp);
203
#define mls_write_perm(buf, items, perdatum) \
204
buf[items++] = cpu_to_le32(perdatum->base_perms);
206
int mls_write_user(user_datum_t *usrdatum, FILE *fp)
214
for (r = usrdatum->ranges; r; r = r->next)
216
buf[0] = cpu_to_le32(nel);
217
items = fwrite(buf, sizeof(__u32), 1, fp);
220
for (r = usrdatum->ranges; r; r = r->next) {
221
if (mls_write_range_helper(&r->range, fp))
227
int mls_write_nlevels(policydb_t *p, FILE *fp)
232
buf[0] = cpu_to_le32(p->nlevels);
233
items = fwrite(buf, sizeof(__u32), 1, fp);
239
int mls_write_trusted(policydb_t *p, FILE *fp)
241
if (ebitmap_write(&p->trustedreaders, fp))
243
if (ebitmap_write(&p->trustedwriters, fp))
245
if (ebitmap_write(&p->trustedobjects, fp))
250
int sens_write(hashtab_key_t key, hashtab_datum_t datum, void *p)
252
level_datum_t *levdatum;
254
size_t items, items2, len;
257
levdatum = (level_datum_t *) datum;
261
buf[items++] = cpu_to_le32(len);
262
buf[items++] = cpu_to_le32(levdatum->isalias);
263
items2 = fwrite(buf, sizeof(__u32), items, fp);
267
items = fwrite(key, 1, len, fp);
271
if (mls_write_level(levdatum->level, fp))
277
int cat_write(hashtab_key_t key, hashtab_datum_t datum, void *p)
279
cat_datum_t *catdatum;
281
size_t items, items2, len;
285
catdatum = (cat_datum_t *) datum;
289
buf[items++] = cpu_to_le32(len);
290
buf[items++] = cpu_to_le32(catdatum->value);
291
buf[items++] = cpu_to_le32(catdatum->isalias);
292
items2 = fwrite(buf, sizeof(__u32), items, fp);
296
items = fwrite(key, 1, len, fp);
303
#define mls_write_range(c, fp) 0
304
#define mls_write_class(c, fp) 0
305
#define mls_write_perm(buf, items, perdatum)
306
#define mls_write_user(u, fp) 0
307
#define mls_write_nlevels(p, fp) 0
308
#define mls_write_trusted(p, fp) 0
312
int cond_write_bool(hashtab_key_t key, hashtab_datum_t datum, void *p)
314
cond_bool_datum_t *booldatum;
319
booldatum = (cond_bool_datum_t*)datum;
323
buf[items++] = cpu_to_le32(booldatum->value);
324
buf[items++] = cpu_to_le32(booldatum->state);
325
buf[items++] = cpu_to_le32(len);
326
items2 = fwrite(buf, sizeof(__u32), items, fp);
329
items = fwrite(key, 1, len, fp);
336
* cond_write_cond_av_list doesn't write out the av_list nodes.
337
* Instead it writes out the key/value pairs from the avtab. This
338
* is necessary because there is no way to uniquely identifying rules
339
* in the avtab so it is not possible to associate individual rules
340
* in the avtab with a conditional without saving them as part of
341
* the conditional. This means that the avtab with the conditional
342
* rules will not be saved but will be rebuilt on policy load.
344
int cond_write_av_list(cond_av_list_t *list, FILE *fp)
347
cond_av_list_t *cur_list;
351
for (cur_list = list; cur_list != NULL; cur_list = cur_list->next) {
352
if (cur_list->node->parse_context)
356
buf[0] = cpu_to_le32(len);
357
items = fwrite(buf, sizeof(__u32), 1, fp);
363
for (cur_list = list; cur_list != NULL; cur_list = cur_list->next) {
364
if (cur_list->node->parse_context)
365
if (avtab_write_item(cur_list->node, fp))
371
int cond_write_node(cond_node_t *node, FILE *fp)
373
cond_expr_t *cur_expr;
375
__u32 items, items2, len;
377
buf[0] = cpu_to_le32(node->cur_state);
378
items = fwrite(buf, sizeof(__u32), 1, fp);
384
for (cur_expr = node->expr; cur_expr != NULL; cur_expr = cur_expr->next)
387
buf[0] = cpu_to_le32(len);
388
items = fwrite(buf, sizeof(__u32), 1, fp);
392
for (cur_expr = node->expr; cur_expr != NULL; cur_expr = cur_expr->next) {
394
buf[items++] = cpu_to_le32(cur_expr->expr_type);
395
buf[items++] = cpu_to_le32(cur_expr->bool);
396
items2 = fwrite(buf, sizeof(__u32), items, fp);
401
if (cond_write_av_list(node->true_list, fp) != 0)
403
if (cond_write_av_list(node->false_list, fp) != 0)
409
int cond_write_list(cond_list_t *list, void *p)
417
for (cur = list; cur != NULL; cur = cur->next)
419
buf[0] = cpu_to_le32(len);
420
items = fwrite(buf, sizeof(__u32), 1, fp);
424
for (cur = list; cur != NULL; cur = cur->next) {
425
if (cond_write_node(cur, p) != 0)
432
* Write a security context structure
433
* to a policydb binary representation file.
435
static int context_write(context_struct_t * c, FILE * fp)
438
size_t items, items2;
441
buf[items++] = cpu_to_le32(c->user);
442
buf[items++] = cpu_to_le32(c->role);
443
buf[items++] = cpu_to_le32(c->type);
444
items2 = fwrite(buf, sizeof(__u32), items, fp);
447
if (mls_write_range(c, fp))
455
* The following *_write functions are used to
456
* write the symbol data to a policy database
457
* binary representation file.
460
static int perm_write(hashtab_key_t key, hashtab_datum_t datum, void *p)
462
perm_datum_t *perdatum;
464
size_t items, items2, len;
467
perdatum = (perm_datum_t *) datum;
471
buf[items++] = cpu_to_le32(len);
472
buf[items++] = cpu_to_le32(perdatum->value);
473
mls_write_perm(buf, items, perdatum);
474
items2 = fwrite(buf, sizeof(__u32), items, fp);
478
items = fwrite(key, 1, len, fp);
486
static int common_write(hashtab_key_t key, hashtab_datum_t datum, void *p)
488
common_datum_t *comdatum;
490
size_t items, items2, len;
493
comdatum = (common_datum_t *) datum;
497
buf[items++] = cpu_to_le32(len);
498
buf[items++] = cpu_to_le32(comdatum->value);
499
buf[items++] = cpu_to_le32(comdatum->permissions.nprim);
500
buf[items++] = cpu_to_le32(comdatum->permissions.table->nel);
501
items2 = fwrite(buf, sizeof(__u32), items, fp);
505
items = fwrite(key, 1, len, fp);
509
if (hashtab_map(comdatum->permissions.table, perm_write, fp))
516
static int class_write(hashtab_key_t key, hashtab_datum_t datum, void *p)
518
class_datum_t *cladatum;
519
constraint_node_t *c;
520
constraint_expr_t *e;
521
__u32 buf[32], ncons, nexpr;
522
size_t items, items2, len, len2;
525
cladatum = (class_datum_t *) datum;
528
if (cladatum->comkey)
529
len2 = strlen(cladatum->comkey);
534
for (c = cladatum->constraints; c; c = c->next) {
539
buf[items++] = cpu_to_le32(len);
540
buf[items++] = cpu_to_le32(len2);
541
buf[items++] = cpu_to_le32(cladatum->value);
542
buf[items++] = cpu_to_le32(cladatum->permissions.nprim);
543
if (cladatum->permissions.table)
544
buf[items++] = cpu_to_le32(cladatum->permissions.table->nel);
547
buf[items++] = cpu_to_le32(ncons);
548
items2 = fwrite(buf, sizeof(__u32), items, fp);
552
items = fwrite(key, 1, len, fp);
556
if (cladatum->comkey) {
557
items = fwrite(cladatum->comkey, 1, len2, fp);
561
if (hashtab_map(cladatum->permissions.table, perm_write, fp))
564
for (c = cladatum->constraints; c; c = c->next) {
566
for (e = c->expr; e; e = e->next) {
569
buf[0] = cpu_to_le32(c->permissions);
570
buf[1] = cpu_to_le32(nexpr);
571
items = fwrite(buf, sizeof(__u32), 2, fp);
574
for (e = c->expr; e; e = e->next) {
576
buf[items++] = cpu_to_le32(e->expr_type);
577
buf[items++] = cpu_to_le32(e->attr);
578
buf[items++] = cpu_to_le32(e->op);
579
items2 = fwrite(buf, sizeof(__u32), items, fp);
583
switch (e->expr_type) {
585
if (ebitmap_write(&e->names, fp))
594
if (mls_write_class(cladatum, fp))
600
static int role_write(hashtab_key_t key, hashtab_datum_t datum, void *p)
604
size_t items, items2, len;
607
role = (role_datum_t *) datum;
611
buf[items++] = cpu_to_le32(len);
612
buf[items++] = cpu_to_le32(role->value);
613
items2 = fwrite(buf, sizeof(__u32), items, fp);
617
items = fwrite(key, 1, len, fp);
621
if (ebitmap_write(&role->dominates, fp))
624
if (ebitmap_write(&role->types, fp))
630
static int type_write(hashtab_key_t key, hashtab_datum_t datum, void *p)
632
type_datum_t *typdatum;
634
size_t items, items2, len;
637
typdatum = (type_datum_t *) datum;
641
buf[items++] = cpu_to_le32(len);
642
buf[items++] = cpu_to_le32(typdatum->value);
643
buf[items++] = cpu_to_le32(typdatum->primary);
644
items2 = fwrite(buf, sizeof(__u32), items, fp);
648
items = fwrite(key, 1, len, fp);
655
static int user_write(hashtab_key_t key, hashtab_datum_t datum, void *p)
657
user_datum_t *usrdatum;
659
size_t items, items2, len;
663
usrdatum = (user_datum_t *) datum;
667
buf[items++] = cpu_to_le32(len);
668
buf[items++] = cpu_to_le32(usrdatum->value);
669
items2 = fwrite(buf, sizeof(__u32), items, fp);
673
items = fwrite(key, 1, len, fp);
677
if (ebitmap_write(&usrdatum->roles, fp))
680
return mls_write_user(usrdatum, fp);
684
static int (*write_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum, void *datap) =
697
* Write the configuration data in a policy database
698
* structure to a policy database binary representation
701
int policydb_write(policydb_t * p, FILE * fp)
703
struct role_allow *ra;
704
struct role_trans *tr;
708
__u32 buf[32], config;
709
size_t items, items2, len, nel;
710
struct policydb_compat_info *info;
711
char *policydb_str = POLICYDB_STRING;
714
mls_set_config(config);
716
/* Write the magic number and string identifiers. */
718
buf[items++] = cpu_to_le32(POLICYDB_MAGIC);
719
len = strlen(POLICYDB_STRING);
720
buf[items++] = cpu_to_le32(len);
721
items2 = fwrite(buf, sizeof(__u32), items, fp);
724
items = fwrite(policydb_str, 1, len, fp);
728
/* Write the version, config, and table sizes. */
730
info = policydb_lookup_compat(policyvers);
732
fprintf(stderr, "policydb_lookup_compat() failed for %d\n", policyvers);
736
buf[items++] = cpu_to_le32(policyvers);
737
buf[items++] = cpu_to_le32(config);
738
buf[items++] = cpu_to_le32(info->sym_num);
739
buf[items++] = cpu_to_le32(info->ocon_num);
741
items2 = fwrite(buf, sizeof(__u32), items, fp);
745
if (mls_write_nlevels(p, fp))
748
num_syms = info->sym_num;
749
for (i = 0; i < num_syms; i++) {
750
buf[0] = cpu_to_le32(p->symtab[i].nprim);
751
buf[1] = cpu_to_le32(p->symtab[i].table->nel);
752
items = fwrite(buf, sizeof(__u32), 2, fp);
755
if (hashtab_map(p->symtab[i].table, write_f[i], fp))
759
if (avtab_write(&p->te_avtab, fp))
762
if (policyvers < POLICYDB_VERSION_BOOL) {
763
if (p->p_bools.nprim)
764
fprintf(stderr, "warning: discarding booleans and conditional rules\n");
767
if (cond_write_list(p->cond_list, fp))
772
for (tr = p->role_tr; tr; tr = tr->next)
774
buf[0] = cpu_to_le32(nel);
775
items = fwrite(buf, sizeof(__u32), 1, fp);
778
for (tr = p->role_tr; tr; tr = tr->next) {
779
buf[0] = cpu_to_le32(tr->role);
780
buf[1] = cpu_to_le32(tr->type);
781
buf[2] = cpu_to_le32(tr->new_role);
782
items = fwrite(buf, sizeof(__u32), 3, fp);
788
for (ra = p->role_allow; ra; ra = ra->next)
790
buf[0] = cpu_to_le32(nel);
791
items = fwrite(buf, sizeof(__u32), 1, fp);
794
for (ra = p->role_allow; ra; ra = ra->next) {
795
buf[0] = cpu_to_le32(ra->role);
796
buf[1] = cpu_to_le32(ra->new_role);
797
items = fwrite(buf, sizeof(__u32), 2, fp);
802
for (i = 0; i < info->ocon_num; i++) {
804
for (c = p->ocontexts[i]; c; c = c->next)
806
buf[0] = cpu_to_le32(nel);
807
items = fwrite(buf, sizeof(__u32), 1, fp);
810
for (c = p->ocontexts[i]; c; c = c->next) {
813
buf[0] = cpu_to_le32(c->sid[0]);
814
items = fwrite(buf, sizeof(__u32), 1, fp);
817
if (context_write(&c->context[0], fp))
822
len = strlen(c->u.name);
823
buf[0] = cpu_to_le32(len);
824
items = fwrite(buf, sizeof(__u32), 1, fp);
827
items = fwrite(c->u.name, 1, len, fp);
830
if (context_write(&c->context[0], fp))
832
if (context_write(&c->context[1], fp))
836
buf[0] = c->u.port.protocol;
837
buf[1] = c->u.port.low_port;
838
buf[2] = c->u.port.high_port;
839
for (j = 0; j < 3; j++) {
840
buf[j] = cpu_to_le32(buf[j]);
842
items = fwrite(buf, sizeof(__u32), 3, fp);
845
if (context_write(&c->context[0], fp))
849
buf[0] = cpu_to_le32(c->u.node.addr);
850
buf[1] = cpu_to_le32(c->u.node.mask);
851
items = fwrite(buf, sizeof(__u32), 2, fp);
854
if (context_write(&c->context[0], fp))
858
buf[0] = cpu_to_le32(c->v.behavior);
859
len = strlen(c->u.name);
860
buf[1] = cpu_to_le32(len);
861
items = fwrite(buf, sizeof(__u32), 2, fp);
864
items = fwrite(c->u.name, 1, len, fp);
867
if (context_write(&c->context[0], fp))
871
for (j = 0; j < 4; j++)
872
buf[j] = cpu_to_le32(c->u.node6.addr[j]);
873
for (j = 0; j < 4; j++)
874
buf[j+4] = cpu_to_le32(c->u.node6.mask[j]);
875
items = fwrite(buf, sizeof(__u32), 8, fp);
878
if (context_write(&c->context[0], fp))
886
for (genfs = p->genfs; genfs; genfs = genfs->next)
888
buf[0] = cpu_to_le32(nel);
889
items = fwrite(buf, sizeof(__u32), 1, fp);
892
for (genfs = p->genfs; genfs; genfs = genfs->next) {
893
len = strlen(genfs->fstype);
894
buf[0] = cpu_to_le32(len);
895
items = fwrite(buf, sizeof(__u32), 1, fp);
898
items = fwrite(genfs->fstype, 1, len, fp);
902
for (c = genfs->head; c; c = c->next)
904
buf[0] = cpu_to_le32(nel);
905
items = fwrite(buf, sizeof(__u32), 1, fp);
908
for (c = genfs->head; c; c = c->next) {
909
len = strlen(c->u.name);
910
buf[0] = cpu_to_le32(len);
911
items = fwrite(buf, sizeof(__u32), 1, fp);
914
items = fwrite(c->u.name, 1, len, fp);
917
buf[0] = cpu_to_le32(c->v.sclass);
918
items = fwrite(buf, sizeof(__u32), 1, fp);
921
if (context_write(&c->context[0], fp))
926
if (mls_write_trusted(p, fp))