Skip to content

Commit fcf26ef

Browse files
committed
Merge branch 'jk/4gb-idx'
The code was not prepared to deal with pack .idx file that is larger than 4GB. * jk/4gb-idx: packfile: detect overflow in .idx file size checks block-sha1: take a size_t length parameter fsck: correctly compute checksums on idx files larger than 4GB use size_t to store pack .idx byte offsets compute pack .idx byte offsets using size_t
2 parents 8f8f10a + 81c4c5c commit fcf26ef

File tree

7 files changed

+19
-19
lines changed

7 files changed

+19
-19
lines changed

block-sha1/sha1.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ void blk_SHA1_Init(blk_SHA_CTX *ctx)
203203
ctx->H[4] = 0xc3d2e1f0;
204204
}
205205

206-
void blk_SHA1_Update(blk_SHA_CTX *ctx, const void *data, unsigned long len)
206+
void blk_SHA1_Update(blk_SHA_CTX *ctx, const void *data, size_t len)
207207
{
208208
unsigned int lenW = ctx->size & 63;
209209

block-sha1/sha1.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ typedef struct {
1313
} blk_SHA_CTX;
1414

1515
void blk_SHA1_Init(blk_SHA_CTX *ctx);
16-
void blk_SHA1_Update(blk_SHA_CTX *ctx, const void *dataIn, unsigned long len);
16+
void blk_SHA1_Update(blk_SHA_CTX *ctx, const void *dataIn, size_t len);
1717
void blk_SHA1_Final(unsigned char hashout[20], blk_SHA_CTX *ctx);
1818

1919
#define platform_SHA_CTX blk_SHA_CTX

builtin/index-pack.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1597,7 +1597,7 @@ static void read_v2_anomalous_offsets(struct packed_git *p,
15971597

15981598
/* The address of the 4-byte offset table */
15991599
idx1 = (((const uint32_t *)((const uint8_t *)p->index_data + p->crc_offset))
1600-
+ p->num_objects /* CRC32 table */
1600+
+ (size_t)p->num_objects /* CRC32 table */
16011601
);
16021602

16031603
/* The address of the 8-byte offset table */

builtin/pack-redundant.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ static struct pack_list * pack_list_difference(const struct pack_list *A,
236236

237237
static void cmp_two_packs(struct pack_list *p1, struct pack_list *p2)
238238
{
239-
unsigned long p1_off = 0, p2_off = 0, p1_step, p2_step;
239+
size_t p1_off = 0, p2_off = 0, p1_step, p2_step;
240240
const unsigned char *p1_base, *p2_base;
241241
struct llist_item *p1_hint = NULL, *p2_hint = NULL;
242242
const unsigned int hashsz = the_hash_algo->rawsz;
@@ -280,7 +280,7 @@ static void cmp_two_packs(struct pack_list *p1, struct pack_list *p2)
280280
static size_t sizeof_union(struct packed_git *p1, struct packed_git *p2)
281281
{
282282
size_t ret = 0;
283-
unsigned long p1_off = 0, p2_off = 0, p1_step, p2_step;
283+
size_t p1_off = 0, p2_off = 0, p1_step, p2_step;
284284
const unsigned char *p1_base, *p2_base;
285285
const unsigned int hashsz = the_hash_algo->rawsz;
286286

@@ -499,7 +499,7 @@ static void scan_alt_odb_packs(void)
499499
static struct pack_list * add_pack(struct packed_git *p)
500500
{
501501
struct pack_list l;
502-
unsigned long off = 0, step;
502+
size_t off = 0, step;
503503
const unsigned char *base;
504504

505505
if (!p->pack_local && !(alt_odb || verbose))

pack-check.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ int check_pack_crc(struct packed_git *p, struct pack_window **w_curs,
3939
} while (len);
4040

4141
index_crc = p->index_data;
42-
index_crc += 2 + 256 + p->num_objects * (the_hash_algo->rawsz/4) + nr;
42+
index_crc += 2 + 256 + (size_t)p->num_objects * (the_hash_algo->rawsz/4) + nr;
4343

4444
return data_crc != ntohl(*index_crc);
4545
}
@@ -164,22 +164,22 @@ static int verify_packfile(struct repository *r,
164164

165165
int verify_pack_index(struct packed_git *p)
166166
{
167-
off_t index_size;
167+
size_t len;
168168
const unsigned char *index_base;
169169
git_hash_ctx ctx;
170170
unsigned char hash[GIT_MAX_RAWSZ];
171171
int err = 0;
172172

173173
if (open_pack_index(p))
174174
return error("packfile %s index not opened", p->pack_name);
175-
index_size = p->index_size;
176175
index_base = p->index_data;
176+
len = p->index_size - the_hash_algo->rawsz;
177177

178178
/* Verify SHA1 sum of the index file */
179179
the_hash_algo->init_fn(&ctx);
180-
the_hash_algo->update_fn(&ctx, index_base, (unsigned int)(index_size - the_hash_algo->rawsz));
180+
the_hash_algo->update_fn(&ctx, index_base, len);
181181
the_hash_algo->final_fn(hash, &ctx);
182-
if (!hasheq(hash, index_base + index_size - the_hash_algo->rawsz))
182+
if (!hasheq(hash, index_base + len))
183183
err = error("Packfile index for %s hash mismatch",
184184
p->pack_name);
185185
return err;

pack-revindex.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ static void create_pack_revindex(struct packed_git *p)
130130

131131
if (p->index_version > 1) {
132132
const uint32_t *off_32 =
133-
(uint32_t *)(index + 8 + p->num_objects * (hashsz + 4));
133+
(uint32_t *)(index + 8 + (size_t)p->num_objects * (hashsz + 4));
134134
const uint32_t *off_64 = off_32 + p->num_objects;
135135
for (i = 0; i < num_ent; i++) {
136136
const uint32_t off = ntohl(*off_32++);

packfile.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ int load_idx(const char *path, const unsigned int hashsz, void *idx_map,
148148
* - hash of the packfile
149149
* - file checksum
150150
*/
151-
if (idx_size != 4 * 256 + nr * (hashsz + 4) + hashsz + hashsz)
151+
if (idx_size != st_add(4 * 256 + hashsz + hashsz, st_mult(nr, hashsz + 4)))
152152
return error("wrong index v1 file size in %s", path);
153153
} else if (version == 2) {
154154
/*
@@ -164,10 +164,10 @@ int load_idx(const char *path, const unsigned int hashsz, void *idx_map,
164164
* variable sized table containing 8-byte entries
165165
* for offsets larger than 2^31.
166166
*/
167-
unsigned long min_size = 8 + 4*256 + nr*(hashsz + 4 + 4) + hashsz + hashsz;
168-
unsigned long max_size = min_size;
167+
size_t min_size = st_add(8 + 4*256 + hashsz + hashsz, st_mult(nr, hashsz + 4 + 4));
168+
size_t max_size = min_size;
169169
if (nr)
170-
max_size += (nr - 1)*8;
170+
max_size = st_add(max_size, st_mult(nr - 1, 8));
171171
if (idx_size < min_size || idx_size > max_size)
172172
return error("wrong index v2 file size in %s", path);
173173
if (idx_size != min_size &&
@@ -1933,14 +1933,14 @@ off_t nth_packed_object_offset(const struct packed_git *p, uint32_t n)
19331933
const unsigned int hashsz = the_hash_algo->rawsz;
19341934
index += 4 * 256;
19351935
if (p->index_version == 1) {
1936-
return ntohl(*((uint32_t *)(index + (hashsz + 4) * n)));
1936+
return ntohl(*((uint32_t *)(index + (hashsz + 4) * (size_t)n)));
19371937
} else {
19381938
uint32_t off;
1939-
index += 8 + p->num_objects * (hashsz + 4);
1939+
index += 8 + (size_t)p->num_objects * (hashsz + 4);
19401940
off = ntohl(*((uint32_t *)(index + 4 * n)));
19411941
if (!(off & 0x80000000))
19421942
return off;
1943-
index += p->num_objects * 4 + (off & 0x7fffffff) * 8;
1943+
index += (size_t)p->num_objects * 4 + (off & 0x7fffffff) * 8;
19441944
check_pack_index_ptr(p, index);
19451945
return get_be64(index);
19461946
}

0 commit comments

Comments
 (0)