Commit 336503dfd73d0370b3c90f12582d86d832ddedc1

Werner Lemberg 2023-07-16T07:36:01

[woff2] Avoid allocation bomb. This is a fix for commit 85167dbd5, reported as https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60615 * src/sfnt/sfwoff2.c (MAX_SFNT_SIZE): New macro. (woff2_open_font): Use it to limit the maximum size of an uncompressed WOFF2 font.

diff --git a/src/sfnt/sfwoff2.c b/src/sfnt/sfwoff2.c
index fecae27..7dec540 100644
--- a/src/sfnt/sfwoff2.c
+++ b/src/sfnt/sfwoff2.c
@@ -36,6 +36,8 @@
 #undef  FT_COMPONENT
 #define FT_COMPONENT  sfwoff2
 
+  /* An arbitrary, heuristic size limit (67MByte) for expanded WOFF2 data. */
+#define MAX_SFNT_SIZE  ( 1 << 26 )
 
 #define READ_255USHORT( var )  FT_SET_ERROR( Read255UShort( stream, &var ) )
 
@@ -2180,9 +2182,8 @@
       else
         sfnt_size = woff2.totalSfntSize;
 
-      /* Value 1<<26 = 67108864 is heuristic. */
-      if (sfnt_size >= (1 << 26))
-        sfnt_size = 1 << 26;
+      if ( sfnt_size >= MAX_SFNT_SIZE )
+        sfnt_size = MAX_SFNT_SIZE;
 
 #ifdef FT_DEBUG_LEVEL_TRACE
       if ( sfnt_size != woff2.totalSfntSize )
@@ -2257,6 +2258,17 @@
       goto Exit;
     }
 
+    /* We must not blindly trust `uncompressed_size` since its   */
+    /* value might be corrupted.  If it is too large, reject the */
+    /* font.  In other words, we don't accept a WOFF2 font that  */
+    /* expands to something larger than MAX_SFNT_SIZE.  If ever  */
+    /* necessary, this limit can be easily adjusted.             */
+    if ( woff2.uncompressed_size > MAX_SFNT_SIZE )
+    {
+      FT_ERROR(( "Uncompressed font too large.\n" ));
+      return FT_THROW( Array_Too_Large );
+    }
+
     /* Allocate memory for uncompressed table data. */
     if ( FT_QALLOC( uncompressed_buf, woff2.uncompressed_size ) ||
          FT_FRAME_ENTER( woff2.totalCompressedSize )            )