[PATCH] Don't segfault if we failed to inflate a packed delta

Subsystems: the rest

DORMANTno replies

2 messages, 2 authors, 2016-06-15 · open the first message on its own page

[PATCH] Don't segfault if we failed to inflate a packed delta

From: Shawn O. Pearce <hidden>
Date: 2016-06-15 22:43:30

Under some types of packfile corruption the zlib stream holding the
data for a delta within a packfile may fail to inflate, due to say
a CRC failure within the compressed data itself.  When this occurs
the unpack_compressed_entry function will return NULL as a signal to
the caller that the data is not available.  Unfortunately we then
tried to use that NULL as though it referenced a memory location
where a delta was stored and tried to apply it to the delta base.
Loading a byte from the NULL address typically causes a SIGSEGV.

cate on #git noticed this failure in `git fsck --full` where the
call to verify_pack() first noticed that the packfile was corrupt
by finding that the packfile's SHA-1 did not match the raw data of
the file.  After finding this fsck went ahead and tried to verify
every object within the packfile, even though the packfile was
already known to be bad.  If we are going to shovel bad data at
the delta unpacking code, we better handle it correctly.

Signed-off-by: Shawn O. Pearce <redacted>
---
 sha1_file.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/sha1_file.c b/sha1_file.c
index b219d4d..9978a58 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -1570,6 +1570,10 @@ static void *unpack_delta_entry(struct packed_git *p,
 		    (uintmax_t)base_offset, p->pack_name);
 
 	delta_data = unpack_compressed_entry(p, w_curs, curpos, delta_size);
+	if (!delta_data)
+		die("failed to unpack compressed delta"
+		    " at %"PRIuMAX" from %s",
+		    (uintmax_t)curpos, p->pack_name);
 	result = patch_delta(base, base_size,
 			     delta_data, delta_size,
 			     sizep);
-- 
1.5.3.rc6.17.g1911

Re: [PATCH] Don't segfault if we failed to inflate a packed delta

From: Linus Torvalds <torvalds@linux-foundation.org>
Date: 2016-06-15 22:43:30


On Sat, 25 Aug 2007, Shawn O. Pearce wrote:
cate on #git noticed this failure in `git fsck --full` where the
call to verify_pack() first noticed that the packfile was corrupt
by finding that the packfile's SHA-1 did not match the raw data of
the file.  After finding this fsck went ahead and tried to verify
every object within the packfile, even though the packfile was
already known to be bad.  If we are going to shovel bad data at
the delta unpacking code, we better handle it correctly.
Hmm. We should actually make "unpack_entry()" return print an error and 
return NULL for these cases, rather than die, I think.

Most of the callers seem to already check for NULL (not "load_tree()" in 
fast-import.c), but for something like fsck, while "die()" is obviously 
better than a SIGSEGV, we should probably continue and try to see what 
else we find.

(Although, to be honest, it might not matter. If your pack-file is corrupt 
enough for this to trigger, there's seldom anything interesting fsck will 
tell, so in practical terms this probably isn't a big deal).

		Linus
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help