0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/hash.h>
0009 #include <linux/slab.h>
0010 #include "common.h"
0011
0012
0013
0014
0015
0016
0017 void tomoyo_warn_oom(const char *function)
0018 {
0019
0020 static pid_t tomoyo_last_pid;
0021 const pid_t pid = current->pid;
0022
0023 if (tomoyo_last_pid != pid) {
0024 pr_warn("ERROR: Out of memory at %s.\n", function);
0025 tomoyo_last_pid = pid;
0026 }
0027 if (!tomoyo_policy_loaded)
0028 panic("MAC Initialization failed.\n");
0029 }
0030
0031
0032 unsigned int tomoyo_memory_used[TOMOYO_MAX_MEMORY_STAT];
0033
0034 unsigned int tomoyo_memory_quota[TOMOYO_MAX_MEMORY_STAT];
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047 bool tomoyo_memory_ok(void *ptr)
0048 {
0049 if (ptr) {
0050 const size_t s = ksize(ptr);
0051
0052 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] += s;
0053 if (!tomoyo_memory_quota[TOMOYO_MEMORY_POLICY] ||
0054 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] <=
0055 tomoyo_memory_quota[TOMOYO_MEMORY_POLICY])
0056 return true;
0057 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] -= s;
0058 }
0059 tomoyo_warn_oom(__func__);
0060 return false;
0061 }
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074 void *tomoyo_commit_ok(void *data, const unsigned int size)
0075 {
0076 void *ptr = kzalloc(size, GFP_NOFS | __GFP_NOWARN);
0077
0078 if (tomoyo_memory_ok(ptr)) {
0079 memmove(ptr, data, size);
0080 memset(data, 0, size);
0081 return ptr;
0082 }
0083 kfree(ptr);
0084 return NULL;
0085 }
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095 struct tomoyo_group *tomoyo_get_group(struct tomoyo_acl_param *param,
0096 const u8 idx)
0097 {
0098 struct tomoyo_group e = { };
0099 struct tomoyo_group *group = NULL;
0100 struct list_head *list;
0101 const char *group_name = tomoyo_read_token(param);
0102 bool found = false;
0103
0104 if (!tomoyo_correct_word(group_name) || idx >= TOMOYO_MAX_GROUP)
0105 return NULL;
0106 e.group_name = tomoyo_get_name(group_name);
0107 if (!e.group_name)
0108 return NULL;
0109 if (mutex_lock_interruptible(&tomoyo_policy_lock))
0110 goto out;
0111 list = ¶m->ns->group_list[idx];
0112 list_for_each_entry(group, list, head.list) {
0113 if (e.group_name != group->group_name ||
0114 atomic_read(&group->head.users) == TOMOYO_GC_IN_PROGRESS)
0115 continue;
0116 atomic_inc(&group->head.users);
0117 found = true;
0118 break;
0119 }
0120 if (!found) {
0121 struct tomoyo_group *entry = tomoyo_commit_ok(&e, sizeof(e));
0122
0123 if (entry) {
0124 INIT_LIST_HEAD(&entry->member_list);
0125 atomic_set(&entry->head.users, 1);
0126 list_add_tail_rcu(&entry->head.list, list);
0127 group = entry;
0128 found = true;
0129 }
0130 }
0131 mutex_unlock(&tomoyo_policy_lock);
0132 out:
0133 tomoyo_put_name(e.group_name);
0134 return found ? group : NULL;
0135 }
0136
0137
0138
0139
0140
0141
0142
0143 struct list_head tomoyo_name_list[TOMOYO_MAX_HASH];
0144
0145
0146
0147
0148
0149
0150
0151
0152 const struct tomoyo_path_info *tomoyo_get_name(const char *name)
0153 {
0154 struct tomoyo_name *ptr;
0155 unsigned int hash;
0156 int len;
0157 struct list_head *head;
0158
0159 if (!name)
0160 return NULL;
0161 len = strlen(name) + 1;
0162 hash = full_name_hash(NULL, (const unsigned char *) name, len - 1);
0163 head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)];
0164 if (mutex_lock_interruptible(&tomoyo_policy_lock))
0165 return NULL;
0166 list_for_each_entry(ptr, head, head.list) {
0167 if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name) ||
0168 atomic_read(&ptr->head.users) == TOMOYO_GC_IN_PROGRESS)
0169 continue;
0170 atomic_inc(&ptr->head.users);
0171 goto out;
0172 }
0173 ptr = kzalloc(sizeof(*ptr) + len, GFP_NOFS | __GFP_NOWARN);
0174 if (tomoyo_memory_ok(ptr)) {
0175 ptr->entry.name = ((char *) ptr) + sizeof(*ptr);
0176 memmove((char *) ptr->entry.name, name, len);
0177 atomic_set(&ptr->head.users, 1);
0178 tomoyo_fill_path_info(&ptr->entry);
0179 list_add_tail(&ptr->head.list, head);
0180 } else {
0181 kfree(ptr);
0182 ptr = NULL;
0183 }
0184 out:
0185 mutex_unlock(&tomoyo_policy_lock);
0186 return ptr ? &ptr->entry : NULL;
0187 }
0188
0189
0190 struct tomoyo_policy_namespace tomoyo_kernel_namespace;
0191
0192
0193
0194
0195 void __init tomoyo_mm_init(void)
0196 {
0197 int idx;
0198
0199 for (idx = 0; idx < TOMOYO_MAX_HASH; idx++)
0200 INIT_LIST_HEAD(&tomoyo_name_list[idx]);
0201 tomoyo_kernel_namespace.name = "<kernel>";
0202 tomoyo_init_policy_namespace(&tomoyo_kernel_namespace);
0203 tomoyo_kernel_domain.ns = &tomoyo_kernel_namespace;
0204 INIT_LIST_HEAD(&tomoyo_kernel_domain.acl_info_list);
0205 tomoyo_kernel_domain.domainname = tomoyo_get_name("<kernel>");
0206 list_add_tail_rcu(&tomoyo_kernel_domain.list, &tomoyo_domain_list);
0207 }