commit 1c28a36116110db5de40e6edf09887651f3ca37b from: Omar Polo date: Tue Oct 25 07:37:58 2022 UTC check size before calling mmap(2) It's only a preparatory step, as checking whether a size_t is less than SIZE_MAX is moot. In a follow-up commit, however, the `filesize' field of the struct got_pack will become off_t and these checks will kick in. This also makes consistent how we guard mmap(2) against empty files. ok and improvements stsp@ commit - 5326bd73c63d9b453093bf46a5a514283348d0ec commit + 1c28a36116110db5de40e6edf09887651f3ca37b blob - f8e685448165384cfc578c0f089b4aa6fb6219c8 blob + 7bc7eb3dcdcec57157f35f8b6c676e1979ba2b76 --- lib/object.c +++ lib/object.c @@ -926,7 +926,10 @@ got_object_raw_alloc(struct got_raw_object **obj, uint size_t hdrlen, off_t size) { const struct got_error *err = NULL; + off_t tot; + tot = hdrlen + size; + *obj = calloc(1, sizeof(**obj)); if (*obj == NULL) { err = got_error_from_errno("calloc"); @@ -944,13 +947,13 @@ got_object_raw_alloc(struct got_raw_object **obj, uint goto done; } - if (sb.st_size != hdrlen + size) { + if (sb.st_size != tot) { err = got_error(GOT_ERR_PRIVSEP_LEN); goto done; } #ifndef GOT_PACK_NO_MMAP - if (hdrlen + size > 0) { - (*obj)->data = mmap(NULL, hdrlen + size, PROT_READ, + if (tot > 0 && tot <= SIZE_MAX) { + (*obj)->data = mmap(NULL, tot, PROT_READ, MAP_PRIVATE, *outfd, 0); if ((*obj)->data == MAP_FAILED) { if (errno != ENOMEM) { blob - fd881a7c9ce48fda7e1c9997d71b47a93bba6268 blob + b043d4d76bcee830e606273e62636fe996c1d756 --- lib/pack.c +++ lib/pack.c @@ -392,13 +392,15 @@ got_packidx_open(struct got_packidx **packidx, } #ifndef GOT_PACK_NO_MMAP - p->map = mmap(NULL, p->len, PROT_READ, MAP_PRIVATE, p->fd, 0); - if (p->map == MAP_FAILED) { - if (errno != ENOMEM) { - err = got_error_from_errno("mmap"); - goto done; + if (p->len > 0 && p->len <= SIZE_MAX) { + p->map = mmap(NULL, p->len, PROT_READ, MAP_PRIVATE, p->fd, 0); + if (p->map == MAP_FAILED) { + if (errno != ENOMEM) { + err = got_error_from_errno("mmap"); + goto done; + } + p->map = NULL; /* fall back to read(2) */ } - p->map = NULL; /* fall back to read(2) */ } #endif @@ -1036,7 +1038,6 @@ static const struct got_error * resolve_offset_delta(struct got_delta_chain *deltas, struct got_packidx *packidx, struct got_pack *pack, off_t delta_offset, size_t tslen, int delta_type, size_t delta_size, unsigned int recursion) - { const struct got_error *err; off_t base_offset; blob - b07bf0c9c711997031a7d3afa3388a27527ef2db blob + 50237bbf7e4f90efc06e68c84cedd6c84631551e --- lib/repository.c +++ lib/repository.c @@ -1428,14 +1428,16 @@ got_repo_cache_pack(struct got_pack **packp, struct go goto done; #ifndef GOT_PACK_NO_MMAP - pack->map = mmap(NULL, pack->filesize, PROT_READ, MAP_PRIVATE, - pack->fd, 0); - if (pack->map == MAP_FAILED) { - if (errno != ENOMEM) { - err = got_error_from_errno("mmap"); - goto done; + if (pack->filesize > 0 && pack->filesize <= SIZE_MAX) { + pack->map = mmap(NULL, pack->filesize, PROT_READ, MAP_PRIVATE, + pack->fd, 0); + if (pack->map == MAP_FAILED) { + if (errno != ENOMEM) { + err = got_error_from_errno("mmap"); + goto done; + } + pack->map = NULL; /* fall back to read(2) */ } - pack->map = NULL; /* fall back to read(2) */ } #endif done: blob - 8a38382357c6aeb5b642965a26a50d9a6621d34e blob + 7fda0c4e47f3539c4b13427d388cc26e749b75bb --- libexec/got-index-pack/got-index-pack.c +++ libexec/got-index-pack/got-index-pack.c @@ -183,10 +183,12 @@ main(int argc, char **argv) } #ifndef GOT_PACK_NO_MMAP - pack.map = mmap(NULL, pack.filesize, PROT_READ, MAP_PRIVATE, - pack.fd, 0); - if (pack.map == MAP_FAILED) - pack.map = NULL; /* fall back to read(2) */ + if (pack.filesize > 0 && pack.filesize <= SIZE_MAX) { + pack.map = mmap(NULL, pack.filesize, PROT_READ, MAP_PRIVATE, + pack.fd, 0); + if (pack.map == MAP_FAILED) + pack.map = NULL; /* fall back to read(2) */ + } #endif err = got_pack_index(&pack, idxfd, tmpfiles[0], tmpfiles[1], tmpfiles[2], pack_hash, send_index_pack_progress, &ibuf, &rl); blob - 268ab18c5371e622b7f9c3a62c9a894a7050de85 blob + e49fd95ba0b7919efe9005b306782db008b22370 --- libexec/got-read-pack/got-read-pack.c +++ libexec/got-read-pack/got-read-pack.c @@ -1146,9 +1146,11 @@ receive_packidx(struct got_packidx **packidx, struct i } #ifndef GOT_PACK_NO_MMAP - p->map = mmap(NULL, p->len, PROT_READ, MAP_PRIVATE, p->fd, 0); - if (p->map == MAP_FAILED) - p->map = NULL; /* fall back to read(2) */ + if (p->len > 0 && p->len <= SIZE_MAX) { + p->map = mmap(NULL, p->len, PROT_READ, MAP_PRIVATE, p->fd, 0); + if (p->map == MAP_FAILED) + p->map = NULL; /* fall back to read(2) */ + } #endif err = got_packidx_init_hdr(p, 1, ipackidx.packfile_size); done: @@ -1874,10 +1876,12 @@ receive_pack(struct got_pack **packp, struct imsgbuf * goto done; #ifndef GOT_PACK_NO_MMAP - pack->map = mmap(NULL, pack->filesize, PROT_READ, MAP_PRIVATE, - pack->fd, 0); - if (pack->map == MAP_FAILED) - pack->map = NULL; /* fall back to read(2) */ + if (pack->filesize > 0 && pack->filesize <= SIZE_MAX) { + pack->map = mmap(NULL, pack->filesize, PROT_READ, MAP_PRIVATE, + pack->fd, 0); + if (pack->map == MAP_FAILED) + pack->map = NULL; /* fall back to read(2) */ + } #endif done: if (err) {