summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Nazarov <skuller@skuller.net>2012-08-19 17:58:02 +0400
committerAndrey Nazarov <skuller@skuller.net>2012-08-19 17:58:02 +0400
commit65b76b01749e9a56e74e641167f2b0df980aa2e2 (patch)
tree9dfe20dd6bb4a6b9d13f9ded78131dc333633cac
parentdad50a933a693cd9701c283f2275b212a4b5e27c (diff)
Protect hunk functions against integer overflow.
-rw-r--r--src/unix/hunk.c23
-rw-r--r--src/windows/hunk.c15
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;
}