aboutsummaryrefslogtreecommitdiffstats
path: root/security/tomoyo/memory.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/tomoyo/memory.c')
-rw-r--r--security/tomoyo/memory.c117
1 files changed, 27 insertions, 90 deletions
diff --git a/security/tomoyo/memory.c b/security/tomoyo/memory.c
index 39d012823f84..78b6143068de 100644
--- a/security/tomoyo/memory.c
+++ b/security/tomoyo/memory.c
@@ -29,16 +29,13 @@ void tomoyo_warn_oom(const char *function)
29 panic("MAC Initialization failed.\n"); 29 panic("MAC Initialization failed.\n");
30} 30}
31 31
32/* Lock for protecting tomoyo_memory_used. */
33static DEFINE_SPINLOCK(tomoyo_policy_memory_lock);
32/* Memoy currently used by policy/audit log/query. */ 34/* Memoy currently used by policy/audit log/query. */
33unsigned int tomoyo_memory_used[TOMOYO_MAX_MEMORY_STAT]; 35unsigned int tomoyo_memory_used[TOMOYO_MAX_MEMORY_STAT];
34/* Memory quota for "policy"/"audit log"/"query". */ 36/* Memory quota for "policy"/"audit log"/"query". */
35unsigned int tomoyo_memory_quota[TOMOYO_MAX_MEMORY_STAT]; 37unsigned int tomoyo_memory_quota[TOMOYO_MAX_MEMORY_STAT];
36 38
37/* Memory allocated for policy. */
38static atomic_t tomoyo_policy_memory_size;
39/* Quota for holding policy. */
40static unsigned int tomoyo_quota_for_policy;
41
42/** 39/**
43 * tomoyo_memory_ok - Check memory quota. 40 * tomoyo_memory_ok - Check memory quota.
44 * 41 *
@@ -50,15 +47,20 @@ static unsigned int tomoyo_quota_for_policy;
50 */ 47 */
51bool tomoyo_memory_ok(void *ptr) 48bool tomoyo_memory_ok(void *ptr)
52{ 49{
53 size_t s = ptr ? ksize(ptr) : 0; 50 if (ptr) {
54 atomic_add(s, &tomoyo_policy_memory_size); 51 const size_t s = ksize(ptr);
55 if (ptr && (!tomoyo_quota_for_policy || 52 bool result;
56 atomic_read(&tomoyo_policy_memory_size) 53 spin_lock(&tomoyo_policy_memory_lock);
57 <= tomoyo_quota_for_policy)) { 54 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] += s;
58 memset(ptr, 0, s); 55 result = !tomoyo_memory_quota[TOMOYO_MEMORY_POLICY] ||
59 return true; 56 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] <=
57 tomoyo_memory_quota[TOMOYO_MEMORY_POLICY];
58 if (!result)
59 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] -= s;
60 spin_unlock(&tomoyo_policy_memory_lock);
61 if (result)
62 return true;
60 } 63 }
61 atomic_sub(s, &tomoyo_policy_memory_size);
62 tomoyo_warn_oom(__func__); 64 tomoyo_warn_oom(__func__);
63 return false; 65 return false;
64} 66}
@@ -91,7 +93,10 @@ void *tomoyo_commit_ok(void *data, const unsigned int size)
91 */ 93 */
92void tomoyo_memory_free(void *ptr) 94void tomoyo_memory_free(void *ptr)
93{ 95{
94 atomic_sub(ksize(ptr), &tomoyo_policy_memory_size); 96 size_t s = ksize(ptr);
97 spin_lock(&tomoyo_policy_memory_lock);
98 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] -= s;
99 spin_unlock(&tomoyo_policy_memory_lock);
95 kfree(ptr); 100 kfree(ptr);
96} 101}
97 102
@@ -162,7 +167,6 @@ const struct tomoyo_path_info *tomoyo_get_name(const char *name)
162 struct tomoyo_name *ptr; 167 struct tomoyo_name *ptr;
163 unsigned int hash; 168 unsigned int hash;
164 int len; 169 int len;
165 int allocated_len;
166 struct list_head *head; 170 struct list_head *head;
167 171
168 if (!name) 172 if (!name)
@@ -179,22 +183,17 @@ const struct tomoyo_path_info *tomoyo_get_name(const char *name)
179 goto out; 183 goto out;
180 } 184 }
181 ptr = kzalloc(sizeof(*ptr) + len, GFP_NOFS); 185 ptr = kzalloc(sizeof(*ptr) + len, GFP_NOFS);
182 allocated_len = ptr ? ksize(ptr) : 0; 186 if (tomoyo_memory_ok(ptr)) {
183 if (!ptr || (tomoyo_quota_for_policy && 187 ptr->entry.name = ((char *) ptr) + sizeof(*ptr);
184 atomic_read(&tomoyo_policy_memory_size) + allocated_len 188 memmove((char *) ptr->entry.name, name, len);
185 > tomoyo_quota_for_policy)) { 189 atomic_set(&ptr->head.users, 1);
190 tomoyo_fill_path_info(&ptr->entry);
191 list_add_tail(&ptr->head.list, head);
192 } else {
186 kfree(ptr); 193 kfree(ptr);
187 ptr = NULL; 194 ptr = NULL;
188 tomoyo_warn_oom(__func__);
189 goto out;
190 } 195 }
191 atomic_add(allocated_len, &tomoyo_policy_memory_size); 196out:
192 ptr->entry.name = ((char *) ptr) + sizeof(*ptr);
193 memmove((char *) ptr->entry.name, name, len);
194 atomic_set(&ptr->head.users, 1);
195 tomoyo_fill_path_info(&ptr->entry);
196 list_add_tail(&ptr->head.list, head);
197 out:
198 mutex_unlock(&tomoyo_policy_lock); 197 mutex_unlock(&tomoyo_policy_lock);
199 return ptr ? &ptr->entry : NULL; 198 return ptr ? &ptr->entry : NULL;
200} 199}
@@ -227,65 +226,3 @@ void __init tomoyo_mm_init(void)
227 } 226 }
228#endif 227#endif
229} 228}
230
231
232/* Memory allocated for query lists. */
233unsigned int tomoyo_query_memory_size;
234/* Quota for holding query lists. */
235unsigned int tomoyo_quota_for_query;
236
237/**
238 * tomoyo_read_memory_counter - Check for memory usage in bytes.
239 *
240 * @head: Pointer to "struct tomoyo_io_buffer".
241 *
242 * Returns memory usage.
243 */
244void tomoyo_read_memory_counter(struct tomoyo_io_buffer *head)
245{
246 if (!head->r.eof) {
247 const unsigned int policy
248 = atomic_read(&tomoyo_policy_memory_size);
249 const unsigned int query = tomoyo_query_memory_size;
250 char buffer[64];
251
252 memset(buffer, 0, sizeof(buffer));
253 if (tomoyo_quota_for_policy)
254 snprintf(buffer, sizeof(buffer) - 1,
255 " (Quota: %10u)",
256 tomoyo_quota_for_policy);
257 else
258 buffer[0] = '\0';
259 tomoyo_io_printf(head, "Policy: %10u%s\n", policy,
260 buffer);
261 if (tomoyo_quota_for_query)
262 snprintf(buffer, sizeof(buffer) - 1,
263 " (Quota: %10u)",
264 tomoyo_quota_for_query);
265 else
266 buffer[0] = '\0';
267 tomoyo_io_printf(head, "Query lists: %10u%s\n", query,
268 buffer);
269 tomoyo_io_printf(head, "Total: %10u\n", policy + query);
270 head->r.eof = true;
271 }
272}
273
274/**
275 * tomoyo_write_memory_quota - Set memory quota.
276 *
277 * @head: Pointer to "struct tomoyo_io_buffer".
278 *
279 * Returns 0.
280 */
281int tomoyo_write_memory_quota(struct tomoyo_io_buffer *head)
282{
283 char *data = head->write_buf;
284 unsigned int size;
285
286 if (sscanf(data, "Policy: %u", &size) == 1)
287 tomoyo_quota_for_policy = size;
288 else if (sscanf(data, "Query lists: %u", &size) == 1)
289 tomoyo_quota_for_query = size;
290 return 0;
291}