Skip to content

Commit

Permalink
Thumbnail size range check
Browse files Browse the repository at this point in the history
  • Loading branch information
alextutubalin committed Jun 22, 2020
1 parent 89f02a0 commit 20ad21c
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 0 deletions.
7 changes: 7 additions & 0 deletions libraw/libraw_const.h
Expand Up @@ -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
Expand Down
33 changes: 33 additions & 0 deletions src/decoders/unpack_thumb.cpp
Expand Up @@ -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)
Expand Down Expand Up @@ -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) {}
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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 &&
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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) ==
Expand Down
14 changes: 14 additions & 0 deletions src/postprocessing/mem_image.cpp
Expand Up @@ -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(
Expand Down
6 changes: 6 additions & 0 deletions src/utils/thumb_utils.cpp
Expand Up @@ -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;
Expand Down

0 comments on commit 20ad21c

Please sign in to comment.