diff options
author | Edward Thomson <ethomson@microsoft.com> | 2015-02-11 11:20:05 -0500 |
---|---|---|
committer | Edward Thomson <ethomson@edwardthomson.com> | 2015-02-12 22:54:47 -0500 |
commit | ec3b4d35f636c26d3c9b5703c3b7f87683800af8 (patch) | |
tree | a1d4330c4efaa1b7097f64f4243224e0581a5b2e /src | |
parent | 2884cc42de8b20a58cec8488d014a853d47c047e (diff) | |
download | libgit2-ec3b4d35f636c26d3c9b5703c3b7f87683800af8.tar.gz |
Use `size_t` to hold size of arrays
Use `size_t` to hold the size of arrays to ease overflow checking,
lest we check for overflow of a `size_t` then promptly truncate
by packing the length into a smaller type.
Diffstat (limited to 'src')
-rw-r--r-- | src/array.h | 4 | ||||
-rw-r--r-- | src/filebuf.c | 13 | ||||
-rw-r--r-- | src/pack-objects.c | 10 | ||||
-rw-r--r-- | src/transports/smart_pkt.c | 17 |
4 files changed, 30 insertions, 14 deletions
diff --git a/src/array.h b/src/array.h index 0d0795370..7c4dbdbc1 100644 --- a/src/array.h +++ b/src/array.h @@ -23,7 +23,7 @@ * * typedef git_array_t(my_struct) my_struct_array_t; */ -#define git_array_t(type) struct { type *ptr; uint32_t size, asize; } +#define git_array_t(type) struct { type *ptr; size_t size, asize; } #define GIT_ARRAY_INIT { NULL, 0, 0 } @@ -45,7 +45,7 @@ typedef git_array_t(char) git_array_generic_t; GIT_INLINE(void *) git_array_grow(void *_a, size_t item_size) { volatile git_array_generic_t *a = _a; - uint32_t new_size; + size_t new_size; char *new_array; if (a->size < 8) { diff --git a/src/filebuf.c b/src/filebuf.c index 1a9157558..94f2bec32 100644 --- a/src/filebuf.c +++ b/src/filebuf.c @@ -408,8 +408,8 @@ int git_filebuf_reserve(git_filebuf *file, void **buffer, size_t len) int git_filebuf_printf(git_filebuf *file, const char *format, ...) { va_list arglist; - size_t space_left; - int len, res; + size_t space_left, len; + int written, res; char *tmp_buffer; ENSURE_BUF_OK(file); @@ -418,15 +418,16 @@ int git_filebuf_printf(git_filebuf *file, const char *format, ...) do { va_start(arglist, format); - len = p_vsnprintf((char *)file->buffer + file->buf_pos, space_left, format, arglist); + written = p_vsnprintf((char *)file->buffer + file->buf_pos, space_left, format, arglist); va_end(arglist); - if (len < 0) { + if (written < 0) { file->last_error = BUFERR_MEM; return -1; } - if ((size_t)len + 1 <= space_left) { + len = written; + if (len + 1 <= space_left) { file->buf_pos += len; return 0; } @@ -436,7 +437,7 @@ int git_filebuf_printf(git_filebuf *file, const char *format, ...) space_left = file->buf_size - file->buf_pos; - } while ((size_t)len + 1 <= space_left); + } while (len + 1 <= space_left); if (GIT_ALLOC_OVERFLOW_ADD(len, 1) || !(tmp_buffer = git__malloc(len + 1))) { diff --git a/src/pack-objects.c b/src/pack-objects.c index 288077078..9b56234b5 100644 --- a/src/pack-objects.c +++ b/src/pack-objects.c @@ -190,6 +190,7 @@ int git_packbuilder_insert(git_packbuilder *pb, const git_oid *oid, { git_pobject *po; khiter_t pos; + size_t newsize; int ret; assert(pb && oid); @@ -203,7 +204,14 @@ int git_packbuilder_insert(git_packbuilder *pb, const git_oid *oid, if (pb->nr_objects >= pb->nr_alloc) { GITERR_CHECK_ALLOC_ADD(pb->nr_alloc, 1024); GITERR_CHECK_ALLOC_MULTIPLY(pb->nr_alloc + 1024, 3 / 2); - pb->nr_alloc = (pb->nr_alloc + 1024) * 3 / 2; + newsize = (pb->nr_alloc + 1024) * 3 / 2; + + if (!git__is_uint32(newsize)) { + giterr_set(GITERR_NOMEMORY, "Packfile too large to fit in memory."); + return -1; + } + + pb->nr_alloc = (uint32_t)newsize; pb->object_list = git__reallocarray(pb->object_list, pb->nr_alloc, sizeof(*po)); diff --git a/src/transports/smart_pkt.c b/src/transports/smart_pkt.c index ad81ad1b0..11c6215ff 100644 --- a/src/transports/smart_pkt.c +++ b/src/transports/smart_pkt.c @@ -484,7 +484,7 @@ static int buffer_want_with_caps(const git_remote_head *head, transport_smart_ca { git_buf str = GIT_BUF_INIT; char oid[GIT_OID_HEXSZ +1] = {0}; - unsigned int len; + size_t len; /* Prefer multi_ack_detailed */ if (caps->multi_ack_detailed) @@ -510,12 +510,19 @@ static int buffer_want_with_caps(const git_remote_head *head, transport_smart_ca if (git_buf_oom(&str)) return -1; - len = (unsigned int) - (strlen("XXXXwant ") + GIT_OID_HEXSZ + 1 /* NUL */ + - git_buf_len(&str) + 1 /* LF */); + len = strlen("XXXXwant ") + GIT_OID_HEXSZ + 1 /* NUL */ + + git_buf_len(&str) + 1 /* LF */; + + if (len > 0xffff) { + giterr_set(GITERR_NET, + "Tried to produce packet with invalid length %d", len); + return -1; + } + git_buf_grow_by(buf, len); git_oid_fmt(oid, &head->oid); - git_buf_printf(buf, "%04xwant %s %s\n", len, oid, git_buf_cstr(&str)); + git_buf_printf(buf, + "%04xwant %s %s\n", (unsigned int)len, oid, git_buf_cstr(&str)); git_buf_free(&str); return git_buf_oom(buf); |