Commit 849f755735bb4ec310eb3f688a23847c0c7162b5

Stefan Sperling 2020-03-18T16:11:32

check pack file hash in the main process

diff --git a/lib/fetch.c b/lib/fetch.c
index 4936c36..e70d912 100644
--- a/lib/fetch.c
+++ b/lib/fetch.c
@@ -297,6 +297,48 @@ done:
 	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*
 got_fetch_pack(struct got_object_id **pack_hash, struct got_pathlist_head *refs,
     struct got_pathlist_head *symrefs, int fetchfd, struct got_repository *repo,
@@ -428,6 +470,14 @@ got_fetch_pack(struct got_object_id **pack_hash, struct got_pathlist_head *refs,
 		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");
diff --git a/libexec/got-fetch-pack/got-fetch-pack.c b/libexec/got-fetch-pack/got-fetch-pack.c
index 14fb915..bbc450c 100644
--- a/libexec/got-fetch-pack/got-fetch-pack.c
+++ b/libexec/got-fetch-pack/got-fetch-pack.c
@@ -214,44 +214,6 @@ match_remote_ref(struct got_pathlist_head *have_refs, struct got_object_id *id,
 	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 *packid,
 		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);