Re: [PATCH] sanity check in add_packed_git()
- From
Junio C Hamano <junkio@cox.net>
- Date
- Dec 22, 2005, 09:39 UTC
- Message-ID
- <7v4q51qxmb.fsf@assigned-by-dhcp.cox.net>
- In-Reply-To
- <Pine.LNX.4.64.0512212046340.25300@iabervon.org>
Daniel Barkalow <barkalow@iabervon.org> writes:
> I'd like to require it to be a hash, just because that makes it > prohibitively difficult to make something people will accept as > pack-05f611b3b8198b262acdf678584d365f8e879aec.pack other than the one from > the git repository.
How about doing something like this, then?
I haven't tried this with http-fetch but with this I think we can unconditionally assign p->sha1 in add_packed_git().
-- >8 -- Subject: [PATCH] Require packfiles to follow the naming convention.
With this, pack files must be named "pack-[0-9a-f]{40}.pack", with corresponding .idx file, and the hexadecimal part must match the SHA1 checksum git-pack-objects computed when the pack was created originally (i.e. sum over sorted object names of all the contained objects). The core would ignore a valid packfile in $GIT_OBJECT_DIRECTORY/packs that "git-unpack-objects" would expand properly if it does not follow the naming convention.
[jc: this breaks existing test t5300.]
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
sha1_file.c | 38 +++++++++++++++++++++++++++++++++++++- 1 files changed, 37 insertions(+), 1 deletions(-)
4ff64a29401b28cfbd925cf86eed8b8e734ed24b
diff --git a/sha1_file.c b/sha1_file.c index 6011473..01ac925 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -319,18 +319,33 @@ struct packed_git *packed_git; static int check_packed_git_idx(const char *path, unsigned long *idx_size_, void **idx_map_) { + SHA_CTX ctx; + unsigned char sha1[20]; + unsigned char packname[20]; void *idx_map; unsigned int *index; unsigned long idx_size; int nr, i; - int fd = open(path, O_RDONLY); + int fd; struct stat st; + + fd = open(path, O_RDONLY); if (fd < 0) return -1; if (fstat(fd, &st)) { close(fd); return -1; } + + /* We require "...../pack-XXXX{40}XXXX.idx" now. + * 5-byte "pack-", 40-byte hex and 4-byte .idx. + */ + i = strlen(path); + if (i < 49 || strcmp(path + i - 4, ".idx") || + strncmp(path + i - 49, "pack-", 5) || + get_sha1_hex(path + i - 44, packname)) + return error("non index file %s ignored", path); + idx_size = st.st_size; idx_map = mmap(NULL, idx_size, PROT_READ, MAP_PRIVATE, fd, 0); close(fd); @@ -362,6 +377,27 @@ static int check_packed_git_idx(const ch if (idx_size != 4*256 + nr * 24 + 20 + 20) return error("wrong index file size"); + /* + * File checksum and index name. + */ + SHA1_Init(&ctx); + SHA1_Update(&ctx, idx_map, idx_size-20); + SHA1_Final(sha1, &ctx); + + if (memcmp(sha1, idx_map + idx_size - 20, 20)) + return error("index checksum mismatch"); + + SHA1_Init(&ctx); + for (i = 0; i < nr; i++) { + unsigned char *ent = (idx_map + 4*256) + i * 24 + 4; + SHA1_Update(&ctx, ent, 20); + } + SHA1_Final(sha1, &ctx); + + if (memcmp(sha1, packname, 20)) + return error("pack index name %s does not match contents %s", + path, sha1_to_hex(sha1)); + return 0; }
-- 1.0.GIT