From: Junio C Hamano <gitster@pobox.com>
To: "Shawn O. Pearce" <spearce@spearce.org>
Cc: Andy Isaacson <adi@hexapodia.org>,
git@vger.kernel.org, Nicolas Pitre <nico@fluxnic.net>,
Alex Riesen <raa.lkml@gmail.com>
Subject: Re: git hang with corrupted .pack
Date: Tue, 20 Oct 2009 09:52:46 -0700 [thread overview]
Message-ID: <7viqeaovmp.fsf@alter.siamese.dyndns.org> (raw)
In-Reply-To: <20091014142351.GI9261@spearce.org> (Shawn O. Pearce's message of "Wed\, 14 Oct 2009 07\:23\:51 -0700")
"Shawn O. Pearce" <spearce@spearce.org> writes:
> Z_BUF_ERROR is returned from inflate() if either the input buffer
> needs more input bytes, or the output buffer has run out of space.
> Previously we only considered the former case, as it meant we needed
> to move the stream's input buffer to the next window in the pack.
>
> We now abort the loop if inflate() returns Z_BUF_ERROR without
> consuming the entire input buffer it was given, or has filled
> the entire output buffer but has not yet returned Z_STREAM_END.
> Either state is a clear indicator that this loop is not working
> as expected, and should not continue.
When the inflated contents is of size 0, avail_out would be 0 and avail_in
would still have something because the input stream needs to have the end
of stream marker that is more than zero byte long.
If that is more than one-byte long, and your avail_in originally fed only
the first byte from that sequence, what happens? Wouldn't inflate eat all
what was given (now avail_in is zero), updated its internal state but it
still hasn't produced anything (avail_out is zero)?
I am not saying the end-of-stream is more than one-byte long (I didn't
check), but we had a similar bug arising from confusing "no more output
data" and "fully consumed input stream" (e.g. 456cdf6 (Fix loose object
uncompression check., 2007-03-19).
Something like that may be what is happening to cause problem Alex is
seeing.
I think the corrupt packdata detection needs an output buffer at least
one-byte larger than what is needed to store the correct result. Then
when we get BUF_ERROR:
- We never look at avail to see if it is zero; !avail_out is not the same
as "it stopped because it ran out of output space". It might mean
"there is nothing more to come but the input stream ended before
signalling that fact to the inflate engine fully".
- We do look at avail_out to find how much data we ended up getting. If
inflate has consumed more buffer than we planned to give it, the stream
is corrupt (at least it is not what we expected to see);
> st = git_inflate(&stream, Z_FINISH);
> + if (st == Z_BUF_ERROR && (stream.avail_in || !stream.avail_out))
> + break;
> curpos += stream.next_in - in;
> } while ((st == Z_OK || st == Z_BUF_ERROR) &&
> stream.total_out < sizeof(delta_head));
> @@ -1594,6 +1596,8 @@ static void *unpack_compressed_entry(struct packed_git *p,
> in = use_pack(p, w_curs, curpos, &stream.avail_in);
> stream.next_in = in;
> st = git_inflate(&stream, Z_FINISH);
> + if (st == Z_BUF_ERROR && (stream.avail_in || !stream.avail_out))
> + break;
> curpos += stream.next_in - in;
> } while (st == Z_OK || st == Z_BUF_ERROR);
> git_inflate_end(&stream);
> --
> 1.6.5.52.g0ff2e
>
> --
> Shawn.
next prev parent reply other threads:[~2009-10-20 16:53 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
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 [this message]
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=7viqeaovmp.fsf@alter.siamese.dyndns.org \
--to=gitster@pobox.com \
--cc=adi@hexapodia.org \
--cc=git@vger.kernel.org \
--cc=nico@fluxnic.net \
--cc=raa.lkml@gmail.com \
--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).