From 41284eb0f944fe2d73708bb4105a8e3ccd0297df Mon Sep 17 00:00:00 2001 From: David Turner Date: Wed, 21 Oct 2015 13:54:11 -0400 Subject: name-hash: don't reuse cache_entry in dir_entry Stop reusing cache_entry in dir_entry; doing so causes a use-after-free bug. During merges, we free entries that we no longer need in the destination index. But those entries might have also been stored in the dir_entry cache, and when a later call to add_to_index found them, they would be used after being freed. To prevent this, change dir_entry to store a copy of the name instead of a pointer to a cache_entry. This entails some refactoring of code that expects the cache_entry. Keith McGuigan diagnosed this bug and wrote the initial patch, but this version does not use any of Keith's code. Helped-by: Keith McGuigan Helped-by: Junio C Hamano Signed-off-by: David Turner Signed-off-by: Junio C Hamano --- read-cache.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) (limited to 'read-cache.c') diff --git a/read-cache.c b/read-cache.c index 9cff715d6b..3c388c35ae 100644 --- a/read-cache.c +++ b/read-cache.c @@ -661,21 +661,7 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st, * entry's directory case. */ if (ignore_case) { - const char *startPtr = ce->name; - const char *ptr = startPtr; - while (*ptr) { - while (*ptr && *ptr != '/') - ++ptr; - if (*ptr == '/') { - struct cache_entry *foundce; - ++ptr; - foundce = index_dir_exists(istate, ce->name, ptr - ce->name - 1); - if (foundce) { - memcpy((void *)startPtr, foundce->name + (startPtr - ce->name), ptr - startPtr); - startPtr = ptr; - } - } - } + adjust_dirname_case(istate, ce->name); } alias = index_file_exists(istate, ce->name, ce_namelen(ce), ignore_case); -- cgit v1.2.1