Commit Diff


commit - ff6b18f831d03b1f4944716195089ced3e9b9fd8
commit + 2967a784ac51b6b48cb8165fd90ec290094455c8
blob - c594b658e1e12ce3a540b0176746a00706b16290
blob + 34977194ae28b73fef4ee4902fd621efaa92ef12
--- lib/got_lib_privsep.h
+++ lib/got_lib_privsep.h
@@ -123,6 +123,11 @@ struct got_imsg_tree_object {
 	int nentries; /* This many TREE_ENTRY messages follow. */
 };
 
+/* Structure for GOT_IMSG_BLOB. */
+struct got_imsg_blob {
+	size_t size;
+};
+
 void got_privsep_send_error(struct imsgbuf *, const struct got_error *);
 const struct got_error *got_privsep_send_obj(struct imsgbuf *,
     struct got_object *, int);
@@ -136,7 +141,7 @@ const struct got_error *got_privsep_recv_tree(struct g
     struct imsgbuf *);
 const struct got_error *got_privsep_send_tree(struct imsgbuf *,
     struct got_tree_object *);
-const struct got_error *got_privsep_send_blob(struct imsgbuf *);
-const struct got_error *got_privsep_recv_blob(struct imsgbuf *);
+const struct got_error *got_privsep_send_blob(struct imsgbuf *, size_t);
+const struct got_error *got_privsep_recv_blob(size_t *, struct imsgbuf *);
 
 /* TODO: Implement the above, and then add more message data types here. */
blob - f3845e17342adbffaf8c43ffc2b8143331bc475c
blob + 6a880752bad61cf62471ea9cf36b1967548859ec
--- lib/object.c
+++ lib/object.c
@@ -1016,11 +1016,9 @@ got_object_tree_close(struct got_tree_object *tree)
 }
 
 static const struct got_error *
-read_blob_object(int outfd, int infd)
+read_blob_object(size_t *size, int outfd, int infd)
 {
-	size_t size;
-
-	return got_inflate_to_fd(&size, infd, outfd);
+	return got_inflate_to_fd(size, infd, outfd);
 }
 
 static const struct got_error *
@@ -1029,6 +1027,7 @@ read_blob_object_privsep_child(int outfd, int infd, in
 	const struct got_error *err = NULL;
 	struct imsgbuf ibuf;
 	int status = 0;
+	size_t size;
 
 	setproctitle("got: read blob object");
 	close(imsg_fds[0]);
@@ -1040,12 +1039,12 @@ read_blob_object_privsep_child(int outfd, int infd, in
 		goto done;
 	}
 
-	err = read_blob_object(outfd, infd);
+	err = read_blob_object(&size, outfd, infd);
 	close(infd);
 	if (err)
 		goto done;
 
-	err = got_privsep_send_blob(&ibuf);
+	err = got_privsep_send_blob(&ibuf, size);
 done:
 	if (err) {
 		got_privsep_send_error(&ibuf, err);
@@ -1058,7 +1057,7 @@ done:
 }
 
 static const struct got_error *
-read_blob_object_privsep(int outfd, int infd)
+read_blob_object_privsep(size_t *size, int outfd, int infd)
 {
 	struct imsgbuf parent_ibuf;
 	int imsg_fds[2];
@@ -1079,7 +1078,7 @@ read_blob_object_privsep(int outfd, int infd)
 
 	close(imsg_fds[1]);
 	imsg_init(&parent_ibuf, imsg_fds[0]);
-	err = got_privsep_recv_blob(&parent_ibuf);
+	err = got_privsep_recv_blob(size, &parent_ibuf);
 	imsg_clear(&parent_ibuf);
 	waitpid(pid, &child_status, 0);
 	close(imsg_fds[0]);
@@ -1115,6 +1114,8 @@ got_object_blob_open(struct got_blob_object **blob,
 			goto done;
 	} else {
 		int infd, outfd;
+		size_t size;
+		struct stat sb;
 
 		err = open_loose_object(&infd, obj, repo);
 		if (err)
@@ -1128,11 +1129,29 @@ got_object_blob_open(struct got_blob_object **blob,
 			goto done;
 		}
 
-		err = read_blob_object_privsep(outfd, infd);
+		err = read_blob_object_privsep(&size, outfd, infd);
 		close(infd);
 		if (err)
 			goto done;
 
+		if (size != obj->hdrlen + obj->size) {
+			err = got_error(GOT_ERR_BAD_OBJ_HDR);
+			close(outfd);
+			goto done;
+		}
+
+		if (fstat(outfd, &sb) == -1) {
+			err = got_error_from_errno();
+			close(outfd);
+			goto done;
+		}
+
+		if (sb.st_size != size) {
+			err = got_error(GOT_ERR_PRIVSEP_LEN);
+			close(outfd);
+			goto done;
+		}
+
 		(*blob)->f = fdopen(outfd, "rb");
 		if ((*blob)->f == NULL) {
 			err = got_error_from_errno();
blob - da7628fd90ec8c45df94754fbc19460724c4828b
blob + b542a8d8493a8740e0a95f43ba093ec43ecd36e7
--- lib/privsep.c
+++ lib/privsep.c
@@ -609,20 +609,26 @@ done:
 }
 
 const struct got_error *
-got_privsep_send_blob(struct imsgbuf *ibuf)
+got_privsep_send_blob(struct imsgbuf *ibuf, size_t size)
 {
+	struct got_imsg_blob iblob;
+
+	iblob.size = size;
 	/* Data has already been written to file descriptor. */
-	if (imsg_compose(ibuf, GOT_IMSG_BLOB, 0, 0, -1, NULL, 0) == -1)
+
+	if (imsg_compose(ibuf, GOT_IMSG_BLOB, 0, 0, -1, &iblob, sizeof(iblob))
+	    == -1)
 		return got_error_from_errno();
 
 	return flush_imsg(ibuf);
 }
 
 const struct got_error *
-got_privsep_recv_blob(struct imsgbuf *ibuf)
+got_privsep_recv_blob(size_t *size, struct imsgbuf *ibuf)
 {
 	const struct got_error *err = NULL;
 	struct imsg imsg;
+	struct got_imsg_blob iblob;
 	size_t datalen;
 
 	err = recv_one_imsg(&imsg, ibuf, 0);
@@ -636,8 +642,10 @@ got_privsep_recv_blob(struct imsgbuf *ibuf)
 		err = recv_imsg_error(&imsg, datalen);
 		break;
 	case GOT_IMSG_BLOB:
-		if (datalen != 0)
+		if (datalen != sizeof(iblob))
 			err = got_error(GOT_ERR_PRIVSEP_LEN);
+		memcpy(&iblob, imsg.data, sizeof(iblob));
+		*size = iblob.size;
 		/* Data has been written to file descriptor. */
 		break;
 	default: