diff options
author | Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> | 2010-02-10 19:43:54 -0500 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2010-02-14 17:00:24 -0500 |
commit | 847b173ea3d6f50936823d07f2245059bf44713b (patch) | |
tree | b53c6d0536af73a078bcff0375f9f4d837f79bba /security/tomoyo/realpath.c | |
parent | ec8e6a4e062e2edebef91e930c20572c9f4c0dda (diff) |
TOMOYO: Add garbage collector.
This patch adds garbage collector support to TOMOYO.
Elements are protected by "struct srcu_struct tomoyo_ss".
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Acked-by: Serge Hallyn <serue@us.ibm.com>
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/tomoyo/realpath.c')
-rw-r--r-- | security/tomoyo/realpath.c | 86 |
1 files changed, 40 insertions, 46 deletions
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c index 9557168b3767..c00df45c7ede 100644 --- a/security/tomoyo/realpath.c +++ b/security/tomoyo/realpath.c | |||
@@ -205,9 +205,9 @@ char *tomoyo_realpath_nofollow(const char *pathname) | |||
205 | } | 205 | } |
206 | 206 | ||
207 | /* Memory allocated for non-string data. */ | 207 | /* Memory allocated for non-string data. */ |
208 | static unsigned int tomoyo_allocated_memory_for_elements; | 208 | static atomic_t tomoyo_policy_memory_size; |
209 | /* Quota for holding non-string data. */ | 209 | /* Quota for holding policy. */ |
210 | static unsigned int tomoyo_quota_for_elements; | 210 | static unsigned int tomoyo_quota_for_policy; |
211 | 211 | ||
212 | /** | 212 | /** |
213 | * tomoyo_memory_ok - Check memory quota. | 213 | * tomoyo_memory_ok - Check memory quota. |
@@ -222,26 +222,30 @@ static unsigned int tomoyo_quota_for_elements; | |||
222 | bool tomoyo_memory_ok(void *ptr) | 222 | bool tomoyo_memory_ok(void *ptr) |
223 | { | 223 | { |
224 | int allocated_len = ptr ? ksize(ptr) : 0; | 224 | int allocated_len = ptr ? ksize(ptr) : 0; |
225 | bool result = false; | 225 | atomic_add(allocated_len, &tomoyo_policy_memory_size); |
226 | if (!ptr || (tomoyo_quota_for_elements && | 226 | if (ptr && (!tomoyo_quota_for_policy || |
227 | tomoyo_allocated_memory_for_elements | 227 | atomic_read(&tomoyo_policy_memory_size) |
228 | + allocated_len > tomoyo_quota_for_elements)) { | 228 | <= tomoyo_quota_for_policy)) { |
229 | printk(KERN_WARNING "ERROR: Out of memory " | ||
230 | "for tomoyo_alloc_element().\n"); | ||
231 | if (!tomoyo_policy_loaded) | ||
232 | panic("MAC Initialization failed.\n"); | ||
233 | } else { | ||
234 | result = true; | ||
235 | tomoyo_allocated_memory_for_elements += allocated_len; | ||
236 | memset(ptr, 0, allocated_len); | 229 | memset(ptr, 0, allocated_len); |
230 | return true; | ||
237 | } | 231 | } |
238 | return result; | 232 | printk(KERN_WARNING "ERROR: Out of memory " |
233 | "for tomoyo_alloc_element().\n"); | ||
234 | if (!tomoyo_policy_loaded) | ||
235 | panic("MAC Initialization failed.\n"); | ||
236 | return false; | ||
239 | } | 237 | } |
240 | 238 | ||
241 | /* Memory allocated for string data in bytes. */ | 239 | /** |
242 | static unsigned int tomoyo_allocated_memory_for_savename; | 240 | * tomoyo_memory_free - Free memory for elements. |
243 | /* Quota for holding string data in bytes. */ | 241 | * |
244 | static unsigned int tomoyo_quota_for_savename; | 242 | * @ptr: Pointer to allocated memory. |
243 | */ | ||
244 | void tomoyo_memory_free(void *ptr) | ||
245 | { | ||
246 | atomic_sub(ksize(ptr), &tomoyo_policy_memory_size); | ||
247 | kfree(ptr); | ||
248 | } | ||
245 | 249 | ||
246 | /* | 250 | /* |
247 | * tomoyo_name_list is used for holding string data used by TOMOYO. | 251 | * tomoyo_name_list is used for holding string data used by TOMOYO. |
@@ -249,7 +253,9 @@ static unsigned int tomoyo_quota_for_savename; | |||
249 | * "/lib/libc-2.5.so"), TOMOYO shares string data in the form of | 253 | * "/lib/libc-2.5.so"), TOMOYO shares string data in the form of |
250 | * "const struct tomoyo_path_info *". | 254 | * "const struct tomoyo_path_info *". |
251 | */ | 255 | */ |
252 | static struct list_head tomoyo_name_list[TOMOYO_MAX_HASH]; | 256 | struct list_head tomoyo_name_list[TOMOYO_MAX_HASH]; |
257 | /* Lock for protecting tomoyo_name_list . */ | ||
258 | DEFINE_MUTEX(tomoyo_name_list_lock); | ||
253 | 259 | ||
254 | /** | 260 | /** |
255 | * tomoyo_get_name - Allocate permanent memory for string data. | 261 | * tomoyo_get_name - Allocate permanent memory for string data. |
@@ -260,7 +266,6 @@ static struct list_head tomoyo_name_list[TOMOYO_MAX_HASH]; | |||
260 | */ | 266 | */ |
261 | const struct tomoyo_path_info *tomoyo_get_name(const char *name) | 267 | const struct tomoyo_path_info *tomoyo_get_name(const char *name) |
262 | { | 268 | { |
263 | static DEFINE_MUTEX(lock); | ||
264 | struct tomoyo_name_entry *ptr; | 269 | struct tomoyo_name_entry *ptr; |
265 | unsigned int hash; | 270 | unsigned int hash; |
266 | int len; | 271 | int len; |
@@ -272,7 +277,7 @@ const struct tomoyo_path_info *tomoyo_get_name(const char *name) | |||
272 | len = strlen(name) + 1; | 277 | len = strlen(name) + 1; |
273 | hash = full_name_hash((const unsigned char *) name, len - 1); | 278 | hash = full_name_hash((const unsigned char *) name, len - 1); |
274 | head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)]; | 279 | head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)]; |
275 | mutex_lock(&lock); | 280 | mutex_lock(&tomoyo_name_list_lock); |
276 | list_for_each_entry(ptr, head, list) { | 281 | list_for_each_entry(ptr, head, list) { |
277 | if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name)) | 282 | if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name)) |
278 | continue; | 283 | continue; |
@@ -281,9 +286,9 @@ const struct tomoyo_path_info *tomoyo_get_name(const char *name) | |||
281 | } | 286 | } |
282 | ptr = kzalloc(sizeof(*ptr) + len, GFP_KERNEL); | 287 | ptr = kzalloc(sizeof(*ptr) + len, GFP_KERNEL); |
283 | allocated_len = ptr ? ksize(ptr) : 0; | 288 | allocated_len = ptr ? ksize(ptr) : 0; |
284 | if (!ptr || (tomoyo_quota_for_savename && | 289 | if (!ptr || (tomoyo_quota_for_policy && |
285 | tomoyo_allocated_memory_for_savename + allocated_len | 290 | atomic_read(&tomoyo_policy_memory_size) + allocated_len |
286 | > tomoyo_quota_for_savename)) { | 291 | > tomoyo_quota_for_policy)) { |
287 | kfree(ptr); | 292 | kfree(ptr); |
288 | printk(KERN_WARNING "ERROR: Out of memory " | 293 | printk(KERN_WARNING "ERROR: Out of memory " |
289 | "for tomoyo_get_name().\n"); | 294 | "for tomoyo_get_name().\n"); |
@@ -292,14 +297,14 @@ const struct tomoyo_path_info *tomoyo_get_name(const char *name) | |||
292 | ptr = NULL; | 297 | ptr = NULL; |
293 | goto out; | 298 | goto out; |
294 | } | 299 | } |
295 | tomoyo_allocated_memory_for_savename += allocated_len; | 300 | atomic_add(allocated_len, &tomoyo_policy_memory_size); |
296 | ptr->entry.name = ((char *) ptr) + sizeof(*ptr); | 301 | ptr->entry.name = ((char *) ptr) + sizeof(*ptr); |
297 | memmove((char *) ptr->entry.name, name, len); | 302 | memmove((char *) ptr->entry.name, name, len); |
298 | atomic_set(&ptr->users, 1); | 303 | atomic_set(&ptr->users, 1); |
299 | tomoyo_fill_path_info(&ptr->entry); | 304 | tomoyo_fill_path_info(&ptr->entry); |
300 | list_add_tail(&ptr->list, head); | 305 | list_add_tail(&ptr->list, head); |
301 | out: | 306 | out: |
302 | mutex_unlock(&lock); | 307 | mutex_unlock(&tomoyo_name_list_lock); |
303 | return ptr ? &ptr->entry : NULL; | 308 | return ptr ? &ptr->entry : NULL; |
304 | } | 309 | } |
305 | 310 | ||
@@ -334,28 +339,19 @@ void __init tomoyo_realpath_init(void) | |||
334 | int tomoyo_read_memory_counter(struct tomoyo_io_buffer *head) | 339 | int tomoyo_read_memory_counter(struct tomoyo_io_buffer *head) |
335 | { | 340 | { |
336 | if (!head->read_eof) { | 341 | if (!head->read_eof) { |
337 | const unsigned int shared | 342 | const unsigned int policy |
338 | = tomoyo_allocated_memory_for_savename; | 343 | = atomic_read(&tomoyo_policy_memory_size); |
339 | const unsigned int private | ||
340 | = tomoyo_allocated_memory_for_elements; | ||
341 | char buffer[64]; | 344 | char buffer[64]; |
342 | 345 | ||
343 | memset(buffer, 0, sizeof(buffer)); | 346 | memset(buffer, 0, sizeof(buffer)); |
344 | if (tomoyo_quota_for_savename) | 347 | if (tomoyo_quota_for_policy) |
345 | snprintf(buffer, sizeof(buffer) - 1, | ||
346 | " (Quota: %10u)", | ||
347 | tomoyo_quota_for_savename); | ||
348 | else | ||
349 | buffer[0] = '\0'; | ||
350 | tomoyo_io_printf(head, "Shared: %10u%s\n", shared, buffer); | ||
351 | if (tomoyo_quota_for_elements) | ||
352 | snprintf(buffer, sizeof(buffer) - 1, | 348 | snprintf(buffer, sizeof(buffer) - 1, |
353 | " (Quota: %10u)", | 349 | " (Quota: %10u)", |
354 | tomoyo_quota_for_elements); | 350 | tomoyo_quota_for_policy); |
355 | else | 351 | else |
356 | buffer[0] = '\0'; | 352 | buffer[0] = '\0'; |
357 | tomoyo_io_printf(head, "Private: %10u%s\n", private, buffer); | 353 | tomoyo_io_printf(head, "Policy: %10u%s\n", policy, buffer); |
358 | tomoyo_io_printf(head, "Total: %10u\n", shared + private); | 354 | tomoyo_io_printf(head, "Total: %10u\n", policy); |
359 | head->read_eof = true; | 355 | head->read_eof = true; |
360 | } | 356 | } |
361 | return 0; | 357 | return 0; |
@@ -373,9 +369,7 @@ int tomoyo_write_memory_quota(struct tomoyo_io_buffer *head) | |||
373 | char *data = head->write_buf; | 369 | char *data = head->write_buf; |
374 | unsigned int size; | 370 | unsigned int size; |
375 | 371 | ||
376 | if (sscanf(data, "Shared: %u", &size) == 1) | 372 | if (sscanf(data, "Policy: %u", &size) == 1) |
377 | tomoyo_quota_for_savename = size; | 373 | tomoyo_quota_for_policy = size; |
378 | else if (sscanf(data, "Private: %u", &size) == 1) | ||
379 | tomoyo_quota_for_elements = size; | ||
380 | return 0; | 374 | return 0; |
381 | } | 375 | } |