Limit how much work sanitize() can do
authorBehdad Esfahbod <behdad@behdad.org>
Mon, 19 Feb 2018 01:28:53 +0000 (17:28 -0800)
committerBehdad Esfahbod <behdad@behdad.org>
Mon, 19 Feb 2018 01:28:53 +0000 (17:28 -0800)
Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=6022

src/Makefile.am
src/hb-open-type-private.hh
test/shaping/data/in-house/fonts/233c1e252e737ca79e03a9fd56b71aaa4a230f2b.ttf [new file with mode: 0644]
test/shaping/data/in-house/tests/fuzzed.tests

index e3915bc..161bdcb 100644 (file)
@@ -170,6 +170,8 @@ FUZZING_CPPFLAGS = \
        -DHB_NDEBUG \
        -DHB_MAX_NESTING_LEVEL=3 \
        -DHB_SANITIZE_MAX_EDITS=3 \
+       -DHB_SANITIZE_MAX_OPS_FACTOR=3 \
+       -DHB_SANITIZE_MAX_OPS_MIN=128 \
        -DHB_BUFFER_MAX_LEN_FACTOR=3 \
        -DHB_BUFFER_MAX_LEN_MIN=8 \
        -DHB_BUFFER_MAX_LEN_DEFAULT=128 \
index 5263d6f..080dcca 100644 (file)
@@ -189,6 +189,12 @@ struct hb_dispatch_context_t
 #ifndef HB_SANITIZE_MAX_EDITS
 #define HB_SANITIZE_MAX_EDITS 32
 #endif
+#ifndef HB_SANITIZE_MAX_OPS_FACTOR
+#define HB_SANITIZE_MAX_OPS_FACTOR 8
+#endif
+#ifndef HB_SANITIZE_MAX_OPS_MIN
+#define HB_SANITIZE_MAX_OPS_MIN 16384
+#endif
 
 struct hb_sanitize_context_t :
        hb_dispatch_context_t<hb_sanitize_context_t, bool, HB_DEBUG_SANITIZE>
@@ -196,7 +202,7 @@ struct hb_sanitize_context_t :
   inline hb_sanitize_context_t (void) :
        debug_depth (0),
        start (nullptr), end (nullptr),
-       writable (false), edit_count (0),
+       writable (false), edit_count (0), max_ops (0),
        blob (nullptr),
        num_glyphs (0) {}
 
@@ -221,6 +227,8 @@ struct hb_sanitize_context_t :
     this->start = hb_blob_get_data (this->blob, nullptr);
     this->end = this->start + hb_blob_get_length (this->blob);
     assert (this->start <= this->end); /* Must not overflow. */
+    this->max_ops = MAX ((unsigned int) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR,
+                        (unsigned) HB_SANITIZE_MAX_OPS_MIN);
     this->edit_count = 0;
     this->debug_depth = 0;
 
@@ -244,7 +252,10 @@ struct hb_sanitize_context_t :
   inline bool check_range (const void *base, unsigned int len) const
   {
     const char *p = (const char *) base;
-    bool ok = this->start <= p && p <= this->end && (unsigned int) (this->end - p) >= len;
+    bool ok = this->max_ops-- > 0 &&
+             this->start <= p &&
+             p <= this->end &&
+             (unsigned int) (this->end - p) >= len;
 
     DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
        "check_range [%p..%p] (%d bytes) in [%p..%p] -> %s",
@@ -308,6 +319,7 @@ struct hb_sanitize_context_t :
   const char *start, *end;
   bool writable;
   unsigned int edit_count;
+  mutable int max_ops;
   hb_blob_t *blob;
   unsigned int num_glyphs;
 };
diff --git a/test/shaping/data/in-house/fonts/233c1e252e737ca79e03a9fd56b71aaa4a230f2b.ttf b/test/shaping/data/in-house/fonts/233c1e252e737ca79e03a9fd56b71aaa4a230f2b.ttf
new file mode 100644 (file)
index 0000000..999f296
Binary files /dev/null and b/test/shaping/data/in-house/fonts/233c1e252e737ca79e03a9fd56b71aaa4a230f2b.ttf differ
index e1a39e4..43a1933 100644 (file)
@@ -20,3 +20,4 @@
 ../fonts/ef2511f215aa3ca847cbfffbf861793b42170875.ttf:--font-funcs=ot:U+0041:[gid0=0+1000]
 ../fonts/9d8a94a67932a3ab75a596fc8b5c6d0392ca9e49.ttf:--font-funcs=ot:U+0041:[gid0=0+1000]
 ../fonts/bbf4a308c402f0678c3e82844892a4da2ebe598f.ttf:--font-funcs=ot:U+0041:[gid0=0+1000]
+../fonts/233c1e252e737ca79e03a9fd56b71aaa4a230f2b.ttf:--font-funcs=ot:U+0041:[gid0=0+1000]