diff options
author | Andrey Nazarov <skuller@skuller.net> | 2012-08-19 17:58:02 +0400 |
---|---|---|
committer | Andrey Nazarov <skuller@skuller.net> | 2012-08-19 17:58:02 +0400 |
commit | 65b76b01749e9a56e74e641167f2b0df980aa2e2 (patch) | |
tree | 9dfe20dd6bb4a6b9d13f9ded78131dc333633cac | |
parent | dad50a933a693cd9701c283f2275b212a4b5e27c (diff) |
Protect hunk functions against integer overflow.
-rw-r--r-- | src/unix/hunk.c | 23 | ||||
-rw-r--r-- | src/windows/hunk.c | 15 |
2 files changed, 31 insertions, 7 deletions
diff --git a/src/unix/hunk.c b/src/unix/hunk.c index ebd0d20..f88da34 100644 --- a/src/unix/hunk.c +++ b/src/unix/hunk.c @@ -25,6 +25,9 @@ void Hunk_Begin(memhunk_t *hunk, size_t maxsize) { void *buf; + if (maxsize > SIZE_MAX - 4095) + Com_Error(ERR_FATAL, "%s: size > SIZE_MAX", __func__); + // reserve a huge chunk of memory, but don't commit any yet hunk->cursize = 0; hunk->maxsize = (maxsize + 4095) & ~4095; @@ -41,12 +44,17 @@ void *Hunk_Alloc(memhunk_t *hunk, size_t size) { void *buf; + if (size > SIZE_MAX - 63) + Com_Error(ERR_FATAL, "%s: size > SIZE_MAX", __func__); + // round to cacheline size = (size + 63) & ~63; - if (hunk->cursize + size > hunk->maxsize) - Com_Error(ERR_FATAL, "%s: unable to allocate %"PRIz" bytes out of %"PRIz, - __func__, size, hunk->maxsize); + if (hunk->cursize > hunk->maxsize) + Com_Error(ERR_FATAL, "%s: cursize > maxsize", __func__); + + if (size > hunk->maxsize - hunk->cursize) + Com_Error(ERR_FATAL, "%s: couldn't allocate %"PRIz" bytes", __func__, size); buf = (byte *)hunk->base + hunk->cursize; hunk->cursize += size; @@ -55,10 +63,12 @@ void *Hunk_Alloc(memhunk_t *hunk, size_t size) void Hunk_End(memhunk_t *hunk) { - size_t newsize = (hunk->cursize + 4095) & ~4095; + size_t newsize; - if (newsize > hunk->maxsize) - Com_Error(ERR_FATAL, "%s: newsize > maxsize", __func__); + if (hunk->cursize > hunk->maxsize) + Com_Error(ERR_FATAL, "%s: cursize > maxsize", __func__); + + newsize = (hunk->cursize + 4095) & ~4095; if (newsize < hunk->maxsize) { #ifdef _GNU_SOURCE @@ -72,6 +82,7 @@ void Hunk_End(memhunk_t *hunk) Com_Error(ERR_FATAL, "%s: could not remap virtual block: %s", __func__, strerror(errno)); } + hunk->mapped = newsize; } diff --git a/src/windows/hunk.c b/src/windows/hunk.c index 24829b9..3002e0d 100644 --- a/src/windows/hunk.c +++ b/src/windows/hunk.c @@ -22,6 +22,9 @@ with this program; if not, write to the Free Software Foundation, Inc., void Hunk_Begin(memhunk_t *hunk, size_t maxsize) { + if (maxsize > SIZE_MAX - 4095) + Com_Error(ERR_FATAL, "%s: size > SIZE_MAX", __func__); + // reserve a huge chunk of memory, but don't commit any yet hunk->cursize = 0; hunk->maxsize = (maxsize + 4095) & ~4095; @@ -36,13 +39,20 @@ void *Hunk_Alloc(memhunk_t *hunk, size_t size) { void *buf; + if (size > SIZE_MAX - 63) + Com_Error(ERR_FATAL, "%s: size > SIZE_MAX", __func__); + // round to cacheline size = (size + 63) & ~63; - hunk->cursize += size; if (hunk->cursize > hunk->maxsize) + Com_Error(ERR_FATAL, "%s: cursize > maxsize", __func__); + + if (size > hunk->maxsize - hunk->cursize) Com_Error(ERR_FATAL, "%s: couldn't allocate %"PRIz" bytes", __func__, size); + hunk->cursize += size; + // commit pages as needed buf = VirtualAlloc(hunk->base, hunk->cursize, MEM_COMMIT, PAGE_READWRITE); if (!buf) @@ -55,6 +65,9 @@ void *Hunk_Alloc(memhunk_t *hunk, size_t size) void Hunk_End(memhunk_t *hunk) { + if (hunk->cursize > hunk->maxsize) + Com_Error(ERR_FATAL, "%s: cursize > maxsize", __func__); + // for statistics hunk->mapped = (hunk->cursize + 4095) & ~4095; } |