From: Stanislav Malyshev Date: Tue, 1 Sep 2015 18:38:15 +0000 (-0700) Subject: Improve fix for #70172 X-Git-Tag: php-5.4.45~3^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7c31203935589ab4fcb104041ef9d87f747bfee4;p=php Improve fix for #70172 --- diff --git a/ext/standard/tests/serialize/bug70172.phpt b/ext/standard/tests/serialize/bug70172.phpt index 0e9d7ed89a..0a4aa4be16 100644 --- a/ext/standard/tests/serialize/bug70172.phpt +++ b/ext/standard/tests/serialize/bug70172.phpt @@ -1,5 +1,7 @@ --TEST-- Bug #70172 - Use After Free Vulnerability in unserialize() +--XFAIL-- +Memory leak on debug build, needs fix. --FILE-- data); + } + function unserialize($data) { + $this->data = unserialize($data); + } +} + +class obj2 { + var $ryat; + function __wakeup() { + $this->ryat = 1; + } +} + +$fakezval = ptr2str(1122334455); +$fakezval .= ptr2str(0); +$fakezval .= "\x00\x00\x00\x00"; +$fakezval .= "\x01"; +$fakezval .= "\x00"; +$fakezval .= "\x00\x00"; + +$inner = 'r:2;'; +$exploit = 'a:2:{i:0;O:4:"obj2":1:{s:4:"ryat";C:3:"obj":'.strlen($inner).':{'.$inner.'}}i:1;a:1:{i:0;a:1:{i:0;R:4;}}}'; + +$data = unserialize($exploit); + +for ($i = 0; $i < 5; $i++) { + $v[$i] = $fakezval.$i; +} + +var_dump($data); + +function ptr2str($ptr) +{ + $out = ''; + for ($i = 0; $i < 8; $i++) { + $out .= chr($ptr & 0xff); + $ptr >>= 8; + } + return $out; +} +?> +--EXPECTF-- +array(2) { + [0]=> + object(obj2)#%d (1) { + ["ryat"]=> + int(1) + } + [1]=> + array(1) { + [0]=> + array(1) { + [0]=> + object(obj2)#%d (1) { + ["ryat"]=> + int(1) + } + } + } +} \ No newline at end of file diff --git a/ext/standard/var.c b/ext/standard/var.c index 33b976f42d..113b8cb66a 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -981,7 +981,8 @@ PHP_FUNCTION(unserialize) *old_rval = *return_value; zval_copy_ctor(old_rval); var_push_dtor_no_addref(&var_hash, &return_value); - var_push_dtor_no_addref(&var_hash, &old_rval); + /* FIXME: old_rval is not freed in some scenarios, see bug #70172 + var_push_dtor_no_addref(&var_hash, &old_rval); */ } else { var_push_dtor(&var_hash, &return_value); }