diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-04-08 11:02:50 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-04-08 11:02:57 -0400 |
commit | ff96e612cba32510e263e17b213235fe5746397e (patch) | |
tree | a8df57d76b10e0901a4fb76cd2987eb9826a560a /security | |
parent | cd84a42f315e50edd454c27a3da3951ccd3d735a (diff) | |
parent | 577c9c456f0e1371cbade38eaf91ae8e8a308555 (diff) |
Merge commit 'v2.6.30-rc1' into core/urgent
Merge reason: need latest upstream to queue up dependent fix
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'security')
-rw-r--r-- | security/device_cgroup.c | 21 | ||||
-rw-r--r-- | security/security.c | 2 | ||||
-rw-r--r-- | security/tomoyo/common.c | 7 | ||||
-rw-r--r-- | security/tomoyo/common.h | 8 | ||||
-rw-r--r-- | security/tomoyo/domain.c | 90 | ||||
-rw-r--r-- | security/tomoyo/realpath.c | 1 |
6 files changed, 21 insertions, 108 deletions
diff --git a/security/device_cgroup.c b/security/device_cgroup.c index 3aacd0fe7179..5fda7df19723 100644 --- a/security/device_cgroup.c +++ b/security/device_cgroup.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/uaccess.h> | 11 | #include <linux/uaccess.h> |
12 | #include <linux/seq_file.h> | 12 | #include <linux/seq_file.h> |
13 | #include <linux/rcupdate.h> | 13 | #include <linux/rcupdate.h> |
14 | #include <linux/mutex.h> | ||
14 | 15 | ||
15 | #define ACC_MKNOD 1 | 16 | #define ACC_MKNOD 1 |
16 | #define ACC_READ 2 | 17 | #define ACC_READ 2 |
@@ -21,9 +22,11 @@ | |||
21 | #define DEV_CHAR 2 | 22 | #define DEV_CHAR 2 |
22 | #define DEV_ALL 4 /* this represents all devices */ | 23 | #define DEV_ALL 4 /* this represents all devices */ |
23 | 24 | ||
25 | static DEFINE_MUTEX(devcgroup_mutex); | ||
26 | |||
24 | /* | 27 | /* |
25 | * whitelist locking rules: | 28 | * whitelist locking rules: |
26 | * hold cgroup_lock() for update/read. | 29 | * hold devcgroup_mutex for update/read. |
27 | * hold rcu_read_lock() for read. | 30 | * hold rcu_read_lock() for read. |
28 | */ | 31 | */ |
29 | 32 | ||
@@ -67,7 +70,7 @@ static int devcgroup_can_attach(struct cgroup_subsys *ss, | |||
67 | } | 70 | } |
68 | 71 | ||
69 | /* | 72 | /* |
70 | * called under cgroup_lock() | 73 | * called under devcgroup_mutex |
71 | */ | 74 | */ |
72 | static int dev_whitelist_copy(struct list_head *dest, struct list_head *orig) | 75 | static int dev_whitelist_copy(struct list_head *dest, struct list_head *orig) |
73 | { | 76 | { |
@@ -92,7 +95,7 @@ free_and_exit: | |||
92 | 95 | ||
93 | /* Stupid prototype - don't bother combining existing entries */ | 96 | /* Stupid prototype - don't bother combining existing entries */ |
94 | /* | 97 | /* |
95 | * called under cgroup_lock() | 98 | * called under devcgroup_mutex |
96 | */ | 99 | */ |
97 | static int dev_whitelist_add(struct dev_cgroup *dev_cgroup, | 100 | static int dev_whitelist_add(struct dev_cgroup *dev_cgroup, |
98 | struct dev_whitelist_item *wh) | 101 | struct dev_whitelist_item *wh) |
@@ -130,7 +133,7 @@ static void whitelist_item_free(struct rcu_head *rcu) | |||
130 | } | 133 | } |
131 | 134 | ||
132 | /* | 135 | /* |
133 | * called under cgroup_lock() | 136 | * called under devcgroup_mutex |
134 | */ | 137 | */ |
135 | static void dev_whitelist_rm(struct dev_cgroup *dev_cgroup, | 138 | static void dev_whitelist_rm(struct dev_cgroup *dev_cgroup, |
136 | struct dev_whitelist_item *wh) | 139 | struct dev_whitelist_item *wh) |
@@ -185,8 +188,10 @@ static struct cgroup_subsys_state *devcgroup_create(struct cgroup_subsys *ss, | |||
185 | list_add(&wh->list, &dev_cgroup->whitelist); | 188 | list_add(&wh->list, &dev_cgroup->whitelist); |
186 | } else { | 189 | } else { |
187 | parent_dev_cgroup = cgroup_to_devcgroup(parent_cgroup); | 190 | parent_dev_cgroup = cgroup_to_devcgroup(parent_cgroup); |
191 | mutex_lock(&devcgroup_mutex); | ||
188 | ret = dev_whitelist_copy(&dev_cgroup->whitelist, | 192 | ret = dev_whitelist_copy(&dev_cgroup->whitelist, |
189 | &parent_dev_cgroup->whitelist); | 193 | &parent_dev_cgroup->whitelist); |
194 | mutex_unlock(&devcgroup_mutex); | ||
190 | if (ret) { | 195 | if (ret) { |
191 | kfree(dev_cgroup); | 196 | kfree(dev_cgroup); |
192 | return ERR_PTR(ret); | 197 | return ERR_PTR(ret); |
@@ -273,7 +278,7 @@ static int devcgroup_seq_read(struct cgroup *cgroup, struct cftype *cft, | |||
273 | * does the access granted to dev_cgroup c contain the access | 278 | * does the access granted to dev_cgroup c contain the access |
274 | * requested in whitelist item refwh. | 279 | * requested in whitelist item refwh. |
275 | * return 1 if yes, 0 if no. | 280 | * return 1 if yes, 0 if no. |
276 | * call with c->lock held | 281 | * call with devcgroup_mutex held |
277 | */ | 282 | */ |
278 | static int may_access_whitelist(struct dev_cgroup *c, | 283 | static int may_access_whitelist(struct dev_cgroup *c, |
279 | struct dev_whitelist_item *refwh) | 284 | struct dev_whitelist_item *refwh) |
@@ -426,11 +431,11 @@ static int devcgroup_access_write(struct cgroup *cgrp, struct cftype *cft, | |||
426 | const char *buffer) | 431 | const char *buffer) |
427 | { | 432 | { |
428 | int retval; | 433 | int retval; |
429 | if (!cgroup_lock_live_group(cgrp)) | 434 | |
430 | return -ENODEV; | 435 | mutex_lock(&devcgroup_mutex); |
431 | retval = devcgroup_update_access(cgroup_to_devcgroup(cgrp), | 436 | retval = devcgroup_update_access(cgroup_to_devcgroup(cgrp), |
432 | cft->private, buffer); | 437 | cft->private, buffer); |
433 | cgroup_unlock(); | 438 | mutex_unlock(&devcgroup_mutex); |
434 | return retval; | 439 | return retval; |
435 | } | 440 | } |
436 | 441 | ||
diff --git a/security/security.c b/security/security.c index 206e53844d2f..5284255c5cdf 100644 --- a/security/security.c +++ b/security/security.c | |||
@@ -445,6 +445,7 @@ int security_inode_create(struct inode *dir, struct dentry *dentry, int mode) | |||
445 | return 0; | 445 | return 0; |
446 | return security_ops->inode_create(dir, dentry, mode); | 446 | return security_ops->inode_create(dir, dentry, mode); |
447 | } | 447 | } |
448 | EXPORT_SYMBOL_GPL(security_inode_create); | ||
448 | 449 | ||
449 | int security_inode_link(struct dentry *old_dentry, struct inode *dir, | 450 | int security_inode_link(struct dentry *old_dentry, struct inode *dir, |
450 | struct dentry *new_dentry) | 451 | struct dentry *new_dentry) |
@@ -475,6 +476,7 @@ int security_inode_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
475 | return 0; | 476 | return 0; |
476 | return security_ops->inode_mkdir(dir, dentry, mode); | 477 | return security_ops->inode_mkdir(dir, dentry, mode); |
477 | } | 478 | } |
479 | EXPORT_SYMBOL_GPL(security_inode_mkdir); | ||
478 | 480 | ||
479 | int security_inode_rmdir(struct inode *dir, struct dentry *dentry) | 481 | int security_inode_rmdir(struct inode *dir, struct dentry *dentry) |
480 | { | 482 | { |
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index 92cea656ad21..a0affd9cfca8 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c | |||
@@ -1252,15 +1252,12 @@ static int tomoyo_write_domain_policy(struct tomoyo_io_buffer *head) | |||
1252 | struct tomoyo_domain_info *domain = head->write_var1; | 1252 | struct tomoyo_domain_info *domain = head->write_var1; |
1253 | bool is_delete = false; | 1253 | bool is_delete = false; |
1254 | bool is_select = false; | 1254 | bool is_select = false; |
1255 | bool is_undelete = false; | ||
1256 | unsigned int profile; | 1255 | unsigned int profile; |
1257 | 1256 | ||
1258 | if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_DELETE)) | 1257 | if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_DELETE)) |
1259 | is_delete = true; | 1258 | is_delete = true; |
1260 | else if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_SELECT)) | 1259 | else if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_SELECT)) |
1261 | is_select = true; | 1260 | is_select = true; |
1262 | else if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_UNDELETE)) | ||
1263 | is_undelete = true; | ||
1264 | if (is_select && tomoyo_is_select_one(head, data)) | 1261 | if (is_select && tomoyo_is_select_one(head, data)) |
1265 | return 0; | 1262 | return 0; |
1266 | /* Don't allow updating policies by non manager programs. */ | 1263 | /* Don't allow updating policies by non manager programs. */ |
@@ -1274,9 +1271,7 @@ static int tomoyo_write_domain_policy(struct tomoyo_io_buffer *head) | |||
1274 | down_read(&tomoyo_domain_list_lock); | 1271 | down_read(&tomoyo_domain_list_lock); |
1275 | domain = tomoyo_find_domain(data); | 1272 | domain = tomoyo_find_domain(data); |
1276 | up_read(&tomoyo_domain_list_lock); | 1273 | up_read(&tomoyo_domain_list_lock); |
1277 | } else if (is_undelete) | 1274 | } else |
1278 | domain = tomoyo_undelete_domain(data); | ||
1279 | else | ||
1280 | domain = tomoyo_find_or_assign_new_domain(data, 0); | 1275 | domain = tomoyo_find_or_assign_new_domain(data, 0); |
1281 | head->write_var1 = domain; | 1276 | head->write_var1 = domain; |
1282 | return 0; | 1277 | return 0; |
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h index 26a76d67aa1c..e77e6a6de0f2 100644 --- a/security/tomoyo/common.h +++ b/security/tomoyo/common.h | |||
@@ -88,10 +88,7 @@ struct tomoyo_domain_info { | |||
88 | /* Name of this domain. Never NULL. */ | 88 | /* Name of this domain. Never NULL. */ |
89 | const struct tomoyo_path_info *domainname; | 89 | const struct tomoyo_path_info *domainname; |
90 | u8 profile; /* Profile number to use. */ | 90 | u8 profile; /* Profile number to use. */ |
91 | u8 is_deleted; /* Delete flag. | 91 | bool is_deleted; /* Delete flag. */ |
92 | 0 = active. | ||
93 | 1 = deleted but undeletable. | ||
94 | 255 = deleted and no longer undeletable. */ | ||
95 | bool quota_warned; /* Quota warnning flag. */ | 92 | bool quota_warned; /* Quota warnning flag. */ |
96 | /* DOMAIN_FLAGS_*. Use tomoyo_set_domain_flag() to modify. */ | 93 | /* DOMAIN_FLAGS_*. Use tomoyo_set_domain_flag() to modify. */ |
97 | u8 flags; | 94 | u8 flags; |
@@ -144,7 +141,6 @@ struct tomoyo_double_path_acl_record { | |||
144 | #define TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN "no_initialize_domain " | 141 | #define TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN "no_initialize_domain " |
145 | #define TOMOYO_KEYWORD_NO_KEEP_DOMAIN "no_keep_domain " | 142 | #define TOMOYO_KEYWORD_NO_KEEP_DOMAIN "no_keep_domain " |
146 | #define TOMOYO_KEYWORD_SELECT "select " | 143 | #define TOMOYO_KEYWORD_SELECT "select " |
147 | #define TOMOYO_KEYWORD_UNDELETE "undelete " | ||
148 | #define TOMOYO_KEYWORD_USE_PROFILE "use_profile " | 144 | #define TOMOYO_KEYWORD_USE_PROFILE "use_profile " |
149 | #define TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "ignore_global_allow_read" | 145 | #define TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "ignore_global_allow_read" |
150 | /* A domain definition starts with <kernel>. */ | 146 | /* A domain definition starts with <kernel>. */ |
@@ -267,8 +263,6 @@ struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname); | |||
267 | struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char * | 263 | struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char * |
268 | domainname, | 264 | domainname, |
269 | const u8 profile); | 265 | const u8 profile); |
270 | /* Undelete a domain. */ | ||
271 | struct tomoyo_domain_info *tomoyo_undelete_domain(const char *domainname); | ||
272 | /* Check mode for specified functionality. */ | 266 | /* Check mode for specified functionality. */ |
273 | unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain, | 267 | unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain, |
274 | const u8 index); | 268 | const u8 index); |
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c index 093a756030bd..2f2b449ffd2d 100644 --- a/security/tomoyo/domain.c +++ b/security/tomoyo/domain.c | |||
@@ -551,9 +551,7 @@ int tomoyo_write_alias_policy(char *data, const bool is_delete) | |||
551 | return tomoyo_update_alias_entry(data, cp, is_delete); | 551 | return tomoyo_update_alias_entry(data, cp, is_delete); |
552 | } | 552 | } |
553 | 553 | ||
554 | /* Domain create/delete/undelete handler. */ | 554 | /* Domain create/delete handler. */ |
555 | |||
556 | /* #define TOMOYO_DEBUG_DOMAIN_UNDELETE */ | ||
557 | 555 | ||
558 | /** | 556 | /** |
559 | * tomoyo_delete_domain - Delete a domain. | 557 | * tomoyo_delete_domain - Delete a domain. |
@@ -571,41 +569,15 @@ int tomoyo_delete_domain(char *domainname) | |||
571 | tomoyo_fill_path_info(&name); | 569 | tomoyo_fill_path_info(&name); |
572 | /***** EXCLUSIVE SECTION START *****/ | 570 | /***** EXCLUSIVE SECTION START *****/ |
573 | down_write(&tomoyo_domain_list_lock); | 571 | down_write(&tomoyo_domain_list_lock); |
574 | #ifdef TOMOYO_DEBUG_DOMAIN_UNDELETE | ||
575 | printk(KERN_DEBUG "tomoyo_delete_domain %s\n", domainname); | ||
576 | list_for_each_entry(domain, &tomoyo_domain_list, list) { | ||
577 | if (tomoyo_pathcmp(domain->domainname, &name)) | ||
578 | continue; | ||
579 | printk(KERN_DEBUG "List: %p %u\n", domain, domain->is_deleted); | ||
580 | } | ||
581 | #endif | ||
582 | /* Is there an active domain? */ | 572 | /* Is there an active domain? */ |
583 | list_for_each_entry(domain, &tomoyo_domain_list, list) { | 573 | list_for_each_entry(domain, &tomoyo_domain_list, list) { |
584 | struct tomoyo_domain_info *domain2; | ||
585 | /* Never delete tomoyo_kernel_domain */ | 574 | /* Never delete tomoyo_kernel_domain */ |
586 | if (domain == &tomoyo_kernel_domain) | 575 | if (domain == &tomoyo_kernel_domain) |
587 | continue; | 576 | continue; |
588 | if (domain->is_deleted || | 577 | if (domain->is_deleted || |
589 | tomoyo_pathcmp(domain->domainname, &name)) | 578 | tomoyo_pathcmp(domain->domainname, &name)) |
590 | continue; | 579 | continue; |
591 | /* Mark already deleted domains as non undeletable. */ | 580 | domain->is_deleted = true; |
592 | list_for_each_entry(domain2, &tomoyo_domain_list, list) { | ||
593 | if (!domain2->is_deleted || | ||
594 | tomoyo_pathcmp(domain2->domainname, &name)) | ||
595 | continue; | ||
596 | #ifdef TOMOYO_DEBUG_DOMAIN_UNDELETE | ||
597 | if (domain2->is_deleted != 255) | ||
598 | printk(KERN_DEBUG | ||
599 | "Marked %p as non undeletable\n", | ||
600 | domain2); | ||
601 | #endif | ||
602 | domain2->is_deleted = 255; | ||
603 | } | ||
604 | /* Delete and mark active domain as undeletable. */ | ||
605 | domain->is_deleted = 1; | ||
606 | #ifdef TOMOYO_DEBUG_DOMAIN_UNDELETE | ||
607 | printk(KERN_DEBUG "Marked %p as undeletable\n", domain); | ||
608 | #endif | ||
609 | break; | 581 | break; |
610 | } | 582 | } |
611 | up_write(&tomoyo_domain_list_lock); | 583 | up_write(&tomoyo_domain_list_lock); |
@@ -614,58 +586,6 @@ int tomoyo_delete_domain(char *domainname) | |||
614 | } | 586 | } |
615 | 587 | ||
616 | /** | 588 | /** |
617 | * tomoyo_undelete_domain - Undelete a domain. | ||
618 | * | ||
619 | * @domainname: The name of domain. | ||
620 | * | ||
621 | * Returns pointer to "struct tomoyo_domain_info" on success, NULL otherwise. | ||
622 | */ | ||
623 | struct tomoyo_domain_info *tomoyo_undelete_domain(const char *domainname) | ||
624 | { | ||
625 | struct tomoyo_domain_info *domain; | ||
626 | struct tomoyo_domain_info *candidate_domain = NULL; | ||
627 | struct tomoyo_path_info name; | ||
628 | |||
629 | name.name = domainname; | ||
630 | tomoyo_fill_path_info(&name); | ||
631 | /***** EXCLUSIVE SECTION START *****/ | ||
632 | down_write(&tomoyo_domain_list_lock); | ||
633 | #ifdef TOMOYO_DEBUG_DOMAIN_UNDELETE | ||
634 | printk(KERN_DEBUG "tomoyo_undelete_domain %s\n", domainname); | ||
635 | list_for_each_entry(domain, &tomoyo_domain_list, list) { | ||
636 | if (tomoyo_pathcmp(domain->domainname, &name)) | ||
637 | continue; | ||
638 | printk(KERN_DEBUG "List: %p %u\n", domain, domain->is_deleted); | ||
639 | } | ||
640 | #endif | ||
641 | list_for_each_entry(domain, &tomoyo_domain_list, list) { | ||
642 | if (tomoyo_pathcmp(&name, domain->domainname)) | ||
643 | continue; | ||
644 | if (!domain->is_deleted) { | ||
645 | /* This domain is active. I can't undelete. */ | ||
646 | candidate_domain = NULL; | ||
647 | #ifdef TOMOYO_DEBUG_DOMAIN_UNDELETE | ||
648 | printk(KERN_DEBUG "%p is active. I can't undelete.\n", | ||
649 | domain); | ||
650 | #endif | ||
651 | break; | ||
652 | } | ||
653 | /* Is this domain undeletable? */ | ||
654 | if (domain->is_deleted == 1) | ||
655 | candidate_domain = domain; | ||
656 | } | ||
657 | if (candidate_domain) { | ||
658 | candidate_domain->is_deleted = 0; | ||
659 | #ifdef TOMOYO_DEBUG_DOMAIN_UNDELETE | ||
660 | printk(KERN_DEBUG "%p was undeleted.\n", candidate_domain); | ||
661 | #endif | ||
662 | } | ||
663 | up_write(&tomoyo_domain_list_lock); | ||
664 | /***** EXCLUSIVE SECTION END *****/ | ||
665 | return candidate_domain; | ||
666 | } | ||
667 | |||
668 | /** | ||
669 | * tomoyo_find_or_assign_new_domain - Create a domain. | 589 | * tomoyo_find_or_assign_new_domain - Create a domain. |
670 | * | 590 | * |
671 | * @domainname: The name of domain. | 591 | * @domainname: The name of domain. |
@@ -711,10 +631,6 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char * | |||
711 | /***** CRITICAL SECTION END *****/ | 631 | /***** CRITICAL SECTION END *****/ |
712 | if (flag) | 632 | if (flag) |
713 | continue; | 633 | continue; |
714 | #ifdef TOMOYO_DEBUG_DOMAIN_UNDELETE | ||
715 | printk(KERN_DEBUG "Reusing %p %s\n", domain, | ||
716 | domain->domainname->name); | ||
717 | #endif | ||
718 | list_for_each_entry(ptr, &domain->acl_info_list, list) { | 634 | list_for_each_entry(ptr, &domain->acl_info_list, list) { |
719 | ptr->type |= TOMOYO_ACL_DELETED; | 635 | ptr->type |= TOMOYO_ACL_DELETED; |
720 | } | 636 | } |
@@ -722,7 +638,7 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char * | |||
722 | domain->profile = profile; | 638 | domain->profile = profile; |
723 | domain->quota_warned = false; | 639 | domain->quota_warned = false; |
724 | mb(); /* Avoid out-of-order execution. */ | 640 | mb(); /* Avoid out-of-order execution. */ |
725 | domain->is_deleted = 0; | 641 | domain->is_deleted = false; |
726 | goto out; | 642 | goto out; |
727 | } | 643 | } |
728 | /* No memory reusable. Create using new memory. */ | 644 | /* No memory reusable. Create using new memory. */ |
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c index d47f16b844b2..3bbe01a7a4b5 100644 --- a/security/tomoyo/realpath.c +++ b/security/tomoyo/realpath.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
13 | #include <linux/mount.h> | 13 | #include <linux/mount.h> |
14 | #include <linux/mnt_namespace.h> | 14 | #include <linux/mnt_namespace.h> |
15 | #include <linux/fs_struct.h> | ||
15 | #include "common.h" | 16 | #include "common.h" |
16 | #include "realpath.h" | 17 | #include "realpath.h" |
17 | 18 | ||