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