Commit Diff


commit - 8b2180d40ae950c447339c459dc82e4708136cbf
commit + b419fc475bafd6efb01d324f86b462e1a24eda93
blob - 8c6c1506e6a1ce41d6b432ec25ddd744d509e7a9
blob + 8706e35fba0b89f57c66633608d8653ef595eba2
--- include/got_error.h
+++ include/got_error.h
@@ -53,6 +53,8 @@
 #define GOT_ERR_PRIVSEP_PIPE	37
 #define GOT_ERR_PRIVSEP_NO_FD	38
 #define GOT_ERR_PRIVSEP_MSG	39
+#define GOT_ERR_PRIVSEP_DIED	40
+#define GOT_ERR_PRIVSEP_EXIT	41
 
 static const struct got_error {
 	int code;
@@ -95,6 +97,8 @@ static const struct got_error {
 	{ GOT_ERR_PRIVSEP_PIPE,	"unprivileged process closed pipe" },
 	{ GOT_ERR_PRIVSEP_NO_FD,"out of file descriptors for privsep" },
 	{ GOT_ERR_PRIVSEP_MSG,"unexpected message from unprivileged process" },
+	{ GOT_ERR_PRIVSEP_DIED,"unprivileged process died unexpectedly" },
+	{ GOT_ERR_PRIVSEP_EXIT,"bad exit code from unprivileged process" },
 };
 
 /*
blob - 070c41a421af9076bc2ee24a8adba8ba911a2a60
blob + c3822193b294b2380efac47729fd22101b9c0157
--- lib/object.c
+++ lib/object.c
@@ -259,6 +259,22 @@ done:
 	imsg_clear(&ibuf);
 	close(imsg_fds[1]);
 	_exit(status);
+}
+
+static const struct got_error *
+wait_for_child(pid_t pid)
+{
+	int child_status;
+
+	waitpid(pid, &child_status, 0);
+
+	if (!WIFEXITED(child_status))
+		return got_error(GOT_ERR_PRIVSEP_DIED);
+
+	if (WEXITSTATUS(child_status) != 0)
+		return got_error(GOT_ERR_PRIVSEP_EXIT);
+
+	return NULL;
 }
 
 static const struct got_error *
@@ -266,9 +282,8 @@ read_object_header_privsep(struct got_object **obj, in
 {
 	struct imsgbuf parent_ibuf;
 	int imsg_fds[2];
-	const struct got_error *err = NULL;
+	const struct got_error *err = NULL, *err_child = NULL;
 	pid_t pid;
-	int child_status;
 
 	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, imsg_fds) == -1)
 		return got_error_from_errno();
@@ -285,9 +300,9 @@ read_object_header_privsep(struct got_object **obj, in
 	imsg_init(&parent_ibuf, imsg_fds[0]);
 	err = got_privsep_recv_obj(obj, &parent_ibuf);
 	imsg_clear(&parent_ibuf);
-	waitpid(pid, &child_status, 0);
+	err_child = wait_for_child(pid);
 	close(imsg_fds[0]);
-	return err;
+	return err ? err : err_child;
 }
 
 static const struct got_error *
@@ -795,11 +810,10 @@ static const struct got_error *
 read_commit_object_privsep(struct got_commit_object **commit,
     struct got_repository *repo, struct got_object *obj, int fd)
 {
-	const struct got_error *err = NULL;
+	const struct got_error *err = NULL, *err_child = NULL;
 	struct imsgbuf parent_ibuf;
 	int imsg_fds[2];
 	pid_t pid;
-	int child_status;
 
 	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, imsg_fds) == -1)
 		return got_error_from_errno();
@@ -816,9 +830,9 @@ read_commit_object_privsep(struct got_commit_object **
 	imsg_init(&parent_ibuf, imsg_fds[0]);
 	err = got_privsep_recv_commit(commit, &parent_ibuf);
 	imsg_clear(&parent_ibuf);
-	waitpid(pid, &child_status, 0);
+	err_child = wait_for_child(pid);
 	close(imsg_fds[0]);
-	return err;
+	return err ? err : err_child;
 }
 
 const struct got_error *
@@ -946,11 +960,10 @@ static const struct got_error *
 read_tree_object_privsep(struct got_tree_object **tree, struct got_object *obj,
     int fd)
 {
-	const struct got_error *err = NULL;
+	const struct got_error *err = NULL, *err_child = NULL;
 	struct imsgbuf parent_ibuf;
 	int imsg_fds[2];
 	pid_t pid;
-	int child_status;
 
 	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, imsg_fds) == -1)
 		return got_error_from_errno();
@@ -967,9 +980,9 @@ read_tree_object_privsep(struct got_tree_object **tree
 	imsg_init(&parent_ibuf, imsg_fds[0]);
 	err = got_privsep_recv_tree(tree, &parent_ibuf);
 	imsg_clear(&parent_ibuf);
-	waitpid(pid, &child_status, 0);
+	err_child = wait_for_child(pid);
 	close(imsg_fds[0]);
-	return err;
+	return err ? err : err_child;
 }
 
 const struct got_error *
@@ -1062,9 +1075,8 @@ read_blob_object_privsep(size_t *size, int outfd, int 
 {
 	struct imsgbuf parent_ibuf;
 	int imsg_fds[2];
-	const struct got_error *err = NULL;
+	const struct got_error *err = NULL, *err_child = NULL;
 	pid_t pid;
-	int child_status;
 
 	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, imsg_fds) == -1)
 		return got_error_from_errno();
@@ -1081,11 +1093,11 @@ read_blob_object_privsep(size_t *size, int outfd, int 
 	imsg_init(&parent_ibuf, imsg_fds[0]);
 	err = got_privsep_recv_blob(size, &parent_ibuf);
 	imsg_clear(&parent_ibuf);
-	waitpid(pid, &child_status, 0);
+	err_child = wait_for_child(pid);
 	close(imsg_fds[0]);
 	if (lseek(outfd, SEEK_SET, 0) == -1)
 		err = got_error_from_errno();
-	return err;
+	return err ? err : err_child;
 }
 
 const struct got_error *