diff options
author | Russell Belfer <rb@github.com> | 2014-03-27 15:28:29 -0700 |
---|---|---|
committer | Russell Belfer <rb@github.com> | 2014-03-27 15:28:29 -0700 |
commit | add8db06f91f1dc9acc7f20f8229f746041de2c8 (patch) | |
tree | 31319dcf88e90f428cd0f90ce8f7f86afea84411 /src/submodule.c | |
parent | 041fad4aac106650f00b7c445675f1c4bb8cfd53 (diff) | |
download | libgit2-add8db06f91f1dc9acc7f20f8229f746041de2c8.tar.gz |
Fix use-after-free in submodule reload
If the first call to release a no-longer-existent submodule freed
the object, the check if a second is needed would dereference the
data that was just freed.
Diffstat (limited to 'src/submodule.c')
-rw-r--r-- | src/submodule.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/src/submodule.c b/src/submodule.c index b07c9d917..0a3762fab 100644 --- a/src/submodule.c +++ b/src/submodule.c @@ -852,10 +852,13 @@ int git_submodule_reload_all(git_repository *repo, int force) git_strmap_foreach_value(repo->submodules, sm, { git_strmap *cache = repo->submodules; - if ((sm->flags & GIT_SUBMODULE_STATUS__IN_FLAGS) == 0) { - submodule_cache_remove_item(cache, sm->name, sm, true); + if (sm && (sm->flags & GIT_SUBMODULE_STATUS__IN_FLAGS) == 0) { + /* we must check path != name before first remove, in case + * that call frees the submodule */ + bool free_as_path = (sm->path != sm->name); - if (sm->path != sm->name) + submodule_cache_remove_item(cache, sm->name, sm, true); + if (free_as_path) submodule_cache_remove_item(cache, sm->path, sm, true); } }); |