aboutsummaryrefslogtreecommitdiff
path: root/security/tomoyo/gc.c
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2011-07-08 13:21:37 +0900
committerJames Morris <jmorris@namei.org>2011-07-11 11:05:32 +1000
commit2066a36125fcbf5220990173b9d8e8bc49ad7538 (patch)
treec8ea3a6d92a8b4b68cda986601336e8e8f58553e /security/tomoyo/gc.c
parent5c4274f13819b40e726f6ee4ef13b4952cff5010 (diff)
TOMOYO: Allow using UID/GID etc. of current thread as conditions.
This patch adds support for permission checks using current thread's UID/GID etc. in addition to pathnames. Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/tomoyo/gc.c')
-rw-r--r--security/tomoyo/gc.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/security/tomoyo/gc.c b/security/tomoyo/gc.c
index 1e1a6c8c832..21fccd67c25 100644
--- a/security/tomoyo/gc.c
+++ b/security/tomoyo/gc.c
@@ -25,6 +25,7 @@ static const u8 tomoyo_element_size[TOMOYO_MAX_POLICY] = {
[TOMOYO_ID_TRANSITION_CONTROL] =
sizeof(struct tomoyo_transition_control),
[TOMOYO_ID_MANAGER] = sizeof(struct tomoyo_manager),
+ /* [TOMOYO_ID_CONDITION] = "struct tomoyo_condition"->size, */
/* [TOMOYO_ID_NAME] = "struct tomoyo_name"->size, */
/* [TOMOYO_ID_ACL] =
tomoyo_acl_size["struct tomoyo_acl_info"->type], */
@@ -162,6 +163,10 @@ static bool tomoyo_add_to_gc(const int type, struct list_head *element)
entry->size = strlen(container_of(element,
typeof(struct tomoyo_name),
head.list)->entry.name) + 1;
+ else if (type == TOMOYO_ID_CONDITION)
+ entry->size =
+ container_of(element, typeof(struct tomoyo_condition),
+ head.list)->size;
else
entry->size = tomoyo_element_size[type];
entry->element = element;
@@ -246,6 +251,7 @@ static void tomoyo_del_acl(struct list_head *element)
{
struct tomoyo_acl_info *acl =
container_of(element, typeof(*acl), list);
+ tomoyo_put_condition(acl->cond);
switch (acl->type) {
case TOMOYO_TYPE_PATH_ACL:
{
@@ -338,6 +344,27 @@ static bool tomoyo_del_domain(struct list_head *element)
return true;
}
+/**
+ * tomoyo_del_condition - Delete members in "struct tomoyo_condition".
+ *
+ * @element: Pointer to "struct list_head".
+ *
+ * Returns nothing.
+ */
+void tomoyo_del_condition(struct list_head *element)
+{
+ struct tomoyo_condition *cond = container_of(element, typeof(*cond),
+ head.list);
+ const u16 condc = cond->condc;
+ const u16 numbers_count = cond->numbers_count;
+ unsigned int i;
+ const struct tomoyo_condition_element *condp
+ = (const struct tomoyo_condition_element *) (cond + 1);
+ struct tomoyo_number_union *numbers_p
+ = (struct tomoyo_number_union *) (condp + condc);
+ for (i = 0; i < numbers_count; i++)
+ tomoyo_put_number_union(numbers_p++);
+}
/**
* tomoyo_del_name - Delete members in "struct tomoyo_name".
@@ -494,15 +521,18 @@ static void tomoyo_collect_entry(void)
}
}
}
- for (i = 0; i < TOMOYO_MAX_HASH; i++) {
- struct list_head *list = &tomoyo_name_list[i];
+ id = TOMOYO_ID_CONDITION;
+ for (i = 0; i < TOMOYO_MAX_HASH + 1; i++) {
+ struct list_head *list = !i ?
+ &tomoyo_condition_list : &tomoyo_name_list[i - 1];
struct tomoyo_shared_acl_head *ptr;
list_for_each_entry(ptr, list, list) {
if (atomic_read(&ptr->users))
continue;
- if (!tomoyo_add_to_gc(TOMOYO_ID_NAME, &ptr->list))
+ if (!tomoyo_add_to_gc(id, &ptr->list))
goto unlock;
}
+ id = TOMOYO_ID_NAME;
}
unlock:
tomoyo_read_unlock(idx);
@@ -557,6 +587,9 @@ static bool tomoyo_kfree_entry(void)
case TOMOYO_ID_MANAGER:
tomoyo_del_manager(element);
break;
+ case TOMOYO_ID_CONDITION:
+ tomoyo_del_condition(element);
+ break;
case TOMOYO_ID_NAME:
/*
* Thirdly, defer until all "struct tomoyo_io_buffer"