Closed Bug 966021 (CVE-2014-1509) Opened 10 years ago Closed 10 years ago

memcpy buffer overrun when _cairo_truetype_index_to_ucs4 calls _cairo_dwrite_load_truetype_table

Categories

(Core :: Graphics: Text, defect)

x86_64
Windows 7
defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla29
Tracking Status
firefox26 --- wontfix
firefox27 --- wontfix
firefox28 --- fixed
firefox29 + fixed
firefox-esr24 28+ fixed
b2g18 --- unaffected
b2g-v1.1hd --- unaffected
b2g-v1.2 --- unaffected
b2g-v1.3 --- unaffected
b2g-v1.4 --- unaffected

People

(Reporter: john_thomson, Assigned: jfkthame)

Details

(Keywords: sec-moderate, Whiteboard: [qa-][adv-main28+][adv-esr24.4+])

Attachments

(2 files, 1 obsolete file)

User Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.76 Safari/537.36

Steps to reproduce:

Install the attached xpi (which creates an ugly Hello World top-level menu...sorry, I adapted one of your tutorials to get a simple reproduction).
On any web page (e.g., google's home page), select the Hello World menu item (which really attempts to generate a pdf of the page to c:\temp\problem.pdf).

(I'm using the FF 26.0 on 64-bit Windows 7 professional...32-bit version of FF, though.)
Crash report details:
AdapterDeviceID: 0x6778
AdapterVendorID: 0x1002
Add-ons: support%40lastpass.com:3.0.12,printPages2Pdf%40reinhold.ripper:0.1.9.3,helloworld%40xulschool.com:0.1,%7B972ce4c6-7e08-4474-a285-3208198ce6fd%7D:26.0
AvailablePageFile: 20080398336
AvailablePhysicalMemory: 5977272320
AvailableVirtualMemory: 3804106752
BuildID: 20131205075310
CrashTime: 1391120848
EMCheckCompatibility: true
FramePoisonBase: 00000000f0de0000
FramePoisonSize: 65536
InstallTime: 1387205692
Notes: AdapterVendorID: 0x1002, AdapterDeviceID: 0x6778, AdapterSubsysID: 21201028, AdapterDriverVersion: 8.922.0.0
Has dual GPUs. GPU #2: AdapterVendorID2: 0x8086, AdapterDeviceID2: 0x0162, AdapterSubsysID2: 05771028, AdapterDriverVersion2: 8.15.10.2712D2D? D2D+ DWrite? DWrite+ D3D10 Layers? D3D10 Layers+ 
ProductID: {ec8030f7-c20a-464f-9b0e-13a3a9e97384}
ProductName: Firefox
ReleaseChannel: release
SecondsSinceLastCrash: 508
StartupTime: 1391120365
SystemMemoryUsePercentage: 64
Theme: classic/1.0
Throttleable: 1
TotalVirtualMemory: 4294836224
URL: about:home
Vendor: Mozilla
Version: 26.0
Winsock_LSP: MSAFD Tcpip [TCP/IP] : 2 : 1 : %SystemRoot%\system32\mswsock.dll 
 MSAFD Tcpip [UDP/IP] : 2 : 2 :  
 MSAFD Tcpip [RAW/IP] : 2 : 3 : %SystemRoot%\system32\mswsock.dll 
 MSAFD Tcpip [TCP/IPv6] : 2 : 1 :  
 MSAFD Tcpip [UDP/IPv6] : 2 : 2 : %SystemRoot%\system32\mswsock.dll 
 MSAFD Tcpip [RAW/IPv6] : 2 : 3 :  
 RSVP TCPv6 Service Provider : 2 : 1 : %SystemRoot%\system32\mswsock.dll 
 RSVP TCP Service Provider : 2 : 1 :  
 RSVP UDPv6 Service Provider : 2 : 2 : %SystemRoot%\system32\mswsock.dll 
 RSVP UDP Service Provider : 2 : 2 : 
useragent_locale: en-US



Actual results:

FireFox crashes. Attaching a debugger, I found that _cairo_truetype_index_to_ucs4 allocates a 4-byte array (buf) and passes it to _cairo_dwrite_load_truetype_table, which loads over 8K of data and uses memcpy to copy it to that buffer. This totally trashes the stack, so you can see what is happening much better if you set a breakpoint to stop things BEFORE the memcpy in line 1057 of mozilla-release\gfx\cairo\cairo\src\cairo-dwrite-font.cpp.


Expected results:

The current web page should be converted to pdf and written to c:\temp\problem.pdf.

(This is not what I'm really trying to do...I really want to call this code through geckofx from .NET as in https://bugzilla.mozilla.org/show_bug.cgi?id=922523. But I've been trying to move things along by pinning down a simpler repro.)
I haven't looked into this deeply, but marking security-sensitive as a precaution because the possibility of trashing several kilobytes of the stack sounds pretty bad.

Bas, Jeff: at first glance it looks like this is a bug in _cairo_dwrite_load_truetype_table, failing to respect the passed-in buffer length.
Group: core-security
Confirmed the crash due to trashing the stack, as described by John, when trying to generate PDF with the dwrite font backend in use.

Inspection of _cairo_dwrite_load_truetype_table also reveals a second bug: it totally ignores the offset parameter. Most of the time, cairo passes 0 as offset, and reads entire tables, but when subsetting fonts for PDF output, it relies on adjusting the offset to read individual glyphs from within the tables. So that was doomed to failure, too.
Assignee: nobody → jfkthame
Status: UNCONFIRMED → ASSIGNED
Ever confirmed: true
With this patch, I get a correct-looking PDF generated from John's test extension (and no crash).
Attachment #8368506 - Flags: review?(bas)
Comment on attachment 8368510 [details] [diff] [review]
make load_truetype_table in the cairo dwrite font backend respect the length and offset parameters.

Oops, duplicate copy of the patch, thanks to bzexport confusion - sorry about the noise.
Attachment #8368510 - Attachment is obsolete: true
Attachment #8368506 - Flags: review?(bas) → review+
Comment on attachment 8368506 [details] [diff] [review]
patch, make dwrite font backend read tables correctly

[Security approval request comment]
How easily could an exploit be constructed based on the patch?

I'm not sure whether this can be reached in a default install, without help of an extension or similar to access the PDF-generation codepath. Once this code is reached, it's trivial to cause a crash by overwriting the stack. It's not clear to me how easily an attacker could achieve something worse than simply DoS; the stack gets overwritten by font data, not by arbitrary data the attacker provides. In principle, the attacker could provide the font data via @font-face, but it would have to pass through OTS sanitization first, so that would greatly constrain what could be injected. Still, I can't rule out the possibility that a carefully-constructed exploit that trashes the stack in a specific way might lead to arbitrary code execution...

Do comments in the patch, the check-in comment, or tests included in the patch paint a bulls-eye on the security problem?

The patch itself makes it obvious what we're fixing; it's not hard to trace back from that and determine that the way to reach this code is to get cairo to generate PDF.

Which older supported branches are affected by this flaw?

All branches (when running on Windows with DirectWrite).

If not all supported branches, which bug introduced the flaw?

n/a

Do you have backports for the affected branches? If not, how different, hard to create, and risky will they be?

Trivial backport; this code hasn't changed since it first landed in bug 527707.

How likely is this patch to cause regressions; how much testing does it need?

Minimal risk; this code was simply broken previously, it can't get any worse!
Attachment #8368506 - Flags: sec-approval?
I spent a full day trying hard just to make the crash occur without using an extension. I was not able to find any way for Javascript running in a web page (rather than an extension) to get at Components.classes (which seems to have been hidden, I think around version 19, for security reasons) in order to get an nsIWebBrowserPrint. Of course, I can't guarantee that exploiters aren't cleverer about this than I am. But all the examples on the web of how to use this API seem to be obsolete.
I would be interesting to know whether this fix solves https://bugzilla.mozilla.org/show_bug.cgi?id=922523. I originally found the problem when trying to work around that bug (as suggested there) by setting gfx.font_rendering.directwrite.enabled. Does the pdf generated with the patch seem to position glyphs correctly rather than using screen hinting?
This won't affect PDF generation when using GDI fonts at all (e.g. for WinXP users), so you'll still get the same poor spacing in that case. But it should allow you to use the workaround of switching to the DirectWrite font backend (even if D2D hardware acceleration isn't in use, which would have forced use of DW fonts anyway) on systems where DW is available.

So none of this will give you a good solution for generating PDFs on WinXP, unfortunately. For that, we'd need to fix the real problem in bug 922523.
Any suggestion on a security rating here. A write into memory after a crash isn't too good but how controllable is it?
Comment 6 gives as much info as I have. Two key points, I think:
(a) this may not be reachable in a default configuration; AFAIK, it requires some kind of extension to access the PDF-generating function. So that probably limits the number of users who'd be exposed.
(b) although the stack is being overwritten, it's not arbitrarily controllable; whatever is being written to the stack must have appeared well-formed as font table data. ISTM that would severely constrain a would-be attacker trying to do more than just DoS.

I don't know where that puts it in your sec-* spectrum... moderate, maybe?
Yeah, let's go with moderate.
Keywords: sec-moderate
Attachment #8368506 - Flags: sec-approval? → sec-approval+
Comment on attachment 8368506 [details] [diff] [review]
patch, make dwrite font backend read tables correctly

[Approval Request Comment]
Bug caused by (feature/regressing bug #): 527707 (DirectWrite font support)

User impact if declined: Any attempt to use cairo PDF output will crash.

Testing completed (on m-c, etc.): Tested locally, confirmed to fix PDF generation on Windows with DirectWrite fonts. Landed on inbound.

Risk to taking this patch (and alternatives if risky): Negligible. Simple fix for a codepath that was clearly broken (but fortunately not hit during normal browser use).

String or IDL/UUID changes made by this patch: none


[Approval Request Comment]
If this is not a sec:{high,crit} bug, please state case for ESR consideration: Although most users won't hit this issue, anyone on D2D-accelerated Windows who tries to use a save-page-as-PDF extension will crash. Fixing this carries no risk for other users, as the code path isn't used otherwise.

User impact if declined: Impossible to use cairo PDF generation on Win/D2D systems.

Fix Landed on Version: 29 (requesting uplift to 28)

Risk to taking this patch (and alternatives if risky): none

String or UUID changes made by this patch: none
Attachment #8368506 - Flags: approval-mozilla-esr24?
Attachment #8368506 - Flags: approval-mozilla-aurora?
https://hg.mozilla.org/mozilla-central/rev/4fe634bea8de
Status: ASSIGNED → RESOLVED
Closed: 10 years ago
Resolution: --- → FIXED
Comment on attachment 8368506 [details] [diff] [review]
patch, make dwrite font backend read tables correctly

Will approve this for ESR24 even though it's sec-moderate since we know that PDF usage is high with ESR users and having this in ESR24 earlier is likely a help to them.
Attachment #8368506 - Flags: approval-mozilla-esr24?
Attachment #8368506 - Flags: approval-mozilla-esr24+
Attachment #8368506 - Flags: approval-mozilla-aurora?
Attachment #8368506 - Flags: approval-mozilla-aurora+
https://hg.mozilla.org/releases/mozilla-aurora/rev/fd6042c0a6bd

In my queue to uplift to esr24 once 24.3 is officially out the door. Marking B2G as unaffected since this is Windows-only.
Matt, can you please verify this is fixed?
Flags: needinfo?(mwobensmith)
Flags: needinfo?(mwobensmith)
I can't seem to reproduce on an affected build. I suspect it has something to do with the fact that I'm using Win7 on a VMware image.

Ioana, can you find someone with Windows hardware to verify this bug fix? Thank you.
Flags: needinfo?(ioana.budnar)
(In reply to Matt Wobensmith from comment #20)
> I can't seem to reproduce on an affected build. I suspect it has something
> to do with the fact that I'm using Win7 on a VMware image.

Right - I presume you don't get D2D acceleration under VMware, and therefore you'll get GDI fonts by default.

You might be able to reproduce by explicitly forcing the use of DirectWrite (gfx.font_rendering.directwrite.enabled = true), but verifying on a system where we actually use D2D would also be good.
Thanks for the tip, Jonathan. Unfortunately, that didn't work for me. We'll get someone who has real Windows hardware to verify.
I tried to reproduce this issue on 3 different Windows 7 x64 machines with Firefox 26 and 27 with HWA enabled. All I got are two messages: "starting print" and "An error occurred while printing.". These are also reproducible with Firefox 28.
Flags: needinfo?(ioana.budnar)
John, can you please help us verify this is fixed? It does not appear as though we can reliably reproduce this on our end. It should currently be fixed in Aurora (aurora.mozilla.org) and Beta (beta.mozilla.org) builds.
Flags: needinfo?(john_thomson)
Whiteboard: [qa-]
I have installed the current version of Aurora (29.0a2) and the demo plugin, and confirmed that the crash does not occur and the pdf is generated successfully.

Thanks very much for fixing this!
For your own efforts to reproduce: it may be important to actually create c:\temp before running the "Hello World" xpi command.

Sorry if the dialogs confused things...I just put them in to localize the line of Javascript in which the crash used to occur.

I'm not sure why you got the "an error occurred during printing" message, but it MIGHT be because the destination directory does not exist.
Flags: needinfo?(john_thomson)
Whiteboard: [qa-] → [qa-][adv-main28+][adv-esr24.4+]
Alias: CVE-2014-1509
Group: core-security
You need to log in before you can comment on or make changes to this bug.