New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 623378 link

Starred by 3 users

Issue metadata

Status: Fixed
Owner:
Last visit > 30 days ago
Closed: Jul 2016
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux , Android , Windows , Chrome , Mac
Pri: 1
Type: Bug-Security



Sign in to add a comment

Security: UAF related to XPointer range-to function

Reported by wellnho...@aevum.de, Jun 26 2016

Issue description

VULNERABILITY DETAILS
Bugs in xmlXPathEvalExpr and xmlXPtrRangeToFunction can lead to a use-after-free and allow control of the instruction pointer.

VERSION
Chrome Version: 51.0.2704.106 stable
Operating System: Windows 10, 64-bit

REPRODUCTION CASE
See the attached files range-to-uaf-poc.xml and range-to-uaf-poc.xsl. If you open the XML file locally, make sure to run Chrome with --allow-file-access-from-files.

FULL DETAILS
The first observation is that xmlXPathEvalExpr which parses and evaluates an XPath expression allows any unparseable content after an expression. After compiling the valid part of the expression, the "cur" element in the xmlXPathParserContextPtr struct points to the beginning of the unparseable content.

If an XPointer expression contains a call to the "range-to" function, xmlXPtrRangeToFunction is invoked during evaluation of the expression. This function calls xmlXPathEvalExpr again, resuming the compilation where the previous call to xmlXPathEvalExpr left off. This leads to additional operations being compiled and added to the xmlXPathStepOp table, possibly reallocating memory for this table.

xmlXPtrRangeToFunction then returns to xmlXPathCompOpEval which is the main runloop for compiled XPath expressions. The "op" argument to xmlXPathCompOpEval points into the StepOp table, assuming the table won't be modified or reallocated during evaluation. If a reallocation occurs as decribed above, "op" points into memory that was previously freed, resulting in a use-after-free.

This can be leveraged to control the instruction pointer if an operation following the "range-to" call is another XPath function call. For function calls, the function pointer is cached in the "cache" element of the StepOp struct. Causing an allocation of the same size as the old StepOp table (10 * 40 = 400 bytes on 32-bit) will typically reuse the old memory area of the table. Using a 400-byte XPath string literal in the second part of the XPath expression which is parsed in xmlXPtrRangeToFunction gives an attacker control over this memory area. The only limitation is that the string literal is stored as UTF-8.

The POC uses an XPointer expression of the form

    xpointer(name(range-to(.))0+0+"[400-byte-buffer]")

"name(...)" could be any function. This function call is only used to transfer control to the address provided by the attacker. "name(range-to(.))" is the expression that will be compiled and evaluated initially. '0+0+"[400-byte-buffer]"' is the expression that will be compiled during evaluation of "range-to(.)". This replaces the original StepOp table with the UTF-8 encoded contents of the string literal. "0+0+" is needed to trigger a reallocation. The 400-byte buffer overwrites an array of 10 xmlXPathStepOp structs:

struct _xmlXPathStepOp {
    xmlXPathOp op;		
    int ch1;			
    int ch2;			
    int value;
    int value2;
    int value3;
    void *value4;
    void *value5;
    void *cache;
    void *cacheURI;
};

"value" must be a negative number to pass a check in xmlXPathCompOpEval. Any four-byte UTF-8 character can be used. "cache" contains the target address. The POC simply uses a sequence of 'GRINNING FACE' (U+1F600) characters. The UTF-8 encoding of this character is 0xF0 0x9F 0x98 0x80. Subsequently, xmlXPathCompOpEval jumps to the address 0x80989FF0.

The POC uses the XSLT "document" function to trigger the evaluation of an XPointer expression. Other mechanisms could be probably used as well. The XPointer expression must be percent encoded since it's part of a URL.

A patch fixing this bug will follow in the next days.

DISCLOSURE
I contribute to libxml2 occasionally. I haven't shared details about this issue with anyone, and I don't plan to do so until it is fixed in Webkit browsers. I didn't write any parts of the buggy code. This bug was found with afl-fuzz and ASan.

 
range-to-uaf-poc.xml
57 bytes View Download
range-to-uaf-poc.xsl
1.4 KB View Download

Comment 1 by aarya@google.com, Jun 26 2016

Cc: metzman@google.com
Components: Blink>XML
Labels: Security_Severity-High Security_Impact-Stable

Comment 3 by metzman@google.com, Jun 27 2016

Status: Untriaged (was: Unconfirmed)
range-to-uaf-poc.xsl needs to be renamed to uaf.xsl in the poc.
uaf.xsl
1.4 KB View Download
Project Member

Comment 4 by sheriffbot@chromium.org, Jun 27 2016

Labels: M-51
Project Member

Comment 5 by sheriffbot@chromium.org, Jun 27 2016

Labels: Pri-1
Owner: dominicc@chromium.org
Status: Assigned (was: Untriaged)
+dominicc - can you take a look at this?

Comment 7 by wellnho...@aevum.de, Jun 28 2016

Here's a patch against libxml2 master fixing the bug.
range-to-uaf.diff
3.8 KB Download
Cc: ddkil...@apple.com scottmg@chromium.org
Labels: OS-Android OS-Chrome OS-Linux OS-Mac OS-Windows
Status: Started (was: Assigned)
Thank you for another detailed bug report and repros.

I have uploaded your patch here: https://codereview.chromium.org/2127493002

I have filed a blank upstream bug: https://bugzilla.gnome.org/show_bug.cgi?id=768428
Labels: Merge-Triage
Status: Fixed (was: Started)
ddkilzer, per wellnhofer's point about disclosure, could you indicate when WebKit picks this up so we can push the repro and patches into the upstream bug tracker?
Project Member

Comment 11 by sheriffbot@chromium.org, Jul 6 2016

Labels: -Restrict-View-SecurityTeam Restrict-View-SecurityNotify
> ddkilzer, per wellnhofer's point about disclosure, could you indicate when WebKit picks this up so we can push the repro and patches into the upstream bug tracker?

Will do.  I'm on vacation this week, but I've created a Radar to track the issue internally.  Note that Safari/WebKit does not ship stand-alone libxml2/libxslt updates, so these changes must go into operating systems (macOS, iOS, etc.).

Comment 13 by ddkil...@apple.com, Jul 11 2016

> ddkilzer, per wellnhofer's point about disclosure, could you indicate when WebKit picks this up so we can push the repro and patches into the upstream bug tracker?

This change will ship with the major OS releases (macOS 10.12 Sierra, iOS 10, tvOS 10, watchOS 3) as we don't have another software update release available, and we don't ship libxml2 outside each OS.

wellnhofer would you be comfortable with this getting disclosed upstream now?
dominicc, I leave the decision when/what/where to disclose to you. If you like, I can add some details that are relevant for libxml2 developers to the upstream bug.
Labels: -Merge-Triage Merge-Request-51 Merge-Request-52 Merge-Request-53
Labels: reward-topanel
Before we approve merge to M52, Could you please confirm whether this change is baked/verified in Canary and safe to merge?
This is an obscure part of a little-used feature. I haven't seen any blowback from this. I think this is safe to merge.
Cc: awhalley@chromium.org
Thank you dominicc@.

I'm OK to take this merge in for M52 and M53 per comment #19. awhalley@, what do you think?


Yes, I agree.
Labels: -Merge-Request-52 -Merge-Request-53 Merge-Approved-53 Merge-Approved-51
Approving merge to M53 branch 2785 and M52 branch 2743 based on comment #21. Please merge ASAP (possibly before 5:00 PM PST today, Friday or latest by 4:00 PM PST on Monday).

Comment 23 Deleted

Labels: -Merge-Approved-51 Merge-Approved-52
Cc: infe...@chromium.org
Ccing reviewer (inferno@). If you can do the merge to M52 and M53 today before 5:00 PM PST would be great as dominicc@ is in Japan.
Project Member

Comment 26 by bugdroid1@chromium.org, Jul 18 2016

Labels: -merge-approved-53 merge-merged-2785
The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/33b71091611f766d3902ed4f948b67f08b2a1f69

commit 33b71091611f766d3902ed4f948b67f08b2a1f69
Author: Martin Barbella <mbarbella@chromium.org>
Date: Mon Jul 18 22:51:13 2016

Delete obsolete XPointer range-to function.

BUG= 623378 

Review-Url: https://codereview.chromium.org/2127493002
Cr-Commit-Position: refs/heads/master@{#403859}
(cherry picked from commit b6ad54b72c7f8c422c288dd9c8756d2a15f30e53)

Review URL: https://codereview.chromium.org/2154263005 .

Cr-Commit-Position: refs/branch-heads/2785@{#206}
Cr-Branched-From: 68623971be0cfc492a2cb0427d7f478e7b214c24-refs/heads/master@{#403382}

[modify] https://crrev.com/33b71091611f766d3902ed4f948b67f08b2a1f69/third_party/libxml/README.chromium
[modify] https://crrev.com/33b71091611f766d3902ed4f948b67f08b2a1f69/third_party/libxml/src/xpath.c
[modify] https://crrev.com/33b71091611f766d3902ed4f948b67f08b2a1f69/third_party/libxml/src/xpointer.c

Project Member

Comment 27 by bugdroid1@chromium.org, Jul 18 2016

Labels: -merge-approved-52 merge-merged-2743
The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/90af22ca17e337cfa3cf8060a97e944643222154

commit 90af22ca17e337cfa3cf8060a97e944643222154
Author: Martin Barbella <mbarbella@chromium.org>
Date: Mon Jul 18 22:56:33 2016

Delete obsolete XPointer range-to function.

BUG= 623378 

Review-Url: https://codereview.chromium.org/2127493002
Cr-Commit-Position: refs/heads/master@{#403859}
(cherry picked from commit b6ad54b72c7f8c422c288dd9c8756d2a15f30e53)
TBR=inferno@chromium.org

Review URL: https://codereview.chromium.org/2154173003 .

Cr-Commit-Position: refs/branch-heads/2743@{#669}
Cr-Branched-From: 2b3ae3b8090361f8af5a611712fc1a5ab2de53cb-refs/heads/master@{#394939}

[modify] https://crrev.com/90af22ca17e337cfa3cf8060a97e944643222154/third_party/libxml/README.chromium
[modify] https://crrev.com/90af22ca17e337cfa3cf8060a97e944643222154/third_party/libxml/src/xpath.c
[modify] https://crrev.com/90af22ca17e337cfa3cf8060a97e944643222154/third_party/libxml/src/xpointer.c

Labels: -M-51 Release-0-M52 M-52
Labels: -Merge-Request-51
Labels: CVE-2016-5131
Labels: reward-3500 reward-unpaid
Our panel has awarded you $3,500 for this bug, congratulations!  A member of our finance team will be in touch over the next few weeks.
Labels: -reward-topanel
Any idea why libxml2 upstream (Daniel Veillard) was not involved with the bug? 
In most of the previous bugs, libxml2 was involved at a very early stage.
Sorry, that was an oversight on my part. I have copied the details upstream.
Labels: -reward-unpaid reward-inprocess
Cc: groebert@google.com
Cc: ail@google.com
Project Member

Comment 40 by sheriffbot@chromium.org, Oct 12 2016

Labels: -Restrict-View-SecurityNotify allpublic
This bug has been closed for more than 14 weeks. Removing security view restrictions.

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot

Comment 41 by ddkil...@apple.com, Oct 14 2016

> Any idea why libxml2 upstream (Daniel Veillard) was not involved with the bug? 
> In most of the previous bugs, libxml2 was involved at a very early stage.

Daniel is very busy.  To get him involved I had to contact him directly a number of times.

Nick Wellnhofer is also an upstream libxml2/libxslt maintainer, so he's also able to review and land patches upstream, but tends to focus mostly on libxslt.

Note that both Daniel and Nick are volunteering their time on these projects.

Labels: CVE_description-submitted

Sign in to add a comment