Download raw body.
check for size_t overflow when mapping memory
diff below ensures that every time we call mmap(2) the size argument
effectively less than SIZE_MAX. In some cases this is a no-op since
filesize is currently size_t and so we've potentially already
truncated the value. In a follow-up commit i'd like to turn the
`filesize' field in the structs got_pack and packidx from size_t to
off_t, so these checks will start to work.
diff 933f287a77cf1c9dced8ed3afbf3850f5c0c1bb3 90ac69281429b4caf05f7b3617e0acabdc062028
commit - 933f287a77cf1c9dced8ed3afbf3850f5c0c1bb3
commit + 90ac69281429b4caf05f7b3617e0acabdc062028
blob - f8e685448165384cfc578c0f089b4aa6fb6219c8
blob + 7f2a014edb74884a7f92a43fb66ec78eb24e3228
--- 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,15 @@ 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,
+ (*obj)->fd = *outfd;
+ *outfd = -1;
+ 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) {
@@ -958,9 +963,6 @@ got_object_raw_alloc(struct got_raw_object **obj, uint
goto done;
}
(*obj)->data = NULL;
- } else {
- (*obj)->fd = *outfd;
- *outfd = -1;
}
}
#endif
blob - becc8ffd68217466f0bad6d811196c0d7137e4df
blob + 0b79146e747f73787b2ee568b7fb74c517ce1d9e
--- 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 < 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 @@ resolve_offset_delta(struct got_delta_chain *deltas,
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 + 7372c43fc3a9bd8d47fb3d868c90311eb3c51451
--- lib/repository.c
+++ lib/repository.c
@@ -1427,15 +1427,18 @@ got_repo_cache_pack(struct got_pack **packp, struct go
if (err)
goto done;
+ pack->map = NULL;
#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 < 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 + e914ae79dd30bfd6591ea94dfadb6d91ddd80c65
--- 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 < 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 + fd77f35cfff0c52c0cf09457929ce3c48d8470c8
--- 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 < 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 < 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) {
check for size_t overflow when mapping memory