All of lore.kernel.org
 help / color / mirror / Atom feed
From: Thomas Rast <trast@inf.ethz.ch>
To: Miklos Vajna <vmiklos@suse.cz>
Cc: Junio C Hamano <gitster@pobox.com>,
	Ramkumar Ramachandra <artagnon@gmail.com>, <git@vger.kernel.org>
Subject: Re: [PATCH v3] cherry-pick: make sure all input objects are commits
Date: Mon, 15 Apr 2013 10:44:01 +0200	[thread overview]
Message-ID: <87vc7odvzi.fsf@linux-k42r.v.cablecom.net> (raw)
In-Reply-To: <20130411130652.GG12770@suse.cz> (Miklos Vajna's message of "Thu, 11 Apr 2013 15:06:52 +0200")

Miklos Vajna <vmiklos@suse.cz> writes:

> Fix this bug and make sure all arguments are commits, and
> for the first non-commit, error out with:
>
> 	fatal: <name>: Can't cherry-pick a <type>

> @@ -1067,6 +1068,23 @@ int sequencer_pick_revisions(struct replay_opts *opts)
>  	if (opts->subcommand == REPLAY_CONTINUE)
>  		return sequencer_continue(opts);
>  
> +	for (i = 0; i < opts->revs->pending.nr; i++) {
> +		unsigned char sha1[20];
> +		const char *name = opts->revs->pending.objects[i].name;
> +
> +		/* This happens when using --stdin. */
> +		if (!strlen(name))
> +			continue;

This is undefined behavior; the pending.objects[i].name has been freed
already.  Luckily valgrind points you right at it:

  ==9178== Invalid read of size 1
  ==9178==    at 0x4CEFB4: sequencer_pick_revisions (sequencer.c:1077)
  ==9178==    by 0x45E7F2: cmd_cherry_pick (revert.c:236)
  ==9178==    by 0x40523C: handle_internal_command (git.c:292)
  ==9178==    by 0x405467: main (git.c:500)
  ==9178==  Address 0x5bedbd0 is 0 bytes inside a block of size 1,001 free'd
  ==9178==    at 0x4C2ACDA: free (vg_replace_malloc.c:468)
  ==9178==    by 0x4D96C7: strbuf_release (strbuf.c:40)
  ==9178==    by 0x4C9AAE: setup_revisions (revision.c:1285)
  ==9178==    by 0x45E6FA: parse_args (revert.c:203)
  ==9178==    by 0x45E7EA: cmd_cherry_pick (revert.c:235)
  ==9178==    by 0x40523C: handle_internal_command (git.c:292)
  ==9178==    by 0x405467: main (git.c:500)

>From a cursory glance it looks like it's actually an existing bug in
read_revisions_from_stdin or handle_revision_arg, depending on which way
you look at it.  read_revisions_from_stdin passes its temporary buffer
down to handle_revision_arg:

        struct strbuf sb;
        [...]
        strbuf_init(&sb, 1000);
        while (strbuf_getwholeline(&sb, stdin, '\n') != EOF) {
                [...]
                if (handle_revision_arg(sb.buf, revs, 0, REVARG_CANNOT_BE_FILENAME))
                        die("bad revision '%s'", sb.buf);
        }

But handle_revision_arg ends up just stuffing that parameter into the
revision-walker options via some helpers:

	add_rev_cmdline(revs, object, arg_, REV_CMD_REV, flags ^ local_flags);
	add_pending_object_with_mode(revs, object, arg, oc.mode);

This seems to have been lurking since 281eee4 (revision: keep track of
the end-user input from the command line, 2011-08-25).

Junio, at which level should we fix it?  We could of course have
read_revisions_from_stdin make a copy of the buffers it passes down, but
perhaps it would be less surprising to instead have handle_revision_arg
make sure it makes a copy of everything it "keeps"?

The easy fix of course is just this:

diff --git i/revision.c w/revision.c
index 3a20c96..181a8db 100644
--- i/revision.c
+++ w/revision.c
@@ -1277,7 +1277,8 @@ static void read_revisions_from_stdin(struct rev_info *revs,
 			}
 			die("options not supported in --stdin mode");
 		}
-		if (handle_revision_arg(sb.buf, revs, 0, REVARG_CANNOT_BE_FILENAME))
+		if (handle_revision_arg(xstrdup(sb.buf), revs, 0,
+					REVARG_CANNOT_BE_FILENAME))
 			die("bad revision '%s'", sb.buf);
 	}
 	if (seen_dashdash)


-- 
Thomas Rast
trast@{inf,student}.ethz.ch

  parent reply	other threads:[~2013-04-15  8:44 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-04-03  9:27 [PATCH] cherry-pick: better error message when the parameter is a non-commit Miklos Vajna
2013-04-08 12:27 ` Miklos Vajna
2013-04-08 16:45   ` Junio C Hamano
2013-04-08 16:56 ` Junio C Hamano
2013-04-11  9:26   ` [PATCH v2] cherry-pick: make sure all input objects are commits Miklos Vajna
2013-04-11 10:22     ` Ramkumar Ramachandra
2013-04-11 11:03       ` Miklos Vajna
2013-04-11 11:42         ` Ramkumar Ramachandra
2013-04-11 13:06           ` [PATCH v3] " Miklos Vajna
2013-04-11 13:27             ` Ramkumar Ramachandra
2013-04-15  8:44             ` Thomas Rast [this message]
2013-04-15 18:29               ` Junio C Hamano
2013-04-15 19:12               ` Junio C Hamano
2013-04-16 14:22                 ` Michael Haggerty
2013-05-09 19:47             ` Junio C Hamano
2013-05-09 20:27               ` Junio C Hamano
2013-05-10  7:07                 ` Miklos Vajna

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87vc7odvzi.fsf@linux-k42r.v.cablecom.net \
    --to=trast@inf.ethz.ch \
    --cc=artagnon@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=vmiklos@suse.cz \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.