php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #69782 NULL pointer dereference
Submitted: 2015-06-09 08:49 UTC Modified: 2015-09-09 10:11 UTC
From: moltesalt at gmail dot com Assigned: stas
Status: Closed Package: XSLT related
PHP Version: 5.6.9 OS:
Private report: No CVE-ID: 2015-6838
 [2015-06-09 08:49 UTC] moltesalt at gmail dot com
Description:
------------
The XSLTProcessor class missed a few checks on the input from the libxslt library. The valuePop() function call able to return with NULL pointer and php does not check that.

These checks missed in xsltprocessor.c lines 304-305 and on lines 239-240 in the same function.
http://lxr.php.net/xref/PHP_5_6/ext/xsl/xsltprocessor.c#305

All php versions affected, including trunk.

Expected result:
----------------
$ php -f xpath.php

Warning: XSLTProcessor::transformToXml(): xmlXPathCompOpEval: function d not found in xpath.php on line 31
Warning: XSLTProcessor::transformToXml(): Unregistered function in xpath.php on line 31
Warning: XSLTProcessor::transformToXml(): Stack usage errror in xpath.php on line 31

Actual result:
--------------
$ php -f xpath.php

Warning: XSLTProcessor::transformToXml(): xmlXPathCompOpEval: function d not found in xpath.php on line 31
Warning: XSLTProcessor::transformToXml(): Unregistered function in xpath.php on line 31
Warning: XSLTProcessor::transformToXml(): Stack usage errror in xpath.php on line 31
Segmentation fault

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-06-09 14:51 UTC] tyrael@php.net
-Type: Bug +Type: Security -Private report: No +Private report: Yes
 [2015-07-03 13:37 UTC] kalle@php.net
Could you try the following patch: http://pastie.org/private/nmxwzf25qahxryfit542q
 [2015-07-03 13:38 UTC] kalle@php.net
-Status: Open +Status: Feedback
 [2015-07-03 13:54 UTC] kalle@php.net
Sorry, this should be the right patch, was a little too early on the trigger button: http://pastie.org/private/puvwu1gtr4qkextmrqmkmq (thanks Anatol)
 [2015-07-04 11:33 UTC] tyrael@php.net
the original report had these attachments for reproducing the issue:
xpath.php :
<?php

$language=trim(file_get_contents("php://stdin"));

$xml = "xpath.xml";
$xsl = "xpath.xsl";

//$COUNTRY_PREFIX="string";

//$xsl = str_replace('$language', "$language", file_get_contents("xpath.xsl"));

function fileToDOMDoc($filename) {
    global $language;
    $dom= new DOMDocument;
    $xmldata = file_get_contents($filename);
    $xmldata = str_replace("&", "&amp;", $xmldata);  // disguise &s going IN to loadXML()
    $xmldata = str_replace('$language', "$language", $xmldata);
    $dom->substituteEntities = true;  // collapse &s going OUT to transformToXML()
    $dom->loadXML($xmldata);
    return $dom;
} 

$xmldoc = fileToDOMDoc($xml);
$xsldoc = fileToDOMDoc($xsl);

$proc = new XSLTProcessor();
//$proc->setParameter("", "language", $language);
//$proc->setParameter("", "COUNTRY_PREFIX", "lofasz");
$proc->registerPHPFunctions();
$proc->importStyleSheet($xsldoc);
echo $proc->transformToXML($xmldoc);
?> 

xpath.xml :
<allusers>
 <user>
  <uid>bob</uid>
 </user>
 <user>
  <uid>joe</uid>
 </user>
</allusers>

xpath.xsl :
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:php="http://php.net/xsl">
 <xsl:output method="xml" encoding="iso-8859-15" indent="yes"/>
 <xsl:param name="COUNTRY_PREFIX"/><xsl:param name="COMPANY_ID"/><xsl:param name="FOOTER_TEXT"/>
 <xsl:param name="language" />
 <xsl:template match="allusers">
  <html><body>
    <h2>Users</h2>
    <table>
    <xsl:for-each select="user">
      <tr><td>
        <xsl:value-of disable-output-escaping="yes"
             select="php:function('ucfirst', $language)"/>
      </td></tr>
    </xsl:for-each>
    </table>
  </body></html>
 </xsl:template>
</xsl:stylesheet>
 [2015-07-04 12:35 UTC] tyrael@php.net
the attached test scripts are a bit messy, they have unnecessary lines, could be made more simple, and it actually had a bug (seems that passing the language data was originally meant to happen through passing it via XSLTProcessor->setParameter but was replaced with a simple str_replace() when loading the xsl file, but that was bugged:
instead of
$xmldata = str_replace('$language', "$language", $xmldata);
you need
$xmldata = str_replace('$language', "'$language'", $xmldata);
then you can run the tests either interactively via typing en then sending ^D, or simply
echo en|php -f xpath.php

but here is the catch: I don't get the segmantation fault or any of those Warnings with 5.6.9
I suspect that the attached files are different what was actually used to reproduce the problem.
 [2015-07-12 04:22 UTC] php-bugs at lists dot php dot net
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Re-Opened". Thank you.
 [2015-07-12 08:06 UTC] stas@php.net
-Status: No Feedback +Status: Re-Opened
 [2015-09-01 19:11 UTC] stas@php.net
-Status: Re-Opened +Status: Closed -Assigned To: +Assigned To: stas
 [2015-09-01 19:11 UTC] stas@php.net
The fix for this bug has been committed.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.

 For Windows:

http://windows.php.net/snapshots/
 
Thank you for the report, and for helping us make PHP better.


 [2015-09-09 10:11 UTC] kaplan@php.net
-CVE-ID: +CVE-ID: 2015-6838
 [2015-09-09 10:11 UTC] kaplan@php.net
This issue was assigned with two CVE: CVE-2015-6837 and CVE-2015-6838. Details at http://seclists.org/oss-sec/2015/q3/524
 [2015-09-15 13:54 UTC] pgajdos at suse dot cz
It seems there is another valuePop() occurence in the code:

http://git.php.net/?p=php-src.git;a=blob;f=ext/xsl/xsltprocessor.c;h=ee52336c4ebd46b2a42046a00b938dcff5461308;hb=HEAD#l234

Shouldn't be the obj value checked there too?
 [2015-10-12 21:34 UTC] thoger at redhat dot com
It seems PHP was making a correct assumption that valuePop() should not return NULL and was hitting a libxml2's bug:

https://git.gnome.org/browse/libxml2/commit/?id=03c6723043775122313f107695066e5744189a08

libxml2 fixed this issue in 2.9.2.  I could not reproduce this PHP crash with libxml2 2.9.2.
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Tue Aug 29 15:01:52 2017 UTC