1 2 /* Author : Stephen Smalley, <sds (at) epoch.ncsc.mil> */ 3 4 /* 5 * Updated: Trusted Computer Solutions, Inc. <dgoeddel (at) trustedcs.com> 6 * 7 * Support for enhanced MLS infrastructure. 8 * 9 * Updated: Frank Mayer <mayerf (at) tresys.com> and Karl MacMillan <kmacmillan (at) tresys.com> 10 * 11 * Added conditional policy language extensions 12 * 13 * Updated: Joshua Brindle <jbrindle (at) tresys.com> and Jason Tang <jtang (at) tresys.org> 14 * 15 * Module writing support 16 * 17 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. 18 * Copyright (C) 2003-2005 Tresys Technology, LLC 19 * 20 * This library is free software; you can redistribute it and/or 21 * modify it under the terms of the GNU Lesser General Public 22 * License as published by the Free Software Foundation; either 23 * version 2.1 of the License, or (at your option) any later version. 24 * 25 * This library is distributed in the hope that it will be useful, 26 * but WITHOUT ANY WARRANTY; without even the implied warranty of 27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 * Lesser General Public License for more details. 29 * 30 * You should have received a copy of the GNU Lesser General Public 31 * License along with this library; if not, write to the Free Software 32 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 33 */ 34 #include <assert.h> 35 #include <stdlib.h> 36 37 #include <sepol/policydb/ebitmap.h> 38 #include <sepol/policydb/avtab.h> 39 #include <sepol/policydb/policydb.h> 40 #include <sepol/policydb/conditional.h> 41 #include <sepol/policydb/expand.h> 42 #include <sepol/policydb/flask.h> 43 44 #include "debug.h" 45 #include "private.h" 46 #include "mls.h" 47 48 struct policy_data { 49 struct policy_file *fp; 50 struct policydb *p; 51 }; 52 53 static int avrule_write_list(avrule_t * avrules, struct policy_file *fp); 54 55 static int ebitmap_write(ebitmap_t * e, struct policy_file *fp) 56 { 57 ebitmap_node_t *n; 58 uint32_t buf[32], bit, count; 59 uint64_t map; 60 size_t items; 61 62 buf[0] = cpu_to_le32(MAPSIZE); 63 buf[1] = cpu_to_le32(e->highbit); 64 65 count = 0; 66 for (n = e->node; n; n = n->next) 67 count++; 68 buf[2] = cpu_to_le32(count); 69 70 items = put_entry(buf, sizeof(uint32_t), 3, fp); 71 if (items != 3) 72 return POLICYDB_ERROR; 73 74 for (n = e->node; n; n = n->next) { 75 bit = cpu_to_le32(n->startbit); 76 items = put_entry(&bit, sizeof(uint32_t), 1, fp); 77 if (items != 1) 78 return POLICYDB_ERROR; 79 map = cpu_to_le64(n->map); 80 items = put_entry(&map, sizeof(uint64_t), 1, fp); 81 if (items != 1) 82 return POLICYDB_ERROR; 83 84 } 85 86 return POLICYDB_SUCCESS; 87 } 88 89 /* Ordering of datums in the original avtab format in the policy file. */ 90 static uint16_t spec_order[] = { 91 AVTAB_ALLOWED, 92 AVTAB_AUDITDENY, 93 AVTAB_AUDITALLOW, 94 AVTAB_TRANSITION, 95 AVTAB_CHANGE, 96 AVTAB_MEMBER 97 }; 98 99 static int avtab_write_item(policydb_t * p, 100 avtab_ptr_t cur, struct policy_file *fp, 101 unsigned merge, unsigned commit, uint32_t * nel) 102 { 103 avtab_ptr_t node; 104 uint16_t buf16[4]; 105 uint32_t buf32[10], lookup, val; 106 size_t items, items2; 107 unsigned set; 108 unsigned int oldvers = (p->policy_type == POLICY_KERN 109 && p->policyvers < POLICYDB_VERSION_AVTAB); 110 unsigned int i; 111 112 if (oldvers) { 113 /* Generate the old avtab format. 114 Requires merging similar entries if uncond avtab. */ 115 if (merge) { 116 if (cur->merged) 117 return POLICYDB_SUCCESS; /* already merged by prior merge */ 118 } 119 120 items = 1; /* item 0 is used for the item count */ 121 val = cur->key.source_type; 122 buf32[items++] = cpu_to_le32(val); 123 val = cur->key.target_type; 124 buf32[items++] = cpu_to_le32(val); 125 val = cur->key.target_class; 126 buf32[items++] = cpu_to_le32(val); 127 128 val = cur->key.specified & ~AVTAB_ENABLED; 129 if (cur->key.specified & AVTAB_ENABLED) 130 val |= AVTAB_ENABLED_OLD; 131 set = 1; 132 133 if (merge) { 134 /* Merge specifier values for all similar (av or type) 135 entries that have the same key. */ 136 if (val & AVTAB_AV) 137 lookup = AVTAB_AV; 138 else if (val & AVTAB_TYPE) 139 lookup = AVTAB_TYPE; 140 else 141 return POLICYDB_ERROR; 142 for (node = avtab_search_node_next(cur, lookup); 143 node; 144 node = avtab_search_node_next(node, lookup)) { 145 val |= (node->key.specified & ~AVTAB_ENABLED); 146 set++; 147 if (node->key.specified & AVTAB_ENABLED) 148 val |= AVTAB_ENABLED_OLD; 149 } 150 } 151 152 if (!(val & (AVTAB_AV | AVTAB_TYPE))) { 153 ERR(fp->handle, "null entry"); 154 return POLICYDB_ERROR; 155 } 156 if ((val & AVTAB_AV) && (val & AVTAB_TYPE)) { 157 ERR(fp->handle, "entry has both access " 158 "vectors and types"); 159 return POLICYDB_ERROR; 160 } 161 162 buf32[items++] = cpu_to_le32(val); 163 164 if (merge) { 165 /* Include datums for all similar (av or type) 166 entries that have the same key. */ 167 for (i = 0; 168 i < (sizeof(spec_order) / sizeof(spec_order[0])); 169 i++) { 170 if (val & spec_order[i]) { 171 if (cur->key.specified & spec_order[i]) 172 node = cur; 173 else { 174 node = 175 avtab_search_node_next(cur, 176 spec_order 177 [i]); 178 if (nel) 179 (*nel)--; /* one less node */ 180 } 181 182 if (!node) { 183 ERR(fp->handle, "missing node"); 184 return POLICYDB_ERROR; 185 } 186 buf32[items++] = 187 cpu_to_le32(node->datum.data); 188 set--; 189 node->merged = 1; 190 } 191 } 192 } else { 193 buf32[items++] = cpu_to_le32(cur->datum.data); 194 cur->merged = 1; 195 set--; 196 } 197 198 if (set) { 199 ERR(fp->handle, "data count wrong"); 200 return POLICYDB_ERROR; 201 } 202 203 buf32[0] = cpu_to_le32(items - 1); 204 205 if (commit) { 206 /* Commit this item to the policy file. */ 207 items2 = put_entry(buf32, sizeof(uint32_t), items, fp); 208 if (items != items2) 209 return POLICYDB_ERROR; 210 } 211 212 return POLICYDB_SUCCESS; 213 } 214 215 /* Generate the new avtab format. */ 216 buf16[0] = cpu_to_le16(cur->key.source_type); 217 buf16[1] = cpu_to_le16(cur->key.target_type); 218 buf16[2] = cpu_to_le16(cur->key.target_class); 219 buf16[3] = cpu_to_le16(cur->key.specified); 220 items = put_entry(buf16, sizeof(uint16_t), 4, fp); 221 if (items != 4) 222 return POLICYDB_ERROR; 223 buf32[0] = cpu_to_le32(cur->datum.data); 224 items = put_entry(buf32, sizeof(uint32_t), 1, fp); 225 if (items != 1) 226 return POLICYDB_ERROR; 227 return POLICYDB_SUCCESS; 228 } 229 230 static inline void avtab_reset_merged(avtab_t * a) 231 { 232 unsigned int i; 233 avtab_ptr_t cur; 234 for (i = 0; i < a->nslot; i++) { 235 for (cur = a->htable[i]; cur; cur = cur->next) 236 cur->merged = 0; 237 } 238 } 239 240 static int avtab_write(struct policydb *p, avtab_t * a, struct policy_file *fp) 241 { 242 unsigned int i; 243 int rc; 244 avtab_t expa; 245 avtab_ptr_t cur; 246 uint32_t nel; 247 size_t items; 248 unsigned int oldvers = (p->policy_type == POLICY_KERN 249 && p->policyvers < POLICYDB_VERSION_AVTAB); 250 251 if (oldvers) { 252 /* Old avtab format. 253 First, we need to expand attributes. Then, we need to 254 merge similar entries, so we need to track merged nodes 255 and compute the final nel. */ 256 if (avtab_init(&expa)) 257 return POLICYDB_ERROR; 258 if (expand_avtab(p, a, &expa)) { 259 rc = -1; 260 goto out; 261 } 262 a = &expa; 263 avtab_reset_merged(a); 264 nel = a->nel; 265 } else { 266 /* New avtab format. nel is good to go. */ 267 nel = cpu_to_le32(a->nel); 268 items = put_entry(&nel, sizeof(uint32_t), 1, fp); 269 if (items != 1) 270 return POLICYDB_ERROR; 271 } 272 273 for (i = 0; i < a->nslot; i++) { 274 for (cur = a->htable[i]; cur; cur = cur->next) { 275 /* If old format, compute final nel. 276 If new format, write out the items. */ 277 if (avtab_write_item(p, cur, fp, 1, !oldvers, &nel)) { 278 rc = -1; 279 goto out; 280 } 281 } 282 } 283 284 if (oldvers) { 285 /* Old avtab format. 286 Write the computed nel value, then write the items. */ 287 nel = cpu_to_le32(nel); 288 items = put_entry(&nel, sizeof(uint32_t), 1, fp); 289 if (items != 1) { 290 rc = -1; 291 goto out; 292 } 293 avtab_reset_merged(a); 294 for (i = 0; i < a->nslot; i++) { 295 for (cur = a->htable[i]; cur; cur = cur->next) { 296 if (avtab_write_item(p, cur, fp, 1, 1, NULL)) { 297 rc = -1; 298 goto out; 299 } 300 } 301 } 302 } 303 304 rc = 0; 305 out: 306 if (oldvers) 307 avtab_destroy(&expa); 308 return rc; 309 } 310 311 /* 312 * Write a semantic MLS level structure to a policydb binary 313 * representation file. 314 */ 315 static int mls_write_semantic_level_helper(mls_semantic_level_t * l, 316 struct policy_file *fp) 317 { 318 uint32_t buf[2], ncat = 0; 319 size_t items; 320 mls_semantic_cat_t *cat; 321 322 for (cat = l->cat; cat; cat = cat->next) 323 ncat++; 324 325 buf[0] = cpu_to_le32(l->sens); 326 buf[1] = cpu_to_le32(ncat); 327 items = put_entry(buf, sizeof(uint32_t), 2, fp); 328 if (items != 2) 329 return POLICYDB_ERROR; 330 331 for (cat = l->cat; cat; cat = cat->next) { 332 buf[0] = cpu_to_le32(cat->low); 333 buf[1] = cpu_to_le32(cat->high); 334 items = put_entry(buf, sizeof(uint32_t), 2, fp); 335 if (items != 2) 336 return POLICYDB_ERROR; 337 } 338 339 return POLICYDB_SUCCESS; 340 } 341 342 /* 343 * Read a semantic MLS range structure to a policydb binary 344 * representation file. 345 */ 346 static int mls_write_semantic_range_helper(mls_semantic_range_t * r, 347 struct policy_file *fp) 348 { 349 int rc; 350 351 rc = mls_write_semantic_level_helper(&r->level[0], fp); 352 if (rc) 353 return rc; 354 355 rc = mls_write_semantic_level_helper(&r->level[1], fp); 356 357 return rc; 358 } 359 360 /* 361 * Write a MLS level structure to a policydb binary 362 * representation file. 363 */ 364 static int mls_write_level(mls_level_t * l, struct policy_file *fp) 365 { 366 uint32_t sens; 367 size_t items; 368 369 sens = cpu_to_le32(l->sens); 370 items = put_entry(&sens, sizeof(uint32_t), 1, fp); 371 if (items != 1) 372 return POLICYDB_ERROR; 373 374 if (ebitmap_write(&l->cat, fp)) 375 return POLICYDB_ERROR; 376 377 return POLICYDB_SUCCESS; 378 } 379 380 /* 381 * Write a MLS range structure to a policydb binary 382 * representation file. 383 */ 384 static int mls_write_range_helper(mls_range_t * r, struct policy_file *fp) 385 { 386 uint32_t buf[3]; 387 size_t items, items2; 388 int eq; 389 390 eq = mls_level_eq(&r->level[1], &r->level[0]); 391 392 items = 1; /* item 0 is used for the item count */ 393 buf[items++] = cpu_to_le32(r->level[0].sens); 394 if (!eq) 395 buf[items++] = cpu_to_le32(r->level[1].sens); 396 buf[0] = cpu_to_le32(items - 1); 397 398 items2 = put_entry(buf, sizeof(uint32_t), items, fp); 399 if (items2 != items) 400 return POLICYDB_ERROR; 401 402 if (ebitmap_write(&r->level[0].cat, fp)) 403 return POLICYDB_ERROR; 404 if (!eq) 405 if (ebitmap_write(&r->level[1].cat, fp)) 406 return POLICYDB_ERROR; 407 408 return POLICYDB_SUCCESS; 409 } 410 411 static int sens_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr) 412 { 413 level_datum_t *levdatum; 414 uint32_t buf[32]; 415 size_t items, items2, len; 416 struct policy_data *pd = ptr; 417 struct policy_file *fp = pd->fp; 418 419 levdatum = (level_datum_t *) datum; 420 421 len = strlen(key); 422 items = 0; 423 buf[items++] = cpu_to_le32(len); 424 buf[items++] = cpu_to_le32(levdatum->isalias); 425 items2 = put_entry(buf, sizeof(uint32_t), items, fp); 426 if (items != items2) 427 return POLICYDB_ERROR; 428 429 items = put_entry(key, 1, len, fp); 430 if (items != len) 431 return POLICYDB_ERROR; 432 433 if (mls_write_level(levdatum->level, fp)) 434 return POLICYDB_ERROR; 435 436 return POLICYDB_SUCCESS; 437 } 438 439 static int cat_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr) 440 { 441 cat_datum_t *catdatum; 442 uint32_t buf[32]; 443 size_t items, items2, len; 444 struct policy_data *pd = ptr; 445 struct policy_file *fp = pd->fp; 446 447 catdatum = (cat_datum_t *) datum; 448 449 len = strlen(key); 450 items = 0; 451 buf[items++] = cpu_to_le32(len); 452 buf[items++] = cpu_to_le32(catdatum->s.value); 453 buf[items++] = cpu_to_le32(catdatum->isalias); 454 items2 = put_entry(buf, sizeof(uint32_t), items, fp); 455 if (items != items2) 456 return POLICYDB_ERROR; 457 458 items = put_entry(key, 1, len, fp); 459 if (items != len) 460 return POLICYDB_ERROR; 461 462 return POLICYDB_SUCCESS; 463 } 464 465 static int role_trans_write(policydb_t *p, struct policy_file *fp) 466 { 467 role_trans_t *r = p->role_tr; 468 role_trans_t *tr; 469 uint32_t buf[3]; 470 size_t nel, items; 471 int new_roletr = (p->policy_type == POLICY_KERN && 472 p->policyvers >= POLICYDB_VERSION_ROLETRANS); 473 int warning_issued = 0; 474 475 nel = 0; 476 for (tr = r; tr; tr = tr->next) 477 if(new_roletr || tr->tclass == SECCLASS_PROCESS) 478 nel++; 479 480 buf[0] = cpu_to_le32(nel); 481 items = put_entry(buf, sizeof(uint32_t), 1, fp); 482 if (items != 1) 483 return POLICYDB_ERROR; 484 for (tr = r; tr; tr = tr->next) { 485 if (!new_roletr && tr->tclass != SECCLASS_PROCESS) { 486 if (!warning_issued) 487 WARN(fp->handle, "Discarding role_transition " 488 "rules for security classes other than " 489 "\"process\""); 490 warning_issued = 1; 491 continue; 492 } 493 buf[0] = cpu_to_le32(tr->role); 494 buf[1] = cpu_to_le32(tr->type); 495 buf[2] = cpu_to_le32(tr->new_role); 496 items = put_entry(buf, sizeof(uint32_t), 3, fp); 497 if (items != 3) 498 return POLICYDB_ERROR; 499 if (new_roletr) { 500 buf[0] = cpu_to_le32(tr->tclass); 501 items = put_entry(buf, sizeof(uint32_t), 1, fp); 502 if (items != 1) 503 return POLICYDB_ERROR; 504 } 505 } 506 507 return POLICYDB_SUCCESS; 508 } 509 510 static int role_allow_write(role_allow_t * r, struct policy_file *fp) 511 { 512 role_allow_t *ra; 513 uint32_t buf[2]; 514 size_t nel, items; 515 516 nel = 0; 517 for (ra = r; ra; ra = ra->next) 518 nel++; 519 buf[0] = cpu_to_le32(nel); 520 items = put_entry(buf, sizeof(uint32_t), 1, fp); 521 if (items != 1) 522 return POLICYDB_ERROR; 523 for (ra = r; ra; ra = ra->next) { 524 buf[0] = cpu_to_le32(ra->role); 525 buf[1] = cpu_to_le32(ra->new_role); 526 items = put_entry(buf, sizeof(uint32_t), 2, fp); 527 if (items != 2) 528 return POLICYDB_ERROR; 529 } 530 return POLICYDB_SUCCESS; 531 } 532 533 static int filename_trans_write(filename_trans_t * r, struct policy_file *fp) 534 { 535 filename_trans_t *ft; 536 uint32_t buf[4]; 537 size_t nel, items, len; 538 539 nel = 0; 540 for (ft = r; ft; ft = ft->next) 541 nel++; 542 buf[0] = cpu_to_le32(nel); 543 items = put_entry(buf, sizeof(uint32_t), 1, fp); 544 if (items != 1) 545 return POLICYDB_ERROR; 546 for (ft = r; ft; ft = ft->next) { 547 len = strlen(ft->name); 548 buf[0] = cpu_to_le32(len); 549 items = put_entry(buf, sizeof(uint32_t), 1, fp); 550 if (items != 1) 551 return POLICYDB_ERROR; 552 553 items = put_entry(ft->name, sizeof(char), len, fp); 554 if (items != len) 555 return POLICYDB_ERROR; 556 557 buf[0] = cpu_to_le32(ft->stype); 558 buf[1] = cpu_to_le32(ft->ttype); 559 buf[2] = cpu_to_le32(ft->tclass); 560 buf[3] = cpu_to_le32(ft->otype); 561 items = put_entry(buf, sizeof(uint32_t), 4, fp); 562 if (items != 4) 563 return POLICYDB_ERROR; 564 } 565 566 return POLICYDB_SUCCESS; 567 } 568 569 static int role_set_write(role_set_t * x, struct policy_file *fp) 570 { 571 size_t items; 572 uint32_t buf[1]; 573 574 if (ebitmap_write(&x->roles, fp)) 575 return POLICYDB_ERROR; 576 577 buf[0] = cpu_to_le32(x->flags); 578 items = put_entry(buf, sizeof(uint32_t), 1, fp); 579 if (items != 1) 580 return POLICYDB_ERROR; 581 582 return POLICYDB_SUCCESS; 583 } 584 585 static int type_set_write(type_set_t * x, struct policy_file *fp) 586 { 587 size_t items; 588 uint32_t buf[1]; 589 590 if (ebitmap_write(&x->types, fp)) 591 return POLICYDB_ERROR; 592 if (ebitmap_write(&x->negset, fp)) 593 return POLICYDB_ERROR; 594 595 buf[0] = cpu_to_le32(x->flags); 596 items = put_entry(buf, sizeof(uint32_t), 1, fp); 597 if (items != 1) 598 return POLICYDB_ERROR; 599 600 return POLICYDB_SUCCESS; 601 } 602 603 static int cond_write_bool(hashtab_key_t key, hashtab_datum_t datum, void *ptr) 604 { 605 cond_bool_datum_t *booldatum; 606 uint32_t buf[3], len; 607 unsigned int items, items2; 608 struct policy_data *pd = ptr; 609 struct policy_file *fp = pd->fp; 610 struct policydb *p = pd->p; 611 612 booldatum = (cond_bool_datum_t *) datum; 613 614 len = strlen(key); 615 items = 0; 616 buf[items++] = cpu_to_le32(booldatum->s.value); 617 buf[items++] = cpu_to_le32(booldatum->state); 618 buf[items++] = cpu_to_le32(len); 619 items2 = put_entry(buf, sizeof(uint32_t), items, fp); 620 if (items != items2) 621 return POLICYDB_ERROR; 622 items = put_entry(key, 1, len, fp); 623 if (items != len) 624 return POLICYDB_ERROR; 625 626 if (p->policy_type != POLICY_KERN && 627 p->policyvers >= MOD_POLICYDB_VERSION_TUNABLE_SEP) { 628 buf[0] = cpu_to_le32(booldatum->flags); 629 items = put_entry(buf, sizeof(uint32_t), 1, fp); 630 if (items != 1) 631 return POLICYDB_ERROR; 632 } 633 634 return POLICYDB_SUCCESS; 635 } 636 637 /* 638 * cond_write_cond_av_list doesn't write out the av_list nodes. 639 * Instead it writes out the key/value pairs from the avtab. This 640 * is necessary because there is no way to uniquely identifying rules 641 * in the avtab so it is not possible to associate individual rules 642 * in the avtab with a conditional without saving them as part of 643 * the conditional. This means that the avtab with the conditional 644 * rules will not be saved but will be rebuilt on policy load. 645 */ 646 static int cond_write_av_list(policydb_t * p, 647 cond_av_list_t * list, struct policy_file *fp) 648 { 649 uint32_t buf[4]; 650 cond_av_list_t *cur_list, *new_list = NULL; 651 avtab_t expa; 652 uint32_t len, items; 653 unsigned int oldvers = (p->policy_type == POLICY_KERN 654 && p->policyvers < POLICYDB_VERSION_AVTAB); 655 int rc = -1; 656 657 if (oldvers) { 658 if (avtab_init(&expa)) 659 return POLICYDB_ERROR; 660 if (expand_cond_av_list(p, list, &new_list, &expa)) 661 goto out; 662 list = new_list; 663 } 664 665 len = 0; 666 for (cur_list = list; cur_list != NULL; cur_list = cur_list->next) { 667 if (cur_list->node->parse_context) 668 len++; 669 } 670 671 buf[0] = cpu_to_le32(len); 672 items = put_entry(buf, sizeof(uint32_t), 1, fp); 673 if (items != 1) 674 goto out; 675 676 if (len == 0) { 677 rc = 0; 678 goto out; 679 } 680 681 for (cur_list = list; cur_list != NULL; cur_list = cur_list->next) { 682 if (cur_list->node->parse_context) 683 if (avtab_write_item(p, cur_list->node, fp, 0, 1, NULL)) 684 goto out; 685 } 686 687 rc = 0; 688 out: 689 if (oldvers) { 690 cond_av_list_destroy(new_list); 691 avtab_destroy(&expa); 692 } 693 694 return rc; 695 } 696 697 static int cond_write_node(policydb_t * p, 698 cond_node_t * node, struct policy_file *fp) 699 { 700 cond_expr_t *cur_expr; 701 uint32_t buf[2]; 702 uint32_t items, items2, len; 703 704 buf[0] = cpu_to_le32(node->cur_state); 705 items = put_entry(buf, sizeof(uint32_t), 1, fp); 706 if (items != 1) 707 return POLICYDB_ERROR; 708 709 /* expr */ 710 len = 0; 711 for (cur_expr = node->expr; cur_expr != NULL; cur_expr = cur_expr->next) 712 len++; 713 714 buf[0] = cpu_to_le32(len); 715 items = put_entry(buf, sizeof(uint32_t), 1, fp); 716 if (items != 1) 717 return POLICYDB_ERROR; 718 719 for (cur_expr = node->expr; cur_expr != NULL; cur_expr = cur_expr->next) { 720 items = 0; 721 buf[items++] = cpu_to_le32(cur_expr->expr_type); 722 buf[items++] = cpu_to_le32(cur_expr->bool); 723 items2 = put_entry(buf, sizeof(uint32_t), items, fp); 724 if (items2 != items) 725 return POLICYDB_ERROR; 726 } 727 728 if (p->policy_type == POLICY_KERN) { 729 if (cond_write_av_list(p, node->true_list, fp) != 0) 730 return POLICYDB_ERROR; 731 if (cond_write_av_list(p, node->false_list, fp) != 0) 732 return POLICYDB_ERROR; 733 } else { 734 if (avrule_write_list(node->avtrue_list, fp)) 735 return POLICYDB_ERROR; 736 if (avrule_write_list(node->avfalse_list, fp)) 737 return POLICYDB_ERROR; 738 } 739 740 if (p->policy_type != POLICY_KERN && 741 p->policyvers >= MOD_POLICYDB_VERSION_TUNABLE_SEP) { 742 buf[0] = cpu_to_le32(node->flags); 743 items = put_entry(buf, sizeof(uint32_t), 1, fp); 744 if (items != 1) 745 return POLICYDB_ERROR; 746 } 747 748 return POLICYDB_SUCCESS; 749 } 750 751 static int cond_write_list(policydb_t * p, cond_list_t * list, 752 struct policy_file *fp) 753 { 754 cond_node_t *cur; 755 uint32_t len, items; 756 uint32_t buf[1]; 757 758 len = 0; 759 for (cur = list; cur != NULL; cur = cur->next) 760 len++; 761 buf[0] = cpu_to_le32(len); 762 items = put_entry(buf, sizeof(uint32_t), 1, fp); 763 if (items != 1) 764 return POLICYDB_ERROR; 765 766 for (cur = list; cur != NULL; cur = cur->next) { 767 if (cond_write_node(p, cur, fp) != 0) 768 return POLICYDB_ERROR; 769 } 770 return POLICYDB_SUCCESS; 771 } 772 773 /* 774 * Write a security context structure 775 * to a policydb binary representation file. 776 */ 777 static int context_write(struct policydb *p, context_struct_t * c, 778 struct policy_file *fp) 779 { 780 uint32_t buf[32]; 781 size_t items, items2; 782 783 items = 0; 784 buf[items++] = cpu_to_le32(c->user); 785 buf[items++] = cpu_to_le32(c->role); 786 buf[items++] = cpu_to_le32(c->type); 787 items2 = put_entry(buf, sizeof(uint32_t), items, fp); 788 if (items2 != items) 789 return POLICYDB_ERROR; 790 if ((p->policyvers >= POLICYDB_VERSION_MLS 791 && p->policy_type == POLICY_KERN) 792 || (p->policyvers >= MOD_POLICYDB_VERSION_MLS 793 && p->policy_type == POLICY_BASE)) 794 if (mls_write_range_helper(&c->range, fp)) 795 return POLICYDB_ERROR; 796 797 return POLICYDB_SUCCESS; 798 } 799 800 /* 801 * The following *_write functions are used to 802 * write the symbol data to a policy database 803 * binary representation file. 804 */ 805 806 static int perm_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr) 807 { 808 perm_datum_t *perdatum; 809 uint32_t buf[32]; 810 size_t items, items2, len; 811 struct policy_data *pd = ptr; 812 struct policy_file *fp = pd->fp; 813 814 perdatum = (perm_datum_t *) datum; 815 816 len = strlen(key); 817 items = 0; 818 buf[items++] = cpu_to_le32(len); 819 buf[items++] = cpu_to_le32(perdatum->s.value); 820 items2 = put_entry(buf, sizeof(uint32_t), items, fp); 821 if (items != items2) 822 return POLICYDB_ERROR; 823 824 items = put_entry(key, 1, len, fp); 825 if (items != len) 826 return POLICYDB_ERROR; 827 828 return POLICYDB_SUCCESS; 829 } 830 831 static int common_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr) 832 { 833 common_datum_t *comdatum; 834 uint32_t buf[32]; 835 size_t items, items2, len; 836 struct policy_data *pd = ptr; 837 struct policy_file *fp = pd->fp; 838 839 comdatum = (common_datum_t *) datum; 840 841 len = strlen(key); 842 items = 0; 843 buf[items++] = cpu_to_le32(len); 844 buf[items++] = cpu_to_le32(comdatum->s.value); 845 buf[items++] = cpu_to_le32(comdatum->permissions.nprim); 846 buf[items++] = cpu_to_le32(comdatum->permissions.table->nel); 847 items2 = put_entry(buf, sizeof(uint32_t), items, fp); 848 if (items != items2) 849 return POLICYDB_ERROR; 850 851 items = put_entry(key, 1, len, fp); 852 if (items != len) 853 return POLICYDB_ERROR; 854 855 if (hashtab_map(comdatum->permissions.table, perm_write, pd)) 856 return POLICYDB_ERROR; 857 858 return POLICYDB_SUCCESS; 859 } 860 861 static int write_cons_helper(policydb_t * p, 862 constraint_node_t * node, int allowxtarget, 863 struct policy_file *fp) 864 { 865 constraint_node_t *c; 866 constraint_expr_t *e; 867 uint32_t buf[3], nexpr; 868 int items; 869 870 for (c = node; c; c = c->next) { 871 nexpr = 0; 872 for (e = c->expr; e; e = e->next) { 873 nexpr++; 874 } 875 buf[0] = cpu_to_le32(c->permissions); 876 buf[1] = cpu_to_le32(nexpr); 877 items = put_entry(buf, sizeof(uint32_t), 2, fp); 878 if (items != 2) 879 return POLICYDB_ERROR; 880 for (e = c->expr; e; e = e->next) { 881 items = 0; 882 buf[0] = cpu_to_le32(e->expr_type); 883 buf[1] = cpu_to_le32(e->attr); 884 buf[2] = cpu_to_le32(e->op); 885 items = put_entry(buf, sizeof(uint32_t), 3, fp); 886 if (items != 3) 887 return POLICYDB_ERROR; 888 889 switch (e->expr_type) { 890 case CEXPR_NAMES: 891 if (!allowxtarget && (e->attr & CEXPR_XTARGET)) 892 return POLICYDB_ERROR; 893 if (ebitmap_write(&e->names, fp)) { 894 return POLICYDB_ERROR; 895 } 896 if (p->policy_type != POLICY_KERN && 897 type_set_write(e->type_names, fp)) { 898 return POLICYDB_ERROR; 899 } 900 break; 901 default: 902 break; 903 } 904 } 905 } 906 907 return POLICYDB_SUCCESS; 908 } 909 910 static int class_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr) 911 { 912 class_datum_t *cladatum; 913 constraint_node_t *c; 914 uint32_t buf[32], ncons; 915 size_t items, items2, len, len2; 916 struct policy_data *pd = ptr; 917 struct policy_file *fp = pd->fp; 918 struct policydb *p = pd->p; 919 920 cladatum = (class_datum_t *) datum; 921 922 len = strlen(key); 923 if (cladatum->comkey) 924 len2 = strlen(cladatum->comkey); 925 else 926 len2 = 0; 927 928 ncons = 0; 929 for (c = cladatum->constraints; c; c = c->next) { 930 ncons++; 931 } 932 933 items = 0; 934 buf[items++] = cpu_to_le32(len); 935 buf[items++] = cpu_to_le32(len2); 936 buf[items++] = cpu_to_le32(cladatum->s.value); 937 buf[items++] = cpu_to_le32(cladatum->permissions.nprim); 938 if (cladatum->permissions.table) 939 buf[items++] = cpu_to_le32(cladatum->permissions.table->nel); 940 else 941 buf[items++] = 0; 942 buf[items++] = cpu_to_le32(ncons); 943 items2 = put_entry(buf, sizeof(uint32_t), items, fp); 944 if (items != items2) 945 return POLICYDB_ERROR; 946 947 items = put_entry(key, 1, len, fp); 948 if (items != len) 949 return POLICYDB_ERROR; 950 951 if (cladatum->comkey) { 952 items = put_entry(cladatum->comkey, 1, len2, fp); 953 if (items != len2) 954 return POLICYDB_ERROR; 955 } 956 if (hashtab_map(cladatum->permissions.table, perm_write, pd)) 957 return POLICYDB_ERROR; 958 959 if (write_cons_helper(p, cladatum->constraints, 0, fp)) 960 return POLICYDB_ERROR; 961 962 if ((p->policy_type == POLICY_KERN 963 && p->policyvers >= POLICYDB_VERSION_VALIDATETRANS) 964 || (p->policy_type == POLICY_BASE 965 && p->policyvers >= MOD_POLICYDB_VERSION_VALIDATETRANS)) { 966 /* write out the validatetrans rule */ 967 ncons = 0; 968 for (c = cladatum->validatetrans; c; c = c->next) { 969 ncons++; 970 } 971 buf[0] = cpu_to_le32(ncons); 972 items = put_entry(buf, sizeof(uint32_t), 1, fp); 973 if (items != 1) 974 return POLICYDB_ERROR; 975 if (write_cons_helper(p, cladatum->validatetrans, 1, fp)) 976 return POLICYDB_ERROR; 977 } 978 979 if ((p->policy_type == POLICY_KERN && 980 p->policyvers >= POLICYDB_VERSION_NEW_OBJECT_DEFAULTS) || 981 (p->policy_type == POLICY_BASE && 982 p->policyvers >= MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS)) { 983 buf[0] = cpu_to_le32(cladatum->default_user); 984 buf[1] = cpu_to_le32(cladatum->default_role); 985 buf[2] = cpu_to_le32(cladatum->default_range); 986 items = put_entry(buf, sizeof(uint32_t), 3, fp); 987 if (items != 3) 988 return POLICYDB_ERROR; 989 } 990 991 return POLICYDB_SUCCESS; 992 } 993 994 static int role_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr) 995 { 996 role_datum_t *role; 997 uint32_t buf[32]; 998 size_t items, items2, len; 999 struct policy_data *pd = ptr; 1000 struct policy_file *fp = pd->fp; 1001 struct policydb *p = pd->p; 1002 1003 role = (role_datum_t *) datum; 1004 1005 /* 1006 * Role attributes are redundant for policy.X, skip them 1007 * when writing the roles symbol table. They are also skipped 1008 * when pp is downgraded. 1009 * 1010 * Their numbers would be deducted in policydb_write(). 1011 */ 1012 if ((role->flavor == ROLE_ATTRIB) && 1013 ((p->policy_type == POLICY_KERN) || 1014 (p->policy_type != POLICY_KERN && 1015 p->policyvers < MOD_POLICYDB_VERSION_ROLEATTRIB))) 1016 return POLICYDB_SUCCESS; 1017 1018 len = strlen(key); 1019 items = 0; 1020 buf[items++] = cpu_to_le32(len); 1021 buf[items++] = cpu_to_le32(role->s.value); 1022 if (policydb_has_boundary_feature(p)) 1023 buf[items++] = cpu_to_le32(role->bounds); 1024 items2 = put_entry(buf, sizeof(uint32_t), items, fp); 1025 if (items != items2) 1026 return POLICYDB_ERROR; 1027 1028 items = put_entry(key, 1, len, fp); 1029 if (items != len) 1030 return POLICYDB_ERROR; 1031 1032 if (ebitmap_write(&role->dominates, fp)) 1033 return POLICYDB_ERROR; 1034 if (p->policy_type == POLICY_KERN) { 1035 if (ebitmap_write(&role->types.types, fp)) 1036 return POLICYDB_ERROR; 1037 } else { 1038 if (type_set_write(&role->types, fp)) 1039 return POLICYDB_ERROR; 1040 } 1041 1042 if (p->policy_type != POLICY_KERN && 1043 p->policyvers >= MOD_POLICYDB_VERSION_ROLEATTRIB) { 1044 buf[0] = cpu_to_le32(role->flavor); 1045 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1046 if (items != 1) 1047 return POLICYDB_ERROR; 1048 1049 if (ebitmap_write(&role->roles, fp)) 1050 return POLICYDB_ERROR; 1051 } 1052 1053 return POLICYDB_SUCCESS; 1054 } 1055 1056 static int type_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr) 1057 { 1058 type_datum_t *typdatum; 1059 uint32_t buf[32]; 1060 size_t items, items2, len; 1061 struct policy_data *pd = ptr; 1062 struct policy_file *fp = pd->fp; 1063 struct policydb *p = pd->p; 1064 1065 typdatum = (type_datum_t *) datum; 1066 1067 /* 1068 * The kernel policy version less than 24 (= POLICYDB_VERSION_BOUNDARY) 1069 * does not support to load entries of attribute, so we skip to write it. 1070 */ 1071 if (p->policy_type == POLICY_KERN 1072 && p->policyvers < POLICYDB_VERSION_BOUNDARY 1073 && typdatum->flavor == TYPE_ATTRIB) 1074 return POLICYDB_SUCCESS; 1075 1076 len = strlen(key); 1077 items = 0; 1078 buf[items++] = cpu_to_le32(len); 1079 buf[items++] = cpu_to_le32(typdatum->s.value); 1080 if (policydb_has_boundary_feature(p)) { 1081 uint32_t properties = 0; 1082 1083 if (p->policy_type != POLICY_KERN 1084 && p->policyvers >= MOD_POLICYDB_VERSION_BOUNDARY_ALIAS) { 1085 buf[items++] = cpu_to_le32(typdatum->primary); 1086 } 1087 1088 if (typdatum->primary) 1089 properties |= TYPEDATUM_PROPERTY_PRIMARY; 1090 1091 if (typdatum->flavor == TYPE_ATTRIB) { 1092 properties |= TYPEDATUM_PROPERTY_ATTRIBUTE; 1093 } else if (typdatum->flavor == TYPE_ALIAS 1094 && p->policy_type != POLICY_KERN) 1095 properties |= TYPEDATUM_PROPERTY_ALIAS; 1096 1097 if (typdatum->flags & TYPE_FLAGS_PERMISSIVE 1098 && p->policy_type != POLICY_KERN) 1099 properties |= TYPEDATUM_PROPERTY_PERMISSIVE; 1100 1101 buf[items++] = cpu_to_le32(properties); 1102 buf[items++] = cpu_to_le32(typdatum->bounds); 1103 } else { 1104 buf[items++] = cpu_to_le32(typdatum->primary); 1105 1106 if (p->policy_type != POLICY_KERN) { 1107 buf[items++] = cpu_to_le32(typdatum->flavor); 1108 1109 if (p->policyvers >= MOD_POLICYDB_VERSION_PERMISSIVE) 1110 buf[items++] = cpu_to_le32(typdatum->flags); 1111 else if (typdatum->flags & TYPE_FLAGS_PERMISSIVE) 1112 WARN(fp->handle, "Warning! Module policy " 1113 "version %d cannot support permissive " 1114 "types, but one was defined", 1115 p->policyvers); 1116 } 1117 } 1118 items2 = put_entry(buf, sizeof(uint32_t), items, fp); 1119 if (items != items2) 1120 return POLICYDB_ERROR; 1121 1122 if (p->policy_type != POLICY_KERN) { 1123 if (ebitmap_write(&typdatum->types, fp)) 1124 return POLICYDB_ERROR; 1125 } 1126 1127 items = put_entry(key, 1, len, fp); 1128 if (items != len) 1129 return POLICYDB_ERROR; 1130 1131 return POLICYDB_SUCCESS; 1132 } 1133 1134 static int user_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr) 1135 { 1136 user_datum_t *usrdatum; 1137 uint32_t buf[32]; 1138 size_t items, items2, len; 1139 struct policy_data *pd = ptr; 1140 struct policy_file *fp = pd->fp; 1141 struct policydb *p = pd->p; 1142 1143 usrdatum = (user_datum_t *) datum; 1144 1145 len = strlen(key); 1146 items = 0; 1147 buf[items++] = cpu_to_le32(len); 1148 buf[items++] = cpu_to_le32(usrdatum->s.value); 1149 if (policydb_has_boundary_feature(p)) 1150 buf[items++] = cpu_to_le32(usrdatum->bounds); 1151 items2 = put_entry(buf, sizeof(uint32_t), items, fp); 1152 if (items != items2) 1153 return POLICYDB_ERROR; 1154 1155 items = put_entry(key, 1, len, fp); 1156 if (items != len) 1157 return POLICYDB_ERROR; 1158 1159 if (p->policy_type == POLICY_KERN) { 1160 if (ebitmap_write(&usrdatum->roles.roles, fp)) 1161 return POLICYDB_ERROR; 1162 } else { 1163 if (role_set_write(&usrdatum->roles, fp)) 1164 return POLICYDB_ERROR; 1165 } 1166 1167 if ((p->policyvers >= POLICYDB_VERSION_MLS 1168 && p->policy_type == POLICY_KERN) 1169 || (p->policyvers >= MOD_POLICYDB_VERSION_MLS 1170 && p->policyvers < MOD_POLICYDB_VERSION_MLS_USERS 1171 && p->policy_type == POLICY_MOD) 1172 || (p->policyvers >= MOD_POLICYDB_VERSION_MLS 1173 && p->policyvers < MOD_POLICYDB_VERSION_MLS_USERS 1174 && p->policy_type == POLICY_BASE)) { 1175 if (mls_write_range_helper(&usrdatum->exp_range, fp)) 1176 return POLICYDB_ERROR; 1177 if (mls_write_level(&usrdatum->exp_dfltlevel, fp)) 1178 return POLICYDB_ERROR; 1179 } else if ((p->policyvers >= MOD_POLICYDB_VERSION_MLS_USERS 1180 && p->policy_type == POLICY_MOD) 1181 || (p->policyvers >= MOD_POLICYDB_VERSION_MLS_USERS 1182 && p->policy_type == POLICY_BASE)) { 1183 if (mls_write_semantic_range_helper(&usrdatum->range, fp)) 1184 return -1; 1185 if (mls_write_semantic_level_helper(&usrdatum->dfltlevel, fp)) 1186 return -1; 1187 } 1188 1189 return POLICYDB_SUCCESS; 1190 } 1191 1192 static int (*write_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum, 1193 void *datap) = { 1194 common_write, class_write, role_write, type_write, user_write, 1195 cond_write_bool, sens_write, cat_write,}; 1196 1197 static int ocontext_write_xen(struct policydb_compat_info *info, policydb_t *p, 1198 struct policy_file *fp) 1199 { 1200 unsigned int i, j; 1201 size_t nel, items; 1202 uint32_t buf[32]; 1203 ocontext_t *c; 1204 for (i = 0; i < info->ocon_num; i++) { 1205 nel = 0; 1206 for (c = p->ocontexts[i]; c; c = c->next) 1207 nel++; 1208 buf[0] = cpu_to_le32(nel); 1209 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1210 if (items != 1) 1211 return POLICYDB_ERROR; 1212 for (c = p->ocontexts[i]; c; c = c->next) { 1213 switch (i) { 1214 case OCON_XEN_ISID: 1215 buf[0] = cpu_to_le32(c->sid[0]); 1216 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1217 if (items != 1) 1218 return POLICYDB_ERROR; 1219 if (context_write(p, &c->context[0], fp)) 1220 return POLICYDB_ERROR; 1221 break; 1222 case OCON_XEN_PIRQ: 1223 buf[0] = cpu_to_le32(c->u.pirq); 1224 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1225 if (items != 1) 1226 return POLICYDB_ERROR; 1227 if (context_write(p, &c->context[0], fp)) 1228 return POLICYDB_ERROR; 1229 break; 1230 case OCON_XEN_IOPORT: 1231 buf[0] = c->u.ioport.low_ioport; 1232 buf[1] = c->u.ioport.high_ioport; 1233 for (j = 0; j < 2; j++) 1234 buf[j] = cpu_to_le32(buf[j]); 1235 items = put_entry(buf, sizeof(uint32_t), 2, fp); 1236 if (items != 2) 1237 return POLICYDB_ERROR; 1238 if (context_write(p, &c->context[0], fp)) 1239 return POLICYDB_ERROR; 1240 break; 1241 case OCON_XEN_IOMEM: 1242 buf[0] = c->u.iomem.low_iomem; 1243 buf[1] = c->u.iomem.high_iomem; 1244 for (j = 0; j < 2; j++) 1245 buf[j] = cpu_to_le32(buf[j]); 1246 items = put_entry(buf, sizeof(uint32_t), 2, fp); 1247 if (items != 2) 1248 return POLICYDB_ERROR; 1249 if (context_write(p, &c->context[0], fp)) 1250 return POLICYDB_ERROR; 1251 break; 1252 case OCON_XEN_PCIDEVICE: 1253 buf[0] = cpu_to_le32(c->u.device); 1254 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1255 if (items != 1) 1256 return POLICYDB_ERROR; 1257 if (context_write(p, &c->context[0], fp)) 1258 return POLICYDB_ERROR; 1259 break; 1260 } 1261 } 1262 } 1263 return POLICYDB_SUCCESS; 1264 } 1265 1266 static int ocontext_write_selinux(struct policydb_compat_info *info, 1267 policydb_t *p, struct policy_file *fp) 1268 { 1269 unsigned int i, j; 1270 size_t nel, items, len; 1271 uint32_t buf[32]; 1272 ocontext_t *c; 1273 for (i = 0; i < info->ocon_num; i++) { 1274 nel = 0; 1275 for (c = p->ocontexts[i]; c; c = c->next) 1276 nel++; 1277 buf[0] = cpu_to_le32(nel); 1278 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1279 if (items != 1) 1280 return POLICYDB_ERROR; 1281 for (c = p->ocontexts[i]; c; c = c->next) { 1282 switch (i) { 1283 case OCON_ISID: 1284 buf[0] = cpu_to_le32(c->sid[0]); 1285 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1286 if (items != 1) 1287 return POLICYDB_ERROR; 1288 if (context_write(p, &c->context[0], fp)) 1289 return POLICYDB_ERROR; 1290 break; 1291 case OCON_FS: 1292 case OCON_NETIF: 1293 len = strlen(c->u.name); 1294 buf[0] = cpu_to_le32(len); 1295 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1296 if (items != 1) 1297 return POLICYDB_ERROR; 1298 items = put_entry(c->u.name, 1, len, fp); 1299 if (items != len) 1300 return POLICYDB_ERROR; 1301 if (context_write(p, &c->context[0], fp)) 1302 return POLICYDB_ERROR; 1303 if (context_write(p, &c->context[1], fp)) 1304 return POLICYDB_ERROR; 1305 break; 1306 case OCON_PORT: 1307 buf[0] = c->u.port.protocol; 1308 buf[1] = c->u.port.low_port; 1309 buf[2] = c->u.port.high_port; 1310 for (j = 0; j < 3; j++) { 1311 buf[j] = cpu_to_le32(buf[j]); 1312 } 1313 items = put_entry(buf, sizeof(uint32_t), 3, fp); 1314 if (items != 3) 1315 return POLICYDB_ERROR; 1316 if (context_write(p, &c->context[0], fp)) 1317 return POLICYDB_ERROR; 1318 break; 1319 case OCON_NODE: 1320 buf[0] = c->u.node.addr; /* network order */ 1321 buf[1] = c->u.node.mask; /* network order */ 1322 items = put_entry(buf, sizeof(uint32_t), 2, fp); 1323 if (items != 2) 1324 return POLICYDB_ERROR; 1325 if (context_write(p, &c->context[0], fp)) 1326 return POLICYDB_ERROR; 1327 break; 1328 case OCON_FSUSE: 1329 buf[0] = cpu_to_le32(c->v.behavior); 1330 len = strlen(c->u.name); 1331 buf[1] = cpu_to_le32(len); 1332 items = put_entry(buf, sizeof(uint32_t), 2, fp); 1333 if (items != 2) 1334 return POLICYDB_ERROR; 1335 items = put_entry(c->u.name, 1, len, fp); 1336 if (items != len) 1337 return POLICYDB_ERROR; 1338 if (context_write(p, &c->context[0], fp)) 1339 return POLICYDB_ERROR; 1340 break; 1341 case OCON_NODE6: 1342 for (j = 0; j < 4; j++) 1343 buf[j] = c->u.node6.addr[j]; /* network order */ 1344 for (j = 0; j < 4; j++) 1345 buf[j + 4] = c->u.node6.mask[j]; /* network order */ 1346 items = put_entry(buf, sizeof(uint32_t), 8, fp); 1347 if (items != 8) 1348 return POLICYDB_ERROR; 1349 if (context_write(p, &c->context[0], fp)) 1350 return POLICYDB_ERROR; 1351 break; 1352 } 1353 } 1354 } 1355 return POLICYDB_SUCCESS; 1356 } 1357 1358 static int ocontext_write(struct policydb_compat_info *info, policydb_t * p, 1359 struct policy_file *fp) 1360 { 1361 int rc = POLICYDB_ERROR; 1362 switch (p->target_platform) { 1363 case SEPOL_TARGET_SELINUX: 1364 rc = ocontext_write_selinux(info, p, fp); 1365 break; 1366 case SEPOL_TARGET_XEN: 1367 rc = ocontext_write_xen(info, p, fp); 1368 break; 1369 } 1370 return rc; 1371 } 1372 1373 static int genfs_write(policydb_t * p, struct policy_file *fp) 1374 { 1375 genfs_t *genfs; 1376 ocontext_t *c; 1377 size_t nel = 0, items, len; 1378 uint32_t buf[32]; 1379 1380 for (genfs = p->genfs; genfs; genfs = genfs->next) 1381 nel++; 1382 buf[0] = cpu_to_le32(nel); 1383 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1384 if (items != 1) 1385 return POLICYDB_ERROR; 1386 for (genfs = p->genfs; genfs; genfs = genfs->next) { 1387 len = strlen(genfs->fstype); 1388 buf[0] = cpu_to_le32(len); 1389 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1390 if (items != 1) 1391 return POLICYDB_ERROR; 1392 items = put_entry(genfs->fstype, 1, len, fp); 1393 if (items != len) 1394 return POLICYDB_ERROR; 1395 nel = 0; 1396 for (c = genfs->head; c; c = c->next) 1397 nel++; 1398 buf[0] = cpu_to_le32(nel); 1399 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1400 if (items != 1) 1401 return POLICYDB_ERROR; 1402 for (c = genfs->head; c; c = c->next) { 1403 len = strlen(c->u.name); 1404 buf[0] = cpu_to_le32(len); 1405 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1406 if (items != 1) 1407 return POLICYDB_ERROR; 1408 items = put_entry(c->u.name, 1, len, fp); 1409 if (items != len) 1410 return POLICYDB_ERROR; 1411 buf[0] = cpu_to_le32(c->v.sclass); 1412 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1413 if (items != 1) 1414 return POLICYDB_ERROR; 1415 if (context_write(p, &c->context[0], fp)) 1416 return POLICYDB_ERROR; 1417 } 1418 } 1419 return POLICYDB_SUCCESS; 1420 } 1421 1422 static int range_write(policydb_t * p, struct policy_file *fp) 1423 { 1424 size_t nel, items; 1425 struct range_trans *rt; 1426 uint32_t buf[2]; 1427 int new_rangetr = (p->policy_type == POLICY_KERN && 1428 p->policyvers >= POLICYDB_VERSION_RANGETRANS); 1429 int warning_issued = 0; 1430 1431 nel = 0; 1432 for (rt = p->range_tr; rt; rt = rt->next) { 1433 /* all range_transitions are written for the new format, only 1434 process related range_transitions are written for the old 1435 format, so count accordingly */ 1436 if (new_rangetr || rt->target_class == SECCLASS_PROCESS) 1437 nel++; 1438 } 1439 buf[0] = cpu_to_le32(nel); 1440 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1441 if (items != 1) 1442 return POLICYDB_ERROR; 1443 for (rt = p->range_tr; rt; rt = rt->next) { 1444 if (!new_rangetr && rt->target_class != SECCLASS_PROCESS) { 1445 if (!warning_issued) 1446 WARN(fp->handle, "Discarding range_transition " 1447 "rules for security classes other than " 1448 "\"process\""); 1449 warning_issued = 1; 1450 continue; 1451 } 1452 buf[0] = cpu_to_le32(rt->source_type); 1453 buf[1] = cpu_to_le32(rt->target_type); 1454 items = put_entry(buf, sizeof(uint32_t), 2, fp); 1455 if (items != 2) 1456 return POLICYDB_ERROR; 1457 if (new_rangetr) { 1458 buf[0] = cpu_to_le32(rt->target_class); 1459 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1460 if (items != 1) 1461 return POLICYDB_ERROR; 1462 } 1463 if (mls_write_range_helper(&rt->target_range, fp)) 1464 return POLICYDB_ERROR; 1465 } 1466 return POLICYDB_SUCCESS; 1467 } 1468 1469 /************** module writing functions below **************/ 1470 1471 static int avrule_write(avrule_t * avrule, struct policy_file *fp) 1472 { 1473 size_t items, items2; 1474 uint32_t buf[32], len; 1475 class_perm_node_t *cur; 1476 1477 items = 0; 1478 buf[items++] = cpu_to_le32(avrule->specified); 1479 buf[items++] = cpu_to_le32(avrule->flags); 1480 items2 = put_entry(buf, sizeof(uint32_t), items, fp); 1481 if (items2 != items) 1482 return POLICYDB_ERROR; 1483 1484 if (type_set_write(&avrule->stypes, fp)) 1485 return POLICYDB_ERROR; 1486 1487 if (type_set_write(&avrule->ttypes, fp)) 1488 return POLICYDB_ERROR; 1489 1490 cur = avrule->perms; 1491 len = 0; 1492 while (cur) { 1493 len++; 1494 cur = cur->next; 1495 } 1496 items = 0; 1497 buf[items++] = cpu_to_le32(len); 1498 items2 = put_entry(buf, sizeof(uint32_t), items, fp); 1499 if (items2 != items) 1500 return POLICYDB_ERROR; 1501 cur = avrule->perms; 1502 while (cur) { 1503 items = 0; 1504 buf[items++] = cpu_to_le32(cur->class); 1505 buf[items++] = cpu_to_le32(cur->data); 1506 items2 = put_entry(buf, sizeof(uint32_t), items, fp); 1507 if (items2 != items) 1508 return POLICYDB_ERROR; 1509 1510 cur = cur->next; 1511 } 1512 1513 return POLICYDB_SUCCESS; 1514 } 1515 1516 static int avrule_write_list(avrule_t * avrules, struct policy_file *fp) 1517 { 1518 uint32_t buf[32], len; 1519 avrule_t *avrule; 1520 1521 avrule = avrules; 1522 len = 0; 1523 while (avrule) { 1524 len++; 1525 avrule = avrule->next; 1526 } 1527 1528 buf[0] = cpu_to_le32(len); 1529 if (put_entry(buf, sizeof(uint32_t), 1, fp) != 1) 1530 return POLICYDB_ERROR; 1531 1532 avrule = avrules; 1533 while (avrule) { 1534 avrule_write(avrule, fp); 1535 avrule = avrule->next; 1536 } 1537 1538 return POLICYDB_SUCCESS; 1539 } 1540 1541 static int only_process(ebitmap_t *in) 1542 { 1543 unsigned int i; 1544 ebitmap_node_t *node; 1545 1546 ebitmap_for_each_bit(in, node, i) { 1547 if (ebitmap_node_get_bit(node, i) && 1548 i != SECCLASS_PROCESS - 1) 1549 return 0; 1550 } 1551 return 1; 1552 } 1553 1554 static int role_trans_rule_write(policydb_t *p, role_trans_rule_t * t, 1555 struct policy_file *fp) 1556 { 1557 int nel = 0; 1558 size_t items; 1559 uint32_t buf[1]; 1560 role_trans_rule_t *tr; 1561 int warned = 0; 1562 int new_role = p->policyvers >= MOD_POLICYDB_VERSION_ROLETRANS; 1563 1564 for (tr = t; tr; tr = tr->next) 1565 if (new_role || only_process(&tr->classes)) 1566 nel++; 1567 1568 buf[0] = cpu_to_le32(nel); 1569 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1570 if (items != 1) 1571 return POLICYDB_ERROR; 1572 for (tr = t; tr; tr = tr->next) { 1573 if (!new_role && !only_process(&tr->classes)) { 1574 if (!warned) 1575 WARN(fp->handle, "Discarding role_transition " 1576 "rules for security classes other than " 1577 "\"process\""); 1578 warned = 1; 1579 continue; 1580 } 1581 if (role_set_write(&tr->roles, fp)) 1582 return POLICYDB_ERROR; 1583 if (type_set_write(&tr->types, fp)) 1584 return POLICYDB_ERROR; 1585 if (new_role) 1586 if (ebitmap_write(&tr->classes, fp)) 1587 return POLICYDB_ERROR; 1588 buf[0] = cpu_to_le32(tr->new_role); 1589 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1590 if (items != 1) 1591 return POLICYDB_ERROR; 1592 } 1593 return POLICYDB_SUCCESS; 1594 } 1595 1596 static int role_allow_rule_write(role_allow_rule_t * r, struct policy_file *fp) 1597 { 1598 int nel = 0; 1599 size_t items; 1600 uint32_t buf[1]; 1601 role_allow_rule_t *ra; 1602 1603 for (ra = r; ra; ra = ra->next) 1604 nel++; 1605 buf[0] = cpu_to_le32(nel); 1606 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1607 if (items != 1) 1608 return POLICYDB_ERROR; 1609 for (ra = r; ra; ra = ra->next) { 1610 if (role_set_write(&ra->roles, fp)) 1611 return POLICYDB_ERROR; 1612 if (role_set_write(&ra->new_roles, fp)) 1613 return POLICYDB_ERROR; 1614 } 1615 return POLICYDB_SUCCESS; 1616 } 1617 1618 static int filename_trans_rule_write(filename_trans_rule_t * t, struct policy_file *fp) 1619 { 1620 int nel = 0; 1621 size_t items; 1622 uint32_t buf[2], len; 1623 filename_trans_rule_t *ftr; 1624 1625 for (ftr = t; ftr; ftr = ftr->next) 1626 nel++; 1627 1628 buf[0] = cpu_to_le32(nel); 1629 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1630 if (items != 1) 1631 return POLICYDB_ERROR; 1632 1633 for (ftr = t; ftr; ftr = ftr->next) { 1634 len = strlen(ftr->name); 1635 buf[0] = cpu_to_le32(len); 1636 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1637 if (items != 1) 1638 return POLICYDB_ERROR; 1639 1640 items = put_entry(ftr->name, sizeof(char), len, fp); 1641 if (items != len) 1642 return POLICYDB_ERROR; 1643 1644 if (type_set_write(&ftr->stypes, fp)) 1645 return POLICYDB_ERROR; 1646 if (type_set_write(&ftr->ttypes, fp)) 1647 return POLICYDB_ERROR; 1648 1649 buf[0] = cpu_to_le32(ftr->tclass); 1650 buf[1] = cpu_to_le32(ftr->otype); 1651 1652 items = put_entry(buf, sizeof(uint32_t), 2, fp); 1653 if (items != 2) 1654 return POLICYDB_ERROR; 1655 } 1656 return POLICYDB_SUCCESS; 1657 } 1658 1659 static int range_trans_rule_write(range_trans_rule_t * t, 1660 struct policy_file *fp) 1661 { 1662 int nel = 0; 1663 size_t items; 1664 uint32_t buf[1]; 1665 range_trans_rule_t *rt; 1666 1667 for (rt = t; rt; rt = rt->next) 1668 nel++; 1669 buf[0] = cpu_to_le32(nel); 1670 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1671 if (items != 1) 1672 return POLICYDB_ERROR; 1673 for (rt = t; rt; rt = rt->next) { 1674 if (type_set_write(&rt->stypes, fp)) 1675 return POLICYDB_ERROR; 1676 if (type_set_write(&rt->ttypes, fp)) 1677 return POLICYDB_ERROR; 1678 if (ebitmap_write(&rt->tclasses, fp)) 1679 return POLICYDB_ERROR; 1680 if (mls_write_semantic_range_helper(&rt->trange, fp)) 1681 return POLICYDB_ERROR; 1682 } 1683 return POLICYDB_SUCCESS; 1684 } 1685 1686 static int scope_index_write(scope_index_t * scope_index, 1687 unsigned int num_scope_syms, 1688 struct policy_file *fp) 1689 { 1690 unsigned int i; 1691 uint32_t buf[1]; 1692 for (i = 0; i < num_scope_syms; i++) { 1693 if (ebitmap_write(scope_index->scope + i, fp) == -1) { 1694 return POLICYDB_ERROR; 1695 } 1696 } 1697 buf[0] = cpu_to_le32(scope_index->class_perms_len); 1698 if (put_entry(buf, sizeof(uint32_t), 1, fp) != 1) { 1699 return POLICYDB_ERROR; 1700 } 1701 for (i = 0; i < scope_index->class_perms_len; i++) { 1702 if (ebitmap_write(scope_index->class_perms_map + i, fp) == -1) { 1703 return POLICYDB_ERROR; 1704 } 1705 } 1706 return POLICYDB_SUCCESS; 1707 } 1708 1709 static int avrule_decl_write(avrule_decl_t * decl, int num_scope_syms, 1710 policydb_t * p, struct policy_file *fp) 1711 { 1712 struct policy_data pd; 1713 uint32_t buf[2]; 1714 int i; 1715 buf[0] = cpu_to_le32(decl->decl_id); 1716 buf[1] = cpu_to_le32(decl->enabled); 1717 if (put_entry(buf, sizeof(uint32_t), 2, fp) != 2) { 1718 return POLICYDB_ERROR; 1719 } 1720 if (cond_write_list(p, decl->cond_list, fp) == -1 || 1721 avrule_write_list(decl->avrules, fp) == -1 || 1722 role_trans_rule_write(p, decl->role_tr_rules, fp) == -1 || 1723 role_allow_rule_write(decl->role_allow_rules, fp) == -1) { 1724 return POLICYDB_ERROR; 1725 } 1726 1727 if (p->policyvers >= MOD_POLICYDB_VERSION_FILENAME_TRANS && 1728 filename_trans_rule_write(decl->filename_trans_rules, fp)) 1729 return POLICYDB_ERROR; 1730 1731 if (p->policyvers >= MOD_POLICYDB_VERSION_RANGETRANS && 1732 range_trans_rule_write(decl->range_tr_rules, fp) == -1) { 1733 return POLICYDB_ERROR; 1734 } 1735 if (scope_index_write(&decl->required, num_scope_syms, fp) == -1 || 1736 scope_index_write(&decl->declared, num_scope_syms, fp) == -1) { 1737 return POLICYDB_ERROR; 1738 } 1739 pd.fp = fp; 1740 pd.p = p; 1741 for (i = 0; i < num_scope_syms; i++) { 1742 buf[0] = cpu_to_le32(decl->symtab[i].nprim); 1743 buf[1] = cpu_to_le32(decl->symtab[i].table->nel); 1744 if (put_entry(buf, sizeof(uint32_t), 2, fp) != 2) { 1745 return POLICYDB_ERROR; 1746 } 1747 if (hashtab_map(decl->symtab[i].table, write_f[i], &pd)) { 1748 return POLICYDB_ERROR; 1749 } 1750 } 1751 return POLICYDB_SUCCESS; 1752 } 1753 1754 static int avrule_block_write(avrule_block_t * block, int num_scope_syms, 1755 policydb_t * p, struct policy_file *fp) 1756 { 1757 /* first write a count of the total number of blocks */ 1758 uint32_t buf[1], num_blocks = 0; 1759 avrule_block_t *cur; 1760 for (cur = block; cur != NULL; cur = cur->next) { 1761 num_blocks++; 1762 } 1763 buf[0] = cpu_to_le32(num_blocks); 1764 if (put_entry(buf, sizeof(uint32_t), 1, fp) != 1) { 1765 return POLICYDB_ERROR; 1766 } 1767 1768 /* now write each block */ 1769 for (cur = block; cur != NULL; cur = cur->next) { 1770 uint32_t num_decls = 0; 1771 avrule_decl_t *decl; 1772 /* write a count of number of branches */ 1773 for (decl = cur->branch_list; decl != NULL; decl = decl->next) { 1774 num_decls++; 1775 } 1776 buf[0] = cpu_to_le32(num_decls); 1777 if (put_entry(buf, sizeof(uint32_t), 1, fp) != 1) { 1778 return POLICYDB_ERROR; 1779 } 1780 for (decl = cur->branch_list; decl != NULL; decl = decl->next) { 1781 if (avrule_decl_write(decl, num_scope_syms, p, fp) == 1782 -1) { 1783 return POLICYDB_ERROR; 1784 } 1785 } 1786 } 1787 return POLICYDB_SUCCESS; 1788 } 1789 1790 static int scope_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr) 1791 { 1792 scope_datum_t *scope = (scope_datum_t *) datum; 1793 struct policy_data *pd = ptr; 1794 struct policy_file *fp = pd->fp; 1795 uint32_t static_buf[32], *dyn_buf = NULL, *buf; 1796 size_t key_len = strlen(key); 1797 unsigned int items = 2 + scope->decl_ids_len, i; 1798 1799 if (items >= (sizeof(static_buf) / 4)) { 1800 /* too many things required, so dynamically create a 1801 * buffer. this would have been easier with C99's 1802 * dynamic arrays... */ 1803 if ((dyn_buf = malloc(items * sizeof(*dyn_buf))) == NULL) { 1804 return POLICYDB_ERROR; 1805 } 1806 buf = dyn_buf; 1807 } else { 1808 buf = static_buf; 1809 } 1810 buf[0] = cpu_to_le32(key_len); 1811 if (put_entry(buf, sizeof(*buf), 1, fp) != 1 || 1812 put_entry(key, 1, key_len, fp) != key_len) { 1813 free(dyn_buf); 1814 return POLICYDB_ERROR; 1815 } 1816 buf[0] = cpu_to_le32(scope->scope); 1817 buf[1] = cpu_to_le32(scope->decl_ids_len); 1818 for (i = 0; i < scope->decl_ids_len; i++) { 1819 buf[2 + i] = cpu_to_le32(scope->decl_ids[i]); 1820 } 1821 if (put_entry(buf, sizeof(*buf), items, fp) != items) { 1822 free(dyn_buf); 1823 return POLICYDB_ERROR; 1824 } 1825 free(dyn_buf); 1826 return POLICYDB_SUCCESS; 1827 } 1828 1829 static int type_attr_uncount(hashtab_key_t key __attribute__ ((unused)), 1830 hashtab_datum_t datum, void *args) 1831 { 1832 type_datum_t *typdatum = datum; 1833 uint32_t *p_nel = args; 1834 1835 if (typdatum->flavor == TYPE_ATTRIB) { 1836 /* uncount attribute from total number of types */ 1837 (*p_nel)--; 1838 } 1839 return 0; 1840 } 1841 1842 static int role_attr_uncount(hashtab_key_t key __attribute__ ((unused)), 1843 hashtab_datum_t datum, void *args) 1844 { 1845 role_datum_t *role = datum; 1846 uint32_t *p_nel = args; 1847 1848 if (role->flavor == ROLE_ATTRIB) { 1849 /* uncount attribute from total number of roles */ 1850 (*p_nel)--; 1851 } 1852 return 0; 1853 } 1854 1855 /* 1856 * Write the configuration data in a policy database 1857 * structure to a policy database binary representation 1858 * file. 1859 */ 1860 int policydb_write(policydb_t * p, struct policy_file *fp) 1861 { 1862 unsigned int i, num_syms; 1863 uint32_t buf[32], config; 1864 size_t items, items2, len; 1865 struct policydb_compat_info *info; 1866 struct policy_data pd; 1867 char *policydb_str; 1868 1869 if (p->unsupported_format) 1870 return POLICYDB_UNSUPPORTED; 1871 1872 pd.fp = fp; 1873 pd.p = p; 1874 1875 config = 0; 1876 if (p->mls) { 1877 if ((p->policyvers < POLICYDB_VERSION_MLS && 1878 p->policy_type == POLICY_KERN) || 1879 (p->policyvers < MOD_POLICYDB_VERSION_MLS && 1880 p->policy_type == POLICY_BASE) || 1881 (p->policyvers < MOD_POLICYDB_VERSION_MLS && 1882 p->policy_type == POLICY_MOD)) { 1883 ERR(fp->handle, "policy version %d cannot support MLS", 1884 p->policyvers); 1885 return POLICYDB_ERROR; 1886 } 1887 config |= POLICYDB_CONFIG_MLS; 1888 } 1889 1890 config |= (POLICYDB_CONFIG_UNKNOWN_MASK & p->handle_unknown); 1891 1892 /* Write the magic number and string identifiers. */ 1893 items = 0; 1894 if (p->policy_type == POLICY_KERN) { 1895 buf[items++] = cpu_to_le32(POLICYDB_MAGIC); 1896 len = strlen(policydb_target_strings[p->target_platform]); 1897 policydb_str = policydb_target_strings[p->target_platform]; 1898 } else { 1899 buf[items++] = cpu_to_le32(POLICYDB_MOD_MAGIC); 1900 len = strlen(POLICYDB_MOD_STRING); 1901 policydb_str = POLICYDB_MOD_STRING; 1902 } 1903 buf[items++] = cpu_to_le32(len); 1904 items2 = put_entry(buf, sizeof(uint32_t), items, fp); 1905 if (items != items2) 1906 return POLICYDB_ERROR; 1907 items = put_entry(policydb_str, 1, len, fp); 1908 if (items != len) 1909 return POLICYDB_ERROR; 1910 1911 /* Write the version, config, and table sizes. */ 1912 items = 0; 1913 info = policydb_lookup_compat(p->policyvers, p->policy_type, 1914 p->target_platform); 1915 if (!info) { 1916 ERR(fp->handle, "compatibility lookup failed for policy " 1917 "version %d", p->policyvers); 1918 return POLICYDB_ERROR; 1919 } 1920 1921 if (p->policy_type != POLICY_KERN) { 1922 buf[items++] = cpu_to_le32(p->policy_type); 1923 } 1924 buf[items++] = cpu_to_le32(p->policyvers); 1925 buf[items++] = cpu_to_le32(config); 1926 buf[items++] = cpu_to_le32(info->sym_num); 1927 buf[items++] = cpu_to_le32(info->ocon_num); 1928 1929 items2 = put_entry(buf, sizeof(uint32_t), items, fp); 1930 if (items != items2) 1931 return POLICYDB_ERROR; 1932 1933 if (p->policy_type == POLICY_MOD) { 1934 /* Write module name and version */ 1935 len = strlen(p->name); 1936 buf[0] = cpu_to_le32(len); 1937 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1938 if (items != 1) 1939 return POLICYDB_ERROR; 1940 items = put_entry(p->name, 1, len, fp); 1941 if (items != len) 1942 return POLICYDB_ERROR; 1943 len = strlen(p->version); 1944 buf[0] = cpu_to_le32(len); 1945 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1946 if (items != 1) 1947 return POLICYDB_ERROR; 1948 items = put_entry(p->version, 1, len, fp); 1949 if (items != len) 1950 return POLICYDB_ERROR; 1951 } 1952 1953 if ((p->policyvers >= POLICYDB_VERSION_POLCAP && 1954 p->policy_type == POLICY_KERN) || 1955 (p->policyvers >= MOD_POLICYDB_VERSION_POLCAP && 1956 p->policy_type == POLICY_BASE) || 1957 (p->policyvers >= MOD_POLICYDB_VERSION_POLCAP && 1958 p->policy_type == POLICY_MOD)) { 1959 if (ebitmap_write(&p->policycaps, fp) == -1) 1960 return POLICYDB_ERROR; 1961 } 1962 1963 if (p->policyvers < POLICYDB_VERSION_PERMISSIVE && 1964 p->policy_type == POLICY_KERN) { 1965 ebitmap_node_t *tnode; 1966 1967 ebitmap_for_each_bit(&p->permissive_map, tnode, i) { 1968 if (ebitmap_node_get_bit(tnode, i)) { 1969 WARN(fp->handle, "Warning! Policy version %d cannot " 1970 "support permissive types, but some were defined", 1971 p->policyvers); 1972 break; 1973 } 1974 } 1975 } 1976 1977 if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE && 1978 p->policy_type == POLICY_KERN) { 1979 if (ebitmap_write(&p->permissive_map, fp) == -1) 1980 return POLICYDB_ERROR; 1981 } 1982 1983 num_syms = info->sym_num; 1984 for (i = 0; i < num_syms; i++) { 1985 buf[0] = cpu_to_le32(p->symtab[i].nprim); 1986 buf[1] = p->symtab[i].table->nel; 1987 1988 /* 1989 * A special case when writing type/attribute symbol table. 1990 * The kernel policy version less than 24 does not support 1991 * to load entries of attribute, so we have to re-calculate 1992 * the actual number of types except for attributes. 1993 */ 1994 if (i == SYM_TYPES && 1995 p->policyvers < POLICYDB_VERSION_BOUNDARY && 1996 p->policy_type == POLICY_KERN) { 1997 hashtab_map(p->symtab[i].table, type_attr_uncount, &buf[1]); 1998 } 1999 2000 /* 2001 * Another special case when writing role/attribute symbol 2002 * table, role attributes are redundant for policy.X, or 2003 * when the pp's version is not big enough. So deduct 2004 * their numbers from p_roles.table->nel. 2005 */ 2006 if ((i == SYM_ROLES) && 2007 ((p->policy_type == POLICY_KERN) || 2008 (p->policy_type != POLICY_KERN && 2009 p->policyvers < MOD_POLICYDB_VERSION_ROLEATTRIB))) 2010 hashtab_map(p->symtab[i].table, role_attr_uncount, &buf[1]); 2011 2012 buf[1] = cpu_to_le32(buf[1]); 2013 items = put_entry(buf, sizeof(uint32_t), 2, fp); 2014 if (items != 2) 2015 return POLICYDB_ERROR; 2016 if (hashtab_map(p->symtab[i].table, write_f[i], &pd)) 2017 return POLICYDB_ERROR; 2018 } 2019 2020 if (p->policy_type == POLICY_KERN) { 2021 if (avtab_write(p, &p->te_avtab, fp)) 2022 return POLICYDB_ERROR; 2023 if (p->policyvers < POLICYDB_VERSION_BOOL) { 2024 if (p->p_bools.nprim) 2025 WARN(fp->handle, "Discarding " 2026 "booleans and conditional rules"); 2027 } else { 2028 if (cond_write_list(p, p->cond_list, fp)) 2029 return POLICYDB_ERROR; 2030 } 2031 if (role_trans_write(p, fp)) 2032 return POLICYDB_ERROR; 2033 if (role_allow_write(p->role_allow, fp)) 2034 return POLICYDB_ERROR; 2035 if (p->policyvers >= POLICYDB_VERSION_FILENAME_TRANS) { 2036 if (filename_trans_write(p->filename_trans, fp)) 2037 return POLICYDB_ERROR; 2038 } else { 2039 if (p->filename_trans) 2040 WARN(fp->handle, "Discarding filename type transition rules"); 2041 } 2042 } else { 2043 if (avrule_block_write(p->global, num_syms, p, fp) == -1) { 2044 return POLICYDB_ERROR; 2045 } 2046 2047 for (i = 0; i < num_syms; i++) { 2048 buf[0] = cpu_to_le32(p->scope[i].table->nel); 2049 if (put_entry(buf, sizeof(uint32_t), 1, fp) != 1) { 2050 return POLICYDB_ERROR; 2051 } 2052 if (hashtab_map(p->scope[i].table, scope_write, &pd)) 2053 return POLICYDB_ERROR; 2054 } 2055 } 2056 2057 if (ocontext_write(info, p, fp) == -1 || genfs_write(p, fp) == -1) { 2058 return POLICYDB_ERROR; 2059 } 2060 2061 if ((p->policyvers >= POLICYDB_VERSION_MLS 2062 && p->policy_type == POLICY_KERN) 2063 || (p->policyvers >= MOD_POLICYDB_VERSION_MLS 2064 && p->policyvers < MOD_POLICYDB_VERSION_RANGETRANS 2065 && p->policy_type == POLICY_BASE)) { 2066 if (range_write(p, fp)) { 2067 return POLICYDB_ERROR; 2068 } 2069 } 2070 2071 if (p->policy_type == POLICY_KERN 2072 && p->policyvers >= POLICYDB_VERSION_AVTAB) { 2073 for (i = 0; i < p->p_types.nprim; i++) { 2074 if (ebitmap_write(&p->type_attr_map[i], fp) == -1) 2075 return POLICYDB_ERROR; 2076 } 2077 } 2078 2079 return POLICYDB_SUCCESS; 2080 } 2081