diff options
author | Jeff Muizelaar <jmuizelaar@mozilla.com> | 2009-07-16 10:30:16 -0400 |
---|---|---|
committer | Jeff Muizelaar <jmuizelaar@mozilla.com> | 2009-09-21 12:20:04 -0400 |
commit | f8f9be616850855f6215b833da9dd718e8599c9e (patch) | |
tree | 583693194a00b70ea165f2b88d8458df6eb62d95 | |
parent | 8319a3961ab1e7c8d58a4874f55f1986f2615a39 (diff) |
Avoid integer overflow when checking buffer bounds
Found by Chris Evans
-rw-r--r-- | iccread.c | 14 |
1 files changed, 11 insertions, 3 deletions
@@ -80,7 +80,10 @@ static void invalid_source(struct mem_source *mem, const char *reason) static uint32_t read_u32(struct mem_source *mem, size_t offset) { - if (offset + 4 > mem->size) { + /* Subtract from mem->size instead of the more intuitive adding to offset. + * This avoids overflowing offset. The subtraction is safe because + * mem->size is guaranteed to be > 4 */ + if (offset > mem->size - 4) { invalid_source(mem, "Invalid offset"); return 0; } else { @@ -90,7 +93,7 @@ static uint32_t read_u32(struct mem_source *mem, size_t offset) static uint16_t read_u16(struct mem_source *mem, size_t offset) { - if (offset + 2 > mem->size) { + if (offset > mem->size - 2) { invalid_source(mem, "Invalid offset"); return 0; } else { @@ -100,7 +103,7 @@ static uint16_t read_u16(struct mem_source *mem, size_t offset) static uint8_t read_u8(struct mem_source *mem, size_t offset) { - if (offset + 1 > mem->size) { + if (offset > mem->size - 1) { invalid_source(mem, "Invalid offset"); return 0; } else { @@ -668,6 +671,7 @@ qcms_profile* qcms_profile_from_memory(const void *mem, size_t size) source.buf = mem; source.size = size; source.valid = true; + length = read_u32(src, 0); if (length <= size) { // shrink the area that we can read if appropriate @@ -676,6 +680,10 @@ qcms_profile* qcms_profile_from_memory(const void *mem, size_t size) return INVALID_PROFILE; } + /* ensure that the profile size is sane so it's easier to reason about */ + if (source.size <= 64 || source.size >= MAX_PROFILE_SIZE) + return INVALID_PROFILE; + profile = qcms_profile_create(); if (!profile) return NO_MEM_PROFILE; |