commit 849f755735bb4ec310eb3f688a23847c0c7162b5 from: Stefan Sperling date: Wed Mar 18 16:11:32 2020 UTC check pack file hash in the main process commit - d2cdc63664daa5fa39c9a6398c33f3724650bfe9 commit + 849f755735bb4ec310eb3f688a23847c0c7162b5 blob - 4936c368b72d20f0700da9ef791558f5eeb7ef03 blob + e70d912a05e9ce0c6576bd19cc148720909a4e6f --- lib/fetch.c +++ lib/fetch.c @@ -295,6 +295,48 @@ done: *repo_name = NULL; } return err; +} + +static const struct got_error * +check_pack_hash(int fd, size_t sz, uint8_t *hcomp) +{ + SHA1_CTX ctx; + uint8_t hexpect[SHA1_DIGEST_LENGTH]; + uint8_t buf[32 * 1024]; + ssize_t n, r, nr; + + if (sz < sizeof(struct got_packfile_hdr) + SHA1_DIGEST_LENGTH) + return got_error_msg(GOT_ERR_BAD_PACKFILE, "short packfile"); + + n = 0; + SHA1Init(&ctx); + while (n < sz - 20) { + nr = sizeof(buf); + if (sz - n - 20 < sizeof(buf)) + nr = sz - n - 20; + r = read(fd, buf, nr); + if (r == -1) + return got_error_from_errno("read"); + if (r != nr) + return got_error_msg(GOT_ERR_BAD_PACKFILE, + "short pack file"); + SHA1Update(&ctx, buf, nr); + n += r; + } + SHA1Final(hcomp, &ctx); + + r = read(fd, hexpect, sizeof(hexpect)); + if (r == -1) + return got_error_from_errno("read"); + if (r != sizeof(hexpect)) + return got_error_msg(GOT_ERR_BAD_PACKFILE, + "short pack file"); + + if (memcmp(hcomp, hexpect, SHA1_DIGEST_LENGTH) != 0) + return got_error_msg(GOT_ERR_BAD_PACKFILE, + "packfile checksum mismatch"); + + return NULL; } const struct got_error* @@ -428,6 +470,14 @@ got_fetch_pack(struct got_object_id **pack_hash, struc err = got_error_from_errno("waitpid"); goto done; } + + if (lseek(packfd, 0, SEEK_SET) == -1) { + err = got_error_from_errno("lseek"); + goto done; + } + err = check_pack_hash(packfd, packfile_size, (*pack_hash)->sha1); + if (err) + goto done; if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, imsg_idxfds) == -1) { err = got_error_from_errno("socketpair"); blob - 14fb915c5bf3a3ec428cfafcae915f83694cc47b blob + bbc450c8f90abf44d108cd6ea866d2f55f94713e --- libexec/got-fetch-pack/got-fetch-pack.c +++ libexec/got-fetch-pack/got-fetch-pack.c @@ -214,44 +214,6 @@ match_remote_ref(struct got_pathlist_head *have_refs, return NULL; } -static const struct got_error * -check_pack_hash(int fd, size_t sz, uint8_t *hcomp) -{ - const struct got_error *err = NULL; - SHA1_CTX ctx; - uint8_t hexpect[SHA1_DIGEST_LENGTH]; - uint8_t buf[32 * 1024]; - ssize_t n, r, nr; - - if (sz < sizeof(struct got_packfile_hdr) + SHA1_DIGEST_LENGTH) - return got_error_msg(GOT_ERR_BAD_PACKFILE, "short packfile"); - - n = 0; - SHA1Init(&ctx); - while (n < sz - 20) { - nr = sizeof(buf); - if (sz - n - 20 < sizeof(buf)) - nr = sz - n - 20; - err = readn(&r, fd, buf, nr); - if (err) - return err; - if (r != nr) - return got_error(GOT_ERR_BAD_PACKFILE); - SHA1Update(&ctx, buf, nr); - n += r; - } - SHA1Final(hcomp, &ctx); - - err = readn(&r, fd, hexpect, sizeof(hexpect)); - if (err) - return err; - if (r != sizeof(hexpect)) - return got_error(GOT_ERR_BAD_PACKFILE); - if (memcmp(hcomp, hexpect, SHA1_DIGEST_LENGTH) != 0) - return got_error(GOT_ERR_BAD_PACKFILE); - return NULL; -} - static int match_branch(char *br, char *pat) { @@ -778,11 +740,6 @@ fetch_pack(int fd, int packfd, struct got_object_id *p if (err) goto done; } - if (lseek(packfd, 0, SEEK_SET) == -1) { - err = got_error_from_errno("lseek"); - goto done; - } - err = check_pack_hash(packfd, packsz, packid->sha1); done: TAILQ_FOREACH(pe, &symrefs, entry) { free((void *)pe->path);