diff options
author | Junio C Hamano <junkio@cox.net> | 2007-01-03 23:09:08 -0800 |
---|---|---|
committer | Junio C Hamano <junkio@cox.net> | 2007-01-04 22:17:59 -0800 |
commit | 8977c110b5bbd230c28c727ddb85856067d55cfb (patch) | |
tree | 99c23def7dd3a9279226614f3af0aba82a555c81 /pack-check.c | |
parent | 1084b845d9d77bcb2e8255636358dd0dc35360a5 (diff) | |
download | git-8977c110b5bbd230c28c727ddb85856067d55cfb.tar.gz |
pack-check.c::verify_packfile(): don't run SHA-1 update on huge datav1.4.4.4
Running the SHA1_Update() on the whole packfile in a single call
revealed an overflow problem we had in the SHA-1 implementation
on POWER architecture some time ago, which was fixed with commit
b47f509b (June 19, 2006). Other SHA-1 implementations may have
a similar problem.
The sliding mmap() series already makes chunked calls to
SHA1_Update(), so this patch itself will become moot when it
graduates to "master", but in the meantime, run the hash
function in smaller chunks to prevent possible future problems.
Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'pack-check.c')
-rw-r--r-- | pack-check.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/pack-check.c b/pack-check.c index c0caaee093..8e123b71ed 100644 --- a/pack-check.c +++ b/pack-check.c @@ -1,16 +1,18 @@ #include "cache.h" #include "pack.h" +#define BATCH (1u<<20) + static int verify_packfile(struct packed_git *p) { unsigned long index_size = p->index_size; void *index_base = p->index_base; SHA_CTX ctx; unsigned char sha1[20]; - unsigned long pack_size = p->pack_size; - void *pack_base; struct pack_header *hdr; int nr_objects, err, i; + unsigned char *packdata; + unsigned long datasize; /* Header consistency check */ hdr = p->pack_base; @@ -25,11 +27,19 @@ static int verify_packfile(struct packed_git *p) "while idx size expects %d", nr_objects, num_packed_objects(p)); + /* Check integrity of pack data with its SHA-1 checksum */ SHA1_Init(&ctx); - pack_base = p->pack_base; - SHA1_Update(&ctx, pack_base, pack_size - 20); + packdata = p->pack_base; + datasize = p->pack_size - 20; + while (datasize) { + unsigned long batch = (datasize < BATCH) ? datasize : BATCH; + SHA1_Update(&ctx, packdata, batch); + datasize -= batch; + packdata += batch; + } SHA1_Final(sha1, &ctx); - if (hashcmp(sha1, (unsigned char *)pack_base + pack_size - 20)) + + if (hashcmp(sha1, (unsigned char *)(p->pack_base) + p->pack_size - 20)) return error("Packfile %s SHA1 mismatch with itself", p->pack_name); if (hashcmp(sha1, (unsigned char *)index_base + index_size - 40)) |