Closed Bug 1672223 (CVE-2020-15999) Opened 11 months ago Closed 11 months ago

Heap buffer overflow due to integer truncation in FreeType

Categories

(Core :: Graphics: Text, defect)

defect

Tracking

()

RESOLVED FIXED
84 Branch
Tracking Status
firefox-esr78 83+ fixed
firefox81 --- wontfix
firefox82 - wontfix
firefox83 + fixed
firefox84 + fixed

People

(Reporter: dveditz, Assigned: RyanVM)

References

Details

(Keywords: csectype-bounds, sec-moderate, Whiteboard: [adv-main83+][adv-esr78.5+][disclosure date 2020-10-26] requires non-default pref)

Attachments

(3 files, 2 obsolete files)

Attached file crbug1139963.html

The Google Chrome team is fixing a heap buffer overflow in freetype. Although our library is called FreeType2 the affected code appears the same. I have not yet tested this in an ASAN build to verify if we are affected, but according to Google Project Zero they have found this being exploited in the wild (against Chrome, presumably)

Calling this sec-critical for now assuming we're affected, and setting the security group to the least-restrictive "Release Track" so it's visible to more people if we have to chemspill.

CREDIT: Sergei Glazunov of Google Project Zero

  • We have evidence that this bug is being used in the wild. *
  • Therefore, this bug is subject to a 7 day disclosure deadline. *

(it was reported to Chrome yesterday, so 6 days left)

From crbug 1139963:

A vulnerability exists in the function Load_SBit_Png, which processes PNG
images embedded into fonts. This function:

  1. Obtains the image width and height from the header as 32-bit integers.
  2. Truncates the obtained values to 16 bit and stores them in a
    TT_SBit_Metrics structure.
  3. Uses the truncated values to calculate the bitmap size.
  4. Allocates the backing store of that size.
  5. Passes png_struct and the backing store to a libpng function.

The issue is that libpng uses the original 32-bit values, which are saved in
png_struct. Therefore, if the original width and/or height are greater than
65535, the allocated buffer won't be able to fit the bitmap

FT_LOCAL_DEF( FT_Error )
  Load_SBit_Png( FT_GlyphSlot     slot,
                 FT_Int           x_offset,
                 FT_Int           y_offset,
                 FT_Int           pix_bits,
                 TT_SBit_Metrics  metrics,
                 FT_Memory        memory,
                 FT_Byte*         data,
                 FT_UInt          png_len,
                 FT_Bool          populate_map_and_metrics,
                 FT_Bool          metrics_only )
  {

[...]

    png_get_IHDR( png, info,
                  &imgWidth, &imgHeight,
                  &bitdepth, &color_type, &interlace,
                  NULL, NULL ); // *** 1 ***

[...]

    if ( populate_map_and_metrics )
    {
      metrics->width  = (FT_UShort)imgWidth; // *** 2 ***
      metrics->height = (FT_UShort)imgHeight;

      map->width      = metrics->width;
      map->rows       = metrics->height;
      map->pixel_mode = FT_PIXEL_MODE_BGRA;
      map->pitch      = (int)( map->width * 4 );

[...]

    if ( populate_map_and_metrics )
    {
      /* this doesn't overflow: 0x7FFF * 0x7FFF * 4 < 2^32 */
      FT_ULong  size = map->rows * (FT_ULong)map->pitch; // *** 3 ***


      error = ft_glyphslot_alloc_bitmap( slot, size ); // *** 4 ***
      if ( error )
        goto DestroyExit;
    }

[...]

    png_read_image( png, rows ); // *** 5 ***

In the announcement that went out for the 2.10.4 release containing this fix, they said if affects anybody who has FT_CONFIG_OPTION_USE_PNG set. AFAICT, that includes us?
https://searchfox.org/mozilla-central/source/modules/freetype2/moz.build#88

As far as I'm aware, Load_SBit_Png will be used for opentype fonts that contain embedded bitmaps (such as Noto Color Emoji), but by default we strip those tables from webfont resources so they can't be used via @font-face, they only work when installed locally.

There's a pref gfx.downloadable_fonts.keep_color_bitmaps that controls this, so it's possible for a user to open up the vulnerability, but it's false by default:
https://searchfox.org/mozilla-central/rev/61728de8273c04fe2417c475fc0637e8b79210d7/modules/libpref/init/StaticPrefList.yaml#4180-4186

As such, I think we should be safe from this with default prefs settings.

thanks for the pref tip. Even with that set I can't get a crash in Windows ASAN Nightly with the testcase. With or without the pref flip I do see the following console warnings so maybe the testcase isn't quite right for Firefox?

downloadable font: bad search range (font-family: "fontname" style:normal weight:400 stretch:100 src index:0) source: (invalid URI)
downloadable font: bad range shift (font-family: "fontname" style:normal weight:400 stretch:100 src index:0) source: (invalid URI)
downloadable font: maxp: Bad maxZones: 0 (font-family: "fontname" style:normal weight:400 stretch:100 src index:0) source: (invalid URI)

It wouldn't affect Windows, we don't use freetype there -- only on Linux and Android.

Having said that, I don't get a crash on Linux even with the pref toggled. (Opt build; maybe ASAN or valgrind would show something, but I don't have those builds on hand immediately.)

I'll lower this to sec-moderate based on the non-default pref being required. We shouldn't have to re-spin Fx82 for this.

Do we have any hints how popular an option gfx.downloadable_fonts.keep_color_bitmaps is? I bet fairly popular in some communities (discussion boards that use that kind of font?) but maybe not all that widespread. I only get a couple of Google hits for sites telling people how they can use the pref to enable emojis.

Whiteboard: [disclosure date 2020-10-26] → [disclosure date 2020-10-26] requires non-default pref

We don't have any actual data afaik, but I doubt it's at all common. There aren't a huge number of such fonts out there besides Noto Color Emoji, which generally comes preinstalled on devices, and is rather big to deploy as a webfont anyhow.

People doing stuff with color webfonts are more often using the outline-based COLR/CPAL format, or sometimes SVG-in-OT, which are unrelated to this issue and don't depend on setting the keep_color_bitmaps pref.

So I don't see this justifying a respin or other highly-urgent response. Given that it's a nice simple patch, I think it'd make sense to cherry-pick it for beta/esr releases, though.

This is CVE-2020-15999.

  • src/sfnt/pngshim.c (Load_SBit_Png): Test bitmap size earlier.
Assignee: nobody → ryanvm
Status: NEW → ASSIGNED

FWIW, the cherry-pick grafts cleanly to all branches.

Alias: CVE-2020-15999

The upstream bug and patch can be found at https://savannah.nongnu.org/bugs/?59308 -- looks like the issue is now essentially public? We should keep our bug hidden as long as the chrome bug is hidden though.

Google Project Zero is now tweeting about this: https://twitter.com/benhawkes/status/1318640422571266048

Status: ASSIGNED → RESOLVED
Closed: 11 months ago
Resolution: --- → FIXED
Target Milestone: --- → 84 Branch

Comment on attachment 9182701 [details]
Bug 1672223 - [sfnt] Fix heap buffer overflow. r=jfkthame

Beta/Release Uplift Approval Request

  • User impact if declined: Publicly-disclosed and exploited security vulnerability
  • Is this code covered by automated tests?: Unknown
  • Has the fix been verified in Nightly?: No
  • Needs manual test from QE?: No
  • If yes, steps to reproduce:
  • List of other uplifts needed: None
  • Risk to taking this patch: Low
  • Why is the change risky/not risky? (and alternatives if risky): Only affects Linux and Android users with a non-default pref set.
  • String changes made/needed:
Attachment #9182701 - Flags: approval-mozilla-esr78?
Attachment #9182701 - Flags: approval-mozilla-beta?

(In reply to Jonathan Kew (:jfkthame) from comment #5)

It wouldn't affect Windows, we don't use freetype there -- only on Linux and Android.

Can I clarify that Android is affected due to in-tree freetype2, but Linux is only affected when the installed system library is vulnerable? Maybe I'm missing where the vendored version is used for Linux, too.

Right, I should have added that on Linux, we don't (AFAIK) use in-tree freetype and so the status here would depend on the system library and not on what we do with our vendored copy.

I assume the pref is not exposed to users on fenix (where about:config is nightly only, AIUI).

Comment on attachment 9182701 [details]
Bug 1672223 - [sfnt] Fix heap buffer overflow. r=jfkthame

a=dveditz

Normally I'd say don't land on ESR this far before release, but in this case with GPZ publicizing the bug there's no harm done.

Attachment #9182701 - Flags: approval-mozilla-esr78?
Attachment #9182701 - Flags: approval-mozilla-esr78+
Attachment #9182701 - Flags: approval-mozilla-beta?
Attachment #9182701 - Flags: approval-mozilla-beta+

Project Zero issue is public now (same content as comment 0):

https://bugs.chromium.org/p/project-zero/issues/detail?id=2103

Whiteboard: [disclosure date 2020-10-26] requires non-default pref → [adv-main83+][disclosure date 2020-10-26] requires non-default pref
Whiteboard: [adv-main83+][disclosure date 2020-10-26] requires non-default pref → [adv-main83+][adv-esr78.5+][disclosure date 2020-10-26] requires non-default pref
Attached file advisory.txt (obsolete) —
Attachment #9187207 - Attachment is obsolete: true
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.