summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2020-02-07 12:50:39 +0100
committerPatrick Steinhardt <ps@pks.im>2020-02-07 13:08:23 +0100
commit7d1b17744a958890cae4648d4b38de2999832d77 (patch)
tree1cbf181d661f0842b0bf1d425c52d7b596c59c4a
parent775af0159bbb449dc2c800ffb1644250932fe6c1 (diff)
downloadlibgit2-7d1b17744a958890cae4648d4b38de2999832d77.tar.gz
cache: fix invalid memory access in case updating cache entry fails
When adding a new entry to our cache where an entry with the same OID exists already, then we only update the existing entry in case it is unparsed and the new entry is parsed. Currently, we do not check the return value of `git_oidmap_set` though when updating the existing entry. As a result, we will _not_ have updated the existing entry if `git_oidmap_set` fails, but have decremented its refcount and incremented the new entry's refcount. Later on, this may likely lead to dereferencing invalid memory. Fix the issue by checking the return value of `git_oidmap_set`. In case it fails, we will simply keep the existing stored instead, even though it's unparsed.
-rw-r--r--src/cache.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/src/cache.c b/src/cache.c
index 32ba993b0..af42b3959 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -208,10 +208,14 @@ static void *cache_store(git_cache *cache, git_cached_obj *entry)
entry = stored_entry;
} else if (stored_entry->flags == GIT_CACHE_STORE_RAW &&
entry->flags == GIT_CACHE_STORE_PARSED) {
- git_cached_obj_decref(stored_entry);
- git_cached_obj_incref(entry);
-
- git_oidmap_set(cache->map, &entry->oid, entry);
+ if (git_oidmap_set(cache->map, &entry->oid, entry) == 0) {
+ git_cached_obj_decref(stored_entry);
+ git_cached_obj_incref(entry);
+ } else {
+ git_cached_obj_decref(entry);
+ git_cached_obj_incref(stored_entry);
+ entry = stored_entry;
+ }
} else {
/* NO OP */
}