[dcraw] harden against corrupt input files (CVE-2013-1438)
Nils Philippsen
nphilipp at fedoraproject.org
Fri Dec 6 17:43:45 UTC 2013
commit cbcfe72399fe7495d7fd392d147146a5bcc2800c
Author: Nils Philippsen <nils at redhat.com>
Date: Fri Dec 6 18:43:25 2013 +0100
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 deletions(-)
---
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 <nils at redhat.com>
+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 <nils at redhat.com> - 9.19-4
+- harden against corrupt input files (CVE-2013-1438)
+
* Fri Sep 13 2013 Nils Philippsen <nils at redhat.com> - 9.19-3
- build against the currently maintained version of lcms (2.x)
More information about the scm-commits
mailing list