[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Fixing CVE-2014-9674 (freetype) in wheezy



Dear security team,
while looking into CVEs that are fixed in Jessie and Squeeze but not yet
in Wheezy I came across:

    https://security-tracker.debian.org/tracker/CVE-2014-9674

Since the fix consists of several commits including a fix for
CVE-2014-9673 (which already was fixed in the package) I pushed
the repo I used to cp the fixes here:

    https://github.com/agx/freetype2/commits/debian/wheezy

I'm happy about any review and and the possibility to upload this to
security master.

Cheers,
 -- Guido
diff --git a/debian/changelog b/debian/changelog
index afe415c..f706b95 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,12 @@
+freetype (2.4.9-1.1+deb7u3) wheezy-security; urgency=medium
+
+  * Non-maintainer upload by LTS team.
+  * CVE-2014-9674: integer overflow and heap-based buffer overflow
+    in Mac_Read_POST_Resource.  The added patch also includes the fixes for
+    CVE-2014-9673 since they overlap. Closes: #777656
+
+ -- Guido Günther <agx@sigxcpu.org>  Sun, 24 Jan 2016 19:41:13 +0100
+
 freetype (2.4.9-1.1+deb7u2) wheezy-security; urgency=high
 
   * Non-maintainer upload.
diff --git a/debian/patches-freetype/CVE-2014-9673.patch b/debian/patches-freetype/CVE-2014-9673.patch
deleted file mode 100644
index 331f40f..0000000
--- a/debian/patches-freetype/CVE-2014-9673.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-diff -aur freetype-2.4.9.orig/src/base/ftobjs.c freetype-2.4.9/src/base/ftobjs.c
---- freetype-2.4.9.orig/src/base/ftobjs.c	2012-02-11 10:29:31.000000000 +0100
-+++ freetype-2.4.9/src/base/ftobjs.c	2015-02-19 11:27:54.271340093 +0100
-@@ -1588,6 +1588,11 @@
-         goto Exit2;
-       if ( FT_READ_LONG( rlen ) )
-         goto Exit;
-+      if ( rlen < 0 )
-+      {
-+        error = FT_Err_Invalid_Offset;
-+        goto Exit;
-+      }
-       if ( FT_READ_USHORT( flags ) )
-         goto Exit;
-       FT_TRACE3(( "POST fragment[%d]: offsets=0x%08x, rlen=0x%08x, flags=0x%04x\n",
-@@ -1605,7 +1610,14 @@
-         rlen = 0;
- 
-       if ( ( flags >> 8 ) == type )
-+      {
-+        if ( 0x7FFFFFFFL - rlen < len )
-+        {
-+          error = FT_Err_Array_Too_Large;
-+          goto Exit2;
-+        }
-         len += rlen;
-+      }
-       else
-       {
-         if ( pfb_lenpos + 3 > pfb_len + 2 )
-@@ -1634,6 +1646,11 @@
-       }
- 
-       error = FT_Err_Cannot_Open_Resource;
-+      if ( rlen > 0x7FFFFFFFL - pfb_pos )
-+      {
-+        error = FT_Err_Array_Too_Large;
-+        goto Exit2;
-+      }
-       if ( pfb_pos > pfb_len || pfb_pos + rlen > pfb_len )
-         goto Exit2;
- 
-Nur in freetype-2.4.9/src/base: ftobjs.c~.
diff --git a/debian/patches-freetype/CVE-2014-9674+CVE-2014-9673.diff b/debian/patches-freetype/CVE-2014-9674+CVE-2014-9673.diff
new file mode 100644
index 0000000..5de5b33
--- /dev/null
+++ b/debian/patches-freetype/CVE-2014-9674+CVE-2014-9673.diff
@@ -0,0 +1,205 @@
+commit c57ccea8fe7bbdc5194bf7f2bdaa3d84a788916c
+Author: Guido Günther <agx@sigxcpu.org>
+Date:   Sun Jan 24 12:13:04 2016 +0100
+
+    Don't use FT_ERR or FT_THROW
+
+commit 920aebcc8fa6ec5dfb1f9eca86598414e2363261
+Author: suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
+Date:   Thu Nov 27 00:20:48 2014 +0900
+
+    * src/base/ftobj.c (Mac_Read_POST_Resource): Additional
+    overflow check in the summation of POST fragment lengths,
+    suggested by Mateusz Jurczyk <mjurczyk@google.com>.
+    
+    (cherry picked from commit cd4a5a26e591d01494567df9dec7f72d59551f6e)
+
+commit 8b51acd483ff65159e0af508a2d47d8f2753ad28
+Author: suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
+Date:   Wed Nov 26 16:39:00 2014 +0900
+
+    * src/base/ftobjs.c (Mac_Read_POST_Resource): Insert comments
+    and fold too long tracing messages.
+    
+    (cherry picked from commit 1720e81e3ecc7c266e54fe40175cc39c47117bf5)
+
+commit 72e8e7cf2c4931bf31046f70db07feb4c89b72ef
+Author: suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
+Date:   Wed Nov 26 16:02:17 2014 +0900
+
+    * src/base/ftobjs.c (Mac_Read_POST_Resource): Use unsigned long
+    variables to read the lengths in POST fragments.  Suggested by
+    Mateusz Jurczyk <mjurczyk@google.com>.
+    
+    (cherry picked from commit 453316792fee912cfced48e9e270e9eb19892e64)
+
+commit f8f730dd9399d6ef5709c672a7b3fa531caececb
+Author: suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
+Date:   Wed Nov 26 15:52:23 2014 +0900
+
+    Fix Savannah bug #43539.
+    
+    * src/base/ftobjs.c (Mac_Read_POST_Resource): Fix integer overflow
+    by a broken POST table in resource-fork.
+    
+    (cherry picked from commit 35252ae9aa1dd9343e9f4884e9ddb1fee10ef415)
+
+commit 61e33db762b54188e83eb0ceedc32503abe50db3
+Author: suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
+Date:   Wed Nov 26 15:43:29 2014 +0900
+
+    Fix Savannah bug #43538.
+    
+    * src/base/ftobjs.c (Mac_Read_POST_Resource): Fix integer overflow
+    by a broken POST table in resource-fork.
+    
+    (cherry picked from commit 240c94a185cd8dae7d03059abec8a5662c35ecd3)
+
+commit ab20e2dc68cbcde838b25b0694e4610b0d9c8017
+Author: suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
+Date:   Wed Nov 26 14:36:12 2014 +0900
+
+    * src/base/ftobjs.c (Mac_Read_POST_Resource): Avoid memory leak
+    by a broken POST table in resource-fork.  Return after freeing
+    the buffered POST table when it is found to be broken.
+    
+    (cherry picked from commit 5aff85301bdce7677766fa1367c82ff41a739637)
+diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c
+index 36ee797..3025a97 100644
+--- a/src/base/ftobjs.c
++++ b/src/base/ftobjs.c
+@@ -1544,9 +1544,9 @@
+     FT_Memory  memory = library->memory;
+     FT_Byte*   pfb_data = NULL;
+     int        i, type, flags;
+-    FT_Long    len;
+-    FT_Long    pfb_len, pfb_pos, pfb_lenpos;
+-    FT_Long    rlen, temp;
++    FT_ULong   len;
++    FT_ULong   pfb_len, pfb_pos, pfb_lenpos;
++    FT_ULong   rlen, temp;
+ 
+ 
+     if ( face_index == -1 )
+@@ -1562,11 +1562,34 @@
+       error = FT_Stream_Seek( stream, offsets[i] );
+       if ( error )
+         goto Exit;
+-      if ( FT_READ_LONG( temp ) )
++      if ( FT_READ_ULONG( temp ) )
+         goto Exit;
++
++      /* FT2 allocator takes signed long buffer length,
++       * too large value causing overflow should be checked
++       */
++      FT_TRACE4(( "                 POST fragment #%d: length=0x%08x\n",
++                  i, temp));
++      if ( 0x7FFFFFFFUL < temp || pfb_len + temp + 6 < pfb_len )
++      {
++        FT_TRACE2(( "             too long fragment length makes"
++                    " pfb_len confused: temp=0x%08x\n", temp ));
++        error = FT_Err_Invalid_Offset;
++        goto Exit;
++      }
++
+       pfb_len += temp + 6;
+     }
+ 
++    FT_TRACE2(( "             total buffer size to concatenate %d"
++                " POST fragments: 0x%08x\n",
++                 resource_cnt, pfb_len + 2));
++    if ( pfb_len + 2 < 6 ) {
++      FT_TRACE2(( "             too long fragment length makes"
++                  " pfb_len confused: pfb_len=0x%08x\n", pfb_len ));
++      error = FT_Err_Array_Too_Large;
++      goto Exit;
++    }
+     if ( FT_ALLOC( pfb_data, (FT_Long)pfb_len + 2 ) )
+       goto Exit;
+ 
+@@ -1586,16 +1609,30 @@
+       error = FT_Stream_Seek( stream, offsets[i] );
+       if ( error )
+         goto Exit2;
+-      if ( FT_READ_LONG( rlen ) )
+-        goto Exit;
++      if ( FT_READ_ULONG( rlen ) )
++        goto Exit2;
++
++      /* FT2 allocator takes signed long buffer length,
++       * too large fragment length causing overflow should be checked
++       */
++      if ( 0x7FFFFFFFUL < rlen )
++      {
++        error = FT_Err_Invalid_Offset;
++        goto Exit2;
++      }
++
+       if ( FT_READ_USHORT( flags ) )
+-        goto Exit;
++        goto Exit2;
+       FT_TRACE3(( "POST fragment[%d]: offsets=0x%08x, rlen=0x%08x, flags=0x%04x\n",
+                    i, offsets[i], rlen, flags ));
+ 
++      error = FT_Err_Array_Too_Large;
+       /* postpone the check of rlen longer than buffer until FT_Stream_Read() */
+       if ( ( flags >> 8 ) == 0 )        /* Comment, should not be loaded */
++      {
++        FT_TRACE3(( "    Skip POST fragment #%d because it is a comment\n", i ));
+         continue;
++      }
+ 
+       /* the flags are part of the resource, so rlen >= 2.  */
+       /* but some fonts declare rlen = 0 for empty fragment */
+@@ -1608,6 +1645,8 @@
+         len += rlen;
+       else
+       {
++        FT_TRACE3(( "    Write POST fragment #%d header (4-byte) to buffer"
++                    " 0x%p + 0x%08x\n", i, pfb_data, pfb_lenpos ));
+         if ( pfb_lenpos + 3 > pfb_len + 2 )
+           goto Exit2;
+         pfb_data[pfb_lenpos    ] = (FT_Byte)( len );
+@@ -1618,6 +1657,8 @@
+         if ( ( flags >> 8 ) == 5 )      /* End of font mark */
+           break;
+ 
++        FT_TRACE3(( "    Write POST fragment #%d header (6-byte) to buffer"
++                    " 0x%p + 0x%08x\n", i, pfb_data, pfb_pos ));
+         if ( pfb_pos + 6 > pfb_len + 2 )
+           goto Exit2;
+         pfb_data[pfb_pos++] = 0x80;
+@@ -1633,16 +1674,18 @@
+         pfb_data[pfb_pos++] = 0;
+       }
+ 
+-      error = FT_Err_Cannot_Open_Resource;
+       if ( pfb_pos > pfb_len || pfb_pos + rlen > pfb_len )
+         goto Exit2;
+ 
++      FT_TRACE3(( "    Load POST fragment #%d (%d byte) to buffer"
++                  " 0x%p + 0x%08x\n", i, rlen, pfb_data, pfb_pos ));
+       error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen );
+       if ( error )
+         goto Exit2;
+       pfb_pos += rlen;
+     }
+ 
++    error = FT_Err_Array_Too_Large;
+     if ( pfb_pos + 2 > pfb_len + 2 )
+       goto Exit2;
+     pfb_data[pfb_pos++] = 0x80;
+@@ -1663,6 +1706,13 @@
+                                   aface );
+ 
+   Exit2:
++    if ( error == FT_Err_Array_Too_Large )
++      FT_TRACE2(( "  Abort due to too-short buffer to store"
++                  " all POST fragments\n" ));
++    else if ( error == FT_Err_Invalid_Offset )
++      FT_TRACE2(( "  Abort due to invalid offset in a POST fragment\n" ));
++    if ( error )
++      error = FT_Err_Cannot_Open_Resource;
+     FT_FREE( pfb_data );
+ 
+   Exit:
diff --git a/debian/patches-freetype/series b/debian/patches-freetype/series
index 0c0aafc..fa6ce8c 100644
--- a/debian/patches-freetype/series
+++ b/debian/patches-freetype/series
@@ -25,8 +25,8 @@ CVE-2014-9671-1.patch
 CVE-2014-9671-2.patch
 CVE-2014-9671-3.patch
 CVE-2014-9672.patch
-CVE-2014-9673.patch
 CVE-2014-9675-1.patch
 CVE-2014-9675-2.patch
 savannah-bug-41309.patch
 savannah-bug-41590.patch
+CVE-2014-9674+CVE-2014-9673.diff

Reply to: