commit b419fc475bafd6efb01d324f86b462e1a24eda93 from: Stefan Sperling date: Thu Apr 26 20:17:43 2018 UTC error out if child dies or does not exit with success 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 *