Bug #72743 [Opn->Csd]: Out-of-bound read in php_stream_filter_create
| From: | laruence@php.net | Date: | Thu, 04 Aug 2016 11:11:08 +0000 |
| Subject: | Bug #72743 [Opn->Csd]: Out-of-bound read in php_stream_filter_create | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-202916@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=72743&edit=1
ID: 72743
Updated by: laruence@php.net
Reported by: loianhtuan at gmail dot com
Summary: Out-of-bound read in php_stream_filter_create
-Status: Open
+Status: Closed
Type: Bug
Package: Filter related
PHP Version: 7.1Git-2016-08-03 (Git)
Block user comment: N
Private report: N
New Comment:
Automatic comment on behalf of laruence@gmail.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=3800e1cf970ce78c565e98803f799fa50737ecc6
Log: Fixed bug #72743 (Out-of-bound read in php_stream_filter_create)
Previous Comments:
------------------------------------------------------------------------
[2016-08-03 07:59:55] loianhtuan at gmail dot com
Description:
------------
Actually OOB read occurs within zend_inline_hash_func when the len is casting from negative integer
to size_t.
<snippet main\streams\filter.c:250>
PHPAPI php_stream_filter *php_stream_filter_create(const char *filtername, zval *filterparams, int
persistent)
{
HashTable *filter_hash = (FG(stream_filters) ? FG(stream_filters) : &stream_filters_hash);
php_stream_filter_factory *factory = NULL;
php_stream_filter *filter = NULL;
int n;
char *period;
n = (int)strlen(filtername); //n become negative
if (NULL != (factory = zend_hash_str_find_ptr(filter_hash, filtername, n))) { //parameter expect 64
bit size_t
</snippet>
<snippet Zend/zend_string.h:325>
static zend_always_inline zend_ulong zend_inline_hash_func(const char *str, size_t len)
{
zend_ulong hash = Z_UL(5381);
/* variant with the hash unrolled eight times */
for (; len >= 8; len -= 8) { //len here is 64bit and very big
hash = ((hash << 5) + hash) + *str++;
</snippet>
proposed patch below only patch the filter_create function. zend_inline_hash_func may need a proper
check too, but I don't know how:
--- a/main/streams/filter.c
+++ b/main/streams/filter.c
@@ -252,10 +252,10 @@ PHPAPI php_stream_filter *php_stream_filter_create(const char *filtername,
zval
HashTable *filter_hash = (FG(stream_filters) ? FG(stream_filters) :
&stream_filters_hash);
php_stream_filter_factory *factory = NULL;
php_stream_filter *filter = NULL;
- int n;
+ size_t n;
char *period;
- n = (int)strlen(filtername);
+ n = strlen(filtername);
if (NULL != (factory = zend_hash_str_find_ptr(filter_hash, filtername, n))) {
filter = factory->create_filter(filtername, filterparams, persistent);
Test script:
---------------
<?php
ini_set('memory_limit',-1);
$fp =
fopen('php://filter/'.str_repeat("A",0x80000000).'/resource=foo',
'w+');
?>
Expected result:
----------------
PHP Warning: fopen(): unable to locate filter
Actual result:
--------------
Stopped reason: SIGSEGV
0x000000000085ef0f in zend_inline_hash_func (str=0x7ffff5a01001 <error: Cannot access memory at
address 0x7ffff5a01001>,
len=0xfffffffefffff008) at /home/vps/git/php-src/Zend/zend_string.h:338
338 hash = ((hash << 5) + hash) + *str++;
gdb-peda$ bt
#0 0x000000000085ef0f in zend_inline_hash_func (str=0x7ffff5a01001 <error: Cannot access memory
at address 0x7ffff5a01001>,
len=0xfffffffefffff008) at /home/vps/git/php-src/Zend/zend_string.h:338
#1 0x0000000000864f09 in zend_hash_str_find (ht=0x10cac80 <stream_filters_hash>,
str=0x7fff75a00001 'A' <repeats 200 times>...,
len=0xffffffff80000000) at /home/vps/git/php-src/Zend/zend_hash.c:1967
#2 0x00000000007ddce0 in zend_hash_str_find_ptr (ht=0x10cac80 <stream_filters_hash>,
str=0x7fff75a00001 'A' <repeats 200 times>...,
len=0xffffffff80000000) at /home/vps/git/php-src/Zend/zend_hash.h:717
#3 0x00000000007de76e in php_stream_filter_create (filtername=0x7fff75a00001 'A'
<repeats 200 times>..., filterparams=0x0, persistent=0x0)
at /home/vps/git/php-src/main/streams/filter.c:260
#4 0x000000000078a370 in php_stream_apply_filter_list (stream=0x7ffff685fb40,
filterlist=0x7fff75a00001 'A' <repeats 200 times>...,
read_chain=0x1, write_chain=0x2) at /home/vps/git/php-src/ext/standard/php_fopen_wrapper.c:156
#5 0x000000000078af78 in php_stream_url_wrap_php (wrapper=0x10a6950 <php_stream_php_wrapper>,
path=0x7ffef580001e "filter/", 'A' <repeats 193 times>...,
mode=0x7ffff6858d58 "w+", options=0x0, opened_path=0x0,
context=0x7ffff6858e00, __php_stream_call_depth=0x1, __zend_filename=0xd723f8
"/home/vps/git/php-src/main/streams/streams.c",
__zend_lineno=0x809, __zend_orig_filename=0xd550d0
"/home/vps/git/php-src/ext/standard/file.c", __zend_orig_lineno=0x366)
at /home/vps/git/php-src/ext/standard/php_fopen_wrapper.c:375
#6 0x00000000007da8db in _php_stream_open_wrapper_ex (path=0x7ffef5800018
"php://filter/", 'A' <repeats 187 times>...,
mode=0x7ffff6858d58 "w+", options=0x8, opened_path=0x0, context=0x7ffff6858e00,
__php_stream_call_depth=0x0,
__zend_filename=0xd550d0 "/home/vps/git/php-src/ext/standard/file.c",
__zend_lineno=0x366, __zend_orig_filename=0x0,
__zend_orig_lineno=0x0) at /home/vps/git/php-src/main/streams/streams.c:2055
#7 0x0000000000730e32 in php_if_fopen (execute_data=0x7ffff6814110, return_value=0x7ffff68140d0)
at /home/vps/git/php-src/ext/standard/file.c:870
#8 0x0000000000670167 in phar_fopen (execute_data=0x7ffff6814110, return_value=0x7ffff68140d0)
at /home/vps/git/php-src/ext/phar/func_interceptors.c:427
#9 0x00000000008ae50b in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER () at
/home/vps/git/php-src/Zend/zend_vm_execute.h:675
#10 0x00000000008adc2e in execute_ex (ex=0x7ffff6814030) at
/home/vps/git/php-src/Zend/zend_vm_execute.h:429
#11 0x00000000008add40 in zend_execute (op_array=0x7ffff687d000, return_value=0x0) at
/home/vps/git/php-src/Zend/zend_vm_execute.h:474
#12 0x000000000084e490 in zend_execute_scripts (type=0x8, retval=0x0, file_count=0x3) at
/home/vps/git/php-src/Zend/zend.c:1447
#13 0x00000000007b9126 in php_execute_script (primary_file=0x7fffffffd6c0) at
/home/vps/git/php-src/main/main.c:2533
#14 0x000000000092d910 in do_cli (argc=0x2, argv=0x10d5770) at
/home/vps/git/php-src/sapi/cli/php_cli.c:990
#15 0x000000000092ead4 in main (argc=0x2, argv=0x10d5770) at
/home/vps/git/php-src/sapi/cli/php_cli.c:1378
#16 0x00007ffff6faaf45 in __libc_start_main (main=0x92e2cc <main>, argc=0x2,
argv=0x7fffffffea68, init=<optimized out>, fini=<optimized out>,
rtld_fini=<optimized out>, stack_end=0x7fffffffea58) at libc-start.c:287
#17 0x0000000000422ca9 in _start ()
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=72743&edit=1