commit ddc7b220d2cafa2ab2e485c71a7a4cbfa9c23beb from: Stefan Sperling date: Sun Sep 08 16:29:14 2019 UTC do not leak ibuf in error paths of read_*_privsep() commit - 6cb9286d20ee5b8d9c024a6e490ce8b7f39d76ed commit + ddc7b220d2cafa2ab2e485c71a7a4cbfa9c23beb blob - ca9b1470b78030edb637ec17878e01fe010a17b1 blob + 7f69adc6bdcc1004a041b2db8b490ff9f5e33bcb --- lib/object.c +++ lib/object.c @@ -350,6 +350,7 @@ static const struct got_error * read_object_header_privsep(struct got_object **obj, struct got_repository *repo, int obj_fd) { + const struct got_error *err; int imsg_fds[2]; pid_t pid; struct imsgbuf *ibuf; @@ -361,20 +362,29 @@ read_object_header_privsep(struct got_object **obj, st if (ibuf == NULL) return got_error_from_errno("calloc"); - if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, imsg_fds) == -1) - return got_error_from_errno("socketpair"); + if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, imsg_fds) == -1) { + err = got_error_from_errno("socketpair"); + free(ibuf); + return err; + } pid = fork(); - if (pid == -1) - return got_error_from_errno("fork"); + if (pid == -1) { + err = got_error_from_errno("fork"); + free(ibuf); + return err; + } else if (pid == 0) { got_privsep_exec_child(imsg_fds, GOT_PATH_PROG_READ_OBJECT, repo->path); /* not reached */ } - if (close(imsg_fds[1]) != 0) - return got_error_from_errno("close"); + if (close(imsg_fds[1]) != 0) { + err = got_error_from_errno("close"); + free(ibuf); + return err; + } repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_OBJECT].imsg_fd = imsg_fds[0]; repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_OBJECT].pid = pid; @@ -515,6 +525,7 @@ static const struct got_error * read_commit_privsep(struct got_commit_object **commit, int obj_fd, struct got_repository *repo) { + const struct got_error *err; int imsg_fds[2]; pid_t pid; struct imsgbuf *ibuf; @@ -526,20 +537,29 @@ read_commit_privsep(struct got_commit_object **commit, if (ibuf == NULL) return got_error_from_errno("calloc"); - if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, imsg_fds) == -1) - return got_error_from_errno("socketpair"); + if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, imsg_fds) == -1) { + err = got_error_from_errno("socketpair"); + free(ibuf); + return err; + } pid = fork(); - if (pid == -1) - return got_error_from_errno("fork"); + if (pid == -1) { + err = got_error_from_errno("fork"); + free(ibuf); + return err; + } else if (pid == 0) { got_privsep_exec_child(imsg_fds, GOT_PATH_PROG_READ_COMMIT, repo->path); /* not reached */ } - if (close(imsg_fds[1]) != 0) - return got_error_from_errno("close"); + if (close(imsg_fds[1]) != 0) { + err = got_error_from_errno("close"); + free(ibuf); + return err; + } repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_COMMIT].imsg_fd = imsg_fds[0]; repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_COMMIT].pid = pid; @@ -694,6 +714,7 @@ const struct got_error * read_tree_privsep(struct got_tree_object **tree, int obj_fd, struct got_repository *repo) { + const struct got_error *err; int imsg_fds[2]; pid_t pid; struct imsgbuf *ibuf; @@ -705,20 +726,29 @@ read_tree_privsep(struct got_tree_object **tree, int o if (ibuf == NULL) return got_error_from_errno("calloc"); - if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, imsg_fds) == -1) - return got_error_from_errno("socketpair"); + if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, imsg_fds) == -1) { + err = got_error_from_errno("socketpair"); + free(ibuf); + return err; + } pid = fork(); - if (pid == -1) - return got_error_from_errno("fork"); + if (pid == -1) { + err = got_error_from_errno("fork"); + free(ibuf); + return err; + } else if (pid == 0) { got_privsep_exec_child(imsg_fds, GOT_PATH_PROG_READ_TREE, repo->path); /* not reached */ } - if (close(imsg_fds[1]) != 0) - return got_error_from_errno("close"); + if (close(imsg_fds[1]) != 0) { + err = got_error_from_errno("close"); + free(ibuf); + return err; + } repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_TREE].imsg_fd = imsg_fds[0]; repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_TREE].pid = pid; @@ -913,6 +943,7 @@ static const struct got_error * read_blob_privsep(uint8_t **outbuf, size_t *size, size_t *hdrlen, int outfd, int infd, struct got_repository *repo) { + const struct got_error *err; int imsg_fds[2]; pid_t pid; struct imsgbuf *ibuf; @@ -926,20 +957,29 @@ read_blob_privsep(uint8_t **outbuf, size_t *size, size if (ibuf == NULL) return got_error_from_errno("calloc"); - if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, imsg_fds) == -1) - return got_error_from_errno("socketpair"); + if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, imsg_fds) == -1) { + err = got_error_from_errno("socketpair"); + free(ibuf); + return err; + } pid = fork(); - if (pid == -1) - return got_error_from_errno("fork"); + if (pid == -1) { + err = got_error_from_errno("fork"); + free(ibuf); + return err; + } else if (pid == 0) { got_privsep_exec_child(imsg_fds, GOT_PATH_PROG_READ_BLOB, repo->path); /* not reached */ } - if (close(imsg_fds[1]) != 0) - return got_error_from_errno("close"); + if (close(imsg_fds[1]) != 0) { + err = got_error_from_errno("close"); + free(ibuf); + return err; + } repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_BLOB].imsg_fd = imsg_fds[0]; repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_BLOB].pid = pid; @@ -1251,6 +1291,7 @@ static const struct got_error * read_tag_privsep(struct got_tag_object **tag, int obj_fd, struct got_repository *repo) { + const struct got_error *err; int imsg_fds[2]; pid_t pid; struct imsgbuf *ibuf; @@ -1262,20 +1303,29 @@ read_tag_privsep(struct got_tag_object **tag, int obj_ if (ibuf == NULL) return got_error_from_errno("calloc"); - if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, imsg_fds) == -1) - return got_error_from_errno("socketpair"); + if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, imsg_fds) == -1) { + err = got_error_from_errno("socketpair"); + free(ibuf); + return err; + } pid = fork(); - if (pid == -1) - return got_error_from_errno("fork"); + if (pid == -1) { + err = got_error_from_errno("fork"); + free(ibuf); + return err; + } else if (pid == 0) { got_privsep_exec_child(imsg_fds, GOT_PATH_PROG_READ_TAG, repo->path); /* not reached */ } - if (close(imsg_fds[1]) != 0) - return got_error_from_errno("close"); + if (close(imsg_fds[1]) != 0) { + err = got_error_from_errno("close"); + free(ibuf); + return err; + } repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_TAG].imsg_fd = imsg_fds[0]; repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_TAG].pid = pid;