All of lore.kernel.org
 help / color / mirror / Atom feed
From: Johan Herland <johan@herland.net>
To: git@vger.kernel.org
Cc: "Johannes Schindelin" <Johannes.Schindelin@gmx.de>,
	"Daniel Barkalow" <barkalow@iabervon.org>,
	"Kristian Høgsberg" <krh@redhat.com>,
	"Santi Béjar" <sbejar@gmail.com>
Subject: [PATCH] Fix premature free of ref_lists while writing temporary refs to file
Date: Tue, 26 Feb 2008 16:35:51 +0100	[thread overview]
Message-ID: <200802261635.51407.johan@herland.net> (raw)
In-Reply-To: <200802261437.18950.johan@herland.net>

We cannot call write_ref_sha1() from within a for_each_ref() callback, since
it will free() the ref_list that the for_each_ref() is currently traversing.

Therefore rewrite setup_tmp_ref() to not call write_ref_sha1(), as already
hinted at in a comment.

This causes the t5700-clone-reference testcases to pass for me.

Signed-off-by: Johan Herland <johan@herland.net>
---

On Tuesday 26 February 2008, Johan Herland wrote:
> On Tuesday 26 February 2008, Johan Herland wrote:
> > Running this test with GDB, I get the following backtrace:
> > 
> > #0  0x0000000000474b87 in is_null_sha1 (sha1=0x100000008 <Address 0x100000008 out of bounds>) at cache.h:464
> > #1  0x0000000000474ad3 in do_one_ref (base=0x4dc8ff "refs/", fn=0x419471 <setup_tmp_ref>, trim=0, cb_data=0x7498d0, entry=0xffffffff) at refs.c:474
> > #2  0x0000000000474e28 in do_for_each_ref (base=0x4dc8ff "refs/", fn=0x419471 <setup_tmp_ref>, trim=0, cb_data=0x7498d0) at refs.c:558
> > #3  0x0000000000474ecd in for_each_ref (fn=0x419471 <setup_tmp_ref>, cb_data=0x7498d0) at refs.c:580
> > #4  0x0000000000419706 in setup_reference (repo=0x745070 "C/.git") at builtin-clone.c:211
> > #5  0x0000000000419fce in cmd_clone (argc=2, argv=0x7fff7a282fa0, prefix=0x0) at builtin-clone.c:422
> > #6  0x0000000000404ba3 in run_command (p=0x6ff710, argc=7, argv=0x7fff7a282fa0) at git.c:248
> > #7  0x0000000000404d55 in handle_internal_command (argc=7, argv=0x7fff7a282fa0) at git.c:378
> > #8  0x0000000000404ebe in main (argc=7, argv=0x7fff7a282fa0) at git.c:442
> > 
> > Seems the "loose" ref_list in do_for_each_ref() becomes corrupted.
> 
> ...and the corruption is done when setup_tmp_ref() calls write_ref_sha1()
> which calls invalidate_cached_refs() (which frees the ref_list that
> do_for_each_ref() is iterating over).
> 
> Not sure how to best solve this. Maybe setup_tmp_ref() shouldn't use
> write_ref_sha1(), but write the ref file directly instead, as hinted
> at in a comment in setup_tmp_ref()?

Here is a shot at fixing this, although I'm not sure it's the best way
of doing so.


Have fun! :)

...Johan

 builtin-clone.c |   43 ++++++++++++++++++++-----------------------
 1 files changed, 20 insertions(+), 23 deletions(-)

diff --git a/builtin-clone.c b/builtin-clone.c
index 6e34e52..d5baffc 100644
--- a/builtin-clone.c
+++ b/builtin-clone.c
@@ -136,14 +136,12 @@ static int
 setup_tmp_ref(const char *refname,
 	      const unsigned char *sha1, int flags, void *cb_data)
 {
-	const char *ref_temp = cb_data;
+	const char *ref_temp = cb_data, *sha1_hex = sha1_to_hex(sha1);
 	char *path;
-	struct lock_file lk;
-	struct ref_lock *rl;
+	int fd;
 
 	/*
 
-	echo "$ref_git/objects" >"$GIT_DIR/objects/info/alternates"
 	(
 		GIT_DIR="$ref_git" git for-each-ref \
 			--format='%(objectname) %(*objectname)'
@@ -158,25 +156,24 @@ setup_tmp_ref(const char *refname,
 
 	*/
 
-	/* We go a bit out of way to use write_ref_sha1() here.  We
-	 * could just write the ref file directly, since neither
-	 * locking or reflog really matters here.  However, let's use
-	 * the standard interface for writing refs as much as is
-	 * possible given that get_git_dir() != the repo we're writing
-	 * the refs in. */
-
-	printf("%s -> %s/%s\n",
-	       sha1_to_hex(sha1), ref_temp, sha1_to_hex(sha1));
-
-	path = mkpath("%s/%s", ref_temp, sha1_to_hex(sha1));
-	rl = xmalloc(sizeof *rl);
-	rl->force_write = 1;
-	rl->lk = &lk;
-	rl->ref_name = xstrdup(sha1_to_hex(sha1));
-	rl->orig_ref_name = xstrdup(rl->ref_name);
-	rl->lock_fd = hold_lock_file_for_update(rl->lk, path, 1);
-	if (write_ref_sha1(rl, sha1, NULL) < 0)
-		die("failed to write temporary ref %s", lk.filename);
+	/* Write the ref file directly, since neither locking or reflog really
+	 * matters here. We should probably use some standard interface for
+	 * writing refs here, although write_ref_sha1() does not work.
+	 * (It frees the ref_list that is currently being iterated by
+	 * for_each_ref().) Keep in mind that get_git_dir() != the repo we're
+	 * writing the refs in. */
+
+	path = mkpath("%s/%s", ref_temp, sha1_hex);
+
+	printf("%s -> %s\n", sha1_hex, path);
+
+	fd = open(path, O_CREAT | O_WRONLY, 0666);
+	if (fd < 0)
+		die("failed to create %s", path);
+	write_or_die(fd, sha1_hex, strlen(sha1_hex));
+	if (close(fd))
+		die("could not close %s", path);
+	fprintf(stderr, "Wrote %s to %s\n", sha1_hex, path);
 
 	return 0;
 }
-- 
1.5.4.3.342.g99e8

  reply	other threads:[~2008-02-26 15:37 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-02-25 21:12 [RFC] Build in clone Daniel Barkalow
2008-02-26  2:21 ` Johan Herland
2008-02-26 11:14   ` Johannes Schindelin
2008-02-26 12:19     ` Johan Herland
2008-02-26 12:58       ` Johan Herland
2008-02-26 13:37         ` Johan Herland
2008-02-26 15:35           ` Johan Herland [this message]
2008-02-26 15:42             ` [PATCH] Fix premature free of ref_lists while writing temporary refs to file Johannes Schindelin
2008-02-26 17:17               ` Johan Herland
2008-02-26 23:07               ` Daniel Barkalow
2008-02-26 23:11                 ` Johan Herland
2008-02-26 15:40   ` [PATCH] Fix premature call to git_config() causing t1020-subdirectory to fail Johan Herland
2008-02-26 15:47     ` Johannes Schindelin
2008-02-26 22:12     ` Daniel Barkalow
2008-02-26 22:40       ` Johannes Schindelin
2008-02-26 22:49         ` Daniel Barkalow
2008-02-27  0:20           ` Junio C Hamano
2008-02-27  0:53             ` Daniel Barkalow
2008-02-27  1:34               ` Junio C Hamano
2008-02-27 19:47                 ` Daniel Barkalow
2008-02-27 20:09                   ` Junio C Hamano
2008-02-27 20:31                     ` Daniel Barkalow
2008-02-26 17:36   ` [RFC] Build in clone Daniel Barkalow
2008-02-26 18:53     ` Kristian Høgsberg
2008-03-02  5:57     ` [PATCH] builtin-clone: create remotes/origin/HEAD symref, if guessed Johannes Schindelin
2008-03-02  6:25       ` [PATCH, fixed] " Johannes Schindelin
2008-03-02  7:46         ` [PATCH] builtin clone: support bundles Johannes Schindelin
2008-03-02 16:19           ` Daniel Barkalow
2008-03-03  0:04             ` Santi Béjar
2008-03-02 16:48           ` Daniel Barkalow
2008-03-02 17:34             ` Johannes Schindelin
2008-03-02 17:50               ` Junio C Hamano
2008-03-02 17:54                 ` Junio C Hamano
2008-03-03  9:04             ` [PATCH] Add test for cloning with "--reference" repo being a subset of source repo Johan Herland
2008-03-03 16:36               ` Daniel Barkalow
2008-03-03 18:21               ` Daniel Barkalow
2008-03-04  3:02                 ` Johan Herland
2008-03-04  3:04                   ` [PATCH 1/2] Add test illustrating issues with sha1_file_name() and switching repos Johan Herland
2008-03-04  3:05                   ` [PATCH 2/2] Overly simplistic fix for issue " Johan Herland
2008-03-04 23:10                   ` [PATCH] Add test for cloning with "--reference" repo being a subset of source repo Daniel Barkalow
2008-03-05  0:24                     ` Daniel Barkalow
2008-03-05 23:56                       ` Johan Herland
2008-03-03 17:05         ` [PATCH, fixed] builtin-clone: create remotes/origin/HEAD symref, if guessed Kristian Høgsberg
2008-03-03 17:09           ` Pierre Habouzit
2008-03-03 19:55             ` Johannes Schindelin
2008-03-03 17:10           ` Johannes Schindelin
2008-03-03 17:41           ` Johan Herland

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=200802261635.51407.johan@herland.net \
    --to=johan@herland.net \
    --cc=Johannes.Schindelin@gmx.de \
    --cc=barkalow@iabervon.org \
    --cc=git@vger.kernel.org \
    --cc=krh@redhat.com \
    --cc=sbejar@gmail.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.