]> git.ipfire.org Git - thirdparty/git.git/commitdiff
remote: fix use-after-free error detected by glibc in ref_remove_duplicates
authorJulian Phillips <julian@quantumfyre.co.uk>
Fri, 13 Nov 2009 21:25:56 +0000 (21:25 +0000)
committerJunio C Hamano <gitster@pobox.com>
Sun, 15 Nov 2009 00:03:06 +0000 (16:03 -0800)
In ref_remove_duplicates, when we encounter a duplicate and remove it
from the list we need to make sure that the prev pointer stays
pointing at the last entry and also skip over adding the just freed
entry to the string_list.

Previously fetch could crash with:
*** glibc detected *** git: corrupted double-linked list: ...

Also add a test to try and catch problems with duplicate removal in
the future.

Acked-by: Nicolas Pitre <nico@fluxnic.net>
Signed-off-by: Julian Phillips <julian@quantumfyre.co.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
remote.c
t/t5510-fetch.sh

index 4f9f0ccc7b799a427130a7f7befdf6e931b30fc7..e0d17bb83060561c17114905c253eebdf925a01c 100644 (file)
--- a/remote.c
+++ b/remote.c
@@ -754,6 +754,8 @@ void ref_remove_duplicates(struct ref *ref_map)
                        prev->next = ref_map->next;
                        free(ref_map->peer_ref);
                        free(ref_map);
+                       ref_map = prev; /* skip this; we freed it */
+                       continue;
                }
 
                item = string_list_insert(ref_map->peer_ref->name, &refs);
index d13c806624bcc8a404be97d61500e8e1d4614c6b..169af1edde557f054ea76b8de681c6dd74e436f2 100755 (executable)
@@ -341,4 +341,15 @@ test_expect_success 'fetch into the current branch with --update-head-ok' '
 
 '
 
+test_expect_success "should be able to fetch with duplicate refspecs" '
+        mkdir dups &&
+        cd dups &&
+        git init &&
+        git config branch.master.remote three &&
+        git config remote.three.url ../three/.git &&
+        git config remote.three.fetch +refs/heads/*:refs/remotes/origin/* &&
+        git config --add remote.three.fetch +refs/heads/*:refs/remotes/origin/* &&
+        git fetch three
+'
+
 test_done