From 24f099951c3a86f04a29adc7b0dda474a3c44722 Mon Sep 17 00:00:00 2001 From: Nils Philippsen Date: Wed, 25 Sep 2013 15:04:43 +0200 Subject: [PATCH] CVE-2013-1438: fix various security issues This fixes division by zero, infinite loop, and null pointer dereference bugs. Ported from Alex Tutubalin's fix in LibRaw (commit 9ae25d8c3a6bfb40c582538193264f74c9b93bc0). --- dcraw.c | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/dcraw.c b/dcraw.c index 96e3d1f..dcf284c 100644 --- a/dcraw.c +++ b/dcraw.c @@ -828,6 +828,9 @@ int CLASS ljpeg_diff (ushort *huff) { int len, diff; + if (!huff) + longjmp(failure, 2); + len = gethuff(huff); if (len == 16 && (!dng_version || dng_version >= 0x1010000)) return -32768; @@ -883,6 +886,8 @@ void CLASS lossless_jpeg_load_raw() ushort *rp; if (!ljpeg_start (&jh, 0)) return; + if (jh.wide < 1 || jh.high < 1 || jh.clrs < 1 || jh.bits < 1) + longjmp (failure, 2); jwide = jh.wide * jh.clrs; for (jrow=0; jrow < jh.high; jrow++) { @@ -902,6 +907,8 @@ void CLASS lossless_jpeg_load_raw() } if (raw_width == 3984 && (col -= 2) < 0) col += (row--,raw_width); + if (row > raw_height) + longjmp (failure, 3); if ((unsigned) row < raw_height) RAW(row,col) = val; if (++col >= raw_width) col = (row++,0); @@ -5444,6 +5451,7 @@ int CLASS parse_tiff_ifd (int base) data_offset = get4()+base; ifd++; break; } + if(len > 1000) len=1000; /* 1000 SubIFDs is enough */ while (len--) { i = ftell(ifp); fseek (ifp, get4()+base, SEEK_SET); @@ -5662,7 +5670,7 @@ guess_cfa_pc: break; case 50715: /* BlackLevelDeltaH */ case 50716: /* BlackLevelDeltaV */ - for (num=i=0; i < len; i++) + for (num=i=0; i < len && i < 65536; i++) num += getreal(type); black += num/len + 0.5; break; @@ -5787,9 +5795,13 @@ void CLASS apply_tiff() if (thumb_offset) { fseek (ifp, thumb_offset, SEEK_SET); if (ljpeg_start (&jh, 1)) { - thumb_misc = jh.bits; - thumb_width = jh.wide; - thumb_height = jh.high; + if ((unsigned)jh.bits < 17 && (unsigned)jh.wide < 0x10000 && + (unsigned)jh.high < 0x10000) + { + thumb_misc = jh.bits; + thumb_width = jh.wide; + thumb_height = jh.high; + } } } for (i=0; i < tiff_nifds; i++) { @@ -5797,8 +5809,9 @@ void CLASS apply_tiff() max_samp = tiff_ifd[i].samples; if (max_samp > 3) max_samp = 3; if ((tiff_ifd[i].comp != 6 || tiff_ifd[i].samples != 3) && - (tiff_ifd[i].width | tiff_ifd[i].height) < 0x10000 && - tiff_ifd[i].width*tiff_ifd[i].height > raw_width*raw_height) { + (tiff_ifd[i].width | tiff_ifd[i].height) < 0x10000 && + (unsigned)tiff_ifd[i].bps < 33 && (unsigned)tiff_ifd[i].samples < 13 && + tiff_ifd[i].width*tiff_ifd[i].height > raw_width*raw_height) { raw_width = tiff_ifd[i].width; raw_height = tiff_ifd[i].height; tiff_bps = tiff_ifd[i].bps; @@ -5884,9 +5897,11 @@ void CLASS apply_tiff() is_raw = 0; for (i=0; i < tiff_nifds; i++) if (i != raw && tiff_ifd[i].samples == max_samp && - tiff_ifd[i].width * tiff_ifd[i].height / (SQR(tiff_ifd[i].bps)+1) > - thumb_width * thumb_height / (SQR(thumb_misc)+1) - && tiff_ifd[i].comp != 34892) { + tiff_ifd[i].bps > 0 && tiff_ifd[i].bps < 33 && + ((unsigned)(tiff_ifd[i].width | tiff_ifd[i].height)) < 0x10000 && + tiff_ifd[i].width * tiff_ifd[i].height / (SQR(tiff_ifd[i].bps)+1) > + thumb_width * thumb_height / (SQR(thumb_misc)+1) + && tiff_ifd[i].comp != 34892) { thumb_width = tiff_ifd[i].width; thumb_height = tiff_ifd[i].height; thumb_offset = tiff_ifd[i].offset; -- 1.8.4.2