diff options
Diffstat (limited to 'security/tomoyo/memory.c')
-rw-r--r-- | security/tomoyo/memory.c | 117 |
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. */ | ||
33 | static DEFINE_SPINLOCK(tomoyo_policy_memory_lock); | ||
32 | /* Memoy currently used by policy/audit log/query. */ | 34 | /* Memoy currently used by policy/audit log/query. */ |
33 | unsigned int tomoyo_memory_used[TOMOYO_MAX_MEMORY_STAT]; | 35 | unsigned int tomoyo_memory_used[TOMOYO_MAX_MEMORY_STAT]; |
34 | /* Memory quota for "policy"/"audit log"/"query". */ | 36 | /* Memory quota for "policy"/"audit log"/"query". */ |
35 | unsigned int tomoyo_memory_quota[TOMOYO_MAX_MEMORY_STAT]; | 37 | unsigned int tomoyo_memory_quota[TOMOYO_MAX_MEMORY_STAT]; |
36 | 38 | ||
37 | /* Memory allocated for policy. */ | ||
38 | static atomic_t tomoyo_policy_memory_size; | ||
39 | /* Quota for holding policy. */ | ||
40 | static 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 | */ |
51 | bool tomoyo_memory_ok(void *ptr) | 48 | bool 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 | */ |
92 | void tomoyo_memory_free(void *ptr) | 94 | void 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); | 196 | out: |
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. */ | ||
233 | unsigned int tomoyo_query_memory_size; | ||
234 | /* Quota for holding query lists. */ | ||
235 | unsigned 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 | */ | ||
244 | void 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 | */ | ||
281 | int 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 | } | ||