diff options
Diffstat (limited to 'security/tomoyo/realpath.c')
-rw-r--r-- | security/tomoyo/realpath.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c index 5f2e33263371..917f564cdab1 100644 --- a/security/tomoyo/realpath.c +++ b/security/tomoyo/realpath.c @@ -13,6 +13,8 @@ #include <linux/mount.h> #include <linux/mnt_namespace.h> #include <linux/fs_struct.h> +#include <linux/hash.h> + #include "common.h" #include "realpath.h" @@ -263,7 +265,8 @@ static unsigned int tomoyo_quota_for_savename; * table. Frequency of appending strings is very low. So we don't need * large (e.g. 64k) hash size. 256 will be sufficient. */ -#define TOMOYO_MAX_HASH 256 +#define TOMOYO_HASH_BITS 8 +#define TOMOYO_MAX_HASH (1u<<TOMOYO_HASH_BITS) /* * tomoyo_name_entry is a structure which is used for linking @@ -315,6 +318,7 @@ const struct tomoyo_path_info *tomoyo_save_name(const char *name) struct tomoyo_free_memory_block_list *fmb; int len; char *cp; + struct list_head *head; if (!name) return NULL; @@ -325,9 +329,10 @@ const struct tomoyo_path_info *tomoyo_save_name(const char *name) return NULL; } hash = full_name_hash((const unsigned char *) name, len - 1); + head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)]; + mutex_lock(&lock); - list_for_each_entry(ptr, &tomoyo_name_list[hash % TOMOYO_MAX_HASH], - list) { + list_for_each_entry(ptr, head, list) { if (hash == ptr->entry.hash && !strcmp(name, ptr->entry.name)) goto out; } @@ -365,7 +370,7 @@ const struct tomoyo_path_info *tomoyo_save_name(const char *name) tomoyo_fill_path_info(&ptr->entry); fmb->ptr += len; fmb->len -= len; - list_add_tail(&ptr->list, &tomoyo_name_list[hash % TOMOYO_MAX_HASH]); + list_add_tail(&ptr->list, head); if (fmb->len == 0) { list_del(&fmb->list); kfree(fmb); |