All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeff King <peff@peff.net>
To: "Kyle J. McKay" <mackyle@gmail.com>
Cc: Jonathon Mah <me@jonathonmah.com>,
	Junio C Hamano <gitster@pobox.com>,
	Git mailing list <git@vger.kernel.org>
Subject: Re: [PATCH] sha1_file.c: make sure open_sha1_file does not open a directory
Date: Sun, 8 Feb 2015 19:54:44 -0500	[thread overview]
Message-ID: <20150209005444.GA16827@peff.net> (raw)
In-Reply-To: <b0993cc1fcac290d7506b24942af300@74d39fa044aa309eaea14b9f57fe79c>

On Sun, Feb 08, 2015 at 03:05:32PM -0800, Kyle J. McKay wrote:

> Since "sha1_file: fix iterating loose alternate objects", it's possible
> for the base member of the alt_odb_list structure to be NUL terminated
> rather than ending with a '/' when open_sha1_file is called.

Good catch. Users of "struct alternate_object_database" expect to be
able to fill in the "name" field, and have a full path in the "base"
field. That is part of the contract of the struct, and the recent fix
does not live up to that contract inside the for_each_loose_file...
callbacks.

For that reason, I don't think your fix is complete. It fixes _one_
caller to work around this breakage of the contract, but it does not do
anything about the other callers (of which you can find several if you
grep for `fill_sha1_path`). I don't know if those can be hit from this
code path, but it does not matter. We jump to a callback with the NUL
set, so we must assume any arbitrary code can be run.

So either we must amend the contract, so that users of alt->base must
check the termination themselves (i.e., your patch, but extended to all
users of alt->base), or we have to fix for_each_loose_file not to leave
the alt_odb struct in such a broken state. I think I'd prefer the
latter.

> While this patch can be applied without "sha1_file: fix iterating
> loose alternate objects" you cannot even get to the failure this fixes
> without first having that patch applied.

Right. This is literally a bug introduced by that patch. It's OK to
munge alt->name[-1] temporarily, but you have to make sure you are not
calling functions which will look at it while it is munged. The way
refs_from_alternate_cb does it is OK (NUL-terminate, xstrdup, then fix
it; or just xmemdupz the correct length, which we know from alt->name).

Something like:

diff --git a/sha1_file.c b/sha1_file.c
index 9e0c271..7253213 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -3396,11 +3396,11 @@ static int loose_from_alt_odb(struct alternate_object_database *alt,
 {
 	struct loose_alt_odb_data *data = vdata;
 	int r;
-	alt->name[-1] = 0;
-	r = for_each_loose_file_in_objdir(alt->base,
+	char *buf = xmemdupz(alt->base, alt->name - alt->base - 1);
+	r = for_each_loose_file_in_objdir(buf,
 					  data->cb, NULL, NULL,
 					  data->data);
-	alt->name[-1] = '/';
+	free(buf);
 	return r;
 }
 

However, the first thing for_each_loose_file_in_objdir is going to do is
stick the path into a strbuf. So perhaps the most sensible thing is to
just teach it to take a strbuf from the caller. I'll work up a patch.

It looks like a1b47246 isn't even in "next" yet, so I'll build it
directly on what is already in master, dropping Jonathan's patch.

-Peff

  reply	other threads:[~2015-02-09  0:54 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-02-08 23:05 [PATCH] sha1_file.c: make sure open_sha1_file does not open a directory Kyle J. McKay
2015-02-09  0:54 ` Jeff King [this message]
2015-02-09  1:12   ` Jeff King
2015-02-09  1:13     ` [PATCH 1/2] for_each_loose_file_in_objdir: take an optional strbuf path Jeff King
2015-02-09  1:15     ` [PATCH 2/2] sha1_file: fix iterating loose alternate objects Jeff King
2015-02-09  9:44       ` Kyle J. McKay
2015-02-09 18:48   ` [PATCH] sha1_file.c: make sure open_sha1_file does not open a directory Junio C Hamano

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=20150209005444.GA16827@peff.net \
    --to=peff@peff.net \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=mackyle@gmail.com \
    --cc=me@jonathonmah.com \
    /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.