commit 3840f4c96dbf09953b6c83fdc338a29817d983d4 from: Stefan Sperling date: Wed Sep 12 22:06:12 2018 UTC fix "rpath" pledge violation in got-read-pack commit - eb46335738e5919462d311fc6dd3b9ee2c0e16e3 commit + 3840f4c96dbf09953b6c83fdc338a29817d983d4 blob - d77cc53056e356b8d086100eaa0cabc75ebe746e blob + b427544ee597fb40d4802b61166507af2c7f124e --- lib/got_lib_object_parse.h +++ lib/got_lib_object_parse.h @@ -44,5 +44,3 @@ const struct got_error *got_object_read_packed_commit_ struct got_commit_object **, struct got_object *, struct got_pack *); const struct got_error *got_object_read_packed_tree_privsep( struct got_tree_object **, struct got_object *, struct got_pack *); -const struct got_error *got_object_read_packed_blob_privsep(size_t *, int, - struct got_object *, struct got_pack *); blob - c36360e3371cbea006d4f4cffe3cad2e726123d4 blob + 63c033d6f774a39c9e2058276608a89c1daa1342 --- lib/got_lib_pack.h +++ lib/got_lib_pack.h @@ -165,7 +165,7 @@ int got_packidx_get_object_idx(struct got_packidx *, s const struct got_error *got_packfile_open_object(struct got_object **, struct got_pack *, struct got_packidx *, int, struct got_object_id *); const struct got_error *got_packfile_extract_object(struct got_pack *, - struct got_object *, FILE *); + struct got_object *, FILE *, FILE *, FILE *); const struct got_error *got_packfile_extract_object_to_mem(uint8_t **, size_t *, struct got_object *, struct got_pack *); const struct got_error *got_pack_get_packfile_size(size_t *, const char *); blob - 3620a1f18ef31e6581d44f359aba047c1430243c blob + 91f70c774b1229a71ff2fd12276504df52656861 --- lib/got_lib_privsep.h +++ lib/got_lib_privsep.h @@ -93,6 +93,9 @@ enum got_imsg_type { GOT_IMSG_PACKIDX, GOT_IMSG_PACK, GOT_IMSG_PACKED_OBJECT_REQUEST, + + /* Message sending file desciprtor to a temporary file. */ + GOT_IMSG_TMPFD, }; /* Structure for GOT_IMSG_ERROR. */ @@ -189,6 +192,7 @@ const struct got_error *got_privsep_send_obj_req(struc struct got_object *); const struct got_error *got_privsep_send_blob_req(struct imsgbuf *, int); const struct got_error *got_privsep_send_blob_outfd(struct imsgbuf *, int); +const struct got_error *got_privsep_send_tmpfd(struct imsgbuf *, int); const struct got_error *got_privsep_send_obj(struct imsgbuf *, struct got_object *); const struct got_error *got_privsep_get_imsg_obj(struct got_object **, blob - 70d904c862876bbd6a22fd646cf6c0fa9be94d6a blob + 7c7fdf3f13ae50b44bf920389211769d3766850f --- lib/object.c +++ lib/object.c @@ -442,7 +442,63 @@ got_object_tree_get_entries(struct got_tree_object *tr { return &tree->entries; } + +static const struct got_error * +read_packed_blob_privsep(size_t *size, int outfd, struct got_object *obj, + struct got_pack *pack) +{ + const struct got_error *err = NULL; + int outfd_child; + int basefd, accumfd; /* temporary files for delta application */ + basefd = got_opentempfd(); + if (basefd == -1) + return got_error_from_errno(); + accumfd = got_opentempfd(); + if (accumfd == -1) + return got_error_from_errno(); + + outfd_child = dup(outfd); + if (outfd_child == -1) + return got_error_from_errno(); + + err = got_privsep_send_obj_req(pack->privsep_child->ibuf, -1, obj); + if (err) + return err; + + err = got_privsep_send_blob_outfd(pack->privsep_child->ibuf, + outfd_child); + if (err) { + close(outfd_child); + return err; + } + err = got_privsep_send_tmpfd(pack->privsep_child->ibuf, + basefd); + if (err) { + close(basefd); + close(accumfd); + close(outfd_child); + return err; + } + + err = got_privsep_send_tmpfd(pack->privsep_child->ibuf, + accumfd); + if (err) { + close(accumfd); + close(outfd_child); + return err; + } + + err = got_privsep_recv_blob(size, pack->privsep_child->ibuf); + if (err) + return err; + + if (lseek(outfd, SEEK_SET, 0) == -1) + err = got_error_from_errno(); + + return err; +} + const struct got_error * got_object_blob_open(struct got_blob_object **blob, struct got_repository *repo, struct got_object *obj, size_t blocksize) @@ -480,8 +536,7 @@ got_object_blob_open(struct got_blob_object **blob, if (err) goto done; } - err = got_object_read_packed_blob_privsep(&size, outfd, - obj, pack); + err = read_packed_blob_privsep(&size, outfd, obj, pack); if (err) goto done; obj->size = size; blob - 091877528d84ffeecce69bcaa5d7a92d7cf41a75 blob + bab79facebb43d058755da15af744e18af33ee0d --- lib/object_parse.c +++ lib/object_parse.c @@ -836,38 +836,6 @@ got_object_read_packed_tree_privsep(struct got_tree_ob return err; return got_privsep_recv_tree(tree, pack->privsep_child->ibuf); -} - -const struct got_error * -got_object_read_packed_blob_privsep(size_t *size, int outfd, - struct got_object *obj, struct got_pack *pack) -{ - const struct got_error *err = NULL; - int outfd_child; - - outfd_child = dup(outfd); - if (outfd_child == -1) - return got_error_from_errno(); - - err = got_privsep_send_obj_req(pack->privsep_child->ibuf, -1, obj); - if (err) - return err; - - err = got_privsep_send_blob_outfd(pack->privsep_child->ibuf, - outfd_child); - if (err) { - close(outfd_child); - return err; - } - - err = got_privsep_recv_blob(size, pack->privsep_child->ibuf); - if (err) - return err; - - if (lseek(outfd, SEEK_SET, 0) == -1) - err = got_error_from_errno(); - - return err; } static const struct got_error * blob - 3560e5c6fecdfae43a2c4fb617448f293a1db529 blob + a6731723b35cc9a1ee34da07102b0a30cdbb2161 --- lib/pack.c +++ lib/pack.c @@ -975,11 +975,10 @@ get_delta_chain_max_size(uint64_t *max_size, struct go static const struct got_error * dump_delta_chain_to_file(size_t *result_size, struct got_delta_chain *deltas, - struct got_pack *pack, FILE *outfile) + struct got_pack *pack, FILE *outfile, FILE *base_file, FILE *accum_file) { const struct got_error *err = NULL; struct got_delta *delta; - FILE *base_file = NULL, *accum_file = NULL; uint8_t *base_buf = NULL, *accum_buf = NULL; size_t accum_size = 0; uint64_t max_size; @@ -997,18 +996,9 @@ dump_delta_chain_to_file(size_t *result_size, struct g if (max_size < GOT_DELTA_RESULT_SIZE_CACHED_MAX) { accum_buf = malloc(max_size); if (accum_buf == NULL) - return got_error_from_errno(); - } else { - base_file = got_opentemp(); - if (base_file == NULL) return got_error_from_errno(); - - accum_file = got_opentemp(); - if (accum_file == NULL) { - err = got_error_from_errno(); - fclose(base_file); - return err; - } + base_file = NULL; + accum_file = NULL; } /* Deltas are ordered in ascending order. */ @@ -1224,7 +1214,7 @@ done: const struct got_error * got_packfile_extract_object(struct got_pack *pack, struct got_object *obj, - FILE *outfile) + FILE *outfile, FILE *base_file, FILE *accum_file) { const struct got_error *err = NULL; @@ -1247,7 +1237,7 @@ got_packfile_extract_object(struct got_pack *pack, str } } else err = dump_delta_chain_to_file(&obj->size, &obj->deltas, pack, - outfile); + outfile, base_file, accum_file); return err; } blob - b7cdab14cb8dc234b6f786daf2860c4c1d25e6cc blob + 9079955e9790c3b92539b537bb8bc36306b3195f --- lib/privsep.c +++ lib/privsep.c @@ -270,6 +270,16 @@ const struct got_error * got_privsep_send_blob_outfd(struct imsgbuf *ibuf, int outfd) { if (imsg_compose(ibuf, GOT_IMSG_BLOB_OUTFD, 0, 0, outfd, NULL, 0) + == -1) + return got_error_from_errno(); + + return flush_imsg(ibuf); +} + +const struct got_error * +got_privsep_send_tmpfd(struct imsgbuf *ibuf, int fd) +{ + if (imsg_compose(ibuf, GOT_IMSG_TMPFD, 0, 0, fd, NULL, 0) == -1) return got_error_from_errno(); blob - 001b16f5d436b8d2a68d194127cb3fde8cac7d97 blob + 51e3ea5274739b0370fd91f0a28663069e7036be --- libexec/got-read-pack/got-read-pack.c +++ libexec/got-read-pack/got-read-pack.c @@ -180,67 +180,82 @@ tree_request(struct imsg *imsg, struct imsgbuf *ibuf, } static const struct got_error * -blob_request(struct imsg *imsg, struct imsgbuf *ibuf, struct got_pack *pack, - struct got_packidx *packidx, struct got_object_cache *objcache) +receive_file(FILE **f, struct imsgbuf *ibuf, int imsg_code) { - const struct got_error *err = NULL; - struct got_object *obj = NULL; - FILE *f = NULL; - struct imsg imsg_outfd; + const struct got_error *err; + struct imsg imsg; size_t datalen; - memset(&imsg_outfd, 0, sizeof(imsg_outfd)); - imsg_outfd.fd = -1; - - err = get_object(&obj, imsg, ibuf, pack, packidx, objcache, - GOT_OBJ_TYPE_BLOB); + err = got_privsep_recv_imsg(&imsg, ibuf, 0); if (err) return err; - err = got_privsep_recv_imsg(&imsg_outfd, ibuf, 0); - if (err) - return err; - - if (imsg_outfd.hdr.type != GOT_IMSG_BLOB_OUTFD) { + if (imsg.hdr.type != imsg_code) { err = got_error(GOT_ERR_PRIVSEP_MSG); goto done; } - datalen = imsg_outfd.hdr.len - IMSG_HEADER_SIZE; + datalen = imsg.hdr.len - IMSG_HEADER_SIZE; if (datalen != 0) { err = got_error(GOT_ERR_PRIVSEP_LEN); goto done; } - if (imsg_outfd.fd == -1) { + if (imsg.fd == -1) { err = got_error(GOT_ERR_PRIVSEP_NO_FD); goto done; } - f = fdopen(imsg_outfd.fd, "w+"); - if (f == NULL) { + *f = fdopen(imsg.fd, "w+"); + if (*f == NULL) { + close(imsg.fd); err = got_error_from_errno(); goto done; } +done: + imsg_free(&imsg); + return err; +} - err = got_packfile_extract_object(pack, obj, f); +static const struct got_error * +blob_request(struct imsg *imsg, struct imsgbuf *ibuf, struct got_pack *pack, + struct got_packidx *packidx, struct got_object_cache *objcache) +{ + const struct got_error *err = NULL; + struct got_object *obj = NULL; + FILE *outfile = NULL, *basefile = NULL, *accumfile = NULL; + + err = get_object(&obj, imsg, ibuf, pack, packidx, objcache, + GOT_OBJ_TYPE_BLOB); if (err) + return err; + + err = receive_file(&outfile, ibuf, GOT_IMSG_BLOB_OUTFD); + if (err) + return err; + err = receive_file(&basefile, ibuf, GOT_IMSG_TMPFD); + if (err) + return err; + err = receive_file(&accumfile, ibuf, GOT_IMSG_TMPFD); + if (err) + return err; + + err = got_packfile_extract_object(pack, obj, outfile, basefile, + accumfile); + if (err) goto done; err = got_privsep_send_blob(ibuf, obj->size); done: - if (f) - fclose(f); - else if (imsg_outfd.fd != -1) - close(imsg_outfd.fd); - imsg_free(&imsg_outfd); + if (outfile) + fclose(outfile); + if (basefile) + fclose(basefile); + if (accumfile) + fclose(accumfile); if (obj) got_object_close(obj); - if (err) { - if (err->code == GOT_ERR_PRIVSEP_PIPE) - err = NULL; - else - got_privsep_send_error(ibuf, err); - } + if (err && err->code != GOT_ERR_PRIVSEP_PIPE) + got_privsep_send_error(ibuf, err); return err; }