diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/tomoyo/realpath.c | 60 |
1 files changed, 10 insertions, 50 deletions
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c index 62363b3bc716..9105e5e29da9 100644 --- a/security/tomoyo/realpath.c +++ b/security/tomoyo/realpath.c | |||
@@ -293,13 +293,6 @@ struct tomoyo_name_entry { | |||
293 | struct tomoyo_path_info entry; | 293 | struct tomoyo_path_info entry; |
294 | }; | 294 | }; |
295 | 295 | ||
296 | /* Structure for available memory region. */ | ||
297 | struct tomoyo_free_memory_block_list { | ||
298 | struct list_head list; | ||
299 | char *ptr; /* Pointer to a free area. */ | ||
300 | int len; /* Length of the area. */ | ||
301 | }; | ||
302 | |||
303 | /* | 296 | /* |
304 | * tomoyo_name_list is used for holding string data used by TOMOYO. | 297 | * tomoyo_name_list is used for holding string data used by TOMOYO. |
305 | * Since same string data is likely used for multiple times (e.g. | 298 | * Since same string data is likely used for multiple times (e.g. |
@@ -314,52 +307,32 @@ static struct list_head tomoyo_name_list[TOMOYO_MAX_HASH]; | |||
314 | * @name: The string to store into the permernent memory. | 307 | * @name: The string to store into the permernent memory. |
315 | * | 308 | * |
316 | * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise. | 309 | * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise. |
317 | * | ||
318 | * The RAM is shared, so NEVER try to modify or kfree() the returned name. | ||
319 | */ | 310 | */ |
320 | const struct tomoyo_path_info *tomoyo_save_name(const char *name) | 311 | const struct tomoyo_path_info *tomoyo_save_name(const char *name) |
321 | { | 312 | { |
322 | static LIST_HEAD(fmb_list); | ||
323 | static DEFINE_MUTEX(lock); | 313 | static DEFINE_MUTEX(lock); |
324 | struct tomoyo_name_entry *ptr; | 314 | struct tomoyo_name_entry *ptr; |
325 | unsigned int hash; | 315 | unsigned int hash; |
326 | /* fmb contains available size in bytes. | ||
327 | fmb is removed from the fmb_list when fmb->len becomes 0. */ | ||
328 | struct tomoyo_free_memory_block_list *fmb; | ||
329 | int len; | 316 | int len; |
330 | char *cp; | 317 | int allocated_len; |
331 | struct list_head *head; | 318 | struct list_head *head; |
332 | 319 | ||
333 | if (!name) | 320 | if (!name) |
334 | return NULL; | 321 | return NULL; |
335 | len = strlen(name) + 1; | 322 | len = strlen(name) + 1; |
336 | if (len > TOMOYO_MAX_PATHNAME_LEN) { | ||
337 | printk(KERN_WARNING "ERROR: Name too long " | ||
338 | "for tomoyo_save_name().\n"); | ||
339 | return NULL; | ||
340 | } | ||
341 | hash = full_name_hash((const unsigned char *) name, len - 1); | 323 | hash = full_name_hash((const unsigned char *) name, len - 1); |
342 | head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)]; | 324 | head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)]; |
343 | |||
344 | mutex_lock(&lock); | 325 | mutex_lock(&lock); |
345 | list_for_each_entry(ptr, head, list) { | 326 | list_for_each_entry(ptr, head, list) { |
346 | if (hash == ptr->entry.hash && !strcmp(name, ptr->entry.name)) | 327 | if (hash == ptr->entry.hash && !strcmp(name, ptr->entry.name)) |
347 | goto out; | 328 | goto out; |
348 | } | 329 | } |
349 | list_for_each_entry(fmb, &fmb_list, list) { | 330 | ptr = kzalloc(sizeof(*ptr) + len, GFP_KERNEL); |
350 | if (len <= fmb->len) | 331 | allocated_len = ptr ? ksize(ptr) : 0; |
351 | goto ready; | 332 | if (!ptr || (tomoyo_quota_for_savename && |
352 | } | 333 | tomoyo_allocated_memory_for_savename + allocated_len |
353 | if (!tomoyo_quota_for_savename || | 334 | > tomoyo_quota_for_savename)) { |
354 | tomoyo_allocated_memory_for_savename + PATH_MAX | 335 | kfree(ptr); |
355 | <= tomoyo_quota_for_savename) | ||
356 | cp = kzalloc(PATH_MAX, GFP_KERNEL); | ||
357 | else | ||
358 | cp = NULL; | ||
359 | fmb = kzalloc(sizeof(*fmb), GFP_KERNEL); | ||
360 | if (!cp || !fmb) { | ||
361 | kfree(cp); | ||
362 | kfree(fmb); | ||
363 | printk(KERN_WARNING "ERROR: Out of memory " | 336 | printk(KERN_WARNING "ERROR: Out of memory " |
364 | "for tomoyo_save_name().\n"); | 337 | "for tomoyo_save_name().\n"); |
365 | if (!tomoyo_policy_loaded) | 338 | if (!tomoyo_policy_loaded) |
@@ -367,24 +340,11 @@ const struct tomoyo_path_info *tomoyo_save_name(const char *name) | |||
367 | ptr = NULL; | 340 | ptr = NULL; |
368 | goto out; | 341 | goto out; |
369 | } | 342 | } |
370 | tomoyo_allocated_memory_for_savename += PATH_MAX; | 343 | tomoyo_allocated_memory_for_savename += allocated_len; |
371 | list_add(&fmb->list, &fmb_list); | 344 | ptr->entry.name = ((char *) ptr) + sizeof(*ptr); |
372 | fmb->ptr = cp; | 345 | memmove((char *) ptr->entry.name, name, len); |
373 | fmb->len = PATH_MAX; | ||
374 | ready: | ||
375 | ptr = tomoyo_alloc_element(sizeof(*ptr)); | ||
376 | if (!ptr) | ||
377 | goto out; | ||
378 | ptr->entry.name = fmb->ptr; | ||
379 | memmove(fmb->ptr, name, len); | ||
380 | tomoyo_fill_path_info(&ptr->entry); | 346 | tomoyo_fill_path_info(&ptr->entry); |
381 | fmb->ptr += len; | ||
382 | fmb->len -= len; | ||
383 | list_add_tail(&ptr->list, head); | 347 | list_add_tail(&ptr->list, head); |
384 | if (fmb->len == 0) { | ||
385 | list_del(&fmb->list); | ||
386 | kfree(fmb); | ||
387 | } | ||
388 | out: | 348 | out: |
389 | mutex_unlock(&lock); | 349 | mutex_unlock(&lock); |
390 | return ptr ? &ptr->entry : NULL; | 350 | return ptr ? &ptr->entry : NULL; |