diff --git a/libraw/libraw_const.h b/libraw/libraw_const.h index aaeba8b1..9327d87a 100644 --- a/libraw/libraw_const.h +++ b/libraw/libraw_const.h @@ -20,7 +20,14 @@ it under the terms of the one of two licenses as you choose: #define LIBRAW_DEFAULT_ADJUST_MAXIMUM_THRESHOLD 0.75 #define LIBRAW_DEFAULT_AUTO_BRIGHTNESS_THRESHOLD 0.01 /* limit allocation size, default is 2Gb */ +#ifndef LIBRAW_MAX_ALLOC_MB_DEFAULT #define LIBRAW_MAX_ALLOC_MB_DEFAULT 2048L +#endif + +/* limit thumbnail size, default is 512Mb*/ +#ifndef LIBRAW_MAX_THUMBNAIL_MB +#define LIBRAW_MAX_THUMBNAIL_MB 512L +#endif /* Check if enough file space exists before tag read */ #ifndef LIBRAW_NO_IOSPACE_CHECK diff --git a/src/decoders/unpack_thumb.cpp b/src/decoders/unpack_thumb.cpp index fa4e2bfc..24ccff3e 100644 --- a/src/decoders/unpack_thumb.cpp +++ b/src/decoders/unpack_thumb.cpp @@ -33,6 +33,25 @@ int LibRaw::unpack_thumb(void) CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY); CHECK_ORDER_BIT(LIBRAW_PROGRESS_THUMB_LOAD); +#define THUMB_SIZE_CHECKT(A) \ + do { \ + if (INT64(A) > 1024ULL * 1024ULL * LIBRAW_MAX_THUMBNAIL_MB) throw LIBRAW_EXCEPTION_IO_CORRUPT; \ + if (INT64(A) > 0 && INT64(A) < 64ULL) throw LIBRAW_EXCEPTION_IO_CORRUPT; \ + } while (0) + +#define THUMB_SIZE_CHECKTNZ(A) \ + do { \ + if (INT64(A) > 1024ULL * 1024ULL * LIBRAW_MAX_THUMBNAIL_MB) throw LIBRAW_EXCEPTION_IO_CORRUPT; \ + if (INT64(A) < 64ULL) throw LIBRAW_EXCEPTION_IO_CORRUPT; \ + } while (0) + + +#define THUMB_SIZE_CHECKWH(W,H) \ + do { \ + if (INT64(W)*INT64(H) > 1024ULL * 1024ULL * LIBRAW_MAX_THUMBNAIL_MB) throw LIBRAW_EXCEPTION_IO_CORRUPT; \ + if (INT64(W)*INT64(H) < 64ULL) throw LIBRAW_EXCEPTION_IO_CORRUPT; \ + } while (0) + try { if (!libraw_internal_data.internal_data.input) @@ -65,6 +84,7 @@ int LibRaw::unpack_thumb(void) if (INT64(ID.toffset) + tsize > ID.input->size() + THUMB_READ_BEYOND) throw LIBRAW_EXCEPTION_IO_EOF; + THUMB_SIZE_CHECKT(tsize); } #else if (0) {} @@ -82,6 +102,8 @@ int LibRaw::unpack_thumb(void) ID.input->seek(ID.toffset, SEEK_SET); if (write_thumb == &LibRaw::jpeg_thumb) { + THUMB_SIZE_CHECKTNZ(T.tlength); + if (T.thumb) free(T.thumb); T.thumb = (char *)malloc(T.tlength); @@ -132,6 +154,8 @@ int LibRaw::unpack_thumb(void) if (colors != 1 && colors != 3) return LIBRAW_UNSUPPORTED_THUMBNAIL; + THUMB_SIZE_CHECKWH(T.twidth, T.theight); + int tlength = T.twidth * T.theight; if (T.thumb) free(T.thumb); @@ -172,6 +196,7 @@ int LibRaw::unpack_thumb(void) else if (write_thumb == &LibRaw::rollei_thumb) { int i; + THUMB_SIZE_CHECKWH(T.twidth, T.theight); int tlength = T.twidth * T.theight; if (T.thumb) free(T.thumb); @@ -198,6 +223,7 @@ int LibRaw::unpack_thumb(void) if (t_bytesps > 1) throw LIBRAW_EXCEPTION_IO_CORRUPT; // 8-bit thumb, but parsed for more // bits + THUMB_SIZE_CHECKWH(T.twidth, T.theight); int t_length = T.twidth * T.theight * t_colors; if (T.tlength && @@ -219,6 +245,7 @@ int LibRaw::unpack_thumb(void) T.tcolors = 1; } T.tlength = total_size; + THUMB_SIZE_CHECKTNZ(T.tlength); if (T.thumb) free(T.thumb); T.thumb = (char *)malloc(T.tlength); @@ -254,6 +281,8 @@ int LibRaw::unpack_thumb(void) if (T.thumb) free(T.thumb); + THUMB_SIZE_CHECKTNZ(T.tlength); + T.thumb = (char *)malloc(T.tlength); if (!T.tcolors) T.tcolors = t_colors; @@ -278,6 +307,10 @@ int LibRaw::unpack_thumb(void) int i_length = T.twidth * T.theight * t_colors * 2; if (!T.tlength) T.tlength = o_length; + THUMB_SIZE_CHECKTNZ(o_length); + THUMB_SIZE_CHECKTNZ(i_length); + THUMB_SIZE_CHECKTNZ(T.tlength); + ushort *t_thumb = (ushort *)calloc(i_length, 1); ID.input->read(t_thumb, 1, i_length); if ((libraw_internal_data.unpacker_data.order == 0x4949) == diff --git a/src/postprocessing/mem_image.cpp b/src/postprocessing/mem_image.cpp index e79c9217..4d2a8781 100644 --- a/src/postprocessing/mem_image.cpp +++ b/src/postprocessing/mem_image.cpp @@ -33,6 +33,20 @@ libraw_processed_image_t *LibRaw::dcraw_make_mem_thumb(int *errcode) return NULL; } + if (T.tlength < 64u) + { + if (errcode) + *errcode = EINVAL; + return NULL; + } + + if (INT64(T.tlength) > 1024ULL * 1024ULL * LIBRAW_MAX_THUMBNAIL_MB) + { + if (errcode) + *errcode = LIBRAW_TOO_BIG; + return NULL; + } + if (T.tformat == LIBRAW_THUMBNAIL_BITMAP) { libraw_processed_image_t *ret = (libraw_processed_image_t *)::malloc( diff --git a/src/utils/thumb_utils.cpp b/src/utils/thumb_utils.cpp index bf6d9bc5..418ba2de 100644 --- a/src/utils/thumb_utils.cpp +++ b/src/utils/thumb_utils.cpp @@ -25,6 +25,12 @@ void LibRaw::kodak_thumb_loader() if (ID.toffset + est_datasize > ID.input->size() + THUMB_READ_BEYOND) throw LIBRAW_EXCEPTION_IO_EOF; + if(INT64(T.theight) * INT64(T.twidth) > 1024ULL * 1024ULL * LIBRAW_MAX_THUMBNAIL_MB) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + + if (INT64(T.theight) * INT64(T.twidth) < 64ULL) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + // some kodak cameras ushort s_height = S.height, s_width = S.width, s_iwidth = S.iwidth, s_iheight = S.iheight;