summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Phillips <julian@quantumfyre.co.uk>2009-11-13 21:25:56 (GMT)
committerJunio C Hamano <gitster@pobox.com>2009-11-15 00:03:06 (GMT)
commit95c96d48e65a597cfd2bf7228ddc8c7ca30b55b7 (patch)
tree22eda8e78a72863e9458d8c798e0b373f02d0daa
parentb1a01e1c0762d117da7dac009b773f310479be12 (diff)
downloadgit-95c96d48e65a597cfd2bf7228ddc8c7ca30b55b7.zip
git-95c96d48e65a597cfd2bf7228ddc8c7ca30b55b7.tar.gz
git-95c96d48e65a597cfd2bf7228ddc8c7ca30b55b7.tar.bz2
remote: fix use-after-free error detected by glibc in ref_remove_duplicates
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>
-rw-r--r--remote.c2
-rwxr-xr-xt/t5510-fetch.sh11
2 files changed, 13 insertions, 0 deletions
diff --git a/remote.c b/remote.c
index 4f9f0cc..e0d17bb 100644
--- 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);
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index d13c806..169af1e 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -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