services.c revision 23970741720360de9dd0a4e87fbeb1d5927aa474
1/* 2 * Implementation of the security services. 3 * 4 * Authors : Stephen Smalley, <sds@epoch.ncsc.mil> 5 * James Morris <jmorris@redhat.com> 6 * 7 * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com> 8 * 9 * Support for enhanced MLS infrastructure. 10 * Support for context based audit filters. 11 * 12 * Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com> 13 * 14 * Added conditional policy language extensions 15 * 16 * Updated: Hewlett-Packard <paul.moore@hp.com> 17 * 18 * Added support for NetLabel 19 * 20 * Copyright (C) 2006 Hewlett-Packard Development Company, L.P. 21 * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. 22 * Copyright (C) 2003 - 2004 Tresys Technology, LLC 23 * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> 24 * This program is free software; you can redistribute it and/or modify 25 * it under the terms of the GNU General Public License as published by 26 * the Free Software Foundation, version 2. 27 */ 28#include <linux/kernel.h> 29#include <linux/slab.h> 30#include <linux/string.h> 31#include <linux/spinlock.h> 32#include <linux/errno.h> 33#include <linux/in.h> 34#include <linux/sched.h> 35#include <linux/audit.h> 36#include <linux/mutex.h> 37#include <net/sock.h> 38#include <net/netlabel.h> 39 40#include "flask.h" 41#include "avc.h" 42#include "avc_ss.h" 43#include "security.h" 44#include "context.h" 45#include "policydb.h" 46#include "sidtab.h" 47#include "services.h" 48#include "conditional.h" 49#include "mls.h" 50#include "objsec.h" 51#include "selinux_netlabel.h" 52 53extern void selnl_notify_policyload(u32 seqno); 54unsigned int policydb_loaded_version; 55 56static DEFINE_RWLOCK(policy_rwlock); 57#define POLICY_RDLOCK read_lock(&policy_rwlock) 58#define POLICY_WRLOCK write_lock_irq(&policy_rwlock) 59#define POLICY_RDUNLOCK read_unlock(&policy_rwlock) 60#define POLICY_WRUNLOCK write_unlock_irq(&policy_rwlock) 61 62static DEFINE_MUTEX(load_mutex); 63#define LOAD_LOCK mutex_lock(&load_mutex) 64#define LOAD_UNLOCK mutex_unlock(&load_mutex) 65 66static struct sidtab sidtab; 67struct policydb policydb; 68int ss_initialized = 0; 69 70/* 71 * The largest sequence number that has been used when 72 * providing an access decision to the access vector cache. 73 * The sequence number only changes when a policy change 74 * occurs. 75 */ 76static u32 latest_granting = 0; 77 78/* Forward declaration. */ 79static int context_struct_to_string(struct context *context, char **scontext, 80 u32 *scontext_len); 81 82/* 83 * Return the boolean value of a constraint expression 84 * when it is applied to the specified source and target 85 * security contexts. 86 * 87 * xcontext is a special beast... It is used by the validatetrans rules 88 * only. For these rules, scontext is the context before the transition, 89 * tcontext is the context after the transition, and xcontext is the context 90 * of the process performing the transition. All other callers of 91 * constraint_expr_eval should pass in NULL for xcontext. 92 */ 93static int constraint_expr_eval(struct context *scontext, 94 struct context *tcontext, 95 struct context *xcontext, 96 struct constraint_expr *cexpr) 97{ 98 u32 val1, val2; 99 struct context *c; 100 struct role_datum *r1, *r2; 101 struct mls_level *l1, *l2; 102 struct constraint_expr *e; 103 int s[CEXPR_MAXDEPTH]; 104 int sp = -1; 105 106 for (e = cexpr; e; e = e->next) { 107 switch (e->expr_type) { 108 case CEXPR_NOT: 109 BUG_ON(sp < 0); 110 s[sp] = !s[sp]; 111 break; 112 case CEXPR_AND: 113 BUG_ON(sp < 1); 114 sp--; 115 s[sp] &= s[sp+1]; 116 break; 117 case CEXPR_OR: 118 BUG_ON(sp < 1); 119 sp--; 120 s[sp] |= s[sp+1]; 121 break; 122 case CEXPR_ATTR: 123 if (sp == (CEXPR_MAXDEPTH-1)) 124 return 0; 125 switch (e->attr) { 126 case CEXPR_USER: 127 val1 = scontext->user; 128 val2 = tcontext->user; 129 break; 130 case CEXPR_TYPE: 131 val1 = scontext->type; 132 val2 = tcontext->type; 133 break; 134 case CEXPR_ROLE: 135 val1 = scontext->role; 136 val2 = tcontext->role; 137 r1 = policydb.role_val_to_struct[val1 - 1]; 138 r2 = policydb.role_val_to_struct[val2 - 1]; 139 switch (e->op) { 140 case CEXPR_DOM: 141 s[++sp] = ebitmap_get_bit(&r1->dominates, 142 val2 - 1); 143 continue; 144 case CEXPR_DOMBY: 145 s[++sp] = ebitmap_get_bit(&r2->dominates, 146 val1 - 1); 147 continue; 148 case CEXPR_INCOMP: 149 s[++sp] = ( !ebitmap_get_bit(&r1->dominates, 150 val2 - 1) && 151 !ebitmap_get_bit(&r2->dominates, 152 val1 - 1) ); 153 continue; 154 default: 155 break; 156 } 157 break; 158 case CEXPR_L1L2: 159 l1 = &(scontext->range.level[0]); 160 l2 = &(tcontext->range.level[0]); 161 goto mls_ops; 162 case CEXPR_L1H2: 163 l1 = &(scontext->range.level[0]); 164 l2 = &(tcontext->range.level[1]); 165 goto mls_ops; 166 case CEXPR_H1L2: 167 l1 = &(scontext->range.level[1]); 168 l2 = &(tcontext->range.level[0]); 169 goto mls_ops; 170 case CEXPR_H1H2: 171 l1 = &(scontext->range.level[1]); 172 l2 = &(tcontext->range.level[1]); 173 goto mls_ops; 174 case CEXPR_L1H1: 175 l1 = &(scontext->range.level[0]); 176 l2 = &(scontext->range.level[1]); 177 goto mls_ops; 178 case CEXPR_L2H2: 179 l1 = &(tcontext->range.level[0]); 180 l2 = &(tcontext->range.level[1]); 181 goto mls_ops; 182mls_ops: 183 switch (e->op) { 184 case CEXPR_EQ: 185 s[++sp] = mls_level_eq(l1, l2); 186 continue; 187 case CEXPR_NEQ: 188 s[++sp] = !mls_level_eq(l1, l2); 189 continue; 190 case CEXPR_DOM: 191 s[++sp] = mls_level_dom(l1, l2); 192 continue; 193 case CEXPR_DOMBY: 194 s[++sp] = mls_level_dom(l2, l1); 195 continue; 196 case CEXPR_INCOMP: 197 s[++sp] = mls_level_incomp(l2, l1); 198 continue; 199 default: 200 BUG(); 201 return 0; 202 } 203 break; 204 default: 205 BUG(); 206 return 0; 207 } 208 209 switch (e->op) { 210 case CEXPR_EQ: 211 s[++sp] = (val1 == val2); 212 break; 213 case CEXPR_NEQ: 214 s[++sp] = (val1 != val2); 215 break; 216 default: 217 BUG(); 218 return 0; 219 } 220 break; 221 case CEXPR_NAMES: 222 if (sp == (CEXPR_MAXDEPTH-1)) 223 return 0; 224 c = scontext; 225 if (e->attr & CEXPR_TARGET) 226 c = tcontext; 227 else if (e->attr & CEXPR_XTARGET) { 228 c = xcontext; 229 if (!c) { 230 BUG(); 231 return 0; 232 } 233 } 234 if (e->attr & CEXPR_USER) 235 val1 = c->user; 236 else if (e->attr & CEXPR_ROLE) 237 val1 = c->role; 238 else if (e->attr & CEXPR_TYPE) 239 val1 = c->type; 240 else { 241 BUG(); 242 return 0; 243 } 244 245 switch (e->op) { 246 case CEXPR_EQ: 247 s[++sp] = ebitmap_get_bit(&e->names, val1 - 1); 248 break; 249 case CEXPR_NEQ: 250 s[++sp] = !ebitmap_get_bit(&e->names, val1 - 1); 251 break; 252 default: 253 BUG(); 254 return 0; 255 } 256 break; 257 default: 258 BUG(); 259 return 0; 260 } 261 } 262 263 BUG_ON(sp != 0); 264 return s[0]; 265} 266 267/* 268 * Compute access vectors based on a context structure pair for 269 * the permissions in a particular class. 270 */ 271static int context_struct_compute_av(struct context *scontext, 272 struct context *tcontext, 273 u16 tclass, 274 u32 requested, 275 struct av_decision *avd) 276{ 277 struct constraint_node *constraint; 278 struct role_allow *ra; 279 struct avtab_key avkey; 280 struct avtab_node *node; 281 struct class_datum *tclass_datum; 282 struct ebitmap *sattr, *tattr; 283 struct ebitmap_node *snode, *tnode; 284 unsigned int i, j; 285 286 /* 287 * Remap extended Netlink classes for old policy versions. 288 * Do this here rather than socket_type_to_security_class() 289 * in case a newer policy version is loaded, allowing sockets 290 * to remain in the correct class. 291 */ 292 if (policydb_loaded_version < POLICYDB_VERSION_NLCLASS) 293 if (tclass >= SECCLASS_NETLINK_ROUTE_SOCKET && 294 tclass <= SECCLASS_NETLINK_DNRT_SOCKET) 295 tclass = SECCLASS_NETLINK_SOCKET; 296 297 if (!tclass || tclass > policydb.p_classes.nprim) { 298 printk(KERN_ERR "security_compute_av: unrecognized class %d\n", 299 tclass); 300 return -EINVAL; 301 } 302 tclass_datum = policydb.class_val_to_struct[tclass - 1]; 303 304 /* 305 * Initialize the access vectors to the default values. 306 */ 307 avd->allowed = 0; 308 avd->decided = 0xffffffff; 309 avd->auditallow = 0; 310 avd->auditdeny = 0xffffffff; 311 avd->seqno = latest_granting; 312 313 /* 314 * If a specific type enforcement rule was defined for 315 * this permission check, then use it. 316 */ 317 avkey.target_class = tclass; 318 avkey.specified = AVTAB_AV; 319 sattr = &policydb.type_attr_map[scontext->type - 1]; 320 tattr = &policydb.type_attr_map[tcontext->type - 1]; 321 ebitmap_for_each_bit(sattr, snode, i) { 322 if (!ebitmap_node_get_bit(snode, i)) 323 continue; 324 ebitmap_for_each_bit(tattr, tnode, j) { 325 if (!ebitmap_node_get_bit(tnode, j)) 326 continue; 327 avkey.source_type = i + 1; 328 avkey.target_type = j + 1; 329 for (node = avtab_search_node(&policydb.te_avtab, &avkey); 330 node != NULL; 331 node = avtab_search_node_next(node, avkey.specified)) { 332 if (node->key.specified == AVTAB_ALLOWED) 333 avd->allowed |= node->datum.data; 334 else if (node->key.specified == AVTAB_AUDITALLOW) 335 avd->auditallow |= node->datum.data; 336 else if (node->key.specified == AVTAB_AUDITDENY) 337 avd->auditdeny &= node->datum.data; 338 } 339 340 /* Check conditional av table for additional permissions */ 341 cond_compute_av(&policydb.te_cond_avtab, &avkey, avd); 342 343 } 344 } 345 346 /* 347 * Remove any permissions prohibited by a constraint (this includes 348 * the MLS policy). 349 */ 350 constraint = tclass_datum->constraints; 351 while (constraint) { 352 if ((constraint->permissions & (avd->allowed)) && 353 !constraint_expr_eval(scontext, tcontext, NULL, 354 constraint->expr)) { 355 avd->allowed = (avd->allowed) & ~(constraint->permissions); 356 } 357 constraint = constraint->next; 358 } 359 360 /* 361 * If checking process transition permission and the 362 * role is changing, then check the (current_role, new_role) 363 * pair. 364 */ 365 if (tclass == SECCLASS_PROCESS && 366 (avd->allowed & (PROCESS__TRANSITION | PROCESS__DYNTRANSITION)) && 367 scontext->role != tcontext->role) { 368 for (ra = policydb.role_allow; ra; ra = ra->next) { 369 if (scontext->role == ra->role && 370 tcontext->role == ra->new_role) 371 break; 372 } 373 if (!ra) 374 avd->allowed = (avd->allowed) & ~(PROCESS__TRANSITION | 375 PROCESS__DYNTRANSITION); 376 } 377 378 return 0; 379} 380 381static int security_validtrans_handle_fail(struct context *ocontext, 382 struct context *ncontext, 383 struct context *tcontext, 384 u16 tclass) 385{ 386 char *o = NULL, *n = NULL, *t = NULL; 387 u32 olen, nlen, tlen; 388 389 if (context_struct_to_string(ocontext, &o, &olen) < 0) 390 goto out; 391 if (context_struct_to_string(ncontext, &n, &nlen) < 0) 392 goto out; 393 if (context_struct_to_string(tcontext, &t, &tlen) < 0) 394 goto out; 395 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, 396 "security_validate_transition: denied for" 397 " oldcontext=%s newcontext=%s taskcontext=%s tclass=%s", 398 o, n, t, policydb.p_class_val_to_name[tclass-1]); 399out: 400 kfree(o); 401 kfree(n); 402 kfree(t); 403 404 if (!selinux_enforcing) 405 return 0; 406 return -EPERM; 407} 408 409int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, 410 u16 tclass) 411{ 412 struct context *ocontext; 413 struct context *ncontext; 414 struct context *tcontext; 415 struct class_datum *tclass_datum; 416 struct constraint_node *constraint; 417 int rc = 0; 418 419 if (!ss_initialized) 420 return 0; 421 422 POLICY_RDLOCK; 423 424 /* 425 * Remap extended Netlink classes for old policy versions. 426 * Do this here rather than socket_type_to_security_class() 427 * in case a newer policy version is loaded, allowing sockets 428 * to remain in the correct class. 429 */ 430 if (policydb_loaded_version < POLICYDB_VERSION_NLCLASS) 431 if (tclass >= SECCLASS_NETLINK_ROUTE_SOCKET && 432 tclass <= SECCLASS_NETLINK_DNRT_SOCKET) 433 tclass = SECCLASS_NETLINK_SOCKET; 434 435 if (!tclass || tclass > policydb.p_classes.nprim) { 436 printk(KERN_ERR "security_validate_transition: " 437 "unrecognized class %d\n", tclass); 438 rc = -EINVAL; 439 goto out; 440 } 441 tclass_datum = policydb.class_val_to_struct[tclass - 1]; 442 443 ocontext = sidtab_search(&sidtab, oldsid); 444 if (!ocontext) { 445 printk(KERN_ERR "security_validate_transition: " 446 " unrecognized SID %d\n", oldsid); 447 rc = -EINVAL; 448 goto out; 449 } 450 451 ncontext = sidtab_search(&sidtab, newsid); 452 if (!ncontext) { 453 printk(KERN_ERR "security_validate_transition: " 454 " unrecognized SID %d\n", newsid); 455 rc = -EINVAL; 456 goto out; 457 } 458 459 tcontext = sidtab_search(&sidtab, tasksid); 460 if (!tcontext) { 461 printk(KERN_ERR "security_validate_transition: " 462 " unrecognized SID %d\n", tasksid); 463 rc = -EINVAL; 464 goto out; 465 } 466 467 constraint = tclass_datum->validatetrans; 468 while (constraint) { 469 if (!constraint_expr_eval(ocontext, ncontext, tcontext, 470 constraint->expr)) { 471 rc = security_validtrans_handle_fail(ocontext, ncontext, 472 tcontext, tclass); 473 goto out; 474 } 475 constraint = constraint->next; 476 } 477 478out: 479 POLICY_RDUNLOCK; 480 return rc; 481} 482 483/** 484 * security_compute_av - Compute access vector decisions. 485 * @ssid: source security identifier 486 * @tsid: target security identifier 487 * @tclass: target security class 488 * @requested: requested permissions 489 * @avd: access vector decisions 490 * 491 * Compute a set of access vector decisions based on the 492 * SID pair (@ssid, @tsid) for the permissions in @tclass. 493 * Return -%EINVAL if any of the parameters are invalid or %0 494 * if the access vector decisions were computed successfully. 495 */ 496int security_compute_av(u32 ssid, 497 u32 tsid, 498 u16 tclass, 499 u32 requested, 500 struct av_decision *avd) 501{ 502 struct context *scontext = NULL, *tcontext = NULL; 503 int rc = 0; 504 505 if (!ss_initialized) { 506 avd->allowed = 0xffffffff; 507 avd->decided = 0xffffffff; 508 avd->auditallow = 0; 509 avd->auditdeny = 0xffffffff; 510 avd->seqno = latest_granting; 511 return 0; 512 } 513 514 POLICY_RDLOCK; 515 516 scontext = sidtab_search(&sidtab, ssid); 517 if (!scontext) { 518 printk(KERN_ERR "security_compute_av: unrecognized SID %d\n", 519 ssid); 520 rc = -EINVAL; 521 goto out; 522 } 523 tcontext = sidtab_search(&sidtab, tsid); 524 if (!tcontext) { 525 printk(KERN_ERR "security_compute_av: unrecognized SID %d\n", 526 tsid); 527 rc = -EINVAL; 528 goto out; 529 } 530 531 rc = context_struct_compute_av(scontext, tcontext, tclass, 532 requested, avd); 533out: 534 POLICY_RDUNLOCK; 535 return rc; 536} 537 538/* 539 * Write the security context string representation of 540 * the context structure `context' into a dynamically 541 * allocated string of the correct size. Set `*scontext' 542 * to point to this string and set `*scontext_len' to 543 * the length of the string. 544 */ 545static int context_struct_to_string(struct context *context, char **scontext, u32 *scontext_len) 546{ 547 char *scontextp; 548 549 *scontext = NULL; 550 *scontext_len = 0; 551 552 /* Compute the size of the context. */ 553 *scontext_len += strlen(policydb.p_user_val_to_name[context->user - 1]) + 1; 554 *scontext_len += strlen(policydb.p_role_val_to_name[context->role - 1]) + 1; 555 *scontext_len += strlen(policydb.p_type_val_to_name[context->type - 1]) + 1; 556 *scontext_len += mls_compute_context_len(context); 557 558 /* Allocate space for the context; caller must free this space. */ 559 scontextp = kmalloc(*scontext_len, GFP_ATOMIC); 560 if (!scontextp) { 561 return -ENOMEM; 562 } 563 *scontext = scontextp; 564 565 /* 566 * Copy the user name, role name and type name into the context. 567 */ 568 sprintf(scontextp, "%s:%s:%s", 569 policydb.p_user_val_to_name[context->user - 1], 570 policydb.p_role_val_to_name[context->role - 1], 571 policydb.p_type_val_to_name[context->type - 1]); 572 scontextp += strlen(policydb.p_user_val_to_name[context->user - 1]) + 573 1 + strlen(policydb.p_role_val_to_name[context->role - 1]) + 574 1 + strlen(policydb.p_type_val_to_name[context->type - 1]); 575 576 mls_sid_to_context(context, &scontextp); 577 578 *scontextp = 0; 579 580 return 0; 581} 582 583#include "initial_sid_to_string.h" 584 585/** 586 * security_sid_to_context - Obtain a context for a given SID. 587 * @sid: security identifier, SID 588 * @scontext: security context 589 * @scontext_len: length in bytes 590 * 591 * Write the string representation of the context associated with @sid 592 * into a dynamically allocated string of the correct size. Set @scontext 593 * to point to this string and set @scontext_len to the length of the string. 594 */ 595int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len) 596{ 597 struct context *context; 598 int rc = 0; 599 600 if (!ss_initialized) { 601 if (sid <= SECINITSID_NUM) { 602 char *scontextp; 603 604 *scontext_len = strlen(initial_sid_to_string[sid]) + 1; 605 scontextp = kmalloc(*scontext_len,GFP_ATOMIC); 606 if (!scontextp) { 607 rc = -ENOMEM; 608 goto out; 609 } 610 strcpy(scontextp, initial_sid_to_string[sid]); 611 *scontext = scontextp; 612 goto out; 613 } 614 printk(KERN_ERR "security_sid_to_context: called before initial " 615 "load_policy on unknown SID %d\n", sid); 616 rc = -EINVAL; 617 goto out; 618 } 619 POLICY_RDLOCK; 620 context = sidtab_search(&sidtab, sid); 621 if (!context) { 622 printk(KERN_ERR "security_sid_to_context: unrecognized SID " 623 "%d\n", sid); 624 rc = -EINVAL; 625 goto out_unlock; 626 } 627 rc = context_struct_to_string(context, scontext, scontext_len); 628out_unlock: 629 POLICY_RDUNLOCK; 630out: 631 return rc; 632 633} 634 635static int security_context_to_sid_core(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid) 636{ 637 char *scontext2; 638 struct context context; 639 struct role_datum *role; 640 struct type_datum *typdatum; 641 struct user_datum *usrdatum; 642 char *scontextp, *p, oldc; 643 int rc = 0; 644 645 if (!ss_initialized) { 646 int i; 647 648 for (i = 1; i < SECINITSID_NUM; i++) { 649 if (!strcmp(initial_sid_to_string[i], scontext)) { 650 *sid = i; 651 goto out; 652 } 653 } 654 *sid = SECINITSID_KERNEL; 655 goto out; 656 } 657 *sid = SECSID_NULL; 658 659 /* Copy the string so that we can modify the copy as we parse it. 660 The string should already by null terminated, but we append a 661 null suffix to the copy to avoid problems with the existing 662 attr package, which doesn't view the null terminator as part 663 of the attribute value. */ 664 scontext2 = kmalloc(scontext_len+1,GFP_KERNEL); 665 if (!scontext2) { 666 rc = -ENOMEM; 667 goto out; 668 } 669 memcpy(scontext2, scontext, scontext_len); 670 scontext2[scontext_len] = 0; 671 672 context_init(&context); 673 *sid = SECSID_NULL; 674 675 POLICY_RDLOCK; 676 677 /* Parse the security context. */ 678 679 rc = -EINVAL; 680 scontextp = (char *) scontext2; 681 682 /* Extract the user. */ 683 p = scontextp; 684 while (*p && *p != ':') 685 p++; 686 687 if (*p == 0) 688 goto out_unlock; 689 690 *p++ = 0; 691 692 usrdatum = hashtab_search(policydb.p_users.table, scontextp); 693 if (!usrdatum) 694 goto out_unlock; 695 696 context.user = usrdatum->value; 697 698 /* Extract role. */ 699 scontextp = p; 700 while (*p && *p != ':') 701 p++; 702 703 if (*p == 0) 704 goto out_unlock; 705 706 *p++ = 0; 707 708 role = hashtab_search(policydb.p_roles.table, scontextp); 709 if (!role) 710 goto out_unlock; 711 context.role = role->value; 712 713 /* Extract type. */ 714 scontextp = p; 715 while (*p && *p != ':') 716 p++; 717 oldc = *p; 718 *p++ = 0; 719 720 typdatum = hashtab_search(policydb.p_types.table, scontextp); 721 if (!typdatum) 722 goto out_unlock; 723 724 context.type = typdatum->value; 725 726 rc = mls_context_to_sid(oldc, &p, &context, &sidtab, def_sid); 727 if (rc) 728 goto out_unlock; 729 730 if ((p - scontext2) < scontext_len) { 731 rc = -EINVAL; 732 goto out_unlock; 733 } 734 735 /* Check the validity of the new context. */ 736 if (!policydb_context_isvalid(&policydb, &context)) { 737 rc = -EINVAL; 738 goto out_unlock; 739 } 740 /* Obtain the new sid. */ 741 rc = sidtab_context_to_sid(&sidtab, &context, sid); 742out_unlock: 743 POLICY_RDUNLOCK; 744 context_destroy(&context); 745 kfree(scontext2); 746out: 747 return rc; 748} 749 750/** 751 * security_context_to_sid - Obtain a SID for a given security context. 752 * @scontext: security context 753 * @scontext_len: length in bytes 754 * @sid: security identifier, SID 755 * 756 * Obtains a SID associated with the security context that 757 * has the string representation specified by @scontext. 758 * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient 759 * memory is available, or 0 on success. 760 */ 761int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid) 762{ 763 return security_context_to_sid_core(scontext, scontext_len, 764 sid, SECSID_NULL); 765} 766 767/** 768 * security_context_to_sid_default - Obtain a SID for a given security context, 769 * falling back to specified default if needed. 770 * 771 * @scontext: security context 772 * @scontext_len: length in bytes 773 * @sid: security identifier, SID 774 * @def_sid: default SID to assign on errror 775 * 776 * Obtains a SID associated with the security context that 777 * has the string representation specified by @scontext. 778 * The default SID is passed to the MLS layer to be used to allow 779 * kernel labeling of the MLS field if the MLS field is not present 780 * (for upgrading to MLS without full relabel). 781 * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient 782 * memory is available, or 0 on success. 783 */ 784int security_context_to_sid_default(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid) 785{ 786 return security_context_to_sid_core(scontext, scontext_len, 787 sid, def_sid); 788} 789 790static int compute_sid_handle_invalid_context( 791 struct context *scontext, 792 struct context *tcontext, 793 u16 tclass, 794 struct context *newcontext) 795{ 796 char *s = NULL, *t = NULL, *n = NULL; 797 u32 slen, tlen, nlen; 798 799 if (context_struct_to_string(scontext, &s, &slen) < 0) 800 goto out; 801 if (context_struct_to_string(tcontext, &t, &tlen) < 0) 802 goto out; 803 if (context_struct_to_string(newcontext, &n, &nlen) < 0) 804 goto out; 805 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, 806 "security_compute_sid: invalid context %s" 807 " for scontext=%s" 808 " tcontext=%s" 809 " tclass=%s", 810 n, s, t, policydb.p_class_val_to_name[tclass-1]); 811out: 812 kfree(s); 813 kfree(t); 814 kfree(n); 815 if (!selinux_enforcing) 816 return 0; 817 return -EACCES; 818} 819 820static int security_compute_sid(u32 ssid, 821 u32 tsid, 822 u16 tclass, 823 u32 specified, 824 u32 *out_sid) 825{ 826 struct context *scontext = NULL, *tcontext = NULL, newcontext; 827 struct role_trans *roletr = NULL; 828 struct avtab_key avkey; 829 struct avtab_datum *avdatum; 830 struct avtab_node *node; 831 int rc = 0; 832 833 if (!ss_initialized) { 834 switch (tclass) { 835 case SECCLASS_PROCESS: 836 *out_sid = ssid; 837 break; 838 default: 839 *out_sid = tsid; 840 break; 841 } 842 goto out; 843 } 844 845 context_init(&newcontext); 846 847 POLICY_RDLOCK; 848 849 scontext = sidtab_search(&sidtab, ssid); 850 if (!scontext) { 851 printk(KERN_ERR "security_compute_sid: unrecognized SID %d\n", 852 ssid); 853 rc = -EINVAL; 854 goto out_unlock; 855 } 856 tcontext = sidtab_search(&sidtab, tsid); 857 if (!tcontext) { 858 printk(KERN_ERR "security_compute_sid: unrecognized SID %d\n", 859 tsid); 860 rc = -EINVAL; 861 goto out_unlock; 862 } 863 864 /* Set the user identity. */ 865 switch (specified) { 866 case AVTAB_TRANSITION: 867 case AVTAB_CHANGE: 868 /* Use the process user identity. */ 869 newcontext.user = scontext->user; 870 break; 871 case AVTAB_MEMBER: 872 /* Use the related object owner. */ 873 newcontext.user = tcontext->user; 874 break; 875 } 876 877 /* Set the role and type to default values. */ 878 switch (tclass) { 879 case SECCLASS_PROCESS: 880 /* Use the current role and type of process. */ 881 newcontext.role = scontext->role; 882 newcontext.type = scontext->type; 883 break; 884 default: 885 /* Use the well-defined object role. */ 886 newcontext.role = OBJECT_R_VAL; 887 /* Use the type of the related object. */ 888 newcontext.type = tcontext->type; 889 } 890 891 /* Look for a type transition/member/change rule. */ 892 avkey.source_type = scontext->type; 893 avkey.target_type = tcontext->type; 894 avkey.target_class = tclass; 895 avkey.specified = specified; 896 avdatum = avtab_search(&policydb.te_avtab, &avkey); 897 898 /* If no permanent rule, also check for enabled conditional rules */ 899 if(!avdatum) { 900 node = avtab_search_node(&policydb.te_cond_avtab, &avkey); 901 for (; node != NULL; node = avtab_search_node_next(node, specified)) { 902 if (node->key.specified & AVTAB_ENABLED) { 903 avdatum = &node->datum; 904 break; 905 } 906 } 907 } 908 909 if (avdatum) { 910 /* Use the type from the type transition/member/change rule. */ 911 newcontext.type = avdatum->data; 912 } 913 914 /* Check for class-specific changes. */ 915 switch (tclass) { 916 case SECCLASS_PROCESS: 917 if (specified & AVTAB_TRANSITION) { 918 /* Look for a role transition rule. */ 919 for (roletr = policydb.role_tr; roletr; 920 roletr = roletr->next) { 921 if (roletr->role == scontext->role && 922 roletr->type == tcontext->type) { 923 /* Use the role transition rule. */ 924 newcontext.role = roletr->new_role; 925 break; 926 } 927 } 928 } 929 break; 930 default: 931 break; 932 } 933 934 /* Set the MLS attributes. 935 This is done last because it may allocate memory. */ 936 rc = mls_compute_sid(scontext, tcontext, tclass, specified, &newcontext); 937 if (rc) 938 goto out_unlock; 939 940 /* Check the validity of the context. */ 941 if (!policydb_context_isvalid(&policydb, &newcontext)) { 942 rc = compute_sid_handle_invalid_context(scontext, 943 tcontext, 944 tclass, 945 &newcontext); 946 if (rc) 947 goto out_unlock; 948 } 949 /* Obtain the sid for the context. */ 950 rc = sidtab_context_to_sid(&sidtab, &newcontext, out_sid); 951out_unlock: 952 POLICY_RDUNLOCK; 953 context_destroy(&newcontext); 954out: 955 return rc; 956} 957 958/** 959 * security_transition_sid - Compute the SID for a new subject/object. 960 * @ssid: source security identifier 961 * @tsid: target security identifier 962 * @tclass: target security class 963 * @out_sid: security identifier for new subject/object 964 * 965 * Compute a SID to use for labeling a new subject or object in the 966 * class @tclass based on a SID pair (@ssid, @tsid). 967 * Return -%EINVAL if any of the parameters are invalid, -%ENOMEM 968 * if insufficient memory is available, or %0 if the new SID was 969 * computed successfully. 970 */ 971int security_transition_sid(u32 ssid, 972 u32 tsid, 973 u16 tclass, 974 u32 *out_sid) 975{ 976 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, out_sid); 977} 978 979/** 980 * security_member_sid - Compute the SID for member selection. 981 * @ssid: source security identifier 982 * @tsid: target security identifier 983 * @tclass: target security class 984 * @out_sid: security identifier for selected member 985 * 986 * Compute a SID to use when selecting a member of a polyinstantiated 987 * object of class @tclass based on a SID pair (@ssid, @tsid). 988 * Return -%EINVAL if any of the parameters are invalid, -%ENOMEM 989 * if insufficient memory is available, or %0 if the SID was 990 * computed successfully. 991 */ 992int security_member_sid(u32 ssid, 993 u32 tsid, 994 u16 tclass, 995 u32 *out_sid) 996{ 997 return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid); 998} 999 1000/** 1001 * security_change_sid - Compute the SID for object relabeling. 1002 * @ssid: source security identifier 1003 * @tsid: target security identifier 1004 * @tclass: target security class 1005 * @out_sid: security identifier for selected member 1006 * 1007 * Compute a SID to use for relabeling an object of class @tclass 1008 * based on a SID pair (@ssid, @tsid). 1009 * Return -%EINVAL if any of the parameters are invalid, -%ENOMEM 1010 * if insufficient memory is available, or %0 if the SID was 1011 * computed successfully. 1012 */ 1013int security_change_sid(u32 ssid, 1014 u32 tsid, 1015 u16 tclass, 1016 u32 *out_sid) 1017{ 1018 return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid); 1019} 1020 1021/* 1022 * Verify that each permission that is defined under the 1023 * existing policy is still defined with the same value 1024 * in the new policy. 1025 */ 1026static int validate_perm(void *key, void *datum, void *p) 1027{ 1028 struct hashtab *h; 1029 struct perm_datum *perdatum, *perdatum2; 1030 int rc = 0; 1031 1032 1033 h = p; 1034 perdatum = datum; 1035 1036 perdatum2 = hashtab_search(h, key); 1037 if (!perdatum2) { 1038 printk(KERN_ERR "security: permission %s disappeared", 1039 (char *)key); 1040 rc = -ENOENT; 1041 goto out; 1042 } 1043 if (perdatum->value != perdatum2->value) { 1044 printk(KERN_ERR "security: the value of permission %s changed", 1045 (char *)key); 1046 rc = -EINVAL; 1047 } 1048out: 1049 return rc; 1050} 1051 1052/* 1053 * Verify that each class that is defined under the 1054 * existing policy is still defined with the same 1055 * attributes in the new policy. 1056 */ 1057static int validate_class(void *key, void *datum, void *p) 1058{ 1059 struct policydb *newp; 1060 struct class_datum *cladatum, *cladatum2; 1061 int rc; 1062 1063 newp = p; 1064 cladatum = datum; 1065 1066 cladatum2 = hashtab_search(newp->p_classes.table, key); 1067 if (!cladatum2) { 1068 printk(KERN_ERR "security: class %s disappeared\n", 1069 (char *)key); 1070 rc = -ENOENT; 1071 goto out; 1072 } 1073 if (cladatum->value != cladatum2->value) { 1074 printk(KERN_ERR "security: the value of class %s changed\n", 1075 (char *)key); 1076 rc = -EINVAL; 1077 goto out; 1078 } 1079 if ((cladatum->comdatum && !cladatum2->comdatum) || 1080 (!cladatum->comdatum && cladatum2->comdatum)) { 1081 printk(KERN_ERR "security: the inherits clause for the access " 1082 "vector definition for class %s changed\n", (char *)key); 1083 rc = -EINVAL; 1084 goto out; 1085 } 1086 if (cladatum->comdatum) { 1087 rc = hashtab_map(cladatum->comdatum->permissions.table, validate_perm, 1088 cladatum2->comdatum->permissions.table); 1089 if (rc) { 1090 printk(" in the access vector definition for class " 1091 "%s\n", (char *)key); 1092 goto out; 1093 } 1094 } 1095 rc = hashtab_map(cladatum->permissions.table, validate_perm, 1096 cladatum2->permissions.table); 1097 if (rc) 1098 printk(" in access vector definition for class %s\n", 1099 (char *)key); 1100out: 1101 return rc; 1102} 1103 1104/* Clone the SID into the new SID table. */ 1105static int clone_sid(u32 sid, 1106 struct context *context, 1107 void *arg) 1108{ 1109 struct sidtab *s = arg; 1110 1111 return sidtab_insert(s, sid, context); 1112} 1113 1114static inline int convert_context_handle_invalid_context(struct context *context) 1115{ 1116 int rc = 0; 1117 1118 if (selinux_enforcing) { 1119 rc = -EINVAL; 1120 } else { 1121 char *s; 1122 u32 len; 1123 1124 context_struct_to_string(context, &s, &len); 1125 printk(KERN_ERR "security: context %s is invalid\n", s); 1126 kfree(s); 1127 } 1128 return rc; 1129} 1130 1131struct convert_context_args { 1132 struct policydb *oldp; 1133 struct policydb *newp; 1134}; 1135 1136/* 1137 * Convert the values in the security context 1138 * structure `c' from the values specified 1139 * in the policy `p->oldp' to the values specified 1140 * in the policy `p->newp'. Verify that the 1141 * context is valid under the new policy. 1142 */ 1143static int convert_context(u32 key, 1144 struct context *c, 1145 void *p) 1146{ 1147 struct convert_context_args *args; 1148 struct context oldc; 1149 struct role_datum *role; 1150 struct type_datum *typdatum; 1151 struct user_datum *usrdatum; 1152 char *s; 1153 u32 len; 1154 int rc; 1155 1156 args = p; 1157 1158 rc = context_cpy(&oldc, c); 1159 if (rc) 1160 goto out; 1161 1162 rc = -EINVAL; 1163 1164 /* Convert the user. */ 1165 usrdatum = hashtab_search(args->newp->p_users.table, 1166 args->oldp->p_user_val_to_name[c->user - 1]); 1167 if (!usrdatum) { 1168 goto bad; 1169 } 1170 c->user = usrdatum->value; 1171 1172 /* Convert the role. */ 1173 role = hashtab_search(args->newp->p_roles.table, 1174 args->oldp->p_role_val_to_name[c->role - 1]); 1175 if (!role) { 1176 goto bad; 1177 } 1178 c->role = role->value; 1179 1180 /* Convert the type. */ 1181 typdatum = hashtab_search(args->newp->p_types.table, 1182 args->oldp->p_type_val_to_name[c->type - 1]); 1183 if (!typdatum) { 1184 goto bad; 1185 } 1186 c->type = typdatum->value; 1187 1188 rc = mls_convert_context(args->oldp, args->newp, c); 1189 if (rc) 1190 goto bad; 1191 1192 /* Check the validity of the new context. */ 1193 if (!policydb_context_isvalid(args->newp, c)) { 1194 rc = convert_context_handle_invalid_context(&oldc); 1195 if (rc) 1196 goto bad; 1197 } 1198 1199 context_destroy(&oldc); 1200out: 1201 return rc; 1202bad: 1203 context_struct_to_string(&oldc, &s, &len); 1204 context_destroy(&oldc); 1205 printk(KERN_ERR "security: invalidating context %s\n", s); 1206 kfree(s); 1207 goto out; 1208} 1209 1210extern void selinux_complete_init(void); 1211 1212/** 1213 * security_load_policy - Load a security policy configuration. 1214 * @data: binary policy data 1215 * @len: length of data in bytes 1216 * 1217 * Load a new set of security policy configuration data, 1218 * validate it and convert the SID table as necessary. 1219 * This function will flush the access vector cache after 1220 * loading the new policy. 1221 */ 1222int security_load_policy(void *data, size_t len) 1223{ 1224 struct policydb oldpolicydb, newpolicydb; 1225 struct sidtab oldsidtab, newsidtab; 1226 struct convert_context_args args; 1227 u32 seqno; 1228 int rc = 0; 1229 struct policy_file file = { data, len }, *fp = &file; 1230 1231 LOAD_LOCK; 1232 1233 if (!ss_initialized) { 1234 avtab_cache_init(); 1235 if (policydb_read(&policydb, fp)) { 1236 LOAD_UNLOCK; 1237 avtab_cache_destroy(); 1238 return -EINVAL; 1239 } 1240 if (policydb_load_isids(&policydb, &sidtab)) { 1241 LOAD_UNLOCK; 1242 policydb_destroy(&policydb); 1243 avtab_cache_destroy(); 1244 return -EINVAL; 1245 } 1246 policydb_loaded_version = policydb.policyvers; 1247 ss_initialized = 1; 1248 seqno = ++latest_granting; 1249 LOAD_UNLOCK; 1250 selinux_complete_init(); 1251 avc_ss_reset(seqno); 1252 selnl_notify_policyload(seqno); 1253 selinux_netlbl_cache_invalidate(); 1254 return 0; 1255 } 1256 1257#if 0 1258 sidtab_hash_eval(&sidtab, "sids"); 1259#endif 1260 1261 if (policydb_read(&newpolicydb, fp)) { 1262 LOAD_UNLOCK; 1263 return -EINVAL; 1264 } 1265 1266 sidtab_init(&newsidtab); 1267 1268 /* Verify that the existing classes did not change. */ 1269 if (hashtab_map(policydb.p_classes.table, validate_class, &newpolicydb)) { 1270 printk(KERN_ERR "security: the definition of an existing " 1271 "class changed\n"); 1272 rc = -EINVAL; 1273 goto err; 1274 } 1275 1276 /* Clone the SID table. */ 1277 sidtab_shutdown(&sidtab); 1278 if (sidtab_map(&sidtab, clone_sid, &newsidtab)) { 1279 rc = -ENOMEM; 1280 goto err; 1281 } 1282 1283 /* Convert the internal representations of contexts 1284 in the new SID table and remove invalid SIDs. */ 1285 args.oldp = &policydb; 1286 args.newp = &newpolicydb; 1287 sidtab_map_remove_on_error(&newsidtab, convert_context, &args); 1288 1289 /* Save the old policydb and SID table to free later. */ 1290 memcpy(&oldpolicydb, &policydb, sizeof policydb); 1291 sidtab_set(&oldsidtab, &sidtab); 1292 1293 /* Install the new policydb and SID table. */ 1294 POLICY_WRLOCK; 1295 memcpy(&policydb, &newpolicydb, sizeof policydb); 1296 sidtab_set(&sidtab, &newsidtab); 1297 seqno = ++latest_granting; 1298 policydb_loaded_version = policydb.policyvers; 1299 POLICY_WRUNLOCK; 1300 LOAD_UNLOCK; 1301 1302 /* Free the old policydb and SID table. */ 1303 policydb_destroy(&oldpolicydb); 1304 sidtab_destroy(&oldsidtab); 1305 1306 avc_ss_reset(seqno); 1307 selnl_notify_policyload(seqno); 1308 selinux_netlbl_cache_invalidate(); 1309 1310 return 0; 1311 1312err: 1313 LOAD_UNLOCK; 1314 sidtab_destroy(&newsidtab); 1315 policydb_destroy(&newpolicydb); 1316 return rc; 1317 1318} 1319 1320/** 1321 * security_port_sid - Obtain the SID for a port. 1322 * @domain: communication domain aka address family 1323 * @type: socket type 1324 * @protocol: protocol number 1325 * @port: port number 1326 * @out_sid: security identifier 1327 */ 1328int security_port_sid(u16 domain, 1329 u16 type, 1330 u8 protocol, 1331 u16 port, 1332 u32 *out_sid) 1333{ 1334 struct ocontext *c; 1335 int rc = 0; 1336 1337 POLICY_RDLOCK; 1338 1339 c = policydb.ocontexts[OCON_PORT]; 1340 while (c) { 1341 if (c->u.port.protocol == protocol && 1342 c->u.port.low_port <= port && 1343 c->u.port.high_port >= port) 1344 break; 1345 c = c->next; 1346 } 1347 1348 if (c) { 1349 if (!c->sid[0]) { 1350 rc = sidtab_context_to_sid(&sidtab, 1351 &c->context[0], 1352 &c->sid[0]); 1353 if (rc) 1354 goto out; 1355 } 1356 *out_sid = c->sid[0]; 1357 } else { 1358 *out_sid = SECINITSID_PORT; 1359 } 1360 1361out: 1362 POLICY_RDUNLOCK; 1363 return rc; 1364} 1365 1366/** 1367 * security_netif_sid - Obtain the SID for a network interface. 1368 * @name: interface name 1369 * @if_sid: interface SID 1370 * @msg_sid: default SID for received packets 1371 */ 1372int security_netif_sid(char *name, 1373 u32 *if_sid, 1374 u32 *msg_sid) 1375{ 1376 int rc = 0; 1377 struct ocontext *c; 1378 1379 POLICY_RDLOCK; 1380 1381 c = policydb.ocontexts[OCON_NETIF]; 1382 while (c) { 1383 if (strcmp(name, c->u.name) == 0) 1384 break; 1385 c = c->next; 1386 } 1387 1388 if (c) { 1389 if (!c->sid[0] || !c->sid[1]) { 1390 rc = sidtab_context_to_sid(&sidtab, 1391 &c->context[0], 1392 &c->sid[0]); 1393 if (rc) 1394 goto out; 1395 rc = sidtab_context_to_sid(&sidtab, 1396 &c->context[1], 1397 &c->sid[1]); 1398 if (rc) 1399 goto out; 1400 } 1401 *if_sid = c->sid[0]; 1402 *msg_sid = c->sid[1]; 1403 } else { 1404 *if_sid = SECINITSID_NETIF; 1405 *msg_sid = SECINITSID_NETMSG; 1406 } 1407 1408out: 1409 POLICY_RDUNLOCK; 1410 return rc; 1411} 1412 1413static int match_ipv6_addrmask(u32 *input, u32 *addr, u32 *mask) 1414{ 1415 int i, fail = 0; 1416 1417 for(i = 0; i < 4; i++) 1418 if(addr[i] != (input[i] & mask[i])) { 1419 fail = 1; 1420 break; 1421 } 1422 1423 return !fail; 1424} 1425 1426/** 1427 * security_node_sid - Obtain the SID for a node (host). 1428 * @domain: communication domain aka address family 1429 * @addrp: address 1430 * @addrlen: address length in bytes 1431 * @out_sid: security identifier 1432 */ 1433int security_node_sid(u16 domain, 1434 void *addrp, 1435 u32 addrlen, 1436 u32 *out_sid) 1437{ 1438 int rc = 0; 1439 struct ocontext *c; 1440 1441 POLICY_RDLOCK; 1442 1443 switch (domain) { 1444 case AF_INET: { 1445 u32 addr; 1446 1447 if (addrlen != sizeof(u32)) { 1448 rc = -EINVAL; 1449 goto out; 1450 } 1451 1452 addr = *((u32 *)addrp); 1453 1454 c = policydb.ocontexts[OCON_NODE]; 1455 while (c) { 1456 if (c->u.node.addr == (addr & c->u.node.mask)) 1457 break; 1458 c = c->next; 1459 } 1460 break; 1461 } 1462 1463 case AF_INET6: 1464 if (addrlen != sizeof(u64) * 2) { 1465 rc = -EINVAL; 1466 goto out; 1467 } 1468 c = policydb.ocontexts[OCON_NODE6]; 1469 while (c) { 1470 if (match_ipv6_addrmask(addrp, c->u.node6.addr, 1471 c->u.node6.mask)) 1472 break; 1473 c = c->next; 1474 } 1475 break; 1476 1477 default: 1478 *out_sid = SECINITSID_NODE; 1479 goto out; 1480 } 1481 1482 if (c) { 1483 if (!c->sid[0]) { 1484 rc = sidtab_context_to_sid(&sidtab, 1485 &c->context[0], 1486 &c->sid[0]); 1487 if (rc) 1488 goto out; 1489 } 1490 *out_sid = c->sid[0]; 1491 } else { 1492 *out_sid = SECINITSID_NODE; 1493 } 1494 1495out: 1496 POLICY_RDUNLOCK; 1497 return rc; 1498} 1499 1500#define SIDS_NEL 25 1501 1502/** 1503 * security_get_user_sids - Obtain reachable SIDs for a user. 1504 * @fromsid: starting SID 1505 * @username: username 1506 * @sids: array of reachable SIDs for user 1507 * @nel: number of elements in @sids 1508 * 1509 * Generate the set of SIDs for legal security contexts 1510 * for a given user that can be reached by @fromsid. 1511 * Set *@sids to point to a dynamically allocated 1512 * array containing the set of SIDs. Set *@nel to the 1513 * number of elements in the array. 1514 */ 1515 1516int security_get_user_sids(u32 fromsid, 1517 char *username, 1518 u32 **sids, 1519 u32 *nel) 1520{ 1521 struct context *fromcon, usercon; 1522 u32 *mysids, *mysids2, sid; 1523 u32 mynel = 0, maxnel = SIDS_NEL; 1524 struct user_datum *user; 1525 struct role_datum *role; 1526 struct av_decision avd; 1527 struct ebitmap_node *rnode, *tnode; 1528 int rc = 0, i, j; 1529 1530 if (!ss_initialized) { 1531 *sids = NULL; 1532 *nel = 0; 1533 goto out; 1534 } 1535 1536 POLICY_RDLOCK; 1537 1538 fromcon = sidtab_search(&sidtab, fromsid); 1539 if (!fromcon) { 1540 rc = -EINVAL; 1541 goto out_unlock; 1542 } 1543 1544 user = hashtab_search(policydb.p_users.table, username); 1545 if (!user) { 1546 rc = -EINVAL; 1547 goto out_unlock; 1548 } 1549 usercon.user = user->value; 1550 1551 mysids = kcalloc(maxnel, sizeof(*mysids), GFP_ATOMIC); 1552 if (!mysids) { 1553 rc = -ENOMEM; 1554 goto out_unlock; 1555 } 1556 1557 ebitmap_for_each_bit(&user->roles, rnode, i) { 1558 if (!ebitmap_node_get_bit(rnode, i)) 1559 continue; 1560 role = policydb.role_val_to_struct[i]; 1561 usercon.role = i+1; 1562 ebitmap_for_each_bit(&role->types, tnode, j) { 1563 if (!ebitmap_node_get_bit(tnode, j)) 1564 continue; 1565 usercon.type = j+1; 1566 1567 if (mls_setup_user_range(fromcon, user, &usercon)) 1568 continue; 1569 1570 rc = context_struct_compute_av(fromcon, &usercon, 1571 SECCLASS_PROCESS, 1572 PROCESS__TRANSITION, 1573 &avd); 1574 if (rc || !(avd.allowed & PROCESS__TRANSITION)) 1575 continue; 1576 rc = sidtab_context_to_sid(&sidtab, &usercon, &sid); 1577 if (rc) { 1578 kfree(mysids); 1579 goto out_unlock; 1580 } 1581 if (mynel < maxnel) { 1582 mysids[mynel++] = sid; 1583 } else { 1584 maxnel += SIDS_NEL; 1585 mysids2 = kcalloc(maxnel, sizeof(*mysids2), GFP_ATOMIC); 1586 if (!mysids2) { 1587 rc = -ENOMEM; 1588 kfree(mysids); 1589 goto out_unlock; 1590 } 1591 memcpy(mysids2, mysids, mynel * sizeof(*mysids2)); 1592 kfree(mysids); 1593 mysids = mysids2; 1594 mysids[mynel++] = sid; 1595 } 1596 } 1597 } 1598 1599 *sids = mysids; 1600 *nel = mynel; 1601 1602out_unlock: 1603 POLICY_RDUNLOCK; 1604out: 1605 return rc; 1606} 1607 1608/** 1609 * security_genfs_sid - Obtain a SID for a file in a filesystem 1610 * @fstype: filesystem type 1611 * @path: path from root of mount 1612 * @sclass: file security class 1613 * @sid: SID for path 1614 * 1615 * Obtain a SID to use for a file in a filesystem that 1616 * cannot support xattr or use a fixed labeling behavior like 1617 * transition SIDs or task SIDs. 1618 */ 1619int security_genfs_sid(const char *fstype, 1620 char *path, 1621 u16 sclass, 1622 u32 *sid) 1623{ 1624 int len; 1625 struct genfs *genfs; 1626 struct ocontext *c; 1627 int rc = 0, cmp = 0; 1628 1629 POLICY_RDLOCK; 1630 1631 for (genfs = policydb.genfs; genfs; genfs = genfs->next) { 1632 cmp = strcmp(fstype, genfs->fstype); 1633 if (cmp <= 0) 1634 break; 1635 } 1636 1637 if (!genfs || cmp) { 1638 *sid = SECINITSID_UNLABELED; 1639 rc = -ENOENT; 1640 goto out; 1641 } 1642 1643 for (c = genfs->head; c; c = c->next) { 1644 len = strlen(c->u.name); 1645 if ((!c->v.sclass || sclass == c->v.sclass) && 1646 (strncmp(c->u.name, path, len) == 0)) 1647 break; 1648 } 1649 1650 if (!c) { 1651 *sid = SECINITSID_UNLABELED; 1652 rc = -ENOENT; 1653 goto out; 1654 } 1655 1656 if (!c->sid[0]) { 1657 rc = sidtab_context_to_sid(&sidtab, 1658 &c->context[0], 1659 &c->sid[0]); 1660 if (rc) 1661 goto out; 1662 } 1663 1664 *sid = c->sid[0]; 1665out: 1666 POLICY_RDUNLOCK; 1667 return rc; 1668} 1669 1670/** 1671 * security_fs_use - Determine how to handle labeling for a filesystem. 1672 * @fstype: filesystem type 1673 * @behavior: labeling behavior 1674 * @sid: SID for filesystem (superblock) 1675 */ 1676int security_fs_use( 1677 const char *fstype, 1678 unsigned int *behavior, 1679 u32 *sid) 1680{ 1681 int rc = 0; 1682 struct ocontext *c; 1683 1684 POLICY_RDLOCK; 1685 1686 c = policydb.ocontexts[OCON_FSUSE]; 1687 while (c) { 1688 if (strcmp(fstype, c->u.name) == 0) 1689 break; 1690 c = c->next; 1691 } 1692 1693 if (c) { 1694 *behavior = c->v.behavior; 1695 if (!c->sid[0]) { 1696 rc = sidtab_context_to_sid(&sidtab, 1697 &c->context[0], 1698 &c->sid[0]); 1699 if (rc) 1700 goto out; 1701 } 1702 *sid = c->sid[0]; 1703 } else { 1704 rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, sid); 1705 if (rc) { 1706 *behavior = SECURITY_FS_USE_NONE; 1707 rc = 0; 1708 } else { 1709 *behavior = SECURITY_FS_USE_GENFS; 1710 } 1711 } 1712 1713out: 1714 POLICY_RDUNLOCK; 1715 return rc; 1716} 1717 1718int security_get_bools(int *len, char ***names, int **values) 1719{ 1720 int i, rc = -ENOMEM; 1721 1722 POLICY_RDLOCK; 1723 *names = NULL; 1724 *values = NULL; 1725 1726 *len = policydb.p_bools.nprim; 1727 if (!*len) { 1728 rc = 0; 1729 goto out; 1730 } 1731 1732 *names = kcalloc(*len, sizeof(char*), GFP_ATOMIC); 1733 if (!*names) 1734 goto err; 1735 1736 *values = kcalloc(*len, sizeof(int), GFP_ATOMIC); 1737 if (!*values) 1738 goto err; 1739 1740 for (i = 0; i < *len; i++) { 1741 size_t name_len; 1742 (*values)[i] = policydb.bool_val_to_struct[i]->state; 1743 name_len = strlen(policydb.p_bool_val_to_name[i]) + 1; 1744 (*names)[i] = kmalloc(sizeof(char) * name_len, GFP_ATOMIC); 1745 if (!(*names)[i]) 1746 goto err; 1747 strncpy((*names)[i], policydb.p_bool_val_to_name[i], name_len); 1748 (*names)[i][name_len - 1] = 0; 1749 } 1750 rc = 0; 1751out: 1752 POLICY_RDUNLOCK; 1753 return rc; 1754err: 1755 if (*names) { 1756 for (i = 0; i < *len; i++) 1757 kfree((*names)[i]); 1758 } 1759 kfree(*values); 1760 goto out; 1761} 1762 1763 1764int security_set_bools(int len, int *values) 1765{ 1766 int i, rc = 0; 1767 int lenp, seqno = 0; 1768 struct cond_node *cur; 1769 1770 POLICY_WRLOCK; 1771 1772 lenp = policydb.p_bools.nprim; 1773 if (len != lenp) { 1774 rc = -EFAULT; 1775 goto out; 1776 } 1777 1778 for (i = 0; i < len; i++) { 1779 if (!!values[i] != policydb.bool_val_to_struct[i]->state) { 1780 audit_log(current->audit_context, GFP_ATOMIC, 1781 AUDIT_MAC_CONFIG_CHANGE, 1782 "bool=%s val=%d old_val=%d auid=%u", 1783 policydb.p_bool_val_to_name[i], 1784 !!values[i], 1785 policydb.bool_val_to_struct[i]->state, 1786 audit_get_loginuid(current->audit_context)); 1787 } 1788 if (values[i]) { 1789 policydb.bool_val_to_struct[i]->state = 1; 1790 } else { 1791 policydb.bool_val_to_struct[i]->state = 0; 1792 } 1793 } 1794 1795 for (cur = policydb.cond_list; cur != NULL; cur = cur->next) { 1796 rc = evaluate_cond_node(&policydb, cur); 1797 if (rc) 1798 goto out; 1799 } 1800 1801 seqno = ++latest_granting; 1802 1803out: 1804 POLICY_WRUNLOCK; 1805 if (!rc) { 1806 avc_ss_reset(seqno); 1807 selnl_notify_policyload(seqno); 1808 } 1809 return rc; 1810} 1811 1812int security_get_bool_value(int bool) 1813{ 1814 int rc = 0; 1815 int len; 1816 1817 POLICY_RDLOCK; 1818 1819 len = policydb.p_bools.nprim; 1820 if (bool >= len) { 1821 rc = -EFAULT; 1822 goto out; 1823 } 1824 1825 rc = policydb.bool_val_to_struct[bool]->state; 1826out: 1827 POLICY_RDUNLOCK; 1828 return rc; 1829} 1830 1831/* 1832 * security_sid_mls_copy() - computes a new sid based on the given 1833 * sid and the mls portion of mls_sid. 1834 */ 1835int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid) 1836{ 1837 struct context *context1; 1838 struct context *context2; 1839 struct context newcon; 1840 char *s; 1841 u32 len; 1842 int rc = 0; 1843 1844 if (!ss_initialized || !selinux_mls_enabled) { 1845 *new_sid = sid; 1846 goto out; 1847 } 1848 1849 context_init(&newcon); 1850 1851 POLICY_RDLOCK; 1852 context1 = sidtab_search(&sidtab, sid); 1853 if (!context1) { 1854 printk(KERN_ERR "security_sid_mls_copy: unrecognized SID " 1855 "%d\n", sid); 1856 rc = -EINVAL; 1857 goto out_unlock; 1858 } 1859 1860 context2 = sidtab_search(&sidtab, mls_sid); 1861 if (!context2) { 1862 printk(KERN_ERR "security_sid_mls_copy: unrecognized SID " 1863 "%d\n", mls_sid); 1864 rc = -EINVAL; 1865 goto out_unlock; 1866 } 1867 1868 newcon.user = context1->user; 1869 newcon.role = context1->role; 1870 newcon.type = context1->type; 1871 rc = mls_copy_context(&newcon, context2); 1872 if (rc) 1873 goto out_unlock; 1874 1875 1876 /* Check the validity of the new context. */ 1877 if (!policydb_context_isvalid(&policydb, &newcon)) { 1878 rc = convert_context_handle_invalid_context(&newcon); 1879 if (rc) 1880 goto bad; 1881 } 1882 1883 rc = sidtab_context_to_sid(&sidtab, &newcon, new_sid); 1884 goto out_unlock; 1885 1886bad: 1887 if (!context_struct_to_string(&newcon, &s, &len)) { 1888 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, 1889 "security_sid_mls_copy: invalid context %s", s); 1890 kfree(s); 1891 } 1892 1893out_unlock: 1894 POLICY_RDUNLOCK; 1895 context_destroy(&newcon); 1896out: 1897 return rc; 1898} 1899 1900struct selinux_audit_rule { 1901 u32 au_seqno; 1902 struct context au_ctxt; 1903}; 1904 1905void selinux_audit_rule_free(struct selinux_audit_rule *rule) 1906{ 1907 if (rule) { 1908 context_destroy(&rule->au_ctxt); 1909 kfree(rule); 1910 } 1911} 1912 1913int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, 1914 struct selinux_audit_rule **rule) 1915{ 1916 struct selinux_audit_rule *tmprule; 1917 struct role_datum *roledatum; 1918 struct type_datum *typedatum; 1919 struct user_datum *userdatum; 1920 int rc = 0; 1921 1922 *rule = NULL; 1923 1924 if (!ss_initialized) 1925 return -ENOTSUPP; 1926 1927 switch (field) { 1928 case AUDIT_SUBJ_USER: 1929 case AUDIT_SUBJ_ROLE: 1930 case AUDIT_SUBJ_TYPE: 1931 case AUDIT_OBJ_USER: 1932 case AUDIT_OBJ_ROLE: 1933 case AUDIT_OBJ_TYPE: 1934 /* only 'equals' and 'not equals' fit user, role, and type */ 1935 if (op != AUDIT_EQUAL && op != AUDIT_NOT_EQUAL) 1936 return -EINVAL; 1937 break; 1938 case AUDIT_SUBJ_SEN: 1939 case AUDIT_SUBJ_CLR: 1940 case AUDIT_OBJ_LEV_LOW: 1941 case AUDIT_OBJ_LEV_HIGH: 1942 /* we do not allow a range, indicated by the presense of '-' */ 1943 if (strchr(rulestr, '-')) 1944 return -EINVAL; 1945 break; 1946 default: 1947 /* only the above fields are valid */ 1948 return -EINVAL; 1949 } 1950 1951 tmprule = kzalloc(sizeof(struct selinux_audit_rule), GFP_KERNEL); 1952 if (!tmprule) 1953 return -ENOMEM; 1954 1955 context_init(&tmprule->au_ctxt); 1956 1957 POLICY_RDLOCK; 1958 1959 tmprule->au_seqno = latest_granting; 1960 1961 switch (field) { 1962 case AUDIT_SUBJ_USER: 1963 case AUDIT_OBJ_USER: 1964 userdatum = hashtab_search(policydb.p_users.table, rulestr); 1965 if (!userdatum) 1966 rc = -EINVAL; 1967 else 1968 tmprule->au_ctxt.user = userdatum->value; 1969 break; 1970 case AUDIT_SUBJ_ROLE: 1971 case AUDIT_OBJ_ROLE: 1972 roledatum = hashtab_search(policydb.p_roles.table, rulestr); 1973 if (!roledatum) 1974 rc = -EINVAL; 1975 else 1976 tmprule->au_ctxt.role = roledatum->value; 1977 break; 1978 case AUDIT_SUBJ_TYPE: 1979 case AUDIT_OBJ_TYPE: 1980 typedatum = hashtab_search(policydb.p_types.table, rulestr); 1981 if (!typedatum) 1982 rc = -EINVAL; 1983 else 1984 tmprule->au_ctxt.type = typedatum->value; 1985 break; 1986 case AUDIT_SUBJ_SEN: 1987 case AUDIT_SUBJ_CLR: 1988 case AUDIT_OBJ_LEV_LOW: 1989 case AUDIT_OBJ_LEV_HIGH: 1990 rc = mls_from_string(rulestr, &tmprule->au_ctxt, GFP_ATOMIC); 1991 break; 1992 } 1993 1994 POLICY_RDUNLOCK; 1995 1996 if (rc) { 1997 selinux_audit_rule_free(tmprule); 1998 tmprule = NULL; 1999 } 2000 2001 *rule = tmprule; 2002 2003 return rc; 2004} 2005 2006int selinux_audit_rule_match(u32 sid, u32 field, u32 op, 2007 struct selinux_audit_rule *rule, 2008 struct audit_context *actx) 2009{ 2010 struct context *ctxt; 2011 struct mls_level *level; 2012 int match = 0; 2013 2014 if (!rule) { 2015 audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, 2016 "selinux_audit_rule_match: missing rule\n"); 2017 return -ENOENT; 2018 } 2019 2020 POLICY_RDLOCK; 2021 2022 if (rule->au_seqno < latest_granting) { 2023 audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, 2024 "selinux_audit_rule_match: stale rule\n"); 2025 match = -ESTALE; 2026 goto out; 2027 } 2028 2029 ctxt = sidtab_search(&sidtab, sid); 2030 if (!ctxt) { 2031 audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, 2032 "selinux_audit_rule_match: unrecognized SID %d\n", 2033 sid); 2034 match = -ENOENT; 2035 goto out; 2036 } 2037 2038 /* a field/op pair that is not caught here will simply fall through 2039 without a match */ 2040 switch (field) { 2041 case AUDIT_SUBJ_USER: 2042 case AUDIT_OBJ_USER: 2043 switch (op) { 2044 case AUDIT_EQUAL: 2045 match = (ctxt->user == rule->au_ctxt.user); 2046 break; 2047 case AUDIT_NOT_EQUAL: 2048 match = (ctxt->user != rule->au_ctxt.user); 2049 break; 2050 } 2051 break; 2052 case AUDIT_SUBJ_ROLE: 2053 case AUDIT_OBJ_ROLE: 2054 switch (op) { 2055 case AUDIT_EQUAL: 2056 match = (ctxt->role == rule->au_ctxt.role); 2057 break; 2058 case AUDIT_NOT_EQUAL: 2059 match = (ctxt->role != rule->au_ctxt.role); 2060 break; 2061 } 2062 break; 2063 case AUDIT_SUBJ_TYPE: 2064 case AUDIT_OBJ_TYPE: 2065 switch (op) { 2066 case AUDIT_EQUAL: 2067 match = (ctxt->type == rule->au_ctxt.type); 2068 break; 2069 case AUDIT_NOT_EQUAL: 2070 match = (ctxt->type != rule->au_ctxt.type); 2071 break; 2072 } 2073 break; 2074 case AUDIT_SUBJ_SEN: 2075 case AUDIT_SUBJ_CLR: 2076 case AUDIT_OBJ_LEV_LOW: 2077 case AUDIT_OBJ_LEV_HIGH: 2078 level = ((field == AUDIT_SUBJ_SEN || 2079 field == AUDIT_OBJ_LEV_LOW) ? 2080 &ctxt->range.level[0] : &ctxt->range.level[1]); 2081 switch (op) { 2082 case AUDIT_EQUAL: 2083 match = mls_level_eq(&rule->au_ctxt.range.level[0], 2084 level); 2085 break; 2086 case AUDIT_NOT_EQUAL: 2087 match = !mls_level_eq(&rule->au_ctxt.range.level[0], 2088 level); 2089 break; 2090 case AUDIT_LESS_THAN: 2091 match = (mls_level_dom(&rule->au_ctxt.range.level[0], 2092 level) && 2093 !mls_level_eq(&rule->au_ctxt.range.level[0], 2094 level)); 2095 break; 2096 case AUDIT_LESS_THAN_OR_EQUAL: 2097 match = mls_level_dom(&rule->au_ctxt.range.level[0], 2098 level); 2099 break; 2100 case AUDIT_GREATER_THAN: 2101 match = (mls_level_dom(level, 2102 &rule->au_ctxt.range.level[0]) && 2103 !mls_level_eq(level, 2104 &rule->au_ctxt.range.level[0])); 2105 break; 2106 case AUDIT_GREATER_THAN_OR_EQUAL: 2107 match = mls_level_dom(level, 2108 &rule->au_ctxt.range.level[0]); 2109 break; 2110 } 2111 } 2112 2113out: 2114 POLICY_RDUNLOCK; 2115 return match; 2116} 2117 2118static int (*aurule_callback)(void) = NULL; 2119 2120static int aurule_avc_callback(u32 event, u32 ssid, u32 tsid, 2121 u16 class, u32 perms, u32 *retained) 2122{ 2123 int err = 0; 2124 2125 if (event == AVC_CALLBACK_RESET && aurule_callback) 2126 err = aurule_callback(); 2127 return err; 2128} 2129 2130static int __init aurule_init(void) 2131{ 2132 int err; 2133 2134 err = avc_add_callback(aurule_avc_callback, AVC_CALLBACK_RESET, 2135 SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0); 2136 if (err) 2137 panic("avc_add_callback() failed, error %d\n", err); 2138 2139 return err; 2140} 2141__initcall(aurule_init); 2142 2143void selinux_audit_set_callback(int (*callback)(void)) 2144{ 2145 aurule_callback = callback; 2146} 2147 2148#ifdef CONFIG_NETLABEL 2149/* 2150 * This is the structure we store inside the NetLabel cache block. 2151 */ 2152#define NETLBL_CACHE(x) ((struct netlbl_cache *)(x)) 2153#define NETLBL_CACHE_T_NONE 0 2154#define NETLBL_CACHE_T_SID 1 2155#define NETLBL_CACHE_T_MLS 2 2156struct netlbl_cache { 2157 u32 type; 2158 union { 2159 u32 sid; 2160 struct mls_range mls_label; 2161 } data; 2162}; 2163 2164/** 2165 * selinux_netlbl_cache_free - Free the NetLabel cached data 2166 * @data: the data to free 2167 * 2168 * Description: 2169 * This function is intended to be used as the free() callback inside the 2170 * netlbl_lsm_cache structure. 2171 * 2172 */ 2173static void selinux_netlbl_cache_free(const void *data) 2174{ 2175 struct netlbl_cache *cache = NETLBL_CACHE(data); 2176 switch (cache->type) { 2177 case NETLBL_CACHE_T_MLS: 2178 ebitmap_destroy(&cache->data.mls_label.level[0].cat); 2179 break; 2180 } 2181 kfree(data); 2182} 2183 2184/** 2185 * selinux_netlbl_cache_add - Add an entry to the NetLabel cache 2186 * @skb: the packet 2187 * @ctx: the SELinux context 2188 * 2189 * Description: 2190 * Attempt to cache the context in @ctx, which was derived from the packet in 2191 * @skb, in the NetLabel subsystem cache. 2192 * 2193 */ 2194static void selinux_netlbl_cache_add(struct sk_buff *skb, struct context *ctx) 2195{ 2196 struct netlbl_cache *cache = NULL; 2197 struct netlbl_lsm_secattr secattr; 2198 2199 netlbl_secattr_init(&secattr); 2200 2201 cache = kzalloc(sizeof(*cache), GFP_ATOMIC); 2202 if (cache == NULL) 2203 goto netlbl_cache_add_failure; 2204 secattr.cache.free = selinux_netlbl_cache_free; 2205 secattr.cache.data = (void *)cache; 2206 2207 cache->type = NETLBL_CACHE_T_MLS; 2208 if (ebitmap_cpy(&cache->data.mls_label.level[0].cat, 2209 &ctx->range.level[0].cat) != 0) 2210 goto netlbl_cache_add_failure; 2211 cache->data.mls_label.level[1].cat.highbit = 2212 cache->data.mls_label.level[0].cat.highbit; 2213 cache->data.mls_label.level[1].cat.node = 2214 cache->data.mls_label.level[0].cat.node; 2215 cache->data.mls_label.level[0].sens = ctx->range.level[0].sens; 2216 cache->data.mls_label.level[1].sens = ctx->range.level[0].sens; 2217 2218 if (netlbl_cache_add(skb, &secattr) != 0) 2219 goto netlbl_cache_add_failure; 2220 2221 return; 2222 2223netlbl_cache_add_failure: 2224 netlbl_secattr_destroy(&secattr, 1); 2225} 2226 2227/** 2228 * selinux_netlbl_cache_invalidate - Invalidate the NetLabel cache 2229 * 2230 * Description: 2231 * Invalidate the NetLabel security attribute mapping cache. 2232 * 2233 */ 2234void selinux_netlbl_cache_invalidate(void) 2235{ 2236 netlbl_cache_invalidate(); 2237} 2238 2239/** 2240 * selinux_netlbl_secattr_to_sid - Convert a NetLabel secattr to a SELinux SID 2241 * @skb: the network packet 2242 * @secattr: the NetLabel packet security attributes 2243 * @base_sid: the SELinux SID to use as a context for MLS only attributes 2244 * @sid: the SELinux SID 2245 * 2246 * Description: 2247 * Convert the given NetLabel packet security attributes in @secattr into a 2248 * SELinux SID. If the @secattr field does not contain a full SELinux 2249 * SID/context then use the context in @base_sid as the foundation. If @skb 2250 * is not NULL attempt to cache as much data as possibile. Returns zero on 2251 * success, negative values on failure. 2252 * 2253 */ 2254static int selinux_netlbl_secattr_to_sid(struct sk_buff *skb, 2255 struct netlbl_lsm_secattr *secattr, 2256 u32 base_sid, 2257 u32 *sid) 2258{ 2259 int rc = -EIDRM; 2260 struct context *ctx; 2261 struct context ctx_new; 2262 struct netlbl_cache *cache; 2263 2264 POLICY_RDLOCK; 2265 2266 if (secattr->cache.data) { 2267 cache = NETLBL_CACHE(secattr->cache.data); 2268 switch (cache->type) { 2269 case NETLBL_CACHE_T_SID: 2270 *sid = cache->data.sid; 2271 rc = 0; 2272 break; 2273 case NETLBL_CACHE_T_MLS: 2274 ctx = sidtab_search(&sidtab, base_sid); 2275 if (ctx == NULL) 2276 goto netlbl_secattr_to_sid_return; 2277 2278 ctx_new.user = ctx->user; 2279 ctx_new.role = ctx->role; 2280 ctx_new.type = ctx->type; 2281 ctx_new.range.level[0].sens = 2282 cache->data.mls_label.level[0].sens; 2283 ctx_new.range.level[0].cat.highbit = 2284 cache->data.mls_label.level[0].cat.highbit; 2285 ctx_new.range.level[0].cat.node = 2286 cache->data.mls_label.level[0].cat.node; 2287 ctx_new.range.level[1].sens = 2288 cache->data.mls_label.level[1].sens; 2289 ctx_new.range.level[1].cat.highbit = 2290 cache->data.mls_label.level[1].cat.highbit; 2291 ctx_new.range.level[1].cat.node = 2292 cache->data.mls_label.level[1].cat.node; 2293 2294 rc = sidtab_context_to_sid(&sidtab, &ctx_new, sid); 2295 break; 2296 default: 2297 goto netlbl_secattr_to_sid_return; 2298 } 2299 } else if (secattr->mls_lvl_vld) { 2300 ctx = sidtab_search(&sidtab, base_sid); 2301 if (ctx == NULL) 2302 goto netlbl_secattr_to_sid_return; 2303 2304 ctx_new.user = ctx->user; 2305 ctx_new.role = ctx->role; 2306 ctx_new.type = ctx->type; 2307 mls_import_lvl(&ctx_new, secattr->mls_lvl, secattr->mls_lvl); 2308 if (secattr->mls_cat) { 2309 if (mls_import_cat(&ctx_new, 2310 secattr->mls_cat, 2311 secattr->mls_cat_len, 2312 NULL, 2313 0) != 0) 2314 goto netlbl_secattr_to_sid_return; 2315 ctx_new.range.level[1].cat.highbit = 2316 ctx_new.range.level[0].cat.highbit; 2317 ctx_new.range.level[1].cat.node = 2318 ctx_new.range.level[0].cat.node; 2319 } else { 2320 ebitmap_init(&ctx_new.range.level[0].cat); 2321 ebitmap_init(&ctx_new.range.level[1].cat); 2322 } 2323 if (mls_context_isvalid(&policydb, &ctx_new) != 1) 2324 goto netlbl_secattr_to_sid_return_cleanup; 2325 2326 rc = sidtab_context_to_sid(&sidtab, &ctx_new, sid); 2327 if (rc != 0) 2328 goto netlbl_secattr_to_sid_return_cleanup; 2329 2330 if (skb != NULL) 2331 selinux_netlbl_cache_add(skb, &ctx_new); 2332 ebitmap_destroy(&ctx_new.range.level[0].cat); 2333 } else { 2334 *sid = SECINITSID_UNLABELED; 2335 rc = 0; 2336 } 2337 2338netlbl_secattr_to_sid_return: 2339 POLICY_RDUNLOCK; 2340 return rc; 2341netlbl_secattr_to_sid_return_cleanup: 2342 ebitmap_destroy(&ctx_new.range.level[0].cat); 2343 goto netlbl_secattr_to_sid_return; 2344} 2345 2346/** 2347 * selinux_netlbl_skbuff_getsid - Get the sid of a packet using NetLabel 2348 * @skb: the packet 2349 * @base_sid: the SELinux SID to use as a context for MLS only attributes 2350 * @sid: the SID 2351 * 2352 * Description: 2353 * Call the NetLabel mechanism to get the security attributes of the given 2354 * packet and use those attributes to determine the correct context/SID to 2355 * assign to the packet. Returns zero on success, negative values on failure. 2356 * 2357 */ 2358static int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, 2359 u32 base_sid, 2360 u32 *sid) 2361{ 2362 int rc; 2363 struct netlbl_lsm_secattr secattr; 2364 2365 netlbl_secattr_init(&secattr); 2366 rc = netlbl_skbuff_getattr(skb, &secattr); 2367 if (rc == 0) 2368 rc = selinux_netlbl_secattr_to_sid(skb, 2369 &secattr, 2370 base_sid, 2371 sid); 2372 netlbl_secattr_destroy(&secattr, 0); 2373 2374 return rc; 2375} 2376 2377/** 2378 * selinux_netlbl_socket_setsid - Label a socket using the NetLabel mechanism 2379 * @sock: the socket to label 2380 * @sid: the SID to use 2381 * 2382 * Description: 2383 * Attempt to label a socket using the NetLabel mechanism using the given 2384 * SID. Returns zero values on success, negative values on failure. 2385 * 2386 */ 2387static int selinux_netlbl_socket_setsid(struct socket *sock, u32 sid) 2388{ 2389 int rc = -ENOENT; 2390 struct sk_security_struct *sksec = sock->sk->sk_security; 2391 struct netlbl_lsm_secattr secattr; 2392 struct context *ctx; 2393 2394 if (!ss_initialized) 2395 return 0; 2396 2397 POLICY_RDLOCK; 2398 2399 ctx = sidtab_search(&sidtab, sid); 2400 if (ctx == NULL) 2401 goto netlbl_socket_setsid_return; 2402 2403 netlbl_secattr_init(&secattr); 2404 secattr.domain = kstrdup(policydb.p_type_val_to_name[ctx->type - 1], 2405 GFP_ATOMIC); 2406 mls_export_lvl(ctx, &secattr.mls_lvl, NULL); 2407 secattr.mls_lvl_vld = 1; 2408 mls_export_cat(ctx, 2409 &secattr.mls_cat, 2410 &secattr.mls_cat_len, 2411 NULL, 2412 NULL); 2413 2414 rc = netlbl_socket_setattr(sock, &secattr); 2415 if (rc == 0) 2416 sksec->nlbl_state = NLBL_LABELED; 2417 2418 netlbl_secattr_destroy(&secattr, 0); 2419 2420netlbl_socket_setsid_return: 2421 POLICY_RDUNLOCK; 2422 return rc; 2423} 2424 2425/** 2426 * selinux_netlbl_sk_security_init - Setup the NetLabel fields 2427 * @ssec: the sk_security_struct 2428 * @family: the socket family 2429 * 2430 * Description: 2431 * Called when a new sk_security_struct is allocated to initialize the NetLabel 2432 * fields. 2433 * 2434 */ 2435void selinux_netlbl_sk_security_init(struct sk_security_struct *ssec, 2436 int family) 2437{ 2438 if (family == PF_INET) 2439 ssec->nlbl_state = NLBL_REQUIRE; 2440 else 2441 ssec->nlbl_state = NLBL_UNSET; 2442} 2443 2444/** 2445 * selinux_netlbl_sk_clone_security - Copy the NetLabel fields 2446 * @ssec: the original sk_security_struct 2447 * @newssec: the cloned sk_security_struct 2448 * 2449 * Description: 2450 * Clone the NetLabel specific sk_security_struct fields from @ssec to 2451 * @newssec. 2452 * 2453 */ 2454void selinux_netlbl_sk_clone_security(struct sk_security_struct *ssec, 2455 struct sk_security_struct *newssec) 2456{ 2457 newssec->sclass = ssec->sclass; 2458 if (ssec->nlbl_state != NLBL_UNSET) 2459 newssec->nlbl_state = NLBL_REQUIRE; 2460 else 2461 newssec->nlbl_state = NLBL_UNSET; 2462} 2463 2464/** 2465 * selinux_netlbl_socket_post_create - Label a socket using NetLabel 2466 * @sock: the socket to label 2467 * @sock_family: the socket family 2468 * @sid: the SID to use 2469 * 2470 * Description: 2471 * Attempt to label a socket using the NetLabel mechanism using the given 2472 * SID. Returns zero values on success, negative values on failure. 2473 * 2474 */ 2475int selinux_netlbl_socket_post_create(struct socket *sock, 2476 int sock_family, 2477 u32 sid) 2478{ 2479 struct inode_security_struct *isec = SOCK_INODE(sock)->i_security; 2480 struct sk_security_struct *sksec = sock->sk->sk_security; 2481 2482 sksec->sclass = isec->sclass; 2483 2484 if (sock_family != PF_INET) 2485 return 0; 2486 2487 sksec->nlbl_state = NLBL_REQUIRE; 2488 return selinux_netlbl_socket_setsid(sock, sid); 2489} 2490 2491/** 2492 * selinux_netlbl_sock_graft - Netlabel the new socket 2493 * @sk: the new connection 2494 * @sock: the new socket 2495 * 2496 * Description: 2497 * The connection represented by @sk is being grafted onto @sock so set the 2498 * socket's NetLabel to match the SID of @sk. 2499 * 2500 */ 2501void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock) 2502{ 2503 struct inode_security_struct *isec = SOCK_INODE(sock)->i_security; 2504 struct sk_security_struct *sksec = sk->sk_security; 2505 struct netlbl_lsm_secattr secattr; 2506 u32 nlbl_peer_sid; 2507 2508 sksec->sclass = isec->sclass; 2509 2510 if (sk->sk_family != PF_INET) 2511 return; 2512 2513 netlbl_secattr_init(&secattr); 2514 if (netlbl_sock_getattr(sk, &secattr) == 0 && 2515 selinux_netlbl_secattr_to_sid(NULL, 2516 &secattr, 2517 sksec->sid, 2518 &nlbl_peer_sid) == 0) 2519 sksec->peer_sid = nlbl_peer_sid; 2520 netlbl_secattr_destroy(&secattr, 0); 2521 2522 sksec->nlbl_state = NLBL_REQUIRE; 2523 2524 /* Try to set the NetLabel on the socket to save time later, if we fail 2525 * here we will pick up the pieces in later calls to 2526 * selinux_netlbl_inode_permission(). */ 2527 selinux_netlbl_socket_setsid(sock, sksec->sid); 2528} 2529 2530/** 2531 * selinux_netlbl_inet_conn_request - Handle a new connection request 2532 * @skb: the packet 2533 * @sock_sid: the SID of the parent socket 2534 * 2535 * Description: 2536 * If present, use the security attributes of the packet in @skb and the 2537 * parent sock's SID to arrive at a SID for the new child sock. Returns the 2538 * SID of the connection or SECSID_NULL on failure. 2539 * 2540 */ 2541u32 selinux_netlbl_inet_conn_request(struct sk_buff *skb, u32 sock_sid) 2542{ 2543 int rc; 2544 u32 peer_sid; 2545 2546 rc = selinux_netlbl_skbuff_getsid(skb, sock_sid, &peer_sid); 2547 if (rc != 0) 2548 return SECSID_NULL; 2549 2550 if (peer_sid == SECINITSID_UNLABELED) 2551 return SECSID_NULL; 2552 2553 return peer_sid; 2554} 2555 2556/** 2557 * selinux_netlbl_inode_permission - Verify the socket is NetLabel labeled 2558 * @inode: the file descriptor's inode 2559 * @mask: the permission mask 2560 * 2561 * Description: 2562 * Looks at a file's inode and if it is marked as a socket protected by 2563 * NetLabel then verify that the socket has been labeled, if not try to label 2564 * the socket now with the inode's SID. Returns zero on success, negative 2565 * values on failure. 2566 * 2567 */ 2568int selinux_netlbl_inode_permission(struct inode *inode, int mask) 2569{ 2570 int rc; 2571 struct inode_security_struct *isec; 2572 struct sk_security_struct *sksec; 2573 struct socket *sock; 2574 2575 if (!S_ISSOCK(inode->i_mode)) 2576 return 0; 2577 2578 sock = SOCKET_I(inode); 2579 isec = inode->i_security; 2580 sksec = sock->sk->sk_security; 2581 mutex_lock(&isec->lock); 2582 if (unlikely(sksec->nlbl_state == NLBL_REQUIRE && 2583 (mask & (MAY_WRITE | MAY_APPEND)))) { 2584 lock_sock(sock->sk); 2585 rc = selinux_netlbl_socket_setsid(sock, sksec->sid); 2586 release_sock(sock->sk); 2587 } else 2588 rc = 0; 2589 mutex_unlock(&isec->lock); 2590 2591 return rc; 2592} 2593 2594/** 2595 * selinux_netlbl_sock_rcv_skb - Do an inbound access check using NetLabel 2596 * @sksec: the sock's sk_security_struct 2597 * @skb: the packet 2598 * @ad: the audit data 2599 * 2600 * Description: 2601 * Fetch the NetLabel security attributes from @skb and perform an access check 2602 * against the receiving socket. Returns zero on success, negative values on 2603 * error. 2604 * 2605 */ 2606int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, 2607 struct sk_buff *skb, 2608 struct avc_audit_data *ad) 2609{ 2610 int rc; 2611 u32 netlbl_sid; 2612 u32 recv_perm; 2613 2614 rc = selinux_netlbl_skbuff_getsid(skb, SECINITSID_NETMSG, &netlbl_sid); 2615 if (rc != 0) 2616 return rc; 2617 2618 if (netlbl_sid == SECINITSID_UNLABELED) 2619 return 0; 2620 2621 switch (sksec->sclass) { 2622 case SECCLASS_UDP_SOCKET: 2623 recv_perm = UDP_SOCKET__RECVFROM; 2624 break; 2625 case SECCLASS_TCP_SOCKET: 2626 recv_perm = TCP_SOCKET__RECVFROM; 2627 break; 2628 default: 2629 recv_perm = RAWIP_SOCKET__RECVFROM; 2630 } 2631 2632 rc = avc_has_perm(sksec->sid, 2633 netlbl_sid, 2634 sksec->sclass, 2635 recv_perm, 2636 ad); 2637 if (rc == 0) 2638 return 0; 2639 2640 netlbl_skbuff_err(skb, rc); 2641 return rc; 2642} 2643 2644/** 2645 * selinux_netlbl_socket_getpeersec_stream - Return the connected peer's SID 2646 * @sock: the socket 2647 * 2648 * Description: 2649 * Examine @sock to find the connected peer's SID. Returns the SID on success 2650 * or SECSID_NULL on error. 2651 * 2652 */ 2653u32 selinux_netlbl_socket_getpeersec_stream(struct socket *sock) 2654{ 2655 struct sk_security_struct *sksec = sock->sk->sk_security; 2656 2657 if (sksec->peer_sid == SECINITSID_UNLABELED) 2658 return SECSID_NULL; 2659 2660 return sksec->peer_sid; 2661} 2662 2663/** 2664 * selinux_netlbl_socket_getpeersec_dgram - Return the SID of a NetLabel packet 2665 * @skb: the packet 2666 * 2667 * Description: 2668 * Examine @skb to find the SID assigned to it by NetLabel. Returns the SID on 2669 * success, SECSID_NULL on error. 2670 * 2671 */ 2672u32 selinux_netlbl_socket_getpeersec_dgram(struct sk_buff *skb) 2673{ 2674 int peer_sid; 2675 struct sock *sk = skb->sk; 2676 struct inode_security_struct *isec; 2677 2678 if (sk == NULL || sk->sk_socket == NULL) 2679 return SECSID_NULL; 2680 2681 isec = SOCK_INODE(sk->sk_socket)->i_security; 2682 if (selinux_netlbl_skbuff_getsid(skb, isec->sid, &peer_sid) != 0) 2683 return SECSID_NULL; 2684 if (peer_sid == SECINITSID_UNLABELED) 2685 return SECSID_NULL; 2686 2687 return peer_sid; 2688} 2689#endif /* CONFIG_NETLABEL */ 2690