1 /* Authors: Karl MacMillan <kmacmillan@tresys.com> 2 * Frank Mayer <mayerf@tresys.com> 3 * 4 * Copyright (C) 2003 - 2004 Tresys Technology, LLC 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, version 2. 8 */ 9 10 #include <linux/kernel.h> 11 #include <linux/errno.h> 12 #include <linux/string.h> 13 #include <linux/spinlock.h> 14 #include <linux/slab.h> 15 16 #include "security.h" 17 #include "conditional.h" 18 #include "services.h" 19 20 /* 21 * cond_evaluate_expr evaluates a conditional expr 22 * in reverse polish notation. It returns true (1), false (0), 23 * or undefined (-1). Undefined occurs when the expression 24 * exceeds the stack depth of COND_EXPR_MAXDEPTH. 25 */ 26 static int cond_evaluate_expr(struct policydb *p, struct cond_expr *expr) 27 { 28 29 struct cond_expr *cur; 30 int s[COND_EXPR_MAXDEPTH]; 31 int sp = -1; 32 33 for (cur = expr; cur; cur = cur->next) { 34 switch (cur->expr_type) { 35 case COND_BOOL: 36 if (sp == (COND_EXPR_MAXDEPTH - 1)) 37 return -1; 38 sp++; 39 s[sp] = p->bool_val_to_struct[cur->bool - 1]->state; 40 break; 41 case COND_NOT: 42 if (sp < 0) 43 return -1; 44 s[sp] = !s[sp]; 45 break; 46 case COND_OR: 47 if (sp < 1) 48 return -1; 49 sp--; 50 s[sp] |= s[sp + 1]; 51 break; 52 case COND_AND: 53 if (sp < 1) 54 return -1; 55 sp--; 56 s[sp] &= s[sp + 1]; 57 break; 58 case COND_XOR: 59 if (sp < 1) 60 return -1; 61 sp--; 62 s[sp] ^= s[sp + 1]; 63 break; 64 case COND_EQ: 65 if (sp < 1) 66 return -1; 67 sp--; 68 s[sp] = (s[sp] == s[sp + 1]); 69 break; 70 case COND_NEQ: 71 if (sp < 1) 72 return -1; 73 sp--; 74 s[sp] = (s[sp] != s[sp + 1]); 75 break; 76 default: 77 return -1; 78 } 79 } 80 return s[0]; 81 } 82 83 /* 84 * evaluate_cond_node evaluates the conditional stored in 85 * a struct cond_node and if the result is different than the 86 * current state of the node it sets the rules in the true/false 87 * list appropriately. If the result of the expression is undefined 88 * all of the rules are disabled for safety. 89 */ 90 int evaluate_cond_node(struct policydb *p, struct cond_node *node) 91 { 92 int new_state; 93 struct cond_av_list *cur; 94 95 new_state = cond_evaluate_expr(p, node->expr); 96 if (new_state != node->cur_state) { 97 node->cur_state = new_state; 98 if (new_state == -1) 99 printk(KERN_ERR "SELinux: expression result was undefined - disabling all rules.\n"); 100 /* turn the rules on or off */ 101 for (cur = node->true_list; cur; cur = cur->next) { 102 if (new_state <= 0) 103 cur->node->key.specified &= ~AVTAB_ENABLED; 104 else 105 cur->node->key.specified |= AVTAB_ENABLED; 106 } 107 108 for (cur = node->false_list; cur; cur = cur->next) { 109 /* -1 or 1 */ 110 if (new_state) 111 cur->node->key.specified &= ~AVTAB_ENABLED; 112 else 113 cur->node->key.specified |= AVTAB_ENABLED; 114 } 115 } 116 return 0; 117 } 118 119 int cond_policydb_init(struct policydb *p) 120 { 121 int rc; 122 123 p->bool_val_to_struct = NULL; 124 p->cond_list = NULL; 125 126 rc = avtab_init(&p->te_cond_avtab); 127 if (rc) 128 return rc; 129 130 return 0; 131 } 132 133 static void cond_av_list_destroy(struct cond_av_list *list) 134 { 135 struct cond_av_list *cur, *next; 136 for (cur = list; cur; cur = next) { 137 next = cur->next; 138 /* the avtab_ptr_t node is destroy by the avtab */ 139 kfree(cur); 140 } 141 } 142 143 static void cond_node_destroy(struct cond_node *node) 144 { 145 struct cond_expr *cur_expr, *next_expr; 146 147 for (cur_expr = node->expr; cur_expr; cur_expr = next_expr) { 148 next_expr = cur_expr->next; 149 kfree(cur_expr); 150 } 151 cond_av_list_destroy(node->true_list); 152 cond_av_list_destroy(node->false_list); 153 kfree(node); 154 } 155 156 static void cond_list_destroy(struct cond_node *list) 157 { 158 struct cond_node *next, *cur; 159 160 if (list == NULL) 161 return; 162 163 for (cur = list; cur; cur = next) { 164 next = cur->next; 165 cond_node_destroy(cur); 166 } 167 } 168 169 void cond_policydb_destroy(struct policydb *p) 170 { 171 kfree(p->bool_val_to_struct); 172 avtab_destroy(&p->te_cond_avtab); 173 cond_list_destroy(p->cond_list); 174 } 175 176 int cond_init_bool_indexes(struct policydb *p) 177 { 178 kfree(p->bool_val_to_struct); 179 p->bool_val_to_struct = kmalloc_array(p->p_bools.nprim, 180 sizeof(*p->bool_val_to_struct), 181 GFP_KERNEL); 182 if (!p->bool_val_to_struct) 183 return -ENOMEM; 184 return 0; 185 } 186 187 int cond_destroy_bool(void *key, void *datum, void *p) 188 { 189 kfree(key); 190 kfree(datum); 191 return 0; 192 } 193 194 int cond_index_bool(void *key, void *datum, void *datap) 195 { 196 struct policydb *p; 197 struct cond_bool_datum *booldatum; 198 struct flex_array *fa; 199 200 booldatum = datum; 201 p = datap; 202 203 if (!booldatum->value || booldatum->value > p->p_bools.nprim) 204 return -EINVAL; 205 206 fa = p->sym_val_to_name[SYM_BOOLS]; 207 if (flex_array_put_ptr(fa, booldatum->value - 1, key, 208 GFP_KERNEL | __GFP_ZERO)) 209 BUG(); 210 p->bool_val_to_struct[booldatum->value - 1] = booldatum; 211 212 return 0; 213 } 214 215 static int bool_isvalid(struct cond_bool_datum *b) 216 { 217 if (!(b->state == 0 || b->state == 1)) 218 return 0; 219 return 1; 220 } 221 222 int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp) 223 { 224 char *key = NULL; 225 struct cond_bool_datum *booldatum; 226 __le32 buf[3]; 227 u32 len; 228 int rc; 229 230 booldatum = kzalloc(sizeof(*booldatum), GFP_KERNEL); 231 if (!booldatum) 232 return -ENOMEM; 233 234 rc = next_entry(buf, fp, sizeof buf); 235 if (rc) 236 goto err; 237 238 booldatum->value = le32_to_cpu(buf[0]); 239 booldatum->state = le32_to_cpu(buf[1]); 240 241 rc = -EINVAL; 242 if (!bool_isvalid(booldatum)) 243 goto err; 244 245 len = le32_to_cpu(buf[2]); 246 if (((len == 0) || (len == (u32)-1))) 247 goto err; 248 249 rc = -ENOMEM; 250 key = kmalloc(len + 1, GFP_KERNEL); 251 if (!key) 252 goto err; 253 rc = next_entry(key, fp, len); 254 if (rc) 255 goto err; 256 key[len] = '\0'; 257 rc = hashtab_insert(h, key, booldatum); 258 if (rc) 259 goto err; 260 261 return 0; 262 err: 263 cond_destroy_bool(key, booldatum, NULL); 264 return rc; 265 } 266 267 struct cond_insertf_data { 268 struct policydb *p; 269 struct cond_av_list *other; 270 struct cond_av_list *head; 271 struct cond_av_list *tail; 272 }; 273 274 static int cond_insertf(struct avtab *a, struct avtab_key *k, struct avtab_datum *d, void *ptr) 275 { 276 struct cond_insertf_data *data = ptr; 277 struct policydb *p = data->p; 278 struct cond_av_list *other = data->other, *list, *cur; 279 struct avtab_node *node_ptr; 280 u8 found; 281 int rc = -EINVAL; 282 283 /* 284 * For type rules we have to make certain there aren't any 285 * conflicting rules by searching the te_avtab and the 286 * cond_te_avtab. 287 */ 288 if (k->specified & AVTAB_TYPE) { 289 if (avtab_search(&p->te_avtab, k)) { 290 printk(KERN_ERR "SELinux: type rule already exists outside of a conditional.\n"); 291 goto err; 292 } 293 /* 294 * If we are reading the false list other will be a pointer to 295 * the true list. We can have duplicate entries if there is only 296 * 1 other entry and it is in our true list. 297 * 298 * If we are reading the true list (other == NULL) there shouldn't 299 * be any other entries. 300 */ 301 if (other) { 302 node_ptr = avtab_search_node(&p->te_cond_avtab, k); 303 if (node_ptr) { 304 if (avtab_search_node_next(node_ptr, k->specified)) { 305 printk(KERN_ERR "SELinux: too many conflicting type rules.\n"); 306 goto err; 307 } 308 found = 0; 309 for (cur = other; cur; cur = cur->next) { 310 if (cur->node == node_ptr) { 311 found = 1; 312 break; 313 } 314 } 315 if (!found) { 316 printk(KERN_ERR "SELinux: conflicting type rules.\n"); 317 goto err; 318 } 319 } 320 } else { 321 if (avtab_search(&p->te_cond_avtab, k)) { 322 printk(KERN_ERR "SELinux: conflicting type rules when adding type rule for true.\n"); 323 goto err; 324 } 325 } 326 } 327 328 node_ptr = avtab_insert_nonunique(&p->te_cond_avtab, k, d); 329 if (!node_ptr) { 330 printk(KERN_ERR "SELinux: could not insert rule.\n"); 331 rc = -ENOMEM; 332 goto err; 333 } 334 335 list = kzalloc(sizeof(*list), GFP_KERNEL); 336 if (!list) { 337 rc = -ENOMEM; 338 goto err; 339 } 340 341 list->node = node_ptr; 342 if (!data->head) 343 data->head = list; 344 else 345 data->tail->next = list; 346 data->tail = list; 347 return 0; 348 349 err: 350 cond_av_list_destroy(data->head); 351 data->head = NULL; 352 return rc; 353 } 354 355 static int cond_read_av_list(struct policydb *p, void *fp, struct cond_av_list **ret_list, struct cond_av_list *other) 356 { 357 int i, rc; 358 __le32 buf[1]; 359 u32 len; 360 struct cond_insertf_data data; 361 362 *ret_list = NULL; 363 364 len = 0; 365 rc = next_entry(buf, fp, sizeof(u32)); 366 if (rc) 367 return rc; 368 369 len = le32_to_cpu(buf[0]); 370 if (len == 0) 371 return 0; 372 373 data.p = p; 374 data.other = other; 375 data.head = NULL; 376 data.tail = NULL; 377 for (i = 0; i < len; i++) { 378 rc = avtab_read_item(&p->te_cond_avtab, fp, p, cond_insertf, 379 &data); 380 if (rc) 381 return rc; 382 } 383 384 *ret_list = data.head; 385 return 0; 386 } 387 388 static int expr_isvalid(struct policydb *p, struct cond_expr *expr) 389 { 390 if (expr->expr_type <= 0 || expr->expr_type > COND_LAST) { 391 printk(KERN_ERR "SELinux: conditional expressions uses unknown operator.\n"); 392 return 0; 393 } 394 395 if (expr->bool > p->p_bools.nprim) { 396 printk(KERN_ERR "SELinux: conditional expressions uses unknown bool.\n"); 397 return 0; 398 } 399 return 1; 400 } 401 402 static int cond_read_node(struct policydb *p, struct cond_node *node, void *fp) 403 { 404 __le32 buf[2]; 405 u32 len, i; 406 int rc; 407 struct cond_expr *expr = NULL, *last = NULL; 408 409 rc = next_entry(buf, fp, sizeof(u32) * 2); 410 if (rc) 411 goto err; 412 413 node->cur_state = le32_to_cpu(buf[0]); 414 415 /* expr */ 416 len = le32_to_cpu(buf[1]); 417 418 for (i = 0; i < len; i++) { 419 rc = next_entry(buf, fp, sizeof(u32) * 2); 420 if (rc) 421 goto err; 422 423 rc = -ENOMEM; 424 expr = kzalloc(sizeof(*expr), GFP_KERNEL); 425 if (!expr) 426 goto err; 427 428 expr->expr_type = le32_to_cpu(buf[0]); 429 expr->bool = le32_to_cpu(buf[1]); 430 431 if (!expr_isvalid(p, expr)) { 432 rc = -EINVAL; 433 kfree(expr); 434 goto err; 435 } 436 437 if (i == 0) 438 node->expr = expr; 439 else 440 last->next = expr; 441 last = expr; 442 } 443 444 rc = cond_read_av_list(p, fp, &node->true_list, NULL); 445 if (rc) 446 goto err; 447 rc = cond_read_av_list(p, fp, &node->false_list, node->true_list); 448 if (rc) 449 goto err; 450 return 0; 451 err: 452 cond_node_destroy(node); 453 return rc; 454 } 455 456 int cond_read_list(struct policydb *p, void *fp) 457 { 458 struct cond_node *node, *last = NULL; 459 __le32 buf[1]; 460 u32 i, len; 461 int rc; 462 463 rc = next_entry(buf, fp, sizeof buf); 464 if (rc) 465 return rc; 466 467 len = le32_to_cpu(buf[0]); 468 469 rc = avtab_alloc(&(p->te_cond_avtab), p->te_avtab.nel); 470 if (rc) 471 goto err; 472 473 for (i = 0; i < len; i++) { 474 rc = -ENOMEM; 475 node = kzalloc(sizeof(*node), GFP_KERNEL); 476 if (!node) 477 goto err; 478 479 rc = cond_read_node(p, node, fp); 480 if (rc) 481 goto err; 482 483 if (i == 0) 484 p->cond_list = node; 485 else 486 last->next = node; 487 last = node; 488 } 489 return 0; 490 err: 491 cond_list_destroy(p->cond_list); 492 p->cond_list = NULL; 493 return rc; 494 } 495 496 int cond_write_bool(void *vkey, void *datum, void *ptr) 497 { 498 char *key = vkey; 499 struct cond_bool_datum *booldatum = datum; 500 struct policy_data *pd = ptr; 501 void *fp = pd->fp; 502 __le32 buf[3]; 503 u32 len; 504 int rc; 505 506 len = strlen(key); 507 buf[0] = cpu_to_le32(booldatum->value); 508 buf[1] = cpu_to_le32(booldatum->state); 509 buf[2] = cpu_to_le32(len); 510 rc = put_entry(buf, sizeof(u32), 3, fp); 511 if (rc) 512 return rc; 513 rc = put_entry(key, 1, len, fp); 514 if (rc) 515 return rc; 516 return 0; 517 } 518 519 /* 520 * cond_write_cond_av_list doesn't write out the av_list nodes. 521 * Instead it writes out the key/value pairs from the avtab. This 522 * is necessary because there is no way to uniquely identifying rules 523 * in the avtab so it is not possible to associate individual rules 524 * in the avtab with a conditional without saving them as part of 525 * the conditional. This means that the avtab with the conditional 526 * rules will not be saved but will be rebuilt on policy load. 527 */ 528 static int cond_write_av_list(struct policydb *p, 529 struct cond_av_list *list, struct policy_file *fp) 530 { 531 __le32 buf[1]; 532 struct cond_av_list *cur_list; 533 u32 len; 534 int rc; 535 536 len = 0; 537 for (cur_list = list; cur_list != NULL; cur_list = cur_list->next) 538 len++; 539 540 buf[0] = cpu_to_le32(len); 541 rc = put_entry(buf, sizeof(u32), 1, fp); 542 if (rc) 543 return rc; 544 545 if (len == 0) 546 return 0; 547 548 for (cur_list = list; cur_list != NULL; cur_list = cur_list->next) { 549 rc = avtab_write_item(p, cur_list->node, fp); 550 if (rc) 551 return rc; 552 } 553 554 return 0; 555 } 556 557 static int cond_write_node(struct policydb *p, struct cond_node *node, 558 struct policy_file *fp) 559 { 560 struct cond_expr *cur_expr; 561 __le32 buf[2]; 562 int rc; 563 u32 len = 0; 564 565 buf[0] = cpu_to_le32(node->cur_state); 566 rc = put_entry(buf, sizeof(u32), 1, fp); 567 if (rc) 568 return rc; 569 570 for (cur_expr = node->expr; cur_expr != NULL; cur_expr = cur_expr->next) 571 len++; 572 573 buf[0] = cpu_to_le32(len); 574 rc = put_entry(buf, sizeof(u32), 1, fp); 575 if (rc) 576 return rc; 577 578 for (cur_expr = node->expr; cur_expr != NULL; cur_expr = cur_expr->next) { 579 buf[0] = cpu_to_le32(cur_expr->expr_type); 580 buf[1] = cpu_to_le32(cur_expr->bool); 581 rc = put_entry(buf, sizeof(u32), 2, fp); 582 if (rc) 583 return rc; 584 } 585 586 rc = cond_write_av_list(p, node->true_list, fp); 587 if (rc) 588 return rc; 589 rc = cond_write_av_list(p, node->false_list, fp); 590 if (rc) 591 return rc; 592 593 return 0; 594 } 595 596 int cond_write_list(struct policydb *p, struct cond_node *list, void *fp) 597 { 598 struct cond_node *cur; 599 u32 len; 600 __le32 buf[1]; 601 int rc; 602 603 len = 0; 604 for (cur = list; cur != NULL; cur = cur->next) 605 len++; 606 buf[0] = cpu_to_le32(len); 607 rc = put_entry(buf, sizeof(u32), 1, fp); 608 if (rc) 609 return rc; 610 611 for (cur = list; cur != NULL; cur = cur->next) { 612 rc = cond_write_node(p, cur, fp); 613 if (rc) 614 return rc; 615 } 616 617 return 0; 618 } 619 620 void cond_compute_xperms(struct avtab *ctab, struct avtab_key *key, 621 struct extended_perms_decision *xpermd) 622 { 623 struct avtab_node *node; 624 625 if (!ctab || !key || !xpermd) 626 return; 627 628 for (node = avtab_search_node(ctab, key); node; 629 node = avtab_search_node_next(node, key->specified)) { 630 if (node->key.specified & AVTAB_ENABLED) 631 services_compute_xperms_decision(xpermd, node); 632 } 633 return; 634 635 } 636 /* Determine whether additional permissions are granted by the conditional 637 * av table, and if so, add them to the result 638 */ 639 void cond_compute_av(struct avtab *ctab, struct avtab_key *key, 640 struct av_decision *avd, struct extended_perms *xperms) 641 { 642 struct avtab_node *node; 643 644 if (!ctab || !key || !avd) 645 return; 646 647 for (node = avtab_search_node(ctab, key); node; 648 node = avtab_search_node_next(node, key->specified)) { 649 if ((u16)(AVTAB_ALLOWED|AVTAB_ENABLED) == 650 (node->key.specified & (AVTAB_ALLOWED|AVTAB_ENABLED))) 651 avd->allowed |= node->datum.u.data; 652 if ((u16)(AVTAB_AUDITDENY|AVTAB_ENABLED) == 653 (node->key.specified & (AVTAB_AUDITDENY|AVTAB_ENABLED))) 654 /* Since a '0' in an auditdeny mask represents a 655 * permission we do NOT want to audit (dontaudit), we use 656 * the '&' operand to ensure that all '0's in the mask 657 * are retained (much unlike the allow and auditallow cases). 658 */ 659 avd->auditdeny &= node->datum.u.data; 660 if ((u16)(AVTAB_AUDITALLOW|AVTAB_ENABLED) == 661 (node->key.specified & (AVTAB_AUDITALLOW|AVTAB_ENABLED))) 662 avd->auditallow |= node->datum.u.data; 663 if (xperms && (node->key.specified & AVTAB_ENABLED) && 664 (node->key.specified & AVTAB_XPERMS)) 665 services_compute_xperms_drivers(xperms, node); 666 } 667 } 668