Subject: Re: git 1.9.0 segfault

From: John Keeping <[email-masked]>
Date: Sat, 8 Mar 2014 18:12:18 +0000

On Sat, Mar 08, 2014 at 04:46:51PM +0000, brian m. carlson wrote:
> On Sat, Mar 08, 2014 at 04:23:43PM +0000, Guillaume Gelin wrote:
> > Hi,
> >
> > http://pastebin.com/Np7L54ar
> We're failing to rename because we got an EFAULT, and then we try to
> print the failing filename, and we get a segfault right here:
> 
> 			if (rename(src, dst) < 0 && !ignore_errors)
> 				die_errno (_("renaming '%s' failed"), src);
> 
> I don't know yet if dst is also bad, but clearly src is.  I'm looking
> into it.

The problem seems to be that we change argc when we append nested
directories to the list and then continue looping over 'source' which
has been realloc'd to be larger.  But we do not realloc
submodule_gitfile at the same time so we start writing beyond the end of
the submodule_gitfile array.

The particular behaviour of glibc's malloc happens to mean (at least on
my system) that this starts overwriting 'src'.

This fixes it for me:

-- >8 --
diff --git a/builtin/mv.c b/builtin/mv.c
index 7e26eb5..23f119a 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -180,6 +180,9 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
 						modes = xrealloc(modes,
 								(argc + last - first)
 								* sizeof(enum update_mode));
+						submodule_gitfile = xrealloc(submodule_gitfile,
+								(argc + last - first)
+								* sizeof(char *));
 					}
 
 					dst = add_slash(dst);