summaryrefslogtreecommitdiffstats
path: root/security/tomoyo/domain.c
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2010-06-12 13:46:22 +0200
committerJames Morris <jmorris@namei.org>2010-08-02 07:34:28 +0200
commit237ab459f12cb98eadd3fe7b85343e183a1076a4 (patch)
treef2835e2945016beb4e29b6a2ed8f9d372dc1b412 /security/tomoyo/domain.c
parentKEYS: Make /proc/keys check to see if a key is possessed before security check (diff)
downloadlinux-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.c51
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