Re: [PATCH v4 3/3] upload-archive: use start_command instead of fork

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Jeff King wrote:
> On Tue, Nov 15, 2011 at 11:22:48AM +0100, Thomas Rast wrote:
> > 
> > I see valgrind failures bisecting to this commit, like so:
> > 
> > ==19125== Syscall param execve(argv[i]) points to unaddressable byte(s)
> > ==19125==    at 0x5303CB7: execve (in /lib64/libc-2.11.3.so)
> > ==19125==    by 0x53045A5: execvpe (in /lib64/libc-2.11.3.so)
> > ==19125==    by 0x4B183C: execv_git_cmd (exec_cmd.c:137)
> > ==19125==    by 0x4F305E: start_command (run-command.c:277)
> > ==19125==    by 0x47F5C9: cmd_upload_archive (upload-archive.c:98)
> > ==19125==    by 0x4051F4: run_builtin (git.c:308)
> > ==19125==    by 0x40538F: handle_internal_command (git.c:466)
> > ==19125==    by 0x405556: main (git.c:553)
> > ==19125==  Address 0x7feffe7d0 is not stack'd, malloc'd or (recently) free'd
> > 
> > when running 'make valgrind' in current master.  Let me know if you
> > need more information.
> 
> With which test, and on what OS? I couldn't replicate running
> t5000 on Linux.

11, and many others after it, on a pretty vanilla opensuse 11.4 VM I
use almost exclusively for the valgrind runs.  I used a pre-3.7 SVN
valgrind build, but 3.6.1 (shipped with opensuse) finds the same.

But after a closer look I think this patch just prodded it enough to
unearth long-existing undefined behaviour: prepare_argv() summarizes
to something like

static void prepare_argv(const char **sent_argv, const char **argv)
{
	char *p, buf[4096];

	for (p = buf;;) {
		len = packet_read_line(0, p, (buf + sizeof buf) - p);
		/* ... p always points into buf ... */
		sent_argv[sent_argc++] = p;
		p += len;
		*p++ = 0;
	}
	sent_argv[sent_argc] = NULL;
}

The code appears to have looked like this ever since the addition of
that file back in 39345a2 (Add git-upload-archive, 2006-09-07).  So
the elements of sent_argv have apparently always pointed into the
stack-allocated 'buf'.

(This correlates with the "Address 0x7feffe7d0 is not stack'd", even
though it's pretty clearly an address into the stack.)

A quick band-aid would be to heap-allocate it instead:

diff --git i/builtin/upload-archive.c w/builtin/upload-archive.c
index c57e8bd..6ab50d3 100644
--- i/builtin/upload-archive.c
+++ w/builtin/upload-archive.c
@@ -22,9 +22,10 @@ static const char lostchild[] =
 static void prepare_argv(const char **sent_argv, const char **argv)
 {
 	const char *arg_cmd = "argument ";
-	char *p, buf[4096];
+	char *p, *buf;
 	int sent_argc;
 	int len;
+	buf = xmalloc(4096);
 
 	/* put received options in sent_argv[] */
 	sent_argc = 2;
@@ -32,7 +33,7 @@ static void prepare_argv(const char **sent_argv, const char **argv)
 	sent_argv[1] = "--remote-request";
 	for (p = buf;;) {
 		/* This will die if not enough free space in buf */
-		len = packet_read_line(0, p, (buf + sizeof buf) - p);
+		len = packet_read_line(0, p, (buf + 4096) - p);
 		if (len == 0)
 			break;	/* got a flush */
 		if (sent_argc > MAX_ARGS - 2)

-- 
Thomas Rast
trast@{inf,student}.ethz.ch
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]