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 (p->policy_type == POLICY_KERN && 899 (p->policyvers >= POLICYDB_VERSION_CONSTRAINT_NAMES) && 900 type_set_write(e->type_names, fp))) { 901 return POLICYDB_ERROR; 902 } 903 break; 904 default: 905 break; 906 } 907 } 908 } 909 910 return POLICYDB_SUCCESS; 911 } 912 913 static int class_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr) 914 { 915 class_datum_t *cladatum; 916 constraint_node_t *c; 917 uint32_t buf[32], ncons; 918 size_t items, items2, len, len2; 919 struct policy_data *pd = ptr; 920 struct policy_file *fp = pd->fp; 921 struct policydb *p = pd->p; 922 923 cladatum = (class_datum_t *) datum; 924 925 len = strlen(key); 926 if (cladatum->comkey) 927 len2 = strlen(cladatum->comkey); 928 else 929 len2 = 0; 930 931 ncons = 0; 932 for (c = cladatum->constraints; c; c = c->next) { 933 ncons++; 934 } 935 936 items = 0; 937 buf[items++] = cpu_to_le32(len); 938 buf[items++] = cpu_to_le32(len2); 939 buf[items++] = cpu_to_le32(cladatum->s.value); 940 buf[items++] = cpu_to_le32(cladatum->permissions.nprim); 941 if (cladatum->permissions.table) 942 buf[items++] = cpu_to_le32(cladatum->permissions.table->nel); 943 else 944 buf[items++] = 0; 945 buf[items++] = cpu_to_le32(ncons); 946 items2 = put_entry(buf, sizeof(uint32_t), items, fp); 947 if (items != items2) 948 return POLICYDB_ERROR; 949 950 items = put_entry(key, 1, len, fp); 951 if (items != len) 952 return POLICYDB_ERROR; 953 954 if (cladatum->comkey) { 955 items = put_entry(cladatum->comkey, 1, len2, fp); 956 if (items != len2) 957 return POLICYDB_ERROR; 958 } 959 if (hashtab_map(cladatum->permissions.table, perm_write, pd)) 960 return POLICYDB_ERROR; 961 962 if (write_cons_helper(p, cladatum->constraints, 0, fp)) 963 return POLICYDB_ERROR; 964 965 if ((p->policy_type == POLICY_KERN 966 && p->policyvers >= POLICYDB_VERSION_VALIDATETRANS) 967 || (p->policy_type == POLICY_BASE 968 && p->policyvers >= MOD_POLICYDB_VERSION_VALIDATETRANS)) { 969 /* write out the validatetrans rule */ 970 ncons = 0; 971 for (c = cladatum->validatetrans; c; c = c->next) { 972 ncons++; 973 } 974 buf[0] = cpu_to_le32(ncons); 975 items = put_entry(buf, sizeof(uint32_t), 1, fp); 976 if (items != 1) 977 return POLICYDB_ERROR; 978 if (write_cons_helper(p, cladatum->validatetrans, 1, fp)) 979 return POLICYDB_ERROR; 980 } 981 982 if ((p->policy_type == POLICY_KERN && 983 p->policyvers >= POLICYDB_VERSION_NEW_OBJECT_DEFAULTS) || 984 (p->policy_type == POLICY_BASE && 985 p->policyvers >= MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS)) { 986 buf[0] = cpu_to_le32(cladatum->default_user); 987 buf[1] = cpu_to_le32(cladatum->default_role); 988 buf[2] = cpu_to_le32(cladatum->default_range); 989 items = put_entry(buf, sizeof(uint32_t), 3, fp); 990 if (items != 3) 991 return POLICYDB_ERROR; 992 } 993 994 if ((p->policy_type == POLICY_KERN && 995 p->policyvers >= POLICYDB_VERSION_DEFAULT_TYPE) || 996 (p->policy_type == POLICY_BASE && 997 p->policyvers >= MOD_POLICYDB_VERSION_DEFAULT_TYPE)) { 998 buf[0] = cpu_to_le32(cladatum->default_type); 999 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1000 if (items != 1) 1001 return POLICYDB_ERROR; 1002 } 1003 1004 return POLICYDB_SUCCESS; 1005 } 1006 1007 static int role_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr) 1008 { 1009 role_datum_t *role; 1010 uint32_t buf[32]; 1011 size_t items, items2, len; 1012 struct policy_data *pd = ptr; 1013 struct policy_file *fp = pd->fp; 1014 struct policydb *p = pd->p; 1015 1016 role = (role_datum_t *) datum; 1017 1018 /* 1019 * Role attributes are redundant for policy.X, skip them 1020 * when writing the roles symbol table. They are also skipped 1021 * when pp is downgraded. 1022 * 1023 * Their numbers would be deducted in policydb_write(). 1024 */ 1025 if ((role->flavor == ROLE_ATTRIB) && 1026 ((p->policy_type == POLICY_KERN) || 1027 (p->policy_type != POLICY_KERN && 1028 p->policyvers < MOD_POLICYDB_VERSION_ROLEATTRIB))) 1029 return POLICYDB_SUCCESS; 1030 1031 len = strlen(key); 1032 items = 0; 1033 buf[items++] = cpu_to_le32(len); 1034 buf[items++] = cpu_to_le32(role->s.value); 1035 if (policydb_has_boundary_feature(p)) 1036 buf[items++] = cpu_to_le32(role->bounds); 1037 items2 = put_entry(buf, sizeof(uint32_t), items, fp); 1038 if (items != items2) 1039 return POLICYDB_ERROR; 1040 1041 items = put_entry(key, 1, len, fp); 1042 if (items != len) 1043 return POLICYDB_ERROR; 1044 1045 if (ebitmap_write(&role->dominates, fp)) 1046 return POLICYDB_ERROR; 1047 if (p->policy_type == POLICY_KERN) { 1048 if (ebitmap_write(&role->types.types, fp)) 1049 return POLICYDB_ERROR; 1050 } else { 1051 if (type_set_write(&role->types, fp)) 1052 return POLICYDB_ERROR; 1053 } 1054 1055 if (p->policy_type != POLICY_KERN && 1056 p->policyvers >= MOD_POLICYDB_VERSION_ROLEATTRIB) { 1057 buf[0] = cpu_to_le32(role->flavor); 1058 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1059 if (items != 1) 1060 return POLICYDB_ERROR; 1061 1062 if (ebitmap_write(&role->roles, fp)) 1063 return POLICYDB_ERROR; 1064 } 1065 1066 return POLICYDB_SUCCESS; 1067 } 1068 1069 static int type_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr) 1070 { 1071 type_datum_t *typdatum; 1072 uint32_t buf[32]; 1073 size_t items, items2, len; 1074 struct policy_data *pd = ptr; 1075 struct policy_file *fp = pd->fp; 1076 struct policydb *p = pd->p; 1077 1078 typdatum = (type_datum_t *) datum; 1079 1080 /* 1081 * The kernel policy version less than 24 (= POLICYDB_VERSION_BOUNDARY) 1082 * does not support to load entries of attribute, so we skip to write it. 1083 */ 1084 if (p->policy_type == POLICY_KERN 1085 && p->policyvers < POLICYDB_VERSION_BOUNDARY 1086 && typdatum->flavor == TYPE_ATTRIB) 1087 return POLICYDB_SUCCESS; 1088 1089 len = strlen(key); 1090 items = 0; 1091 buf[items++] = cpu_to_le32(len); 1092 buf[items++] = cpu_to_le32(typdatum->s.value); 1093 if (policydb_has_boundary_feature(p)) { 1094 uint32_t properties = 0; 1095 1096 if (p->policy_type != POLICY_KERN 1097 && p->policyvers >= MOD_POLICYDB_VERSION_BOUNDARY_ALIAS) { 1098 buf[items++] = cpu_to_le32(typdatum->primary); 1099 } 1100 1101 if (typdatum->primary) 1102 properties |= TYPEDATUM_PROPERTY_PRIMARY; 1103 1104 if (typdatum->flavor == TYPE_ATTRIB) { 1105 properties |= TYPEDATUM_PROPERTY_ATTRIBUTE; 1106 } else if (typdatum->flavor == TYPE_ALIAS 1107 && p->policy_type != POLICY_KERN) 1108 properties |= TYPEDATUM_PROPERTY_ALIAS; 1109 1110 if (typdatum->flags & TYPE_FLAGS_PERMISSIVE 1111 && p->policy_type != POLICY_KERN) 1112 properties |= TYPEDATUM_PROPERTY_PERMISSIVE; 1113 1114 buf[items++] = cpu_to_le32(properties); 1115 buf[items++] = cpu_to_le32(typdatum->bounds); 1116 } else { 1117 buf[items++] = cpu_to_le32(typdatum->primary); 1118 1119 if (p->policy_type != POLICY_KERN) { 1120 buf[items++] = cpu_to_le32(typdatum->flavor); 1121 1122 if (p->policyvers >= MOD_POLICYDB_VERSION_PERMISSIVE) 1123 buf[items++] = cpu_to_le32(typdatum->flags); 1124 else if (typdatum->flags & TYPE_FLAGS_PERMISSIVE) 1125 WARN(fp->handle, "Warning! Module policy " 1126 "version %d cannot support permissive " 1127 "types, but one was defined", 1128 p->policyvers); 1129 } 1130 } 1131 items2 = put_entry(buf, sizeof(uint32_t), items, fp); 1132 if (items != items2) 1133 return POLICYDB_ERROR; 1134 1135 if (p->policy_type != POLICY_KERN) { 1136 if (ebitmap_write(&typdatum->types, fp)) 1137 return POLICYDB_ERROR; 1138 } 1139 1140 items = put_entry(key, 1, len, fp); 1141 if (items != len) 1142 return POLICYDB_ERROR; 1143 1144 return POLICYDB_SUCCESS; 1145 } 1146 1147 static int user_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr) 1148 { 1149 user_datum_t *usrdatum; 1150 uint32_t buf[32]; 1151 size_t items, items2, len; 1152 struct policy_data *pd = ptr; 1153 struct policy_file *fp = pd->fp; 1154 struct policydb *p = pd->p; 1155 1156 usrdatum = (user_datum_t *) datum; 1157 1158 len = strlen(key); 1159 items = 0; 1160 buf[items++] = cpu_to_le32(len); 1161 buf[items++] = cpu_to_le32(usrdatum->s.value); 1162 if (policydb_has_boundary_feature(p)) 1163 buf[items++] = cpu_to_le32(usrdatum->bounds); 1164 items2 = put_entry(buf, sizeof(uint32_t), items, fp); 1165 if (items != items2) 1166 return POLICYDB_ERROR; 1167 1168 items = put_entry(key, 1, len, fp); 1169 if (items != len) 1170 return POLICYDB_ERROR; 1171 1172 if (p->policy_type == POLICY_KERN) { 1173 if (ebitmap_write(&usrdatum->roles.roles, fp)) 1174 return POLICYDB_ERROR; 1175 } else { 1176 if (role_set_write(&usrdatum->roles, fp)) 1177 return POLICYDB_ERROR; 1178 } 1179 1180 if ((p->policyvers >= POLICYDB_VERSION_MLS 1181 && p->policy_type == POLICY_KERN) 1182 || (p->policyvers >= MOD_POLICYDB_VERSION_MLS 1183 && p->policyvers < MOD_POLICYDB_VERSION_MLS_USERS 1184 && p->policy_type == POLICY_MOD) 1185 || (p->policyvers >= MOD_POLICYDB_VERSION_MLS 1186 && p->policyvers < MOD_POLICYDB_VERSION_MLS_USERS 1187 && p->policy_type == POLICY_BASE)) { 1188 if (mls_write_range_helper(&usrdatum->exp_range, fp)) 1189 return POLICYDB_ERROR; 1190 if (mls_write_level(&usrdatum->exp_dfltlevel, fp)) 1191 return POLICYDB_ERROR; 1192 } else if ((p->policyvers >= MOD_POLICYDB_VERSION_MLS_USERS 1193 && p->policy_type == POLICY_MOD) 1194 || (p->policyvers >= MOD_POLICYDB_VERSION_MLS_USERS 1195 && p->policy_type == POLICY_BASE)) { 1196 if (mls_write_semantic_range_helper(&usrdatum->range, fp)) 1197 return -1; 1198 if (mls_write_semantic_level_helper(&usrdatum->dfltlevel, fp)) 1199 return -1; 1200 } 1201 1202 return POLICYDB_SUCCESS; 1203 } 1204 1205 static int (*write_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum, 1206 void *datap) = { 1207 common_write, class_write, role_write, type_write, user_write, 1208 cond_write_bool, sens_write, cat_write,}; 1209 1210 static int ocontext_write_xen(struct policydb_compat_info *info, policydb_t *p, 1211 struct policy_file *fp) 1212 { 1213 unsigned int i, j; 1214 size_t nel, items; 1215 uint32_t buf[32]; 1216 ocontext_t *c; 1217 for (i = 0; i < info->ocon_num; i++) { 1218 nel = 0; 1219 for (c = p->ocontexts[i]; c; c = c->next) 1220 nel++; 1221 buf[0] = cpu_to_le32(nel); 1222 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1223 if (items != 1) 1224 return POLICYDB_ERROR; 1225 for (c = p->ocontexts[i]; c; c = c->next) { 1226 switch (i) { 1227 case OCON_XEN_ISID: 1228 buf[0] = cpu_to_le32(c->sid[0]); 1229 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1230 if (items != 1) 1231 return POLICYDB_ERROR; 1232 if (context_write(p, &c->context[0], fp)) 1233 return POLICYDB_ERROR; 1234 break; 1235 case OCON_XEN_PIRQ: 1236 buf[0] = cpu_to_le32(c->u.pirq); 1237 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1238 if (items != 1) 1239 return POLICYDB_ERROR; 1240 if (context_write(p, &c->context[0], fp)) 1241 return POLICYDB_ERROR; 1242 break; 1243 case OCON_XEN_IOPORT: 1244 buf[0] = c->u.ioport.low_ioport; 1245 buf[1] = c->u.ioport.high_ioport; 1246 for (j = 0; j < 2; j++) 1247 buf[j] = cpu_to_le32(buf[j]); 1248 items = put_entry(buf, sizeof(uint32_t), 2, fp); 1249 if (items != 2) 1250 return POLICYDB_ERROR; 1251 if (context_write(p, &c->context[0], fp)) 1252 return POLICYDB_ERROR; 1253 break; 1254 case OCON_XEN_IOMEM: 1255 buf[0] = c->u.iomem.low_iomem; 1256 buf[1] = c->u.iomem.high_iomem; 1257 for (j = 0; j < 2; j++) 1258 buf[j] = cpu_to_le32(buf[j]); 1259 items = put_entry(buf, sizeof(uint32_t), 2, fp); 1260 if (items != 2) 1261 return POLICYDB_ERROR; 1262 if (context_write(p, &c->context[0], fp)) 1263 return POLICYDB_ERROR; 1264 break; 1265 case OCON_XEN_PCIDEVICE: 1266 buf[0] = cpu_to_le32(c->u.device); 1267 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1268 if (items != 1) 1269 return POLICYDB_ERROR; 1270 if (context_write(p, &c->context[0], fp)) 1271 return POLICYDB_ERROR; 1272 break; 1273 } 1274 } 1275 } 1276 return POLICYDB_SUCCESS; 1277 } 1278 1279 static int ocontext_write_selinux(struct policydb_compat_info *info, 1280 policydb_t *p, struct policy_file *fp) 1281 { 1282 unsigned int i, j; 1283 size_t nel, items, len; 1284 uint32_t buf[32]; 1285 ocontext_t *c; 1286 for (i = 0; i < info->ocon_num; i++) { 1287 nel = 0; 1288 for (c = p->ocontexts[i]; c; c = c->next) 1289 nel++; 1290 buf[0] = cpu_to_le32(nel); 1291 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1292 if (items != 1) 1293 return POLICYDB_ERROR; 1294 for (c = p->ocontexts[i]; c; c = c->next) { 1295 switch (i) { 1296 case OCON_ISID: 1297 buf[0] = cpu_to_le32(c->sid[0]); 1298 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1299 if (items != 1) 1300 return POLICYDB_ERROR; 1301 if (context_write(p, &c->context[0], fp)) 1302 return POLICYDB_ERROR; 1303 break; 1304 case OCON_FS: 1305 case OCON_NETIF: 1306 len = strlen(c->u.name); 1307 buf[0] = cpu_to_le32(len); 1308 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1309 if (items != 1) 1310 return POLICYDB_ERROR; 1311 items = put_entry(c->u.name, 1, len, fp); 1312 if (items != len) 1313 return POLICYDB_ERROR; 1314 if (context_write(p, &c->context[0], fp)) 1315 return POLICYDB_ERROR; 1316 if (context_write(p, &c->context[1], fp)) 1317 return POLICYDB_ERROR; 1318 break; 1319 case OCON_PORT: 1320 buf[0] = c->u.port.protocol; 1321 buf[1] = c->u.port.low_port; 1322 buf[2] = c->u.port.high_port; 1323 for (j = 0; j < 3; j++) { 1324 buf[j] = cpu_to_le32(buf[j]); 1325 } 1326 items = put_entry(buf, sizeof(uint32_t), 3, fp); 1327 if (items != 3) 1328 return POLICYDB_ERROR; 1329 if (context_write(p, &c->context[0], fp)) 1330 return POLICYDB_ERROR; 1331 break; 1332 case OCON_NODE: 1333 buf[0] = c->u.node.addr; /* network order */ 1334 buf[1] = c->u.node.mask; /* network order */ 1335 items = put_entry(buf, sizeof(uint32_t), 2, fp); 1336 if (items != 2) 1337 return POLICYDB_ERROR; 1338 if (context_write(p, &c->context[0], fp)) 1339 return POLICYDB_ERROR; 1340 break; 1341 case OCON_FSUSE: 1342 buf[0] = cpu_to_le32(c->v.behavior); 1343 len = strlen(c->u.name); 1344 buf[1] = cpu_to_le32(len); 1345 items = put_entry(buf, sizeof(uint32_t), 2, fp); 1346 if (items != 2) 1347 return POLICYDB_ERROR; 1348 items = put_entry(c->u.name, 1, len, fp); 1349 if (items != len) 1350 return POLICYDB_ERROR; 1351 if (context_write(p, &c->context[0], fp)) 1352 return POLICYDB_ERROR; 1353 break; 1354 case OCON_NODE6: 1355 for (j = 0; j < 4; j++) 1356 buf[j] = c->u.node6.addr[j]; /* network order */ 1357 for (j = 0; j < 4; j++) 1358 buf[j + 4] = c->u.node6.mask[j]; /* network order */ 1359 items = put_entry(buf, sizeof(uint32_t), 8, fp); 1360 if (items != 8) 1361 return POLICYDB_ERROR; 1362 if (context_write(p, &c->context[0], fp)) 1363 return POLICYDB_ERROR; 1364 break; 1365 } 1366 } 1367 } 1368 return POLICYDB_SUCCESS; 1369 } 1370 1371 static int ocontext_write(struct policydb_compat_info *info, policydb_t * p, 1372 struct policy_file *fp) 1373 { 1374 int rc = POLICYDB_ERROR; 1375 switch (p->target_platform) { 1376 case SEPOL_TARGET_SELINUX: 1377 rc = ocontext_write_selinux(info, p, fp); 1378 break; 1379 case SEPOL_TARGET_XEN: 1380 rc = ocontext_write_xen(info, p, fp); 1381 break; 1382 } 1383 return rc; 1384 } 1385 1386 static int genfs_write(policydb_t * p, struct policy_file *fp) 1387 { 1388 genfs_t *genfs; 1389 ocontext_t *c; 1390 size_t nel = 0, items, len; 1391 uint32_t buf[32]; 1392 1393 for (genfs = p->genfs; genfs; genfs = genfs->next) 1394 nel++; 1395 buf[0] = cpu_to_le32(nel); 1396 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1397 if (items != 1) 1398 return POLICYDB_ERROR; 1399 for (genfs = p->genfs; genfs; genfs = genfs->next) { 1400 len = strlen(genfs->fstype); 1401 buf[0] = cpu_to_le32(len); 1402 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1403 if (items != 1) 1404 return POLICYDB_ERROR; 1405 items = put_entry(genfs->fstype, 1, len, fp); 1406 if (items != len) 1407 return POLICYDB_ERROR; 1408 nel = 0; 1409 for (c = genfs->head; c; c = c->next) 1410 nel++; 1411 buf[0] = cpu_to_le32(nel); 1412 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1413 if (items != 1) 1414 return POLICYDB_ERROR; 1415 for (c = genfs->head; c; c = c->next) { 1416 len = strlen(c->u.name); 1417 buf[0] = cpu_to_le32(len); 1418 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1419 if (items != 1) 1420 return POLICYDB_ERROR; 1421 items = put_entry(c->u.name, 1, len, fp); 1422 if (items != len) 1423 return POLICYDB_ERROR; 1424 buf[0] = cpu_to_le32(c->v.sclass); 1425 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1426 if (items != 1) 1427 return POLICYDB_ERROR; 1428 if (context_write(p, &c->context[0], fp)) 1429 return POLICYDB_ERROR; 1430 } 1431 } 1432 return POLICYDB_SUCCESS; 1433 } 1434 1435 static int range_write(policydb_t * p, struct policy_file *fp) 1436 { 1437 size_t nel, items; 1438 struct range_trans *rt; 1439 uint32_t buf[2]; 1440 int new_rangetr = (p->policy_type == POLICY_KERN && 1441 p->policyvers >= POLICYDB_VERSION_RANGETRANS); 1442 int warning_issued = 0; 1443 1444 nel = 0; 1445 for (rt = p->range_tr; rt; rt = rt->next) { 1446 /* all range_transitions are written for the new format, only 1447 process related range_transitions are written for the old 1448 format, so count accordingly */ 1449 if (new_rangetr || rt->target_class == SECCLASS_PROCESS) 1450 nel++; 1451 } 1452 buf[0] = cpu_to_le32(nel); 1453 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1454 if (items != 1) 1455 return POLICYDB_ERROR; 1456 for (rt = p->range_tr; rt; rt = rt->next) { 1457 if (!new_rangetr && rt->target_class != SECCLASS_PROCESS) { 1458 if (!warning_issued) 1459 WARN(fp->handle, "Discarding range_transition " 1460 "rules for security classes other than " 1461 "\"process\""); 1462 warning_issued = 1; 1463 continue; 1464 } 1465 buf[0] = cpu_to_le32(rt->source_type); 1466 buf[1] = cpu_to_le32(rt->target_type); 1467 items = put_entry(buf, sizeof(uint32_t), 2, fp); 1468 if (items != 2) 1469 return POLICYDB_ERROR; 1470 if (new_rangetr) { 1471 buf[0] = cpu_to_le32(rt->target_class); 1472 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1473 if (items != 1) 1474 return POLICYDB_ERROR; 1475 } 1476 if (mls_write_range_helper(&rt->target_range, fp)) 1477 return POLICYDB_ERROR; 1478 } 1479 return POLICYDB_SUCCESS; 1480 } 1481 1482 /************** module writing functions below **************/ 1483 1484 static int avrule_write(avrule_t * avrule, struct policy_file *fp) 1485 { 1486 size_t items, items2; 1487 uint32_t buf[32], len; 1488 class_perm_node_t *cur; 1489 1490 items = 0; 1491 buf[items++] = cpu_to_le32(avrule->specified); 1492 buf[items++] = cpu_to_le32(avrule->flags); 1493 items2 = put_entry(buf, sizeof(uint32_t), items, fp); 1494 if (items2 != items) 1495 return POLICYDB_ERROR; 1496 1497 if (type_set_write(&avrule->stypes, fp)) 1498 return POLICYDB_ERROR; 1499 1500 if (type_set_write(&avrule->ttypes, fp)) 1501 return POLICYDB_ERROR; 1502 1503 cur = avrule->perms; 1504 len = 0; 1505 while (cur) { 1506 len++; 1507 cur = cur->next; 1508 } 1509 items = 0; 1510 buf[items++] = cpu_to_le32(len); 1511 items2 = put_entry(buf, sizeof(uint32_t), items, fp); 1512 if (items2 != items) 1513 return POLICYDB_ERROR; 1514 cur = avrule->perms; 1515 while (cur) { 1516 items = 0; 1517 buf[items++] = cpu_to_le32(cur->class); 1518 buf[items++] = cpu_to_le32(cur->data); 1519 items2 = put_entry(buf, sizeof(uint32_t), items, fp); 1520 if (items2 != items) 1521 return POLICYDB_ERROR; 1522 1523 cur = cur->next; 1524 } 1525 1526 return POLICYDB_SUCCESS; 1527 } 1528 1529 static int avrule_write_list(avrule_t * avrules, struct policy_file *fp) 1530 { 1531 uint32_t buf[32], len; 1532 avrule_t *avrule; 1533 1534 avrule = avrules; 1535 len = 0; 1536 while (avrule) { 1537 len++; 1538 avrule = avrule->next; 1539 } 1540 1541 buf[0] = cpu_to_le32(len); 1542 if (put_entry(buf, sizeof(uint32_t), 1, fp) != 1) 1543 return POLICYDB_ERROR; 1544 1545 avrule = avrules; 1546 while (avrule) { 1547 avrule_write(avrule, fp); 1548 avrule = avrule->next; 1549 } 1550 1551 return POLICYDB_SUCCESS; 1552 } 1553 1554 static int only_process(ebitmap_t *in) 1555 { 1556 unsigned int i; 1557 ebitmap_node_t *node; 1558 1559 ebitmap_for_each_bit(in, node, i) { 1560 if (ebitmap_node_get_bit(node, i) && 1561 i != SECCLASS_PROCESS - 1) 1562 return 0; 1563 } 1564 return 1; 1565 } 1566 1567 static int role_trans_rule_write(policydb_t *p, role_trans_rule_t * t, 1568 struct policy_file *fp) 1569 { 1570 int nel = 0; 1571 size_t items; 1572 uint32_t buf[1]; 1573 role_trans_rule_t *tr; 1574 int warned = 0; 1575 int new_role = p->policyvers >= MOD_POLICYDB_VERSION_ROLETRANS; 1576 1577 for (tr = t; tr; tr = tr->next) 1578 if (new_role || only_process(&tr->classes)) 1579 nel++; 1580 1581 buf[0] = cpu_to_le32(nel); 1582 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1583 if (items != 1) 1584 return POLICYDB_ERROR; 1585 for (tr = t; tr; tr = tr->next) { 1586 if (!new_role && !only_process(&tr->classes)) { 1587 if (!warned) 1588 WARN(fp->handle, "Discarding role_transition " 1589 "rules for security classes other than " 1590 "\"process\""); 1591 warned = 1; 1592 continue; 1593 } 1594 if (role_set_write(&tr->roles, fp)) 1595 return POLICYDB_ERROR; 1596 if (type_set_write(&tr->types, fp)) 1597 return POLICYDB_ERROR; 1598 if (new_role) 1599 if (ebitmap_write(&tr->classes, fp)) 1600 return POLICYDB_ERROR; 1601 buf[0] = cpu_to_le32(tr->new_role); 1602 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1603 if (items != 1) 1604 return POLICYDB_ERROR; 1605 } 1606 return POLICYDB_SUCCESS; 1607 } 1608 1609 static int role_allow_rule_write(role_allow_rule_t * r, struct policy_file *fp) 1610 { 1611 int nel = 0; 1612 size_t items; 1613 uint32_t buf[1]; 1614 role_allow_rule_t *ra; 1615 1616 for (ra = r; ra; ra = ra->next) 1617 nel++; 1618 buf[0] = cpu_to_le32(nel); 1619 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1620 if (items != 1) 1621 return POLICYDB_ERROR; 1622 for (ra = r; ra; ra = ra->next) { 1623 if (role_set_write(&ra->roles, fp)) 1624 return POLICYDB_ERROR; 1625 if (role_set_write(&ra->new_roles, fp)) 1626 return POLICYDB_ERROR; 1627 } 1628 return POLICYDB_SUCCESS; 1629 } 1630 1631 static int filename_trans_rule_write(filename_trans_rule_t * t, struct policy_file *fp) 1632 { 1633 int nel = 0; 1634 size_t items; 1635 uint32_t buf[2], len; 1636 filename_trans_rule_t *ftr; 1637 1638 for (ftr = t; ftr; ftr = ftr->next) 1639 nel++; 1640 1641 buf[0] = cpu_to_le32(nel); 1642 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1643 if (items != 1) 1644 return POLICYDB_ERROR; 1645 1646 for (ftr = t; ftr; ftr = ftr->next) { 1647 len = strlen(ftr->name); 1648 buf[0] = cpu_to_le32(len); 1649 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1650 if (items != 1) 1651 return POLICYDB_ERROR; 1652 1653 items = put_entry(ftr->name, sizeof(char), len, fp); 1654 if (items != len) 1655 return POLICYDB_ERROR; 1656 1657 if (type_set_write(&ftr->stypes, fp)) 1658 return POLICYDB_ERROR; 1659 if (type_set_write(&ftr->ttypes, fp)) 1660 return POLICYDB_ERROR; 1661 1662 buf[0] = cpu_to_le32(ftr->tclass); 1663 buf[1] = cpu_to_le32(ftr->otype); 1664 1665 items = put_entry(buf, sizeof(uint32_t), 2, fp); 1666 if (items != 2) 1667 return POLICYDB_ERROR; 1668 } 1669 return POLICYDB_SUCCESS; 1670 } 1671 1672 static int range_trans_rule_write(range_trans_rule_t * t, 1673 struct policy_file *fp) 1674 { 1675 int nel = 0; 1676 size_t items; 1677 uint32_t buf[1]; 1678 range_trans_rule_t *rt; 1679 1680 for (rt = t; rt; rt = rt->next) 1681 nel++; 1682 buf[0] = cpu_to_le32(nel); 1683 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1684 if (items != 1) 1685 return POLICYDB_ERROR; 1686 for (rt = t; rt; rt = rt->next) { 1687 if (type_set_write(&rt->stypes, fp)) 1688 return POLICYDB_ERROR; 1689 if (type_set_write(&rt->ttypes, fp)) 1690 return POLICYDB_ERROR; 1691 if (ebitmap_write(&rt->tclasses, fp)) 1692 return POLICYDB_ERROR; 1693 if (mls_write_semantic_range_helper(&rt->trange, fp)) 1694 return POLICYDB_ERROR; 1695 } 1696 return POLICYDB_SUCCESS; 1697 } 1698 1699 static int scope_index_write(scope_index_t * scope_index, 1700 unsigned int num_scope_syms, 1701 struct policy_file *fp) 1702 { 1703 unsigned int i; 1704 uint32_t buf[1]; 1705 for (i = 0; i < num_scope_syms; i++) { 1706 if (ebitmap_write(scope_index->scope + i, fp) == -1) { 1707 return POLICYDB_ERROR; 1708 } 1709 } 1710 buf[0] = cpu_to_le32(scope_index->class_perms_len); 1711 if (put_entry(buf, sizeof(uint32_t), 1, fp) != 1) { 1712 return POLICYDB_ERROR; 1713 } 1714 for (i = 0; i < scope_index->class_perms_len; i++) { 1715 if (ebitmap_write(scope_index->class_perms_map + i, fp) == -1) { 1716 return POLICYDB_ERROR; 1717 } 1718 } 1719 return POLICYDB_SUCCESS; 1720 } 1721 1722 static int avrule_decl_write(avrule_decl_t * decl, int num_scope_syms, 1723 policydb_t * p, struct policy_file *fp) 1724 { 1725 struct policy_data pd; 1726 uint32_t buf[2]; 1727 int i; 1728 buf[0] = cpu_to_le32(decl->decl_id); 1729 buf[1] = cpu_to_le32(decl->enabled); 1730 if (put_entry(buf, sizeof(uint32_t), 2, fp) != 2) { 1731 return POLICYDB_ERROR; 1732 } 1733 if (cond_write_list(p, decl->cond_list, fp) == -1 || 1734 avrule_write_list(decl->avrules, fp) == -1 || 1735 role_trans_rule_write(p, decl->role_tr_rules, fp) == -1 || 1736 role_allow_rule_write(decl->role_allow_rules, fp) == -1) { 1737 return POLICYDB_ERROR; 1738 } 1739 1740 if (p->policyvers >= MOD_POLICYDB_VERSION_FILENAME_TRANS && 1741 filename_trans_rule_write(decl->filename_trans_rules, fp)) 1742 return POLICYDB_ERROR; 1743 1744 if (p->policyvers >= MOD_POLICYDB_VERSION_RANGETRANS && 1745 range_trans_rule_write(decl->range_tr_rules, fp) == -1) { 1746 return POLICYDB_ERROR; 1747 } 1748 if (scope_index_write(&decl->required, num_scope_syms, fp) == -1 || 1749 scope_index_write(&decl->declared, num_scope_syms, fp) == -1) { 1750 return POLICYDB_ERROR; 1751 } 1752 pd.fp = fp; 1753 pd.p = p; 1754 for (i = 0; i < num_scope_syms; i++) { 1755 buf[0] = cpu_to_le32(decl->symtab[i].nprim); 1756 buf[1] = cpu_to_le32(decl->symtab[i].table->nel); 1757 if (put_entry(buf, sizeof(uint32_t), 2, fp) != 2) { 1758 return POLICYDB_ERROR; 1759 } 1760 if (hashtab_map(decl->symtab[i].table, write_f[i], &pd)) { 1761 return POLICYDB_ERROR; 1762 } 1763 } 1764 return POLICYDB_SUCCESS; 1765 } 1766 1767 static int avrule_block_write(avrule_block_t * block, int num_scope_syms, 1768 policydb_t * p, struct policy_file *fp) 1769 { 1770 /* first write a count of the total number of blocks */ 1771 uint32_t buf[1], num_blocks = 0; 1772 avrule_block_t *cur; 1773 for (cur = block; cur != NULL; cur = cur->next) { 1774 num_blocks++; 1775 } 1776 buf[0] = cpu_to_le32(num_blocks); 1777 if (put_entry(buf, sizeof(uint32_t), 1, fp) != 1) { 1778 return POLICYDB_ERROR; 1779 } 1780 1781 /* now write each block */ 1782 for (cur = block; cur != NULL; cur = cur->next) { 1783 uint32_t num_decls = 0; 1784 avrule_decl_t *decl; 1785 /* write a count of number of branches */ 1786 for (decl = cur->branch_list; decl != NULL; decl = decl->next) { 1787 num_decls++; 1788 } 1789 buf[0] = cpu_to_le32(num_decls); 1790 if (put_entry(buf, sizeof(uint32_t), 1, fp) != 1) { 1791 return POLICYDB_ERROR; 1792 } 1793 for (decl = cur->branch_list; decl != NULL; decl = decl->next) { 1794 if (avrule_decl_write(decl, num_scope_syms, p, fp) == 1795 -1) { 1796 return POLICYDB_ERROR; 1797 } 1798 } 1799 } 1800 return POLICYDB_SUCCESS; 1801 } 1802 1803 static int scope_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr) 1804 { 1805 scope_datum_t *scope = (scope_datum_t *) datum; 1806 struct policy_data *pd = ptr; 1807 struct policy_file *fp = pd->fp; 1808 uint32_t static_buf[32], *dyn_buf = NULL, *buf; 1809 size_t key_len = strlen(key); 1810 unsigned int items = 2 + scope->decl_ids_len, i; 1811 int rc; 1812 1813 buf = static_buf; 1814 if (items >= (sizeof(static_buf) / 4)) { 1815 /* too many things required, so dynamically create a 1816 * buffer. this would have been easier with C99's 1817 * dynamic arrays... */ 1818 rc = POLICYDB_ERROR; 1819 dyn_buf = malloc(items * sizeof(*dyn_buf)); 1820 if (!dyn_buf) 1821 goto err; 1822 buf = dyn_buf; 1823 } 1824 buf[0] = cpu_to_le32(key_len); 1825 1826 rc = POLICYDB_ERROR; 1827 if (put_entry(buf, sizeof(*buf), 1, fp) != 1 || 1828 put_entry(key, 1, key_len, fp) != key_len) 1829 goto err; 1830 buf[0] = cpu_to_le32(scope->scope); 1831 buf[1] = cpu_to_le32(scope->decl_ids_len); 1832 1833 for (i = 0; i < scope->decl_ids_len; i++) 1834 buf[2 + i] = cpu_to_le32(scope->decl_ids[i]); 1835 1836 rc = POLICYDB_ERROR; 1837 if (put_entry(buf, sizeof(*buf), items, fp) != items) 1838 goto err; 1839 rc = POLICYDB_SUCCESS; 1840 err: 1841 free(dyn_buf); 1842 return rc; 1843 } 1844 1845 static int type_attr_uncount(hashtab_key_t key __attribute__ ((unused)), 1846 hashtab_datum_t datum, void *args) 1847 { 1848 type_datum_t *typdatum = datum; 1849 uint32_t *p_nel = args; 1850 1851 if (typdatum->flavor == TYPE_ATTRIB) { 1852 /* uncount attribute from total number of types */ 1853 (*p_nel)--; 1854 } 1855 return 0; 1856 } 1857 1858 static int role_attr_uncount(hashtab_key_t key __attribute__ ((unused)), 1859 hashtab_datum_t datum, void *args) 1860 { 1861 role_datum_t *role = datum; 1862 uint32_t *p_nel = args; 1863 1864 if (role->flavor == ROLE_ATTRIB) { 1865 /* uncount attribute from total number of roles */ 1866 (*p_nel)--; 1867 } 1868 return 0; 1869 } 1870 1871 /* 1872 * Write the configuration data in a policy database 1873 * structure to a policy database binary representation 1874 * file. 1875 */ 1876 int policydb_write(policydb_t * p, struct policy_file *fp) 1877 { 1878 unsigned int i, num_syms; 1879 uint32_t buf[32], config; 1880 size_t items, items2, len; 1881 struct policydb_compat_info *info; 1882 struct policy_data pd; 1883 char *policydb_str; 1884 1885 if (p->unsupported_format) 1886 return POLICYDB_UNSUPPORTED; 1887 1888 pd.fp = fp; 1889 pd.p = p; 1890 1891 config = 0; 1892 if (p->mls) { 1893 if ((p->policyvers < POLICYDB_VERSION_MLS && 1894 p->policy_type == POLICY_KERN) || 1895 (p->policyvers < MOD_POLICYDB_VERSION_MLS && 1896 p->policy_type == POLICY_BASE) || 1897 (p->policyvers < MOD_POLICYDB_VERSION_MLS && 1898 p->policy_type == POLICY_MOD)) { 1899 ERR(fp->handle, "policy version %d cannot support MLS", 1900 p->policyvers); 1901 return POLICYDB_ERROR; 1902 } 1903 config |= POLICYDB_CONFIG_MLS; 1904 } 1905 1906 config |= (POLICYDB_CONFIG_UNKNOWN_MASK & p->handle_unknown); 1907 1908 /* Write the magic number and string identifiers. */ 1909 items = 0; 1910 if (p->policy_type == POLICY_KERN) { 1911 buf[items++] = cpu_to_le32(POLICYDB_MAGIC); 1912 len = strlen(policydb_target_strings[p->target_platform]); 1913 policydb_str = policydb_target_strings[p->target_platform]; 1914 } else { 1915 buf[items++] = cpu_to_le32(POLICYDB_MOD_MAGIC); 1916 len = strlen(POLICYDB_MOD_STRING); 1917 policydb_str = POLICYDB_MOD_STRING; 1918 } 1919 buf[items++] = cpu_to_le32(len); 1920 items2 = put_entry(buf, sizeof(uint32_t), items, fp); 1921 if (items != items2) 1922 return POLICYDB_ERROR; 1923 items = put_entry(policydb_str, 1, len, fp); 1924 if (items != len) 1925 return POLICYDB_ERROR; 1926 1927 /* Write the version, config, and table sizes. */ 1928 items = 0; 1929 info = policydb_lookup_compat(p->policyvers, p->policy_type, 1930 p->target_platform); 1931 if (!info) { 1932 ERR(fp->handle, "compatibility lookup failed for policy " 1933 "version %d", p->policyvers); 1934 return POLICYDB_ERROR; 1935 } 1936 1937 if (p->policy_type != POLICY_KERN) { 1938 buf[items++] = cpu_to_le32(p->policy_type); 1939 } 1940 buf[items++] = cpu_to_le32(p->policyvers); 1941 buf[items++] = cpu_to_le32(config); 1942 buf[items++] = cpu_to_le32(info->sym_num); 1943 buf[items++] = cpu_to_le32(info->ocon_num); 1944 1945 items2 = put_entry(buf, sizeof(uint32_t), items, fp); 1946 if (items != items2) 1947 return POLICYDB_ERROR; 1948 1949 if (p->policy_type == POLICY_MOD) { 1950 /* Write module name and version */ 1951 len = strlen(p->name); 1952 buf[0] = cpu_to_le32(len); 1953 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1954 if (items != 1) 1955 return POLICYDB_ERROR; 1956 items = put_entry(p->name, 1, len, fp); 1957 if (items != len) 1958 return POLICYDB_ERROR; 1959 len = strlen(p->version); 1960 buf[0] = cpu_to_le32(len); 1961 items = put_entry(buf, sizeof(uint32_t), 1, fp); 1962 if (items != 1) 1963 return POLICYDB_ERROR; 1964 items = put_entry(p->version, 1, len, fp); 1965 if (items != len) 1966 return POLICYDB_ERROR; 1967 } 1968 1969 if ((p->policyvers >= POLICYDB_VERSION_POLCAP && 1970 p->policy_type == POLICY_KERN) || 1971 (p->policyvers >= MOD_POLICYDB_VERSION_POLCAP && 1972 p->policy_type == POLICY_BASE) || 1973 (p->policyvers >= MOD_POLICYDB_VERSION_POLCAP && 1974 p->policy_type == POLICY_MOD)) { 1975 if (ebitmap_write(&p->policycaps, fp) == -1) 1976 return POLICYDB_ERROR; 1977 } 1978 1979 if (p->policyvers < POLICYDB_VERSION_PERMISSIVE && 1980 p->policy_type == POLICY_KERN) { 1981 ebitmap_node_t *tnode; 1982 1983 ebitmap_for_each_bit(&p->permissive_map, tnode, i) { 1984 if (ebitmap_node_get_bit(tnode, i)) { 1985 WARN(fp->handle, "Warning! Policy version %d cannot " 1986 "support permissive types, but some were defined", 1987 p->policyvers); 1988 break; 1989 } 1990 } 1991 } 1992 1993 if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE && 1994 p->policy_type == POLICY_KERN) { 1995 if (ebitmap_write(&p->permissive_map, fp) == -1) 1996 return POLICYDB_ERROR; 1997 } 1998 1999 num_syms = info->sym_num; 2000 for (i = 0; i < num_syms; i++) { 2001 buf[0] = cpu_to_le32(p->symtab[i].nprim); 2002 buf[1] = p->symtab[i].table->nel; 2003 2004 /* 2005 * A special case when writing type/attribute symbol table. 2006 * The kernel policy version less than 24 does not support 2007 * to load entries of attribute, so we have to re-calculate 2008 * the actual number of types except for attributes. 2009 */ 2010 if (i == SYM_TYPES && 2011 p->policyvers < POLICYDB_VERSION_BOUNDARY && 2012 p->policy_type == POLICY_KERN) { 2013 hashtab_map(p->symtab[i].table, type_attr_uncount, &buf[1]); 2014 } 2015 2016 /* 2017 * Another special case when writing role/attribute symbol 2018 * table, role attributes are redundant for policy.X, or 2019 * when the pp's version is not big enough. So deduct 2020 * their numbers from p_roles.table->nel. 2021 */ 2022 if ((i == SYM_ROLES) && 2023 ((p->policy_type == POLICY_KERN) || 2024 (p->policy_type != POLICY_KERN && 2025 p->policyvers < MOD_POLICYDB_VERSION_ROLEATTRIB))) 2026 (void)hashtab_map(p->symtab[i].table, role_attr_uncount, &buf[1]); 2027 2028 buf[1] = cpu_to_le32(buf[1]); 2029 items = put_entry(buf, sizeof(uint32_t), 2, fp); 2030 if (items != 2) 2031 return POLICYDB_ERROR; 2032 if (hashtab_map(p->symtab[i].table, write_f[i], &pd)) 2033 return POLICYDB_ERROR; 2034 } 2035 2036 if (p->policy_type == POLICY_KERN) { 2037 if (avtab_write(p, &p->te_avtab, fp)) 2038 return POLICYDB_ERROR; 2039 if (p->policyvers < POLICYDB_VERSION_BOOL) { 2040 if (p->p_bools.nprim) 2041 WARN(fp->handle, "Discarding " 2042 "booleans and conditional rules"); 2043 } else { 2044 if (cond_write_list(p, p->cond_list, fp)) 2045 return POLICYDB_ERROR; 2046 } 2047 if (role_trans_write(p, fp)) 2048 return POLICYDB_ERROR; 2049 if (role_allow_write(p->role_allow, fp)) 2050 return POLICYDB_ERROR; 2051 if (p->policyvers >= POLICYDB_VERSION_FILENAME_TRANS) { 2052 if (filename_trans_write(p->filename_trans, fp)) 2053 return POLICYDB_ERROR; 2054 } else { 2055 if (p->filename_trans) 2056 WARN(fp->handle, "Discarding filename type transition rules"); 2057 } 2058 } else { 2059 if (avrule_block_write(p->global, num_syms, p, fp) == -1) { 2060 return POLICYDB_ERROR; 2061 } 2062 2063 for (i = 0; i < num_syms; i++) { 2064 buf[0] = cpu_to_le32(p->scope[i].table->nel); 2065 if (put_entry(buf, sizeof(uint32_t), 1, fp) != 1) { 2066 return POLICYDB_ERROR; 2067 } 2068 if (hashtab_map(p->scope[i].table, scope_write, &pd)) 2069 return POLICYDB_ERROR; 2070 } 2071 } 2072 2073 if (ocontext_write(info, p, fp) == -1 || genfs_write(p, fp) == -1) { 2074 return POLICYDB_ERROR; 2075 } 2076 2077 if ((p->policyvers >= POLICYDB_VERSION_MLS 2078 && p->policy_type == POLICY_KERN) 2079 || (p->policyvers >= MOD_POLICYDB_VERSION_MLS 2080 && p->policyvers < MOD_POLICYDB_VERSION_RANGETRANS 2081 && p->policy_type == POLICY_BASE)) { 2082 if (range_write(p, fp)) { 2083 return POLICYDB_ERROR; 2084 } 2085 } 2086 2087 if (p->policy_type == POLICY_KERN 2088 && p->policyvers >= POLICYDB_VERSION_AVTAB) { 2089 for (i = 0; i < p->p_types.nprim; i++) { 2090 if (ebitmap_write(&p->type_attr_map[i], fp) == -1) 2091 return POLICYDB_ERROR; 2092 } 2093 } 2094 2095 return POLICYDB_SUCCESS; 2096 } 2097