diff options
author | David Turner <dturner@twopensource.com> | 2015-10-21 13:54:11 -0400 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2015-10-21 12:47:38 -0700 |
commit | 41284eb0f944fe2d73708bb4105a8e3ccd0297df (patch) | |
tree | d9fb4779370efc2eec5079f72c210bdec900ef87 /read-cache.c | |
parent | 441c4a40173fe1ee8a5c0094e587dfc47e2a6460 (diff) | |
download | git-41284eb0f944fe2d73708bb4105a8e3ccd0297df.tar.gz |
name-hash: don't reuse cache_entry in dir_entrydt/name-hash-dir-entry-fix
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 <kmcguigan@twitter.com> diagnosed this bug and wrote
the initial patch, but this version does not use any of Keith's code.
Helped-by: Keith McGuigan <kmcguigan@twitter.com>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: David Turner <dturner@twopensource.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'read-cache.c')
-rw-r--r-- | read-cache.c | 16 |
1 files changed, 1 insertions, 15 deletions
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); |