Linus Torvalds [off-list ref] writes:
NOTE! This is all assuming my theory that a packed entry was broken in the
first place was correct. We obviously still don't _know_ what the problem
was. So far it's just a theory.
But it is a good theory. More plausible than alpha particle
hitting the output buffer of zlib at the right moment, although
the effects are the same ;-).
So it might well be the case that we should simply add an extra integrity
check to the raw data copy in builtin-pack-objects.c: write_object().
I would agree that it is a sensible thing to do to insert check
at places shown in the attached. The revalidate_pack_piece()
would:
- decode object header to make sure it decodes to sensible
enum object_type value from the start of the buffer given as
its first argument;
- if it is of type OBJ_DELTA, skip 20-byte base object name;
- the second argument is the length of the piece -- make sure
the above steps did not require more than the length;
- make sure the remainder is sane by running inflate() into
void. When fed the remainder in full, inflate() should
return Z_OK.
For the first step we need to refactor unpack_object_header() in
sha1_file.c a tiny bit to reuse it.
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index 46f524d..0521cad 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -276,6 +282,7 @@ static unsigned long write_object(struct
map = map_sha1_file(entry->sha1, &mapsize);
if (map && !legacy_loose_object(map)) {
/* We can copy straight into the pack file */
+ revalidate_pack_piece(map, mapsize);
sha1write(f, map, mapsize);
munmap(map, mapsize);
written++;@@ -319,6 +326,7 @@ static unsigned long write_object(struct
datalen = find_packed_object_size(p, entry->in_pack_offset);
buf = (char *) p->pack_base + entry->in_pack_offset;
+ revalidate_pack_piece(buf, datalen);
sha1write(f, buf, datalen);
unuse_packed_git(p);
hdrlen = 0; /* not really */