diff options
author | Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> | 2010-06-12 13:46:22 +0200 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2010-08-02 07:34:28 +0200 |
commit | 237ab459f12cb98eadd3fe7b85343e183a1076a4 (patch) | |
tree | f2835e2945016beb4e29b6a2ed8f9d372dc1b412 /security/tomoyo/domain.c | |
parent | KEYS: Make /proc/keys check to see if a key is possessed before security check (diff) | |
download | linux-237ab459f12cb98eadd3fe7b85343e183a1076a4.tar.xz linux-237ab459f12cb98eadd3fe7b85343e183a1076a4.zip |
TOMOYO: Use callback for updating entries.
Use common "struct list_head" + "bool" + "u8" structure and
use common code for elements using that structure.
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/domain.c')
-rw-r--r-- | security/tomoyo/domain.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c index 09ec37c12a9c..f774e73e0022 100644 --- a/security/tomoyo/domain.c +++ b/security/tomoyo/domain.c @@ -15,6 +15,57 @@ /* The initial domain. */ struct tomoyo_domain_info tomoyo_kernel_domain; +/** + * tomoyo_update_domain - Update an entry for domain policy. + * + * @new_entry: Pointer to "struct tomoyo_acl_info". + * @size: Size of @new_entry in bytes. + * @is_delete: True if it is a delete request. + * @domain: Pointer to "struct tomoyo_domain_info". + * @check_duplicate: Callback function to find duplicated entry. + * @merge_duplicate: Callback function to merge duplicated entry. + * + * Returns 0 on success, negative value otherwise. + * + * Caller holds tomoyo_read_lock(). + */ +int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size, + bool is_delete, struct tomoyo_domain_info *domain, + bool (*check_duplicate) (const struct tomoyo_acl_info + *, + const struct tomoyo_acl_info + *), + bool (*merge_duplicate) (struct tomoyo_acl_info *, + struct tomoyo_acl_info *, + const bool)) +{ + int error = is_delete ? -ENOENT : -ENOMEM; + struct tomoyo_acl_info *entry; + + if (mutex_lock_interruptible(&tomoyo_policy_lock)) + return error; + list_for_each_entry_rcu(entry, &domain->acl_info_list, list) { + if (!check_duplicate(entry, new_entry)) + continue; + if (merge_duplicate) + entry->is_deleted = merge_duplicate(entry, new_entry, + is_delete); + else + entry->is_deleted = is_delete; + error = 0; + break; + } + if (error && !is_delete) { + entry = tomoyo_commit_ok(new_entry, size); + if (entry) { + list_add_tail_rcu(&entry->list, &domain->acl_info_list); + error = 0; + } + } + mutex_unlock(&tomoyo_policy_lock); + return error; +} + /* * tomoyo_domain_list is used for holding list of domains. * The ->acl_info_list of "struct tomoyo_domain_info" is used for holding |