From cbcfe72399fe7495d7fd392d147146a5bcc2800c Mon Sep 17 00:00:00 2001 From: Nils Philippsen Date: Fri, 6 Dec 2013 18:43:25 +0100 Subject: [PATCH] harden against corrupt input files (CVE-2013-1438) --- dcraw-9.19-CVE-2013-1438.patch | 108 +++++++++++++++++++++++++++++++++ dcraw.spec | 7 ++- 2 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 dcraw-9.19-CVE-2013-1438.patch diff --git a/dcraw-9.19-CVE-2013-1438.patch b/dcraw-9.19-CVE-2013-1438.patch new file mode 100644 index 0000000..96fa150 --- /dev/null +++ b/dcraw-9.19-CVE-2013-1438.patch @@ -0,0 +1,108 @@ +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 + diff --git a/dcraw.spec b/dcraw.spec index 69d69b5..651cb36 100644 --- a/dcraw.spec +++ b/dcraw.spec @@ -1,12 +1,13 @@ Summary: Tool for decoding raw image data from digital cameras Name: dcraw Version: 9.19 -Release: 3%{?dist} +Release: 4%{?dist} Group: Applications/Multimedia License: GPLv2+ URL: http://cybercom.net/~dcoffin/dcraw Source0: http://cybercom.net/~dcoffin/dcraw/archive/dcraw-%{version}.tar.gz Patch0: dcraw-9.19-lcms2.patch +Patch1: dcraw-9.19-CVE-2013-1438.patch BuildRequires: gettext BuildRequires: libjpeg-devel BuildRequires: lcms2-devel @@ -20,6 +21,7 @@ downloaded from digital cameras. %prep %setup -q -n dcraw %patch0 -p1 -b .lcms2 +%patch1 -p1 -b .CVE-2013-1438 %build gcc %optflags \ @@ -71,6 +73,9 @@ rm -rf %buildroot %{_mandir}/man1/* %changelog +* Fri Dec 06 2013 Nils Philippsen - 9.19-4 +- harden against corrupt input files (CVE-2013-1438) + * Fri Sep 13 2013 Nils Philippsen - 9.19-3 - build against the currently maintained version of lcms (2.x)