pack-check.c::verify_packfile(): don't run SHA-1 update on huge data
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>
maint
v1.4.4.4
parent
1084b845d9
commit
8977c110b5
20
pack-check.c
20
pack-check.c
|
@ -1,16 +1,18 @@
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
#include "pack.h"
|
#include "pack.h"
|
||||||
|
|
||||||
|
#define BATCH (1u<<20)
|
||||||
|
|
||||||
static int verify_packfile(struct packed_git *p)
|
static int verify_packfile(struct packed_git *p)
|
||||||
{
|
{
|
||||||
unsigned long index_size = p->index_size;
|
unsigned long index_size = p->index_size;
|
||||||
void *index_base = p->index_base;
|
void *index_base = p->index_base;
|
||||||
SHA_CTX ctx;
|
SHA_CTX ctx;
|
||||||
unsigned char sha1[20];
|
unsigned char sha1[20];
|
||||||
unsigned long pack_size = p->pack_size;
|
|
||||||
void *pack_base;
|
|
||||||
struct pack_header *hdr;
|
struct pack_header *hdr;
|
||||||
int nr_objects, err, i;
|
int nr_objects, err, i;
|
||||||
|
unsigned char *packdata;
|
||||||
|
unsigned long datasize;
|
||||||
|
|
||||||
/* Header consistency check */
|
/* Header consistency check */
|
||||||
hdr = p->pack_base;
|
hdr = p->pack_base;
|
||||||
|
@ -25,11 +27,19 @@ static int verify_packfile(struct packed_git *p)
|
||||||
"while idx size expects %d", nr_objects,
|
"while idx size expects %d", nr_objects,
|
||||||
num_packed_objects(p));
|
num_packed_objects(p));
|
||||||
|
|
||||||
|
/* Check integrity of pack data with its SHA-1 checksum */
|
||||||
SHA1_Init(&ctx);
|
SHA1_Init(&ctx);
|
||||||
pack_base = p->pack_base;
|
packdata = p->pack_base;
|
||||||
SHA1_Update(&ctx, pack_base, pack_size - 20);
|
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);
|
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",
|
return error("Packfile %s SHA1 mismatch with itself",
|
||||||
p->pack_name);
|
p->pack_name);
|
||||||
if (hashcmp(sha1, (unsigned char *)index_base + index_size - 40))
|
if (hashcmp(sha1, (unsigned char *)index_base + index_size - 40))
|
||||||
|
|
Loading…
Reference in New Issue