php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #72959 timelib_meridian out-of-bounds access
Submitted: 2016-08-28 22:32 UTC Modified: 2018-01-02 18:19 UTC
From: fernando at null-life dot com Assigned: derick (profile)
Status: Closed Package: Date/time related
PHP Version: 5.6.25 OS: *
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: fernando at null-life dot com
New email:
PHP Version: OS:

 

 [2016-08-28 22:32 UTC] fernando at null-life dot com
Description:
------------
Invalid date format causes out-of-bounds read at timelib_meridian through timelib strtotime. This code can also be reached through "wddx_deserialize" function.


Source code 
https://github.com/php/php-src/blob/master/ext/date/lib/parse_date.re#L381

static timelib_sll timelib_meridian(char **ptr, timelib_sll h)
{
    timelib_sll retval = 0;

    while (!strchr("AaPp", **ptr)) {
        ++*ptr;
    }
    if (**ptr == 'a' || **ptr == 'A') {
        if (h == 12) {
            retval = -12;
        }
    } else if (h != 12) {
        retval = 12;
    }
    ++*ptr;                                        // out of bounds
    if (**ptr == '.') {                            // read
        *ptr += 3;
    } else {
        ++*ptr;
    }
    return retval;
}


GDB output:

gdb -q --args /home/operac/build3/bin/php -n poc.php
No symbol table is loaded.  Use the "file" command.
Breakpoint 1 (__asan_report_error) pending.
Reading symbols from /home/operac/build3/bin/php...done.
gdb-peda$ b timelib_meridian
Breakpoint 2 at 0x42ea3d: file ext/date/lib/parse_date.re, line 517.
gdb-peda$ r
Starting program: /home/operac/build3/bin/php -n poc.php
...
Breakpoint 2, 0x000000000042ea3d in timelib_meridian (ptr=ptr@entry=0x7fffffff9d60, h=0x0) at ext/date/lib/parse_date.re:517
517     }
gdb-peda$ p ptr
$1 = (char **) 0x7fffffff9d60
gdb-peda$ p **ptr
$2 = 0x0                  // the function "timelib_meridian" tries to parser null string




Test script:
---------------
<?php

$xml = <<<XML
<dateTime>Dec 08:00AM 0</dateTime>
XML;

$array = wddx_deserialize($xml);

strtotime("Jan 12:00AM 0");

Expected result:
----------------
No crash

Actual result:
--------------
ASan output:

==12822==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000235d at pc 0x00000042ebbe bp 0x7ffc63de5370 sp 0x7ffc63de5360
READ of size 1 at 0x60200000235d thread T0
    #0 0x42ebbd in timelib_meridian ext/date/lib/parse_date.re:396
    #1 0x4d417d in scan ext/date/lib/parse_date.re:1658
    #2 0x4d417d in timelib_strtotime ext/date/lib/parse_date.re:1786
    #3 0x48fbd8 in php_parse_date /home/operac/php-src-56/php-src/ext/date/php_date.c:1433
    #4 0x15b09c2 in php_wddx_process_data /home/operac/php-src-56/php-src/ext/wddx/wddx.c:1143
    #5 0x7fdd077a778f in xmlParseCharData (/usr/lib/x86_64-linux-gnu/libxml2.so.2+0x4678f)
    #6 0x7fdd077b7cd6  (/usr/lib/x86_64-linux-gnu/libxml2.so.2+0x56cd6)
    #7 0x7fdd077b862a in xmlParseChunk (/usr/lib/x86_64-linux-gnu/libxml2.so.2+0x5762a)
    #8 0x15fb62a in php_XML_Parse /home/operac/php-src-56/php-src/ext/xml/compat.c:605
    #9 0x15d2b3a in php_wddx_deserialize_ex /home/operac/php-src-56/php-src/ext/wddx/wddx.c:1176
    #10 0x15d3d97 in zif_wddx_deserialize /home/operac/php-src-56/php-src/ext/wddx/wddx.c:1392
    #11 0x1d6bc67 in zend_do_fcall_common_helper_SPEC /home/operac/php-src-56/php-src/Zend/zend_vm_execute.h:558
    #12 0x1c1773c in execute_ex /home/operac/php-src-56/php-src/Zend/zend_vm_execute.h:363
    #13 0x195afda in zend_execute_scripts /home/operac/php-src-56/php-src/Zend/zend.c:1341
    #14 0x16a889f in php_execute_script /home/operac/php-src-56/php-src/main/main.c:2613
    #15 0x1d749ef in do_cli /home/operac/php-src-56/php-src/sapi/cli/php_cli.c:994
    #16 0x4551b0 in main /home/operac/php-src-56/php-src/sapi/cli/php_cli.c:1378
    #17 0x7fdd06a4a82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #18 0x455838 in _start (/home/operac/build3/bin/php+0x455838)

0x60200000235d is located 0 bytes to the right of 13-byte region [0x602000002350,0x60200000235d)
allocated by thread T0 here:
    #0 0x7fdd0901479a in __interceptor_calloc (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x9879a)
    #1 0x4a24b5 in timelib_string ext/date/lib/parse_date.re:442
    #2 0x4d3cff in scan ext/date/lib/parse_date.re:1642
    #3 0x4d3cff in timelib_strtotime ext/date/lib/parse_date.re:1786
    #4 0x48fbd8 in php_parse_date /home/operac/php-src-56/php-src/ext/date/php_date.c:1433
    #5 0x15b09c2 in php_wddx_process_data /home/operac/php-src-56/php-src/ext/wddx/wddx.c:1143
    #6 0x7fdd077a778f in xmlParseCharData (/usr/lib/x86_64-linux-gnu/libxml2.so.2+0x4678f)

SUMMARY: AddressSanitizer: heap-buffer-overflow ext/date/lib/parse_date.re:396 timelib_meridian

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-09-06 00:55 UTC] stas@php.net
-Assigned To: +Assigned To: derick
 [2016-09-06 00:55 UTC] stas@php.net
Looks like there's a deeper issue hiding here: 

When parsing Dec 08:00AM 0 it is interpreted as Dec being month and 08 being day, which makes 00 hour, and AM has disappeared when trying to get minute, so timelib_meridian never sees it. So looks like such string should be rejected, but it is not rejected. 

Derick, could you take a look? I can fix the read-past-end issue, but I feel like the real fix should be in other place.
 [2018-01-02 04:59 UTC] stas@php.net
-Status: Assigned +Status: Feedback
 [2018-01-02 04:59 UTC] stas@php.net
Doesn't seem to happen for me with recent code, is it still reproducible?
 [2018-01-02 18:16 UTC] stas@php.net
-Status: Feedback +Status: Closed
 [2018-01-02 18:19 UTC] stas@php.net
I see however that the patch was merged only into PHP 7. Since we still have security support for 5.6, could we also merge it into 5.6?
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Thu Jan 02 22:01:28 2025 UTC