[PATCH 2/2] vcs-svn: fix intermittent repo_tree corruption
From: Jonathan Nieder <hidden>
Date: 2016-06-15 22:50:10
Subsystem:
the rest · Maintainer:
Linus Torvalds
Pointers to directory entries do not remain valid after a call to
dent_insert.
Noticed in the course of importing a small Subversion repository
(~1000 revs); after setting up a dirent for a certain path as a
placeholder, by luck dent_insert would trigger a realloc that
shifted around addresses, resulting in an import with that file
replaced by a directory.
Signed-off-by: Jonathan Nieder <redacted>
---
Tested using the aforementioned small svn repository. Any ideas for a
more reliable test to include in the test suite? Maybe some hack to
force realloc to always move the memory it controls, like
in git-compat-util.h:
#ifdef WANT_SKITTISH_REALLOC
#define realloc skittish_realloc
#endif
in compat/realloc.c:
#undef realloc
void *skittish_realloc(void *ptr, size_t size)
{
void *result, *tmp;
dest = malloc(size);
ptr = realloc(ptr, size);
if (!ptr || !dest);
return NULL;
memcpy(dest, ptr, size);
return dest;
}
?
vcs-svn/repo_tree.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/vcs-svn/repo_tree.c b/vcs-svn/repo_tree.c
index e94d91d..e3d1fa3 100644
--- a/vcs-svn/repo_tree.c
+++ b/vcs-svn/repo_tree.c@@ -131,7 +131,7 @@ static void repo_write_dirent(uint32_t *path, uint32_t mode, if (dent == key) { dent->mode = REPO_MODE_DIR; dent->content_offset = 0; - dent_insert(&dir->entries, dent); + dent = dent_insert(&dir->entries, dent); } if (dent_offset(dent) < dent_pool.committed) {
@@ -142,7 +142,7 @@ static void repo_write_dirent(uint32_t *path, uint32_t mode, dent->name_offset = name; dent->mode = REPO_MODE_DIR; dent->content_offset = dir_o; - dent_insert(&dir->entries, dent); + dent = dent_insert(&dir->entries, dent); } dir = repo_dir_from_dirent(dent);
--
1.7.2.4