Commit add8db06f91f1dc9acc7f20f8229f746041de2c8

Russell Belfer 2014-03-27T15:28:29

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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
diff --git a/src/submodule.c b/src/submodule.c
index b07c9d9..0a3762f 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);
 		}
 	});