From 15ffda3bcd697e6f3a0cc13e141da865f36f3b53 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 11 Nov 2020 16:14:09 +1100 Subject: Fix T82602: checking image header reads past buffer bounds Use the size argument to ensure checking the header doesn't read past the buffer bounds when reading corrupt/truncated headers from image files. --- source/blender/imbuf/intern/cineon/cineon_dpx.c | 8 +++---- source/blender/imbuf/intern/cineon/logImageCore.c | 26 +++++++++++++++-------- source/blender/imbuf/intern/cineon/logImageCore.h | 4 ++-- 3 files changed, 23 insertions(+), 15 deletions(-) (limited to 'source/blender/imbuf/intern/cineon') diff --git a/source/blender/imbuf/intern/cineon/cineon_dpx.c b/source/blender/imbuf/intern/cineon/cineon_dpx.c index 8bbd9fbb285..de54e6dab9d 100644 --- a/source/blender/imbuf/intern/cineon/cineon_dpx.c +++ b/source/blender/imbuf/intern/cineon/cineon_dpx.c @@ -188,9 +188,9 @@ bool imb_save_cineon(struct ImBuf *buf, const char *filepath, int flags) return imb_save_dpx_cineon(buf, filepath, 1, flags); } -bool imb_is_a_cineon(const unsigned char *buf, size_t UNUSED(size)) +bool imb_is_a_cineon(const unsigned char *buf, size_t size) { - return logImageIsCineon(buf); + return logImageIsCineon(buf, size); } ImBuf *imb_load_cineon(const unsigned char *mem, @@ -209,9 +209,9 @@ bool imb_save_dpx(struct ImBuf *buf, const char *filepath, int flags) return imb_save_dpx_cineon(buf, filepath, 0, flags); } -bool imb_is_a_dpx(const unsigned char *buf, size_t UNUSED(size)) +bool imb_is_a_dpx(const unsigned char *buf, size_t size) { - return logImageIsDpx(buf); + return logImageIsDpx(buf, size); } ImBuf *imb_load_dpx(const unsigned char *mem, diff --git a/source/blender/imbuf/intern/cineon/logImageCore.c b/source/blender/imbuf/intern/cineon/logImageCore.c index d5f5691c5f0..2d42609fdf5 100644 --- a/source/blender/imbuf/intern/cineon/logImageCore.c +++ b/source/blender/imbuf/intern/cineon/logImageCore.c @@ -96,15 +96,23 @@ void logImageSetVerbose(int verbosity) * IO stuff */ -int logImageIsDpx(const void *buffer) +int logImageIsDpx(const void *buffer, const unsigned int size) { - unsigned int magicNum = *(unsigned int *)buffer; + unsigned int magicNum; + if (size < sizeof(magicNum)) { + return 0; + } + magicNum = *(unsigned int *)buffer; return (magicNum == DPX_FILE_MAGIC || magicNum == swap_uint(DPX_FILE_MAGIC, 1)); } -int logImageIsCineon(const void *buffer) +int logImageIsCineon(const void *buffer, const unsigned int size) { - unsigned int magicNum = *(unsigned int *)buffer; + unsigned int magicNum; + if (size < sizeof(magicNum)) { + return 0; + } + magicNum = *(unsigned int *)buffer; return (magicNum == CINEON_FILE_MAGIC || magicNum == swap_uint(CINEON_FILE_MAGIC, 1)); } @@ -119,17 +127,17 @@ LogImageFile *logImageOpenFromFile(const char *filename, int cineon) return NULL; } - if (fread(&magicNum, sizeof(unsigned int), 1, f) != 1) { + if (fread(&magicNum, sizeof(magicNum), 1, f) != 1) { fclose(f); return NULL; } fclose(f); - if (logImageIsDpx(&magicNum)) { + if (logImageIsDpx(&magicNum, sizeof(magicNum))) { return dpxOpen((const unsigned char *)filename, 0, 0); } - if (logImageIsCineon(&magicNum)) { + if (logImageIsCineon(&magicNum, sizeof(magicNum))) { return cineonOpen((const unsigned char *)filename, 0, 0); } @@ -138,10 +146,10 @@ LogImageFile *logImageOpenFromFile(const char *filename, int cineon) LogImageFile *logImageOpenFromMemory(const unsigned char *buffer, unsigned int size) { - if (logImageIsDpx(buffer)) { + if (logImageIsDpx(buffer, size)) { return dpxOpen(buffer, 1, size); } - if (logImageIsCineon(buffer)) { + if (logImageIsCineon(buffer, size)) { return cineonOpen(buffer, 1, size); } diff --git a/source/blender/imbuf/intern/cineon/logImageCore.h b/source/blender/imbuf/intern/cineon/logImageCore.h index a2d50f21a98..c2704a086b6 100644 --- a/source/blender/imbuf/intern/cineon/logImageCore.h +++ b/source/blender/imbuf/intern/cineon/logImageCore.h @@ -181,8 +181,8 @@ enum descriptor { /* int functions return 0 for OK */ void logImageSetVerbose(int verbosity); -int logImageIsDpx(const void *buffer); -int logImageIsCineon(const void *buffer); +int logImageIsDpx(const void *buffer, unsigned int size); +int logImageIsCineon(const void *buffer, unsigned int size); LogImageFile *logImageOpenFromMemory(const unsigned char *buffer, unsigned int size); LogImageFile *logImageOpenFromFile(const char *filename, int cineon); void logImageGetSize(LogImageFile *logImage, int *width, int *height, int *depth); -- cgit v1.2.3