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