From d345a7b12e7e0aa0afc5d073a1773a36d20e1846 Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Mon, 11 Oct 2010 16:09:21 -0400 Subject: [PATCH] name cache: bug fix for name_cache_search() symptom: in certain cases, name_cache_find_or_create() was returning ERROR_FILE_EXISTS, which should never happen! cause: the string comparisons in name_cache_search() and name_cache_insert() were returning different results when the argument to name_cache_search() is a) not null-terminated, and b) shorter than the other string. this caused name_cache_search() to search the wrong branch of the rbtree and fail to find the component, while name_cache_insert() would correctly find it and return ERROR_FILE_EXISTS fix: compare the string lengths before calling strncmp() to avoid comparing past the end of the component. moved the comparisons to a separate component_cmp() function called by both name_cache_search() and name_cache_insert() to make sure they get the same result! Signed-off-by: Casey Bodley --- daemon/name_cache.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/daemon/name_cache.c b/daemon/name_cache.c index fa4b2b1..757ae1c 100644 --- a/daemon/name_cache.c +++ b/daemon/name_cache.c @@ -531,6 +531,16 @@ static void name_cache_entry_invalidate( name_cache_unlink(cache, entry); } +static int component_cmp( + IN const char *lhs, + IN unsigned short lhs_len, + IN const char *rhs, + IN unsigned short rhs_len) +{ + const int diff = rhs_len - lhs_len; + return diff ? diff : strncmp(lhs, rhs, lhs_len); +} + static struct name_cache_entry* name_cache_search( IN struct nfs41_name_cache *cache, IN struct name_cache_entry *parent, @@ -552,8 +562,9 @@ static struct name_cache_entry* name_cache_search( while (node) { entry = rb_entry(node, struct name_cache_entry, rbnode); - result = strncmp(component->name, entry->component, - max(component->len, entry->component_len)); + result = component_cmp(component->name, component->len, + entry->component, entry->component_len); + if (result < 0) node = node->rb_left; else if (result > 0) @@ -658,7 +669,8 @@ static int name_cache_insert( while (*node) { current = rb_entry(*node, struct name_cache_entry, rbnode); - result = strcmp(entry->component, current->component); + result = component_cmp(entry->component, entry->component_len, + current->component, current->component_len); prev = *node; if (result < 0)