error out if child dies or does not exit with success
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
diff --git a/include/got_error.h b/include/got_error.h
index 8c6c150..8706e35 100644
--- a/include/got_error.h
+++ b/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" },
};
/*
diff --git a/lib/object.c b/lib/object.c
index 070c41a..c382219 100644
--- a/lib/object.c
+++ b/lib/object.c
@@ -262,13 +262,28 @@ done:
}
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 *
read_object_header_privsep(struct got_object **obj, int fd)
{
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, int fd)
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 **commit,
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, struct got_object *obj,
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 infd)
{
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 infd)
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 *