domain.c revision bd03a3e4c9a9df0c6b007045fa7fc8889111a478
1/* 2 * security/tomoyo/domain.c 3 * 4 * Domain transition functions for TOMOYO. 5 * 6 * Copyright (C) 2005-2010 NTT DATA CORPORATION 7 */ 8 9#include "common.h" 10#include <linux/binfmts.h> 11#include <linux/slab.h> 12 13/* Variables definitions.*/ 14 15/* The initial domain. */ 16struct tomoyo_domain_info tomoyo_kernel_domain; 17 18/** 19 * tomoyo_update_policy - Update an entry for exception policy. 20 * 21 * @new_entry: Pointer to "struct tomoyo_acl_info". 22 * @size: Size of @new_entry in bytes. 23 * @param: Pointer to "struct tomoyo_acl_param". 24 * @check_duplicate: Callback function to find duplicated entry. 25 * 26 * Returns 0 on success, negative value otherwise. 27 * 28 * Caller holds tomoyo_read_lock(). 29 */ 30int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size, 31 struct tomoyo_acl_param *param, 32 bool (*check_duplicate) (const struct tomoyo_acl_head 33 *, 34 const struct tomoyo_acl_head 35 *)) 36{ 37 int error = param->is_delete ? -ENOENT : -ENOMEM; 38 struct tomoyo_acl_head *entry; 39 struct list_head *list = param->list; 40 41 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 42 return -ENOMEM; 43 list_for_each_entry_rcu(entry, list, list) { 44 if (!check_duplicate(entry, new_entry)) 45 continue; 46 entry->is_deleted = param->is_delete; 47 error = 0; 48 break; 49 } 50 if (error && !param->is_delete) { 51 entry = tomoyo_commit_ok(new_entry, size); 52 if (entry) { 53 list_add_tail_rcu(&entry->list, list); 54 error = 0; 55 } 56 } 57 mutex_unlock(&tomoyo_policy_lock); 58 return error; 59} 60 61/** 62 * tomoyo_same_acl_head - Check for duplicated "struct tomoyo_acl_info" entry. 63 * 64 * @a: Pointer to "struct tomoyo_acl_info". 65 * @b: Pointer to "struct tomoyo_acl_info". 66 * 67 * Returns true if @a == @b, false otherwise. 68 */ 69static inline bool tomoyo_same_acl_head(const struct tomoyo_acl_info *a, 70 const struct tomoyo_acl_info *b) 71{ 72 return a->type == b->type; 73} 74 75/** 76 * tomoyo_update_domain - Update an entry for domain policy. 77 * 78 * @new_entry: Pointer to "struct tomoyo_acl_info". 79 * @size: Size of @new_entry in bytes. 80 * @param: Pointer to "struct tomoyo_acl_param". 81 * @check_duplicate: Callback function to find duplicated entry. 82 * @merge_duplicate: Callback function to merge duplicated entry. 83 * 84 * Returns 0 on success, negative value otherwise. 85 * 86 * Caller holds tomoyo_read_lock(). 87 */ 88int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size, 89 struct tomoyo_acl_param *param, 90 bool (*check_duplicate) (const struct tomoyo_acl_info 91 *, 92 const struct tomoyo_acl_info 93 *), 94 bool (*merge_duplicate) (struct tomoyo_acl_info *, 95 struct tomoyo_acl_info *, 96 const bool)) 97{ 98 const bool is_delete = param->is_delete; 99 int error = is_delete ? -ENOENT : -ENOMEM; 100 struct tomoyo_acl_info *entry; 101 struct list_head * const list = param->list; 102 103 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 104 return error; 105 list_for_each_entry_rcu(entry, list, list) { 106 if (!tomoyo_same_acl_head(entry, new_entry) || 107 !check_duplicate(entry, new_entry)) 108 continue; 109 if (merge_duplicate) 110 entry->is_deleted = merge_duplicate(entry, new_entry, 111 is_delete); 112 else 113 entry->is_deleted = is_delete; 114 error = 0; 115 break; 116 } 117 if (error && !is_delete) { 118 entry = tomoyo_commit_ok(new_entry, size); 119 if (entry) { 120 list_add_tail_rcu(&entry->list, list); 121 error = 0; 122 } 123 } 124 mutex_unlock(&tomoyo_policy_lock); 125 return error; 126} 127 128/** 129 * tomoyo_check_acl - Do permission check. 130 * 131 * @r: Pointer to "struct tomoyo_request_info". 132 * @check_entry: Callback function to check type specific parameters. 133 * 134 * Returns 0 on success, negative value otherwise. 135 * 136 * Caller holds tomoyo_read_lock(). 137 */ 138void tomoyo_check_acl(struct tomoyo_request_info *r, 139 bool (*check_entry) (struct tomoyo_request_info *, 140 const struct tomoyo_acl_info *)) 141{ 142 const struct tomoyo_domain_info *domain = r->domain; 143 struct tomoyo_acl_info *ptr; 144 bool retried = false; 145 const struct list_head *list = &domain->acl_info_list; 146 147retry: 148 list_for_each_entry_rcu(ptr, list, list) { 149 if (ptr->is_deleted || ptr->type != r->param_type) 150 continue; 151 if (check_entry(r, ptr)) { 152 r->granted = true; 153 return; 154 } 155 } 156 if (!retried) { 157 retried = true; 158 list = &domain->ns->acl_group[domain->group]; 159 goto retry; 160 } 161 r->granted = false; 162} 163 164/* The list for "struct tomoyo_domain_info". */ 165LIST_HEAD(tomoyo_domain_list); 166 167/** 168 * tomoyo_last_word - Get last component of a domainname. 169 * 170 * @name: Domainname to check. 171 * 172 * Returns the last word of @domainname. 173 */ 174static const char *tomoyo_last_word(const char *name) 175{ 176 const char *cp = strrchr(name, ' '); 177 if (cp) 178 return cp + 1; 179 return name; 180} 181 182/** 183 * tomoyo_same_transition_control - Check for duplicated "struct tomoyo_transition_control" entry. 184 * 185 * @a: Pointer to "struct tomoyo_acl_head". 186 * @b: Pointer to "struct tomoyo_acl_head". 187 * 188 * Returns true if @a == @b, false otherwise. 189 */ 190static bool tomoyo_same_transition_control(const struct tomoyo_acl_head *a, 191 const struct tomoyo_acl_head *b) 192{ 193 const struct tomoyo_transition_control *p1 = container_of(a, 194 typeof(*p1), 195 head); 196 const struct tomoyo_transition_control *p2 = container_of(b, 197 typeof(*p2), 198 head); 199 return p1->type == p2->type && p1->is_last_name == p2->is_last_name 200 && p1->domainname == p2->domainname 201 && p1->program == p2->program; 202} 203 204/** 205 * tomoyo_write_transition_control - Write "struct tomoyo_transition_control" list. 206 * 207 * @param: Pointer to "struct tomoyo_acl_param". 208 * @type: Type of this entry. 209 * 210 * Returns 0 on success, negative value otherwise. 211 */ 212int tomoyo_write_transition_control(struct tomoyo_acl_param *param, 213 const u8 type) 214{ 215 struct tomoyo_transition_control e = { .type = type }; 216 int error = param->is_delete ? -ENOENT : -ENOMEM; 217 char *program = param->data; 218 char *domainname = strstr(program, " from "); 219 if (domainname) { 220 *domainname = '\0'; 221 domainname += 6; 222 } else if (type == TOMOYO_TRANSITION_CONTROL_NO_KEEP || 223 type == TOMOYO_TRANSITION_CONTROL_KEEP) { 224 domainname = program; 225 program = NULL; 226 } 227 if (program && strcmp(program, "any")) { 228 if (!tomoyo_correct_path(program)) 229 return -EINVAL; 230 e.program = tomoyo_get_name(program); 231 if (!e.program) 232 goto out; 233 } 234 if (domainname && strcmp(domainname, "any")) { 235 if (!tomoyo_correct_domain(domainname)) { 236 if (!tomoyo_correct_path(domainname)) 237 goto out; 238 e.is_last_name = true; 239 } 240 e.domainname = tomoyo_get_name(domainname); 241 if (!e.domainname) 242 goto out; 243 } 244 param->list = ¶m->ns->policy_list[TOMOYO_ID_TRANSITION_CONTROL]; 245 error = tomoyo_update_policy(&e.head, sizeof(e), param, 246 tomoyo_same_transition_control); 247out: 248 tomoyo_put_name(e.domainname); 249 tomoyo_put_name(e.program); 250 return error; 251} 252 253/** 254 * tomoyo_scan_transition - Try to find specific domain transition type. 255 * 256 * @list: Pointer to "struct list_head". 257 * @domainname: The name of current domain. 258 * @program: The name of requested program. 259 * @last_name: The last component of @domainname. 260 * @type: One of values in "enum tomoyo_transition_type". 261 * 262 * Returns true if found one, false otherwise. 263 * 264 * Caller holds tomoyo_read_lock(). 265 */ 266static inline bool tomoyo_scan_transition 267(const struct list_head *list, const struct tomoyo_path_info *domainname, 268 const struct tomoyo_path_info *program, const char *last_name, 269 const enum tomoyo_transition_type type) 270{ 271 const struct tomoyo_transition_control *ptr; 272 list_for_each_entry_rcu(ptr, list, head.list) { 273 if (ptr->head.is_deleted || ptr->type != type) 274 continue; 275 if (ptr->domainname) { 276 if (!ptr->is_last_name) { 277 if (ptr->domainname != domainname) 278 continue; 279 } else { 280 /* 281 * Use direct strcmp() since this is 282 * unlikely used. 283 */ 284 if (strcmp(ptr->domainname->name, last_name)) 285 continue; 286 } 287 } 288 if (ptr->program && tomoyo_pathcmp(ptr->program, program)) 289 continue; 290 return true; 291 } 292 return false; 293} 294 295/** 296 * tomoyo_transition_type - Get domain transition type. 297 * 298 * @ns: Pointer to "struct tomoyo_policy_namespace". 299 * @domainname: The name of current domain. 300 * @program: The name of requested program. 301 * 302 * Returns TOMOYO_TRANSITION_CONTROL_TRANSIT if executing @program causes 303 * domain transition across namespaces, TOMOYO_TRANSITION_CONTROL_INITIALIZE if 304 * executing @program reinitializes domain transition within that namespace, 305 * TOMOYO_TRANSITION_CONTROL_KEEP if executing @program stays at @domainname , 306 * others otherwise. 307 * 308 * Caller holds tomoyo_read_lock(). 309 */ 310static enum tomoyo_transition_type tomoyo_transition_type 311(const struct tomoyo_policy_namespace *ns, 312 const struct tomoyo_path_info *domainname, 313 const struct tomoyo_path_info *program) 314{ 315 const char *last_name = tomoyo_last_word(domainname->name); 316 enum tomoyo_transition_type type = TOMOYO_TRANSITION_CONTROL_NO_RESET; 317 while (type < TOMOYO_MAX_TRANSITION_TYPE) { 318 const struct list_head * const list = 319 &ns->policy_list[TOMOYO_ID_TRANSITION_CONTROL]; 320 if (!tomoyo_scan_transition(list, domainname, program, 321 last_name, type)) { 322 type++; 323 continue; 324 } 325 if (type != TOMOYO_TRANSITION_CONTROL_NO_RESET && 326 type != TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE) 327 break; 328 /* 329 * Do not check for reset_domain if no_reset_domain matched. 330 * Do not check for initialize_domain if no_initialize_domain 331 * matched. 332 */ 333 type++; 334 type++; 335 } 336 return type; 337} 338 339/** 340 * tomoyo_same_aggregator - Check for duplicated "struct tomoyo_aggregator" entry. 341 * 342 * @a: Pointer to "struct tomoyo_acl_head". 343 * @b: Pointer to "struct tomoyo_acl_head". 344 * 345 * Returns true if @a == @b, false otherwise. 346 */ 347static bool tomoyo_same_aggregator(const struct tomoyo_acl_head *a, 348 const struct tomoyo_acl_head *b) 349{ 350 const struct tomoyo_aggregator *p1 = container_of(a, typeof(*p1), 351 head); 352 const struct tomoyo_aggregator *p2 = container_of(b, typeof(*p2), 353 head); 354 return p1->original_name == p2->original_name && 355 p1->aggregated_name == p2->aggregated_name; 356} 357 358/** 359 * tomoyo_write_aggregator - Write "struct tomoyo_aggregator" list. 360 * 361 * @param: Pointer to "struct tomoyo_acl_param". 362 * 363 * Returns 0 on success, negative value otherwise. 364 * 365 * Caller holds tomoyo_read_lock(). 366 */ 367int tomoyo_write_aggregator(struct tomoyo_acl_param *param) 368{ 369 struct tomoyo_aggregator e = { }; 370 int error = param->is_delete ? -ENOENT : -ENOMEM; 371 const char *original_name = tomoyo_read_token(param); 372 const char *aggregated_name = tomoyo_read_token(param); 373 if (!tomoyo_correct_word(original_name) || 374 !tomoyo_correct_path(aggregated_name)) 375 return -EINVAL; 376 e.original_name = tomoyo_get_name(original_name); 377 e.aggregated_name = tomoyo_get_name(aggregated_name); 378 if (!e.original_name || !e.aggregated_name || 379 e.aggregated_name->is_patterned) /* No patterns allowed. */ 380 goto out; 381 param->list = ¶m->ns->policy_list[TOMOYO_ID_AGGREGATOR]; 382 error = tomoyo_update_policy(&e.head, sizeof(e), param, 383 tomoyo_same_aggregator); 384out: 385 tomoyo_put_name(e.original_name); 386 tomoyo_put_name(e.aggregated_name); 387 return error; 388} 389 390/** 391 * tomoyo_find_namespace - Find specified namespace. 392 * 393 * @name: Name of namespace to find. 394 * @len: Length of @name. 395 * 396 * Returns pointer to "struct tomoyo_policy_namespace" if found, 397 * NULL otherwise. 398 * 399 * Caller holds tomoyo_read_lock(). 400 */ 401static struct tomoyo_policy_namespace *tomoyo_find_namespace 402(const char *name, const unsigned int len) 403{ 404 struct tomoyo_policy_namespace *ns; 405 list_for_each_entry(ns, &tomoyo_namespace_list, namespace_list) { 406 if (strncmp(name, ns->name, len) || 407 (name[len] && name[len] != ' ')) 408 continue; 409 return ns; 410 } 411 return NULL; 412} 413 414/** 415 * tomoyo_assign_namespace - Create a new namespace. 416 * 417 * @domainname: Name of namespace to create. 418 * 419 * Returns pointer to "struct tomoyo_policy_namespace" on success, 420 * NULL otherwise. 421 * 422 * Caller holds tomoyo_read_lock(). 423 */ 424struct tomoyo_policy_namespace *tomoyo_assign_namespace(const char *domainname) 425{ 426 struct tomoyo_policy_namespace *ptr; 427 struct tomoyo_policy_namespace *entry; 428 const char *cp = domainname; 429 unsigned int len = 0; 430 while (*cp && *cp++ != ' ') 431 len++; 432 ptr = tomoyo_find_namespace(domainname, len); 433 if (ptr) 434 return ptr; 435 if (len >= TOMOYO_EXEC_TMPSIZE - 10 || !tomoyo_domain_def(domainname)) 436 return NULL; 437 entry = kzalloc(sizeof(*entry) + len + 1, GFP_NOFS); 438 if (!entry) 439 return NULL; 440 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 441 goto out; 442 ptr = tomoyo_find_namespace(domainname, len); 443 if (!ptr && tomoyo_memory_ok(entry)) { 444 char *name = (char *) (entry + 1); 445 ptr = entry; 446 memmove(name, domainname, len); 447 name[len] = '\0'; 448 entry->name = name; 449 tomoyo_init_policy_namespace(entry); 450 entry = NULL; 451 } 452 mutex_unlock(&tomoyo_policy_lock); 453out: 454 kfree(entry); 455 return ptr; 456} 457 458/** 459 * tomoyo_namespace_jump - Check for namespace jump. 460 * 461 * @domainname: Name of domain. 462 * 463 * Returns true if namespace differs, false otherwise. 464 */ 465static bool tomoyo_namespace_jump(const char *domainname) 466{ 467 const char *namespace = tomoyo_current_namespace()->name; 468 const int len = strlen(namespace); 469 return strncmp(domainname, namespace, len) || 470 (domainname[len] && domainname[len] != ' '); 471} 472 473/** 474 * tomoyo_assign_domain - Create a domain or a namespace. 475 * 476 * @domainname: The name of domain. 477 * @transit: True if transit to domain found or created. 478 * 479 * Returns pointer to "struct tomoyo_domain_info" on success, NULL otherwise. 480 * 481 * Caller holds tomoyo_read_lock(). 482 */ 483struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname, 484 const bool transit) 485{ 486 struct tomoyo_domain_info e = { }; 487 struct tomoyo_domain_info *entry = tomoyo_find_domain(domainname); 488 bool created = false; 489 if (entry) { 490 if (transit) { 491 /* 492 * Since namespace is created at runtime, profiles may 493 * not be created by the moment the process transits to 494 * that domain. Do not perform domain transition if 495 * profile for that domain is not yet created. 496 */ 497 if (!entry->ns->profile_ptr[entry->profile]) 498 return NULL; 499 } 500 return entry; 501 } 502 /* Requested domain does not exist. */ 503 /* Don't create requested domain if domainname is invalid. */ 504 if (strlen(domainname) >= TOMOYO_EXEC_TMPSIZE - 10 || 505 !tomoyo_correct_domain(domainname)) 506 return NULL; 507 /* 508 * Since definition of profiles and acl_groups may differ across 509 * namespaces, do not inherit "use_profile" and "use_group" settings 510 * by automatically creating requested domain upon domain transition. 511 */ 512 if (transit && tomoyo_namespace_jump(domainname)) 513 return NULL; 514 e.ns = tomoyo_assign_namespace(domainname); 515 if (!e.ns) 516 return NULL; 517 /* 518 * "use_profile" and "use_group" settings for automatically created 519 * domains are inherited from current domain. These are 0 for manually 520 * created domains. 521 */ 522 if (transit) { 523 const struct tomoyo_domain_info *domain = tomoyo_domain(); 524 e.profile = domain->profile; 525 e.group = domain->group; 526 } 527 e.domainname = tomoyo_get_name(domainname); 528 if (!e.domainname) 529 return NULL; 530 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 531 goto out; 532 entry = tomoyo_find_domain(domainname); 533 if (!entry) { 534 entry = tomoyo_commit_ok(&e, sizeof(e)); 535 if (entry) { 536 INIT_LIST_HEAD(&entry->acl_info_list); 537 list_add_tail_rcu(&entry->list, &tomoyo_domain_list); 538 created = true; 539 } 540 } 541 mutex_unlock(&tomoyo_policy_lock); 542out: 543 tomoyo_put_name(e.domainname); 544 if (entry && transit) { 545 if (created) { 546 struct tomoyo_request_info r; 547 tomoyo_init_request_info(&r, entry, 548 TOMOYO_MAC_FILE_EXECUTE); 549 r.granted = false; 550 tomoyo_write_log(&r, "use_profile %u\n", 551 entry->profile); 552 tomoyo_write_log(&r, "use_group %u\n", entry->group); 553 } 554 } 555 return entry; 556} 557 558/** 559 * tomoyo_find_next_domain - Find a domain. 560 * 561 * @bprm: Pointer to "struct linux_binprm". 562 * 563 * Returns 0 on success, negative value otherwise. 564 * 565 * Caller holds tomoyo_read_lock(). 566 */ 567int tomoyo_find_next_domain(struct linux_binprm *bprm) 568{ 569 struct tomoyo_request_info r; 570 char *tmp = kzalloc(TOMOYO_EXEC_TMPSIZE, GFP_NOFS); 571 struct tomoyo_domain_info *old_domain = tomoyo_domain(); 572 struct tomoyo_domain_info *domain = NULL; 573 const char *original_name = bprm->filename; 574 u8 mode; 575 bool is_enforce; 576 int retval = -ENOMEM; 577 bool need_kfree = false; 578 bool reject_on_transition_failure = false; 579 struct tomoyo_path_info rn = { }; /* real name */ 580 581 mode = tomoyo_init_request_info(&r, NULL, TOMOYO_MAC_FILE_EXECUTE); 582 is_enforce = (mode == TOMOYO_CONFIG_ENFORCING); 583 if (!tmp) 584 goto out; 585 586 retry: 587 if (need_kfree) { 588 kfree(rn.name); 589 need_kfree = false; 590 } 591 /* Get symlink's pathname of program. */ 592 retval = -ENOENT; 593 rn.name = tomoyo_realpath_nofollow(original_name); 594 if (!rn.name) 595 goto out; 596 tomoyo_fill_path_info(&rn); 597 need_kfree = true; 598 599 /* Check 'aggregator' directive. */ 600 { 601 struct tomoyo_aggregator *ptr; 602 struct list_head *list = 603 &old_domain->ns->policy_list[TOMOYO_ID_AGGREGATOR]; 604 /* Check 'aggregator' directive. */ 605 list_for_each_entry_rcu(ptr, list, head.list) { 606 if (ptr->head.is_deleted || 607 !tomoyo_path_matches_pattern(&rn, 608 ptr->original_name)) 609 continue; 610 kfree(rn.name); 611 need_kfree = false; 612 /* This is OK because it is read only. */ 613 rn = *ptr->aggregated_name; 614 break; 615 } 616 } 617 618 /* Check execute permission. */ 619 retval = tomoyo_path_permission(&r, TOMOYO_TYPE_EXECUTE, &rn); 620 if (retval == TOMOYO_RETRY_REQUEST) 621 goto retry; 622 if (retval < 0) 623 goto out; 624 /* 625 * To be able to specify domainnames with wildcards, use the 626 * pathname specified in the policy (which may contain 627 * wildcard) rather than the pathname passed to execve() 628 * (which never contains wildcard). 629 */ 630 if (r.param.path.matched_path) { 631 if (need_kfree) 632 kfree(rn.name); 633 need_kfree = false; 634 /* This is OK because it is read only. */ 635 rn = *r.param.path.matched_path; 636 } 637 638 /* Calculate domain to transit to. */ 639 switch (tomoyo_transition_type(old_domain->ns, old_domain->domainname, 640 &rn)) { 641 case TOMOYO_TRANSITION_CONTROL_RESET: 642 /* Transit to the root of specified namespace. */ 643 snprintf(tmp, TOMOYO_EXEC_TMPSIZE - 1, "<%s>", rn.name); 644 /* 645 * Make do_execve() fail if domain transition across namespaces 646 * has failed. 647 */ 648 reject_on_transition_failure = true; 649 break; 650 case TOMOYO_TRANSITION_CONTROL_INITIALIZE: 651 /* Transit to the child of current namespace's root. */ 652 snprintf(tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s", 653 old_domain->ns->name, rn.name); 654 break; 655 case TOMOYO_TRANSITION_CONTROL_KEEP: 656 /* Keep current domain. */ 657 domain = old_domain; 658 break; 659 default: 660 if (old_domain == &tomoyo_kernel_domain && 661 !tomoyo_policy_loaded) { 662 /* 663 * Needn't to transit from kernel domain before 664 * starting /sbin/init. But transit from kernel domain 665 * if executing initializers because they might start 666 * before /sbin/init. 667 */ 668 domain = old_domain; 669 } else { 670 /* Normal domain transition. */ 671 snprintf(tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s", 672 old_domain->domainname->name, rn.name); 673 } 674 break; 675 } 676 if (!domain) 677 domain = tomoyo_assign_domain(tmp, true); 678 if (domain) 679 retval = 0; 680 else if (reject_on_transition_failure) { 681 printk(KERN_WARNING "ERROR: Domain '%s' not ready.\n", tmp); 682 retval = -ENOMEM; 683 } else if (r.mode == TOMOYO_CONFIG_ENFORCING) 684 retval = -ENOMEM; 685 else { 686 retval = 0; 687 if (!old_domain->transition_failed) { 688 old_domain->transition_failed = true; 689 r.granted = false; 690 tomoyo_write_log(&r, "%s", "transition_failed\n"); 691 printk(KERN_WARNING 692 "ERROR: Domain '%s' not defined.\n", tmp); 693 } 694 } 695 out: 696 if (!domain) 697 domain = old_domain; 698 /* Update reference count on "struct tomoyo_domain_info". */ 699 atomic_inc(&domain->users); 700 bprm->cred->security = domain; 701 if (need_kfree) 702 kfree(rn.name); 703 kfree(tmp); 704 return retval; 705} 706