aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/tomoyo/common.c28
-rw-r--r--security/tomoyo/domain.c147
-rw-r--r--security/tomoyo/file.c234
3 files changed, 183 insertions, 226 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index ae3ed7313ee0..a53ee059da48 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -1103,10 +1103,10 @@ static LIST_HEAD(tomoyo_policy_manager_list);
1103static int tomoyo_update_manager_entry(const char *manager, 1103static int tomoyo_update_manager_entry(const char *manager,
1104 const bool is_delete) 1104 const bool is_delete)
1105{ 1105{
1106 struct tomoyo_policy_manager_entry *new_entry; 1106 struct tomoyo_policy_manager_entry *entry = NULL;
1107 struct tomoyo_policy_manager_entry *ptr; 1107 struct tomoyo_policy_manager_entry *ptr;
1108 const struct tomoyo_path_info *saved_manager; 1108 const struct tomoyo_path_info *saved_manager;
1109 int error = -ENOMEM; 1109 int error = is_delete ? -ENOENT : -ENOMEM;
1110 bool is_domain = false; 1110 bool is_domain = false;
1111 1111
1112 if (tomoyo_is_domain_def(manager)) { 1112 if (tomoyo_is_domain_def(manager)) {
@@ -1120,29 +1120,25 @@ static int tomoyo_update_manager_entry(const char *manager,
1120 saved_manager = tomoyo_save_name(manager); 1120 saved_manager = tomoyo_save_name(manager);
1121 if (!saved_manager) 1121 if (!saved_manager)
1122 return -ENOMEM; 1122 return -ENOMEM;
1123 new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL); 1123 if (!is_delete)
1124 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
1124 mutex_lock(&tomoyo_policy_lock); 1125 mutex_lock(&tomoyo_policy_lock);
1125 list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) { 1126 list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) {
1126 if (ptr->manager != saved_manager) 1127 if (ptr->manager != saved_manager)
1127 continue; 1128 continue;
1128 ptr->is_deleted = is_delete; 1129 ptr->is_deleted = is_delete;
1129 error = 0; 1130 error = 0;
1130 goto out; 1131 break;
1131 } 1132 }
1132 if (is_delete) { 1133 if (!is_delete && error && tomoyo_memory_ok(entry)) {
1133 error = -ENOENT; 1134 entry->manager = saved_manager;
1134 goto out; 1135 entry->is_domain = is_domain;
1136 list_add_tail_rcu(&entry->list, &tomoyo_policy_manager_list);
1137 entry = NULL;
1138 error = 0;
1135 } 1139 }
1136 if (!tomoyo_memory_ok(new_entry))
1137 goto out;
1138 new_entry->manager = saved_manager;
1139 new_entry->is_domain = is_domain;
1140 list_add_tail_rcu(&new_entry->list, &tomoyo_policy_manager_list);
1141 new_entry = NULL;
1142 error = 0;
1143 out:
1144 mutex_unlock(&tomoyo_policy_lock); 1140 mutex_unlock(&tomoyo_policy_lock);
1145 kfree(new_entry); 1141 kfree(entry);
1146 return error; 1142 return error;
1147} 1143}
1148 1144
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index ec612ae87b51..229de1e71a38 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -201,11 +201,11 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
201 const bool is_not, 201 const bool is_not,
202 const bool is_delete) 202 const bool is_delete)
203{ 203{
204 struct tomoyo_domain_initializer_entry *new_entry; 204 struct tomoyo_domain_initializer_entry *entry = NULL;
205 struct tomoyo_domain_initializer_entry *ptr; 205 struct tomoyo_domain_initializer_entry *ptr;
206 const struct tomoyo_path_info *saved_program; 206 const struct tomoyo_path_info *saved_program;
207 const struct tomoyo_path_info *saved_domainname = NULL; 207 const struct tomoyo_path_info *saved_domainname = NULL;
208 int error = -ENOMEM; 208 int error = is_delete ? -ENOENT : -ENOMEM;
209 bool is_last_name = false; 209 bool is_last_name = false;
210 210
211 if (!tomoyo_is_correct_path(program, 1, -1, -1, __func__)) 211 if (!tomoyo_is_correct_path(program, 1, -1, -1, __func__))
@@ -218,12 +218,13 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
218 return -EINVAL; 218 return -EINVAL;
219 saved_domainname = tomoyo_save_name(domainname); 219 saved_domainname = tomoyo_save_name(domainname);
220 if (!saved_domainname) 220 if (!saved_domainname)
221 return -ENOMEM; 221 goto out;
222 } 222 }
223 saved_program = tomoyo_save_name(program); 223 saved_program = tomoyo_save_name(program);
224 if (!saved_program) 224 if (!saved_program)
225 return -ENOMEM; 225 goto out;
226 new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL); 226 if (!is_delete)
227 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
227 mutex_lock(&tomoyo_policy_lock); 228 mutex_lock(&tomoyo_policy_lock);
228 list_for_each_entry_rcu(ptr, &tomoyo_domain_initializer_list, list) { 229 list_for_each_entry_rcu(ptr, &tomoyo_domain_initializer_list, list) {
229 if (ptr->is_not != is_not || 230 if (ptr->is_not != is_not ||
@@ -232,24 +233,21 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
232 continue; 233 continue;
233 ptr->is_deleted = is_delete; 234 ptr->is_deleted = is_delete;
234 error = 0; 235 error = 0;
235 goto out; 236 break;
236 } 237 }
237 if (is_delete) { 238 if (!is_delete && error && tomoyo_memory_ok(entry)) {
238 error = -ENOENT; 239 entry->domainname = saved_domainname;
239 goto out; 240 entry->program = saved_program;
241 entry->is_not = is_not;
242 entry->is_last_name = is_last_name;
243 list_add_tail_rcu(&entry->list,
244 &tomoyo_domain_initializer_list);
245 entry = NULL;
246 error = 0;
240 } 247 }
241 if (!tomoyo_memory_ok(new_entry))
242 goto out;
243 new_entry->domainname = saved_domainname;
244 new_entry->program = saved_program;
245 new_entry->is_not = is_not;
246 new_entry->is_last_name = is_last_name;
247 list_add_tail_rcu(&new_entry->list, &tomoyo_domain_initializer_list);
248 new_entry = NULL;
249 error = 0;
250 out:
251 mutex_unlock(&tomoyo_policy_lock); 248 mutex_unlock(&tomoyo_policy_lock);
252 kfree(new_entry); 249 out:
250 kfree(entry);
253 return error; 251 return error;
254} 252}
255 253
@@ -419,11 +417,11 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
419 const bool is_not, 417 const bool is_not,
420 const bool is_delete) 418 const bool is_delete)
421{ 419{
422 struct tomoyo_domain_keeper_entry *new_entry; 420 struct tomoyo_domain_keeper_entry *entry = NULL;
423 struct tomoyo_domain_keeper_entry *ptr; 421 struct tomoyo_domain_keeper_entry *ptr;
424 const struct tomoyo_path_info *saved_domainname; 422 const struct tomoyo_path_info *saved_domainname;
425 const struct tomoyo_path_info *saved_program = NULL; 423 const struct tomoyo_path_info *saved_program = NULL;
426 int error = -ENOMEM; 424 int error = is_delete ? -ENOENT : -ENOMEM;
427 bool is_last_name = false; 425 bool is_last_name = false;
428 426
429 if (!tomoyo_is_domain_def(domainname) && 427 if (!tomoyo_is_domain_def(domainname) &&
@@ -436,12 +434,13 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
436 return -EINVAL; 434 return -EINVAL;
437 saved_program = tomoyo_save_name(program); 435 saved_program = tomoyo_save_name(program);
438 if (!saved_program) 436 if (!saved_program)
439 return -ENOMEM; 437 goto out;
440 } 438 }
441 saved_domainname = tomoyo_save_name(domainname); 439 saved_domainname = tomoyo_save_name(domainname);
442 if (!saved_domainname) 440 if (!saved_domainname)
443 return -ENOMEM; 441 goto out;
444 new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL); 442 if (!is_delete)
443 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
445 mutex_lock(&tomoyo_policy_lock); 444 mutex_lock(&tomoyo_policy_lock);
446 list_for_each_entry_rcu(ptr, &tomoyo_domain_keeper_list, list) { 445 list_for_each_entry_rcu(ptr, &tomoyo_domain_keeper_list, list) {
447 if (ptr->is_not != is_not || 446 if (ptr->is_not != is_not ||
@@ -450,24 +449,20 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
450 continue; 449 continue;
451 ptr->is_deleted = is_delete; 450 ptr->is_deleted = is_delete;
452 error = 0; 451 error = 0;
453 goto out; 452 break;
454 } 453 }
455 if (is_delete) { 454 if (!is_delete && error && tomoyo_memory_ok(entry)) {
456 error = -ENOENT; 455 entry->domainname = saved_domainname;
457 goto out; 456 entry->program = saved_program;
457 entry->is_not = is_not;
458 entry->is_last_name = is_last_name;
459 list_add_tail_rcu(&entry->list, &tomoyo_domain_keeper_list);
460 entry = NULL;
461 error = 0;
458 } 462 }
459 if (!tomoyo_memory_ok(new_entry))
460 goto out;
461 new_entry->domainname = saved_domainname;
462 new_entry->program = saved_program;
463 new_entry->is_not = is_not;
464 new_entry->is_last_name = is_last_name;
465 list_add_tail_rcu(&new_entry->list, &tomoyo_domain_keeper_list);
466 new_entry = NULL;
467 error = 0;
468 out:
469 mutex_unlock(&tomoyo_policy_lock); 463 mutex_unlock(&tomoyo_policy_lock);
470 kfree(new_entry); 464 out:
465 kfree(entry);
471 return error; 466 return error;
472} 467}
473 468
@@ -619,11 +614,11 @@ static int tomoyo_update_alias_entry(const char *original_name,
619 const char *aliased_name, 614 const char *aliased_name,
620 const bool is_delete) 615 const bool is_delete)
621{ 616{
622 struct tomoyo_alias_entry *new_entry; 617 struct tomoyo_alias_entry *entry = NULL;
623 struct tomoyo_alias_entry *ptr; 618 struct tomoyo_alias_entry *ptr;
624 const struct tomoyo_path_info *saved_original_name; 619 const struct tomoyo_path_info *saved_original_name;
625 const struct tomoyo_path_info *saved_aliased_name; 620 const struct tomoyo_path_info *saved_aliased_name;
626 int error = -ENOMEM; 621 int error = is_delete ? -ENOENT : -ENOMEM;
627 622
628 if (!tomoyo_is_correct_path(original_name, 1, -1, -1, __func__) || 623 if (!tomoyo_is_correct_path(original_name, 1, -1, -1, __func__) ||
629 !tomoyo_is_correct_path(aliased_name, 1, -1, -1, __func__)) 624 !tomoyo_is_correct_path(aliased_name, 1, -1, -1, __func__))
@@ -631,8 +626,9 @@ static int tomoyo_update_alias_entry(const char *original_name,
631 saved_original_name = tomoyo_save_name(original_name); 626 saved_original_name = tomoyo_save_name(original_name);
632 saved_aliased_name = tomoyo_save_name(aliased_name); 627 saved_aliased_name = tomoyo_save_name(aliased_name);
633 if (!saved_original_name || !saved_aliased_name) 628 if (!saved_original_name || !saved_aliased_name)
634 return -ENOMEM; 629 goto out;
635 new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL); 630 if (!is_delete)
631 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
636 mutex_lock(&tomoyo_policy_lock); 632 mutex_lock(&tomoyo_policy_lock);
637 list_for_each_entry_rcu(ptr, &tomoyo_alias_list, list) { 633 list_for_each_entry_rcu(ptr, &tomoyo_alias_list, list) {
638 if (ptr->original_name != saved_original_name || 634 if (ptr->original_name != saved_original_name ||
@@ -640,22 +636,18 @@ static int tomoyo_update_alias_entry(const char *original_name,
640 continue; 636 continue;
641 ptr->is_deleted = is_delete; 637 ptr->is_deleted = is_delete;
642 error = 0; 638 error = 0;
643 goto out; 639 break;
644 } 640 }
645 if (is_delete) { 641 if (!is_delete && error && tomoyo_memory_ok(entry)) {
646 error = -ENOENT; 642 entry->original_name = saved_original_name;
647 goto out; 643 entry->aliased_name = saved_aliased_name;
644 list_add_tail_rcu(&entry->list, &tomoyo_alias_list);
645 entry = NULL;
646 error = 0;
648 } 647 }
649 if (!tomoyo_memory_ok(new_entry))
650 goto out;
651 new_entry->original_name = saved_original_name;
652 new_entry->aliased_name = saved_aliased_name;
653 list_add_tail_rcu(&new_entry->list, &tomoyo_alias_list);
654 new_entry = NULL;
655 error = 0;
656 out:
657 mutex_unlock(&tomoyo_policy_lock); 648 mutex_unlock(&tomoyo_policy_lock);
658 kfree(new_entry); 649 out:
650 kfree(entry);
659 return error; 651 return error;
660} 652}
661 653
@@ -722,32 +714,37 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
722 domainname, 714 domainname,
723 const u8 profile) 715 const u8 profile)
724{ 716{
717 struct tomoyo_domain_info *entry;
725 struct tomoyo_domain_info *domain; 718 struct tomoyo_domain_info *domain;
726 const struct tomoyo_path_info *saved_domainname; 719 const struct tomoyo_path_info *saved_domainname;
720 bool found = false;
727 721
728 mutex_lock(&tomoyo_policy_lock);
729 domain = tomoyo_find_domain(domainname);
730 if (domain)
731 goto out;
732 if (!tomoyo_is_correct_domain(domainname, __func__)) 722 if (!tomoyo_is_correct_domain(domainname, __func__))
733 goto out; 723 return NULL;
734 saved_domainname = tomoyo_save_name(domainname); 724 saved_domainname = tomoyo_save_name(domainname);
735 if (!saved_domainname) 725 if (!saved_domainname)
736 goto out; 726 return NULL;
737 domain = kmalloc(sizeof(*domain), GFP_KERNEL); 727 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
738 if (tomoyo_memory_ok(domain)) { 728 mutex_lock(&tomoyo_policy_lock);
739 INIT_LIST_HEAD(&domain->acl_info_list); 729 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
740 domain->domainname = saved_domainname; 730 if (domain->is_deleted ||
741 domain->profile = profile; 731 tomoyo_pathcmp(saved_domainname, domain->domainname))
742 list_add_tail_rcu(&domain->list, &tomoyo_domain_list); 732 continue;
743 } else { 733 found = true;
744 kfree(domain); 734 break;
745 domain = NULL; 735 }
736 if (!found && tomoyo_memory_ok(entry)) {
737 INIT_LIST_HEAD(&entry->acl_info_list);
738 entry->domainname = saved_domainname;
739 entry->profile = profile;
740 list_add_tail_rcu(&entry->list, &tomoyo_domain_list);
741 domain = entry;
742 entry = NULL;
743 found = true;
746 } 744 }
747
748 out:
749 mutex_unlock(&tomoyo_policy_lock); 745 mutex_unlock(&tomoyo_policy_lock);
750 return domain; 746 kfree(entry);
747 return found ? domain : NULL;
751} 748}
752 749
753/** 750/**
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c
index 84c821a245ca..f4a27714e077 100644
--- a/security/tomoyo/file.c
+++ b/security/tomoyo/file.c
@@ -215,38 +215,34 @@ static LIST_HEAD(tomoyo_globally_readable_list);
215static int tomoyo_update_globally_readable_entry(const char *filename, 215static int tomoyo_update_globally_readable_entry(const char *filename,
216 const bool is_delete) 216 const bool is_delete)
217{ 217{
218 struct tomoyo_globally_readable_file_entry *new_entry; 218 struct tomoyo_globally_readable_file_entry *entry = NULL;
219 struct tomoyo_globally_readable_file_entry *ptr; 219 struct tomoyo_globally_readable_file_entry *ptr;
220 const struct tomoyo_path_info *saved_filename; 220 const struct tomoyo_path_info *saved_filename;
221 int error = -ENOMEM; 221 int error = is_delete ? -ENOENT : -ENOMEM;
222 222
223 if (!tomoyo_is_correct_path(filename, 1, 0, -1, __func__)) 223 if (!tomoyo_is_correct_path(filename, 1, 0, -1, __func__))
224 return -EINVAL; 224 return -EINVAL;
225 saved_filename = tomoyo_save_name(filename); 225 saved_filename = tomoyo_save_name(filename);
226 if (!saved_filename) 226 if (!saved_filename)
227 return -ENOMEM; 227 return -ENOMEM;
228 new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL); 228 if (!is_delete)
229 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
229 mutex_lock(&tomoyo_policy_lock); 230 mutex_lock(&tomoyo_policy_lock);
230 list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) { 231 list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) {
231 if (ptr->filename != saved_filename) 232 if (ptr->filename != saved_filename)
232 continue; 233 continue;
233 ptr->is_deleted = is_delete; 234 ptr->is_deleted = is_delete;
234 error = 0; 235 error = 0;
235 goto out; 236 break;
236 } 237 }
237 if (is_delete) { 238 if (!is_delete && error && tomoyo_memory_ok(entry)) {
238 error = -ENOENT; 239 entry->filename = saved_filename;
239 goto out; 240 list_add_tail_rcu(&entry->list, &tomoyo_globally_readable_list);
241 entry = NULL;
242 error = 0;
240 } 243 }
241 if (!tomoyo_memory_ok(new_entry))
242 goto out;
243 new_entry->filename = saved_filename;
244 list_add_tail_rcu(&new_entry->list, &tomoyo_globally_readable_list);
245 new_entry = NULL;
246 error = 0;
247 out:
248 mutex_unlock(&tomoyo_policy_lock); 244 mutex_unlock(&tomoyo_policy_lock);
249 kfree(new_entry); 245 kfree(entry);
250 return error; 246 return error;
251} 247}
252 248
@@ -364,38 +360,35 @@ static LIST_HEAD(tomoyo_pattern_list);
364static int tomoyo_update_file_pattern_entry(const char *pattern, 360static int tomoyo_update_file_pattern_entry(const char *pattern,
365 const bool is_delete) 361 const bool is_delete)
366{ 362{
367 struct tomoyo_pattern_entry *new_entry; 363 struct tomoyo_pattern_entry *entry = NULL;
368 struct tomoyo_pattern_entry *ptr; 364 struct tomoyo_pattern_entry *ptr;
369 const struct tomoyo_path_info *saved_pattern; 365 const struct tomoyo_path_info *saved_pattern;
370 int error = -ENOMEM; 366 int error = is_delete ? -ENOENT : -ENOMEM;
371 367
372 if (!tomoyo_is_correct_path(pattern, 0, 1, 0, __func__))
373 return -EINVAL;
374 saved_pattern = tomoyo_save_name(pattern); 368 saved_pattern = tomoyo_save_name(pattern);
375 if (!saved_pattern) 369 if (!saved_pattern)
376 return -ENOMEM; 370 return error;
377 new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL); 371 if (!saved_pattern->is_patterned)
372 goto out;
373 if (!is_delete)
374 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
378 mutex_lock(&tomoyo_policy_lock); 375 mutex_lock(&tomoyo_policy_lock);
379 list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) { 376 list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) {
380 if (saved_pattern != ptr->pattern) 377 if (saved_pattern != ptr->pattern)
381 continue; 378 continue;
382 ptr->is_deleted = is_delete; 379 ptr->is_deleted = is_delete;
383 error = 0; 380 error = 0;
384 goto out; 381 break;
385 } 382 }
386 if (is_delete) { 383 if (!is_delete && error && tomoyo_memory_ok(entry)) {
387 error = -ENOENT; 384 entry->pattern = saved_pattern;
388 goto out; 385 list_add_tail_rcu(&entry->list, &tomoyo_pattern_list);
386 entry = NULL;
387 error = 0;
389 } 388 }
390 if (!tomoyo_memory_ok(new_entry))
391 goto out;
392 new_entry->pattern = saved_pattern;
393 list_add_tail_rcu(&new_entry->list, &tomoyo_pattern_list);
394 new_entry = NULL;
395 error = 0;
396 out:
397 mutex_unlock(&tomoyo_policy_lock); 389 mutex_unlock(&tomoyo_policy_lock);
398 kfree(new_entry); 390 out:
391 kfree(entry);
399 return error; 392 return error;
400} 393}
401 394
@@ -518,37 +511,34 @@ static LIST_HEAD(tomoyo_no_rewrite_list);
518static int tomoyo_update_no_rewrite_entry(const char *pattern, 511static int tomoyo_update_no_rewrite_entry(const char *pattern,
519 const bool is_delete) 512 const bool is_delete)
520{ 513{
521 struct tomoyo_no_rewrite_entry *new_entry, *ptr; 514 struct tomoyo_no_rewrite_entry *entry = NULL;
515 struct tomoyo_no_rewrite_entry *ptr;
522 const struct tomoyo_path_info *saved_pattern; 516 const struct tomoyo_path_info *saved_pattern;
523 int error = -ENOMEM; 517 int error = is_delete ? -ENOENT : -ENOMEM;
524 518
525 if (!tomoyo_is_correct_path(pattern, 0, 0, 0, __func__)) 519 if (!tomoyo_is_correct_path(pattern, 0, 0, 0, __func__))
526 return -EINVAL; 520 return -EINVAL;
527 saved_pattern = tomoyo_save_name(pattern); 521 saved_pattern = tomoyo_save_name(pattern);
528 if (!saved_pattern) 522 if (!saved_pattern)
529 return -ENOMEM; 523 return error;
530 new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL); 524 if (!is_delete)
525 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
531 mutex_lock(&tomoyo_policy_lock); 526 mutex_lock(&tomoyo_policy_lock);
532 list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) { 527 list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) {
533 if (ptr->pattern != saved_pattern) 528 if (ptr->pattern != saved_pattern)
534 continue; 529 continue;
535 ptr->is_deleted = is_delete; 530 ptr->is_deleted = is_delete;
536 error = 0; 531 error = 0;
537 goto out; 532 break;
538 } 533 }
539 if (is_delete) { 534 if (!is_delete && error && tomoyo_memory_ok(entry)) {
540 error = -ENOENT; 535 entry->pattern = saved_pattern;
541 goto out; 536 list_add_tail_rcu(&entry->list, &tomoyo_no_rewrite_list);
537 entry = NULL;
538 error = 0;
542 } 539 }
543 if (!tomoyo_memory_ok(new_entry))
544 goto out;
545 new_entry->pattern = saved_pattern;
546 list_add_tail_rcu(&new_entry->list, &tomoyo_no_rewrite_list);
547 new_entry = NULL;
548 error = 0;
549 out:
550 mutex_unlock(&tomoyo_policy_lock); 540 mutex_unlock(&tomoyo_policy_lock);
551 kfree(new_entry); 541 kfree(entry);
552 return error; 542 return error;
553} 543}
554 544
@@ -869,8 +859,8 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
869 (1 << TOMOYO_TYPE_READ_ACL) | (1 << TOMOYO_TYPE_WRITE_ACL); 859 (1 << TOMOYO_TYPE_READ_ACL) | (1 << TOMOYO_TYPE_WRITE_ACL);
870 const struct tomoyo_path_info *saved_filename; 860 const struct tomoyo_path_info *saved_filename;
871 struct tomoyo_acl_info *ptr; 861 struct tomoyo_acl_info *ptr;
872 struct tomoyo_single_path_acl_record *acl; 862 struct tomoyo_single_path_acl_record *entry = NULL;
873 int error = -ENOMEM; 863 int error = is_delete ? -ENOENT : -ENOMEM;
874 const u32 perm = 1 << type; 864 const u32 perm = 1 << type;
875 865
876 if (!domain) 866 if (!domain)
@@ -880,67 +870,55 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
880 saved_filename = tomoyo_save_name(filename); 870 saved_filename = tomoyo_save_name(filename);
881 if (!saved_filename) 871 if (!saved_filename)
882 return -ENOMEM; 872 return -ENOMEM;
873 if (!is_delete)
874 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
883 mutex_lock(&tomoyo_policy_lock); 875 mutex_lock(&tomoyo_policy_lock);
884 if (is_delete)
885 goto delete;
886 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { 876 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
877 struct tomoyo_single_path_acl_record *acl =
878 container_of(ptr, struct tomoyo_single_path_acl_record,
879 head);
887 if (ptr->type != TOMOYO_TYPE_SINGLE_PATH_ACL) 880 if (ptr->type != TOMOYO_TYPE_SINGLE_PATH_ACL)
888 continue; 881 continue;
889 acl = container_of(ptr, struct tomoyo_single_path_acl_record,
890 head);
891 if (acl->filename != saved_filename) 882 if (acl->filename != saved_filename)
892 continue; 883 continue;
893 if (perm <= 0xFFFF) 884 if (is_delete) {
894 acl->perm |= perm; 885 if (perm <= 0xFFFF)
895 else 886 acl->perm &= ~perm;
896 acl->perm_high |= (perm >> 16); 887 else
897 if ((acl->perm & rw_mask) == rw_mask) 888 acl->perm_high &= ~(perm >> 16);
898 acl->perm |= 1 << TOMOYO_TYPE_READ_WRITE_ACL; 889 if ((acl->perm & rw_mask) != rw_mask)
899 else if (acl->perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL)) 890 acl->perm &= ~(1 << TOMOYO_TYPE_READ_WRITE_ACL);
900 acl->perm |= rw_mask; 891 else if (!(acl->perm &
892 (1 << TOMOYO_TYPE_READ_WRITE_ACL)))
893 acl->perm &= ~rw_mask;
894 } else {
895 if (perm <= 0xFFFF)
896 acl->perm |= perm;
897 else
898 acl->perm_high |= (perm >> 16);
899 if ((acl->perm & rw_mask) == rw_mask)
900 acl->perm |= 1 << TOMOYO_TYPE_READ_WRITE_ACL;
901 else if (acl->perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL))
902 acl->perm |= rw_mask;
903 }
901 error = 0; 904 error = 0;
902 goto out; 905 break;
903 }
904 /* Not found. Append it to the tail. */
905 acl = kmalloc(sizeof(*acl), GFP_KERNEL);
906 if (!tomoyo_memory_ok(acl)) {
907 kfree(acl);
908 acl = NULL;
909 goto out;
910 } 906 }
911 acl->head.type = TOMOYO_TYPE_SINGLE_PATH_ACL; 907 if (!is_delete && error && tomoyo_memory_ok(entry)) {
912 if (perm <= 0xFFFF) 908 entry->head.type = TOMOYO_TYPE_SINGLE_PATH_ACL;
913 acl->perm = perm;
914 else
915 acl->perm_high = (perm >> 16);
916 if (perm == (1 << TOMOYO_TYPE_READ_WRITE_ACL))
917 acl->perm |= rw_mask;
918 acl->filename = saved_filename;
919 list_add_tail_rcu(&acl->head.list, &domain->acl_info_list);
920 error = 0;
921 goto out;
922 delete:
923 error = -ENOENT;
924 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
925 if (ptr->type != TOMOYO_TYPE_SINGLE_PATH_ACL)
926 continue;
927 acl = container_of(ptr, struct tomoyo_single_path_acl_record,
928 head);
929 if (acl->filename != saved_filename)
930 continue;
931 if (perm <= 0xFFFF) 909 if (perm <= 0xFFFF)
932 acl->perm &= ~perm; 910 entry->perm = perm;
933 else 911 else
934 acl->perm_high &= ~(perm >> 16); 912 entry->perm_high = (perm >> 16);
935 if ((acl->perm & rw_mask) != rw_mask) 913 if (perm == (1 << TOMOYO_TYPE_READ_WRITE_ACL))
936 acl->perm &= ~(1 << TOMOYO_TYPE_READ_WRITE_ACL); 914 entry->perm |= rw_mask;
937 else if (!(acl->perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL))) 915 entry->filename = saved_filename;
938 acl->perm &= ~rw_mask; 916 list_add_tail_rcu(&entry->head.list, &domain->acl_info_list);
917 entry = NULL;
939 error = 0; 918 error = 0;
940 break;
941 } 919 }
942 out:
943 mutex_unlock(&tomoyo_policy_lock); 920 mutex_unlock(&tomoyo_policy_lock);
921 kfree(entry);
944 return error; 922 return error;
945} 923}
946 924
@@ -965,8 +943,8 @@ static int tomoyo_update_double_path_acl(const u8 type, const char *filename1,
965 const struct tomoyo_path_info *saved_filename1; 943 const struct tomoyo_path_info *saved_filename1;
966 const struct tomoyo_path_info *saved_filename2; 944 const struct tomoyo_path_info *saved_filename2;
967 struct tomoyo_acl_info *ptr; 945 struct tomoyo_acl_info *ptr;
968 struct tomoyo_double_path_acl_record *acl; 946 struct tomoyo_double_path_acl_record *entry = NULL;
969 int error = -ENOMEM; 947 int error = is_delete ? -ENOENT : -ENOMEM;
970 const u8 perm = 1 << type; 948 const u8 perm = 1 << type;
971 949
972 if (!domain) 950 if (!domain)
@@ -977,52 +955,38 @@ static int tomoyo_update_double_path_acl(const u8 type, const char *filename1,
977 saved_filename1 = tomoyo_save_name(filename1); 955 saved_filename1 = tomoyo_save_name(filename1);
978 saved_filename2 = tomoyo_save_name(filename2); 956 saved_filename2 = tomoyo_save_name(filename2);
979 if (!saved_filename1 || !saved_filename2) 957 if (!saved_filename1 || !saved_filename2)
980 return -ENOMEM; 958 goto out;
959 if (!is_delete)
960 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
981 mutex_lock(&tomoyo_policy_lock); 961 mutex_lock(&tomoyo_policy_lock);
982 if (is_delete)
983 goto delete;
984 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { 962 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
963 struct tomoyo_double_path_acl_record *acl =
964 container_of(ptr, struct tomoyo_double_path_acl_record,
965 head);
985 if (ptr->type != TOMOYO_TYPE_DOUBLE_PATH_ACL) 966 if (ptr->type != TOMOYO_TYPE_DOUBLE_PATH_ACL)
986 continue; 967 continue;
987 acl = container_of(ptr, struct tomoyo_double_path_acl_record,
988 head);
989 if (acl->filename1 != saved_filename1 || 968 if (acl->filename1 != saved_filename1 ||
990 acl->filename2 != saved_filename2) 969 acl->filename2 != saved_filename2)
991 continue; 970 continue;
992 acl->perm |= perm; 971 if (is_delete)
972 acl->perm &= ~perm;
973 else
974 acl->perm |= perm;
993 error = 0; 975 error = 0;
994 goto out; 976 break;
995 }
996 /* Not found. Append it to the tail. */
997 acl = kmalloc(sizeof(*acl), GFP_KERNEL);
998 if (!tomoyo_memory_ok(acl)) {
999 kfree(acl);
1000 acl = NULL;
1001 goto out;
1002 } 977 }
1003 acl->head.type = TOMOYO_TYPE_DOUBLE_PATH_ACL; 978 if (!is_delete && error && tomoyo_memory_ok(entry)) {
1004 acl->perm = perm; 979 entry->head.type = TOMOYO_TYPE_DOUBLE_PATH_ACL;
1005 acl->filename1 = saved_filename1; 980 entry->perm = perm;
1006 acl->filename2 = saved_filename2; 981 entry->filename1 = saved_filename1;
1007 list_add_tail_rcu(&acl->head.list, &domain->acl_info_list); 982 entry->filename2 = saved_filename2;
1008 error = 0; 983 list_add_tail_rcu(&entry->head.list, &domain->acl_info_list);
1009 goto out; 984 entry = NULL;
1010 delete:
1011 error = -ENOENT;
1012 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
1013 if (ptr->type != TOMOYO_TYPE_DOUBLE_PATH_ACL)
1014 continue;
1015 acl = container_of(ptr, struct tomoyo_double_path_acl_record,
1016 head);
1017 if (acl->filename1 != saved_filename1 ||
1018 acl->filename2 != saved_filename2)
1019 continue;
1020 acl->perm &= ~perm;
1021 error = 0; 985 error = 0;
1022 break;
1023 } 986 }
1024 out:
1025 mutex_unlock(&tomoyo_policy_lock); 987 mutex_unlock(&tomoyo_policy_lock);
988 out:
989 kfree(entry);
1026 return error; 990 return error;
1027} 991}
1028 992