git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Alex Riesen <raa.lkml@gmail.com>
To: Junio C Hamano <gitster@pobox.com>
Cc: Nicolas Pitre <nico@fluxnic.net>,
	"Shawn O. Pearce" <spearce@spearce.org>,
	Andy Isaacson <adi@hexapodia.org>,
	git@vger.kernel.org
Subject: Re: git hang with corrupted .pack
Date: Tue, 20 Oct 2009 17:14:26 +0200	[thread overview]
Message-ID: <81b0412b0910200814v269e91fbkd7841308685e1c54@mail.gmail.com> (raw)
In-Reply-To: <7vbpk985t1.fsf@alter.siamese.dyndns.org>

[-- Attachment #1: Type: text/plain, Size: 1963 bytes --]

On Thu, Oct 15, 2009 at 09:39, Junio C Hamano <gitster@pobox.com> wrote:
> Nicolas Pitre <nico@fluxnic.net> writes:
>
>> I confirm this test without the fix reproduces the infinite loop (and
>> does stall the test suite).
>
> Thanks, both of you.

I seem to have problems with this change (on Cygwin). Sometimes
accessing an object in a pack fails in unpack_compressed_entry.
When it happens, both avail_in and avail_out of the stream are 0,
and the reported status is Z_BUF_ERROR.
Output with the second attached patch:

error: *** inflate error: 0x862380 size=1256, avail_in=0 (was 697),
avail_out=0 (was 1256)
error: *** unpack_compressed_entry failed
error: failed to read object 3296766eb5531ef051ae392114de5d75556f5613
at offset 2620741 from
.git/objects/pack/pack-996206790aaefbf4d34c86b3ff546bb924546b7c.pack
fatal: object 3296766eb5531ef051ae392114de5d75556f5613 is corrupted

I cannot reproduce the problem on a normal system (a 64bit, reasonably modern
Linux in my case). An attempt to use an upgraded zlib on this cygwin system was
not successful, there was an updated library, but a clean recompile didn't
change anything.

I worked the case around by allocating a bit more than uncompressed data need.
In case someone else also sees the problem, below is how. The size of the
overallocation is arbitrary.

diff --git a/sha1_file.c b/sha1_file.c
index 4cc8939..66c2519 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -1585,11 +1585,11 @@ static void *unpack_compressed_entry(struct
packed_git *p,
 	z_stream stream;
 	unsigned char *buffer, *in;

-	buffer = xmalloc(size + 1);
-	buffer[size] = 0;
+	buffer = xmalloc(size + 8);
+	memset(buffer + size, 0, 8);
 	memset(&stream, 0, sizeof(stream));
 	stream.next_out = buffer;
-	stream.avail_out = size;
+	stream.avail_out = size + 8;

 	git_inflate_init(&stream);
 	do {
-- 
1.6.5.59.g000dd

The problematic repo is a little big to post (it's my cygwin-git repo),
I'll have to find hosting for it first.

[-- Attachment #2: 0001-Workaround-inflate-sometimes-failing-to-unpack-data.diff --]
[-- Type: application/octet-stream, Size: 1341 bytes --]

From 643fdf50e4343c3ce3a4b99183dba8d35a10c877 Mon Sep 17 00:00:00 2001
From: Alex Riesen <raa.lkml@gmail.com>
Date: Tue, 20 Oct 2009 16:42:26 +0200
Subject: [PATCH 1/2] Workaround inflate sometimes fails to unpack data

When it happens, zlib stream's avail_in and avail_out are 0, the returned
status is Z_BUF_ERROR. The values weren't 0 before calling inflate.

error: *** inflate error: 0x862380 size=1256, avail_in=0 (was 697), avail_out=0 (was 1256)
error: *** unpack_compressed_entry failed
error: failed to read object 3296766eb5531ef051ae392114de5d75556f5613 at offset 2620741 from .git/objects/pack/pack-996206790aaefbf4d34c86b3ff546bb924546b7c.pack
fatal: object 3296766eb5531ef051ae392114de5d75556f5613 is corrupted
---
 sha1_file.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/sha1_file.c b/sha1_file.c
index 4cc8939..66c2519 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -1585,11 +1585,11 @@ static void *unpack_compressed_entry(struct packed_git *p,
 	z_stream stream;
 	unsigned char *buffer, *in;
 
-	buffer = xmalloc(size + 1);
-	buffer[size] = 0;
+	buffer = xmalloc(size + 8);
+	memset(buffer + size, 0, 8);
 	memset(&stream, 0, sizeof(stream));
 	stream.next_out = buffer;
-	stream.avail_out = size;
+	stream.avail_out = size + 8;
 
 	git_inflate_init(&stream);
 	do {
-- 
1.6.5.59.g000dd


[-- Attachment #3: 0002-Debugging-strange-failure-in-zlibs-inflate.diff --]
[-- Type: application/octet-stream, Size: 1910 bytes --]

From fc5b47d953f171d7591349acad9a23d3ec683ce9 Mon Sep 17 00:00:00 2001
From: Alex Riesen <raa.lkml@gmail.com>
Date: Tue, 20 Oct 2009 15:53:33 +0200
Subject: [PATCH 2/2] Debugging strange failure in zlibs inflate

---
 sha1_file.c |   18 ++++++++++++++++++
 1 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/sha1_file.c b/sha1_file.c
index 66c2519..1bf240e 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -1594,10 +1594,24 @@ static void *unpack_compressed_entry(struct packed_git *p,
 	git_inflate_init(&stream);
 	do {
 		in = use_pack(p, w_curs, curpos, &stream.avail_in);
+		unsigned prev_ain = stream.avail_in;
+		unsigned prev_aout = stream.avail_out;
+		if (!stream.avail_in)
+			error("*** avail_in=0, inflate will fail!");
+		if (!stream.avail_out)
+			error("*** avail_out=0, inflate will fail!");
 		stream.next_in = in;
 		st = git_inflate(&stream, Z_FINISH);
 		if (st == Z_BUF_ERROR && (stream.avail_in || !stream.avail_out))
+                {
+			error("*** inflate error: %p size=%lu, "
+			      "avail_in=%d (was %u), "
+			      "avail_out=%d (was %u)",
+			      buffer, size,
+			      stream.avail_in, prev_ain,
+			      stream.avail_out, prev_aout);
 			break;
+                }
 		curpos += stream.next_in - in;
 	} while (st == Z_OK || st == Z_BUF_ERROR);
 	git_inflate_end(&stream);
@@ -1654,6 +1668,8 @@ static void *cache_or_unpack_entry(struct packed_git *p, off_t base_offset,
 		delta_base_cached -= ent->size;
 	} else {
 		ret = xmemdupz(ent->data, ent->size);
+		if (!ret)
+			fprintf(stderr, "*** no memory\n");
 	}
 	*type = ent->type;
 	*base_size = ent->size;
@@ -1815,6 +1831,8 @@ void *unpack_entry(struct packed_git *p, off_t obj_offset,
 	case OBJ_BLOB:
 	case OBJ_TAG:
 		data = unpack_compressed_entry(p, &w_curs, curpos, *sizep);
+		if (!data)
+			error("*** unpack_compressed_entry failed");
 		break;
 	default:
 		data = NULL;
-- 
1.6.5.59.g000dd


  reply	other threads:[~2009-10-20 15:14 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-10-14  4:22 git hang with corrupted .pack Andy Isaacson
2009-10-14 14:23 ` Shawn O. Pearce
2009-10-14 16:09   ` Nicolas Pitre
2009-10-14 16:12     ` Shawn O. Pearce
2009-10-14 16:42       ` Nicolas Pitre
2009-10-14 18:03         ` Shawn O. Pearce
2009-10-14 18:39           ` Nicolas Pitre
2009-10-15  7:39             ` Junio C Hamano
2009-10-20 15:14               ` Alex Riesen [this message]
2009-10-20 15:23                 ` Sverre Rabbelier
2009-10-20 15:36                   ` Alex Riesen
2009-10-26  2:35                 ` Junio C Hamano
2009-10-26  7:07                   ` Alex Riesen
2009-10-26 14:23                   ` Shawn O. Pearce
2009-11-03 21:31                 ` Pascal Obry
2009-11-03 22:28                   ` Shawn O. Pearce
2009-11-03 22:34                     ` Pascal Obry
2009-10-20 16:52   ` Junio C Hamano
2009-10-20 17:13     ` Junio C Hamano
2009-10-20 19:33       ` Junio C Hamano
2009-10-20 19:46         ` Nicolas Pitre
2009-10-20 20:50           ` Junio C Hamano
2009-10-22  6:06             ` 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=81b0412b0910200814v269e91fbkd7841308685e1c54@mail.gmail.com \
    --to=raa.lkml@gmail.com \
    --cc=adi@hexapodia.org \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=nico@fluxnic.net \
    --cc=spearce@spearce.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).