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 5f2e3326337..917f564cdab 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);  |