0001
0002
0003
0004
0005
0006
0007
0008 #include "common.h"
0009
0010 #include <linux/binfmts.h>
0011 #include <linux/slab.h>
0012 #include <linux/rculist.h>
0013
0014
0015
0016
0017 struct tomoyo_domain_info tomoyo_kernel_domain;
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size,
0032 struct tomoyo_acl_param *param,
0033 bool (*check_duplicate)(const struct tomoyo_acl_head
0034 *,
0035 const struct tomoyo_acl_head
0036 *))
0037 {
0038 int error = param->is_delete ? -ENOENT : -ENOMEM;
0039 struct tomoyo_acl_head *entry;
0040 struct list_head *list = param->list;
0041
0042 if (mutex_lock_interruptible(&tomoyo_policy_lock))
0043 return -ENOMEM;
0044 list_for_each_entry_rcu(entry, list, list,
0045 srcu_read_lock_held(&tomoyo_ss)) {
0046 if (entry->is_deleted == TOMOYO_GC_IN_PROGRESS)
0047 continue;
0048 if (!check_duplicate(entry, new_entry))
0049 continue;
0050 entry->is_deleted = param->is_delete;
0051 error = 0;
0052 break;
0053 }
0054 if (error && !param->is_delete) {
0055 entry = tomoyo_commit_ok(new_entry, size);
0056 if (entry) {
0057 list_add_tail_rcu(&entry->list, list);
0058 error = 0;
0059 }
0060 }
0061 mutex_unlock(&tomoyo_policy_lock);
0062 return error;
0063 }
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073 static inline bool tomoyo_same_acl_head(const struct tomoyo_acl_info *a,
0074 const struct tomoyo_acl_info *b)
0075 {
0076 return a->type == b->type && a->cond == b->cond;
0077 }
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092 int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size,
0093 struct tomoyo_acl_param *param,
0094 bool (*check_duplicate)(const struct tomoyo_acl_info
0095 *,
0096 const struct tomoyo_acl_info
0097 *),
0098 bool (*merge_duplicate)(struct tomoyo_acl_info *,
0099 struct tomoyo_acl_info *,
0100 const bool))
0101 {
0102 const bool is_delete = param->is_delete;
0103 int error = is_delete ? -ENOENT : -ENOMEM;
0104 struct tomoyo_acl_info *entry;
0105 struct list_head * const list = param->list;
0106
0107 if (param->data[0]) {
0108 new_entry->cond = tomoyo_get_condition(param);
0109 if (!new_entry->cond)
0110 return -EINVAL;
0111
0112
0113
0114
0115 if (new_entry->cond->transit &&
0116 !(new_entry->type == TOMOYO_TYPE_PATH_ACL &&
0117 container_of(new_entry, struct tomoyo_path_acl, head)
0118 ->perm == 1 << TOMOYO_TYPE_EXECUTE))
0119 goto out;
0120 }
0121 if (mutex_lock_interruptible(&tomoyo_policy_lock))
0122 goto out;
0123 list_for_each_entry_rcu(entry, list, list,
0124 srcu_read_lock_held(&tomoyo_ss)) {
0125 if (entry->is_deleted == TOMOYO_GC_IN_PROGRESS)
0126 continue;
0127 if (!tomoyo_same_acl_head(entry, new_entry) ||
0128 !check_duplicate(entry, new_entry))
0129 continue;
0130 if (merge_duplicate)
0131 entry->is_deleted = merge_duplicate(entry, new_entry,
0132 is_delete);
0133 else
0134 entry->is_deleted = is_delete;
0135 error = 0;
0136 break;
0137 }
0138 if (error && !is_delete) {
0139 entry = tomoyo_commit_ok(new_entry, size);
0140 if (entry) {
0141 list_add_tail_rcu(&entry->list, list);
0142 error = 0;
0143 }
0144 }
0145 mutex_unlock(&tomoyo_policy_lock);
0146 out:
0147 tomoyo_put_condition(new_entry->cond);
0148 return error;
0149 }
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161 void tomoyo_check_acl(struct tomoyo_request_info *r,
0162 bool (*check_entry)(struct tomoyo_request_info *,
0163 const struct tomoyo_acl_info *))
0164 {
0165 const struct tomoyo_domain_info *domain = r->domain;
0166 struct tomoyo_acl_info *ptr;
0167 const struct list_head *list = &domain->acl_info_list;
0168 u16 i = 0;
0169
0170 retry:
0171 list_for_each_entry_rcu(ptr, list, list,
0172 srcu_read_lock_held(&tomoyo_ss)) {
0173 if (ptr->is_deleted || ptr->type != r->param_type)
0174 continue;
0175 if (!check_entry(r, ptr))
0176 continue;
0177 if (!tomoyo_condition(r, ptr->cond))
0178 continue;
0179 r->matched_acl = ptr;
0180 r->granted = true;
0181 return;
0182 }
0183 for (; i < TOMOYO_MAX_ACL_GROUPS; i++) {
0184 if (!test_bit(i, domain->group))
0185 continue;
0186 list = &domain->ns->acl_group[i++];
0187 goto retry;
0188 }
0189 r->granted = false;
0190 }
0191
0192
0193 LIST_HEAD(tomoyo_domain_list);
0194
0195
0196
0197
0198
0199
0200
0201
0202 static const char *tomoyo_last_word(const char *name)
0203 {
0204 const char *cp = strrchr(name, ' ');
0205
0206 if (cp)
0207 return cp + 1;
0208 return name;
0209 }
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219 static bool tomoyo_same_transition_control(const struct tomoyo_acl_head *a,
0220 const struct tomoyo_acl_head *b)
0221 {
0222 const struct tomoyo_transition_control *p1 = container_of(a,
0223 typeof(*p1),
0224 head);
0225 const struct tomoyo_transition_control *p2 = container_of(b,
0226 typeof(*p2),
0227 head);
0228
0229 return p1->type == p2->type && p1->is_last_name == p2->is_last_name
0230 && p1->domainname == p2->domainname
0231 && p1->program == p2->program;
0232 }
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242 int tomoyo_write_transition_control(struct tomoyo_acl_param *param,
0243 const u8 type)
0244 {
0245 struct tomoyo_transition_control e = { .type = type };
0246 int error = param->is_delete ? -ENOENT : -ENOMEM;
0247 char *program = param->data;
0248 char *domainname = strstr(program, " from ");
0249
0250 if (domainname) {
0251 *domainname = '\0';
0252 domainname += 6;
0253 } else if (type == TOMOYO_TRANSITION_CONTROL_NO_KEEP ||
0254 type == TOMOYO_TRANSITION_CONTROL_KEEP) {
0255 domainname = program;
0256 program = NULL;
0257 }
0258 if (program && strcmp(program, "any")) {
0259 if (!tomoyo_correct_path(program))
0260 return -EINVAL;
0261 e.program = tomoyo_get_name(program);
0262 if (!e.program)
0263 goto out;
0264 }
0265 if (domainname && strcmp(domainname, "any")) {
0266 if (!tomoyo_correct_domain(domainname)) {
0267 if (!tomoyo_correct_path(domainname))
0268 goto out;
0269 e.is_last_name = true;
0270 }
0271 e.domainname = tomoyo_get_name(domainname);
0272 if (!e.domainname)
0273 goto out;
0274 }
0275 param->list = ¶m->ns->policy_list[TOMOYO_ID_TRANSITION_CONTROL];
0276 error = tomoyo_update_policy(&e.head, sizeof(e), param,
0277 tomoyo_same_transition_control);
0278 out:
0279 tomoyo_put_name(e.domainname);
0280 tomoyo_put_name(e.program);
0281 return error;
0282 }
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297 static inline bool tomoyo_scan_transition
0298 (const struct list_head *list, const struct tomoyo_path_info *domainname,
0299 const struct tomoyo_path_info *program, const char *last_name,
0300 const enum tomoyo_transition_type type)
0301 {
0302 const struct tomoyo_transition_control *ptr;
0303
0304 list_for_each_entry_rcu(ptr, list, head.list,
0305 srcu_read_lock_held(&tomoyo_ss)) {
0306 if (ptr->head.is_deleted || ptr->type != type)
0307 continue;
0308 if (ptr->domainname) {
0309 if (!ptr->is_last_name) {
0310 if (ptr->domainname != domainname)
0311 continue;
0312 } else {
0313
0314
0315
0316
0317 if (strcmp(ptr->domainname->name, last_name))
0318 continue;
0319 }
0320 }
0321 if (ptr->program && tomoyo_pathcmp(ptr->program, program))
0322 continue;
0323 return true;
0324 }
0325 return false;
0326 }
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343 static enum tomoyo_transition_type tomoyo_transition_type
0344 (const struct tomoyo_policy_namespace *ns,
0345 const struct tomoyo_path_info *domainname,
0346 const struct tomoyo_path_info *program)
0347 {
0348 const char *last_name = tomoyo_last_word(domainname->name);
0349 enum tomoyo_transition_type type = TOMOYO_TRANSITION_CONTROL_NO_RESET;
0350
0351 while (type < TOMOYO_MAX_TRANSITION_TYPE) {
0352 const struct list_head * const list =
0353 &ns->policy_list[TOMOYO_ID_TRANSITION_CONTROL];
0354
0355 if (!tomoyo_scan_transition(list, domainname, program,
0356 last_name, type)) {
0357 type++;
0358 continue;
0359 }
0360 if (type != TOMOYO_TRANSITION_CONTROL_NO_RESET &&
0361 type != TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE)
0362 break;
0363
0364
0365
0366
0367
0368 type++;
0369 type++;
0370 }
0371 return type;
0372 }
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382 static bool tomoyo_same_aggregator(const struct tomoyo_acl_head *a,
0383 const struct tomoyo_acl_head *b)
0384 {
0385 const struct tomoyo_aggregator *p1 = container_of(a, typeof(*p1),
0386 head);
0387 const struct tomoyo_aggregator *p2 = container_of(b, typeof(*p2),
0388 head);
0389
0390 return p1->original_name == p2->original_name &&
0391 p1->aggregated_name == p2->aggregated_name;
0392 }
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403 int tomoyo_write_aggregator(struct tomoyo_acl_param *param)
0404 {
0405 struct tomoyo_aggregator e = { };
0406 int error = param->is_delete ? -ENOENT : -ENOMEM;
0407 const char *original_name = tomoyo_read_token(param);
0408 const char *aggregated_name = tomoyo_read_token(param);
0409
0410 if (!tomoyo_correct_word(original_name) ||
0411 !tomoyo_correct_path(aggregated_name))
0412 return -EINVAL;
0413 e.original_name = tomoyo_get_name(original_name);
0414 e.aggregated_name = tomoyo_get_name(aggregated_name);
0415 if (!e.original_name || !e.aggregated_name ||
0416 e.aggregated_name->is_patterned)
0417 goto out;
0418 param->list = ¶m->ns->policy_list[TOMOYO_ID_AGGREGATOR];
0419 error = tomoyo_update_policy(&e.head, sizeof(e), param,
0420 tomoyo_same_aggregator);
0421 out:
0422 tomoyo_put_name(e.original_name);
0423 tomoyo_put_name(e.aggregated_name);
0424 return error;
0425 }
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438 static struct tomoyo_policy_namespace *tomoyo_find_namespace
0439 (const char *name, const unsigned int len)
0440 {
0441 struct tomoyo_policy_namespace *ns;
0442
0443 list_for_each_entry(ns, &tomoyo_namespace_list, namespace_list) {
0444 if (strncmp(name, ns->name, len) ||
0445 (name[len] && name[len] != ' '))
0446 continue;
0447 return ns;
0448 }
0449 return NULL;
0450 }
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462 struct tomoyo_policy_namespace *tomoyo_assign_namespace(const char *domainname)
0463 {
0464 struct tomoyo_policy_namespace *ptr;
0465 struct tomoyo_policy_namespace *entry;
0466 const char *cp = domainname;
0467 unsigned int len = 0;
0468
0469 while (*cp && *cp++ != ' ')
0470 len++;
0471 ptr = tomoyo_find_namespace(domainname, len);
0472 if (ptr)
0473 return ptr;
0474 if (len >= TOMOYO_EXEC_TMPSIZE - 10 || !tomoyo_domain_def(domainname))
0475 return NULL;
0476 entry = kzalloc(sizeof(*entry) + len + 1, GFP_NOFS | __GFP_NOWARN);
0477 if (mutex_lock_interruptible(&tomoyo_policy_lock))
0478 goto out;
0479 ptr = tomoyo_find_namespace(domainname, len);
0480 if (!ptr && tomoyo_memory_ok(entry)) {
0481 char *name = (char *) (entry + 1);
0482
0483 ptr = entry;
0484 memmove(name, domainname, len);
0485 name[len] = '\0';
0486 entry->name = name;
0487 tomoyo_init_policy_namespace(entry);
0488 entry = NULL;
0489 }
0490 mutex_unlock(&tomoyo_policy_lock);
0491 out:
0492 kfree(entry);
0493 return ptr;
0494 }
0495
0496
0497
0498
0499
0500
0501
0502
0503 static bool tomoyo_namespace_jump(const char *domainname)
0504 {
0505 const char *namespace = tomoyo_current_namespace()->name;
0506 const int len = strlen(namespace);
0507
0508 return strncmp(domainname, namespace, len) ||
0509 (domainname[len] && domainname[len] != ' ');
0510 }
0511
0512
0513
0514
0515
0516
0517
0518
0519
0520
0521
0522 struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname,
0523 const bool transit)
0524 {
0525 struct tomoyo_domain_info e = { };
0526 struct tomoyo_domain_info *entry = tomoyo_find_domain(domainname);
0527 bool created = false;
0528
0529 if (entry) {
0530 if (transit) {
0531
0532
0533
0534
0535
0536
0537 if (tomoyo_policy_loaded &&
0538 !entry->ns->profile_ptr[entry->profile])
0539 return NULL;
0540 }
0541 return entry;
0542 }
0543
0544
0545 if (strlen(domainname) >= TOMOYO_EXEC_TMPSIZE - 10 ||
0546 !tomoyo_correct_domain(domainname))
0547 return NULL;
0548
0549
0550
0551
0552
0553 if (transit && tomoyo_namespace_jump(domainname))
0554 return NULL;
0555 e.ns = tomoyo_assign_namespace(domainname);
0556 if (!e.ns)
0557 return NULL;
0558
0559
0560
0561
0562
0563 if (transit) {
0564 const struct tomoyo_domain_info *domain = tomoyo_domain();
0565
0566 e.profile = domain->profile;
0567 memcpy(e.group, domain->group, sizeof(e.group));
0568 }
0569 e.domainname = tomoyo_get_name(domainname);
0570 if (!e.domainname)
0571 return NULL;
0572 if (mutex_lock_interruptible(&tomoyo_policy_lock))
0573 goto out;
0574 entry = tomoyo_find_domain(domainname);
0575 if (!entry) {
0576 entry = tomoyo_commit_ok(&e, sizeof(e));
0577 if (entry) {
0578 INIT_LIST_HEAD(&entry->acl_info_list);
0579 list_add_tail_rcu(&entry->list, &tomoyo_domain_list);
0580 created = true;
0581 }
0582 }
0583 mutex_unlock(&tomoyo_policy_lock);
0584 out:
0585 tomoyo_put_name(e.domainname);
0586 if (entry && transit) {
0587 if (created) {
0588 struct tomoyo_request_info r;
0589 int i;
0590
0591 tomoyo_init_request_info(&r, entry,
0592 TOMOYO_MAC_FILE_EXECUTE);
0593 r.granted = false;
0594 tomoyo_write_log(&r, "use_profile %u\n",
0595 entry->profile);
0596 for (i = 0; i < TOMOYO_MAX_ACL_GROUPS; i++)
0597 if (test_bit(i, entry->group))
0598 tomoyo_write_log(&r, "use_group %u\n",
0599 i);
0600 tomoyo_update_stat(TOMOYO_STAT_POLICY_UPDATES);
0601 }
0602 }
0603 return entry;
0604 }
0605
0606
0607
0608
0609
0610
0611
0612
0613 static int tomoyo_environ(struct tomoyo_execve *ee)
0614 {
0615 struct tomoyo_request_info *r = &ee->r;
0616 struct linux_binprm *bprm = ee->bprm;
0617
0618 struct tomoyo_page_dump env_page = { };
0619 char *arg_ptr;
0620 int arg_len = 0;
0621 unsigned long pos = bprm->p;
0622 int offset = pos % PAGE_SIZE;
0623 int argv_count = bprm->argc;
0624 int envp_count = bprm->envc;
0625 int error = -ENOMEM;
0626
0627 ee->r.type = TOMOYO_MAC_ENVIRON;
0628 ee->r.profile = r->domain->profile;
0629 ee->r.mode = tomoyo_get_mode(r->domain->ns, ee->r.profile,
0630 TOMOYO_MAC_ENVIRON);
0631 if (!r->mode || !envp_count)
0632 return 0;
0633 arg_ptr = kzalloc(TOMOYO_EXEC_TMPSIZE, GFP_NOFS);
0634 if (!arg_ptr)
0635 goto out;
0636 while (error == -ENOMEM) {
0637 if (!tomoyo_dump_page(bprm, pos, &env_page))
0638 goto out;
0639 pos += PAGE_SIZE - offset;
0640
0641 while (argv_count && offset < PAGE_SIZE) {
0642 if (!env_page.data[offset++])
0643 argv_count--;
0644 }
0645 if (argv_count) {
0646 offset = 0;
0647 continue;
0648 }
0649 while (offset < PAGE_SIZE) {
0650 const unsigned char c = env_page.data[offset++];
0651
0652 if (c && arg_len < TOMOYO_EXEC_TMPSIZE - 10) {
0653 if (c == '=') {
0654 arg_ptr[arg_len++] = '\0';
0655 } else if (c == '\\') {
0656 arg_ptr[arg_len++] = '\\';
0657 arg_ptr[arg_len++] = '\\';
0658 } else if (c > ' ' && c < 127) {
0659 arg_ptr[arg_len++] = c;
0660 } else {
0661 arg_ptr[arg_len++] = '\\';
0662 arg_ptr[arg_len++] = (c >> 6) + '0';
0663 arg_ptr[arg_len++]
0664 = ((c >> 3) & 7) + '0';
0665 arg_ptr[arg_len++] = (c & 7) + '0';
0666 }
0667 } else {
0668 arg_ptr[arg_len] = '\0';
0669 }
0670 if (c)
0671 continue;
0672 if (tomoyo_env_perm(r, arg_ptr)) {
0673 error = -EPERM;
0674 break;
0675 }
0676 if (!--envp_count) {
0677 error = 0;
0678 break;
0679 }
0680 arg_len = 0;
0681 }
0682 offset = 0;
0683 }
0684 out:
0685 if (r->mode != TOMOYO_CONFIG_ENFORCING)
0686 error = 0;
0687 kfree(env_page.data);
0688 kfree(arg_ptr);
0689 return error;
0690 }
0691
0692
0693
0694
0695
0696
0697
0698
0699
0700
0701 int tomoyo_find_next_domain(struct linux_binprm *bprm)
0702 {
0703 struct tomoyo_domain_info *old_domain = tomoyo_domain();
0704 struct tomoyo_domain_info *domain = NULL;
0705 const char *original_name = bprm->filename;
0706 int retval = -ENOMEM;
0707 bool reject_on_transition_failure = false;
0708 const struct tomoyo_path_info *candidate;
0709 struct tomoyo_path_info exename;
0710 struct tomoyo_execve *ee = kzalloc(sizeof(*ee), GFP_NOFS);
0711
0712 if (!ee)
0713 return -ENOMEM;
0714 ee->tmp = kzalloc(TOMOYO_EXEC_TMPSIZE, GFP_NOFS);
0715 if (!ee->tmp) {
0716 kfree(ee);
0717 return -ENOMEM;
0718 }
0719
0720 tomoyo_init_request_info(&ee->r, NULL, TOMOYO_MAC_FILE_EXECUTE);
0721 ee->r.ee = ee;
0722 ee->bprm = bprm;
0723 ee->r.obj = &ee->obj;
0724 ee->obj.path1 = bprm->file->f_path;
0725
0726 retval = -ENOENT;
0727 exename.name = tomoyo_realpath_nofollow(original_name);
0728 if (!exename.name)
0729 goto out;
0730 tomoyo_fill_path_info(&exename);
0731 retry:
0732
0733 {
0734 struct tomoyo_aggregator *ptr;
0735 struct list_head *list =
0736 &old_domain->ns->policy_list[TOMOYO_ID_AGGREGATOR];
0737
0738
0739 candidate = &exename;
0740 list_for_each_entry_rcu(ptr, list, head.list,
0741 srcu_read_lock_held(&tomoyo_ss)) {
0742 if (ptr->head.is_deleted ||
0743 !tomoyo_path_matches_pattern(&exename,
0744 ptr->original_name))
0745 continue;
0746 candidate = ptr->aggregated_name;
0747 break;
0748 }
0749 }
0750
0751
0752 retval = tomoyo_execute_permission(&ee->r, candidate);
0753 if (retval == TOMOYO_RETRY_REQUEST)
0754 goto retry;
0755 if (retval < 0)
0756 goto out;
0757
0758
0759
0760
0761
0762
0763 if (ee->r.param.path.matched_path)
0764 candidate = ee->r.param.path.matched_path;
0765
0766
0767
0768
0769
0770
0771
0772 if (ee->transition) {
0773 const char *domainname = ee->transition->name;
0774
0775 reject_on_transition_failure = true;
0776 if (!strcmp(domainname, "keep"))
0777 goto force_keep_domain;
0778 if (!strcmp(domainname, "child"))
0779 goto force_child_domain;
0780 if (!strcmp(domainname, "reset"))
0781 goto force_reset_domain;
0782 if (!strcmp(domainname, "initialize"))
0783 goto force_initialize_domain;
0784 if (!strcmp(domainname, "parent")) {
0785 char *cp;
0786
0787 strncpy(ee->tmp, old_domain->domainname->name,
0788 TOMOYO_EXEC_TMPSIZE - 1);
0789 cp = strrchr(ee->tmp, ' ');
0790 if (cp)
0791 *cp = '\0';
0792 } else if (*domainname == '<')
0793 strncpy(ee->tmp, domainname, TOMOYO_EXEC_TMPSIZE - 1);
0794 else
0795 snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s",
0796 old_domain->domainname->name, domainname);
0797 goto force_jump_domain;
0798 }
0799
0800
0801
0802
0803 switch (tomoyo_transition_type(old_domain->ns, old_domain->domainname,
0804 candidate)) {
0805 case TOMOYO_TRANSITION_CONTROL_RESET:
0806 force_reset_domain:
0807
0808 snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "<%s>",
0809 candidate->name);
0810
0811
0812
0813
0814 reject_on_transition_failure = true;
0815 break;
0816 case TOMOYO_TRANSITION_CONTROL_INITIALIZE:
0817 force_initialize_domain:
0818
0819 snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s",
0820 old_domain->ns->name, candidate->name);
0821 break;
0822 case TOMOYO_TRANSITION_CONTROL_KEEP:
0823 force_keep_domain:
0824
0825 domain = old_domain;
0826 break;
0827 default:
0828 if (old_domain == &tomoyo_kernel_domain &&
0829 !tomoyo_policy_loaded) {
0830
0831
0832
0833
0834
0835
0836 domain = old_domain;
0837 break;
0838 }
0839 force_child_domain:
0840
0841 snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s",
0842 old_domain->domainname->name, candidate->name);
0843 break;
0844 }
0845 force_jump_domain:
0846 if (!domain)
0847 domain = tomoyo_assign_domain(ee->tmp, true);
0848 if (domain)
0849 retval = 0;
0850 else if (reject_on_transition_failure) {
0851 pr_warn("ERROR: Domain '%s' not ready.\n", ee->tmp);
0852 retval = -ENOMEM;
0853 } else if (ee->r.mode == TOMOYO_CONFIG_ENFORCING)
0854 retval = -ENOMEM;
0855 else {
0856 retval = 0;
0857 if (!old_domain->flags[TOMOYO_DIF_TRANSITION_FAILED]) {
0858 old_domain->flags[TOMOYO_DIF_TRANSITION_FAILED] = true;
0859 ee->r.granted = false;
0860 tomoyo_write_log(&ee->r, "%s", tomoyo_dif
0861 [TOMOYO_DIF_TRANSITION_FAILED]);
0862 pr_warn("ERROR: Domain '%s' not defined.\n", ee->tmp);
0863 }
0864 }
0865 out:
0866 if (!domain)
0867 domain = old_domain;
0868
0869 {
0870 struct tomoyo_task *s = tomoyo_task(current);
0871
0872 s->old_domain_info = s->domain_info;
0873 s->domain_info = domain;
0874 atomic_inc(&domain->users);
0875 }
0876 kfree(exename.name);
0877 if (!retval) {
0878 ee->r.domain = domain;
0879 retval = tomoyo_environ(ee);
0880 }
0881 kfree(ee->tmp);
0882 kfree(ee->dump.data);
0883 kfree(ee);
0884 return retval;
0885 }
0886
0887
0888
0889
0890
0891
0892
0893
0894
0895
0896 bool tomoyo_dump_page(struct linux_binprm *bprm, unsigned long pos,
0897 struct tomoyo_page_dump *dump)
0898 {
0899 struct page *page;
0900 #ifdef CONFIG_MMU
0901 int ret;
0902 #endif
0903
0904
0905 if (!dump->data) {
0906 dump->data = kzalloc(PAGE_SIZE, GFP_NOFS);
0907 if (!dump->data)
0908 return false;
0909 }
0910
0911 #ifdef CONFIG_MMU
0912
0913
0914
0915
0916
0917 mmap_read_lock(bprm->mm);
0918 ret = get_user_pages_remote(bprm->mm, pos, 1,
0919 FOLL_FORCE, &page, NULL, NULL);
0920 mmap_read_unlock(bprm->mm);
0921 if (ret <= 0)
0922 return false;
0923 #else
0924 page = bprm->page[pos / PAGE_SIZE];
0925 #endif
0926 if (page != dump->page) {
0927 const unsigned int offset = pos % PAGE_SIZE;
0928
0929
0930
0931
0932
0933 char *kaddr = kmap_atomic(page);
0934
0935 dump->page = page;
0936 memcpy(dump->data + offset, kaddr + offset,
0937 PAGE_SIZE - offset);
0938 kunmap_atomic(kaddr);
0939 }
0940
0941 #ifdef CONFIG_MMU
0942 put_page(page);
0943 #endif
0944 return true;
0945 }