Bug #73933 [Opn]: error/segfault with ldap_mod_replace and opcache

From: Date: Mon, 16 Jan 2017 13:07:38 +0000
Subject: Bug #73933 [Opn]: error/segfault with ldap_mod_replace and opcache
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-206668@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=73933&edit=1 ID: 73933 Updated by: nikic@php.net Reported by: ryan dot brothers at gmail dot com Summary: error/segfault with ldap_mod_replace and opcache Status: Open Type: Bug Package: opcache Operating System: Linux PHP Version: 7.1.0 Block user comment: N Private report: N New Comment: @laruence: This only separates the outer array. The inner array(s) also need to be separated. You're right that using zval_get_string() here is inconvenient, because we'd have to release the strings later. Previous Comments: ------------------------------------------------------------------------ [2017-01-16 12:32:25] ryan dot brothers at gmail dot com laruence - thanks, I'm still seeing the segfault or various errors such as "Invalid syntax" or "Encoding error" when repeatedly calling the script with your patch. It always works the first time, but not later runs. Using opcache.protect_memory, you should be able to reproduce the segfault in CLI without having a working LDAP server: php -n -d zend_extension=opcache.so -d opcache.enable_cli=1 -d opcache.protect_memory=1 ldap.php <?php define('AAA', 1); error_reporting(E_ALL); $ldap = ldap_connect('127.0.0.1', 5000); ldap_mod_replace($ldap, null, array( 'lockoutTime' => array(0), )); ldap_close($ldap); ------------------------------------------------------------------------ [2017-01-16 03:45:09] laruence@php.net @nikic didn't notice your comment, it can not be done by changing convert to zval_get_string, since it require an place to hold the zend_string(ldap using char * directly). so, separate array is a better way to fix this. ------------------------------------------------------------------------ [2017-01-16 03:37:23] laruence@php.net I think it is because ldap edit the const array argument in place, please try with the following patch: diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index 4068384..5c1b6da 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -1427,7 +1427,7 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper) zend_ulong index; int is_full_add=0; /* flag for full add operation so ldap_mod_add can be put back into oper, gerrit THomson */ - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rsa", &link, &dn, &dn_len, &entry) != SUCCESS) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "rsa/", &link, &dn, &dn_len, &entry) != SUCCESS) { return; } thanks ------------------------------------------------------------------------ [2017-01-14 13:05:11] ryan dot brothers at gmail dot com Thanks. Yes, if I do opcache.protect_memory=1, then the segfault happens every time when running over CLI. You should be able to reproduce without a working LDAP server. In my script above, 127.0.0.1:5000 is just a made-up port with nothing listening on it. I'm running this to cause the segfault: php -n -d zend_extension=opcache.so -d opcache.enable_cli=1 -d opcache.protect_memory=1 ldap.php where ldap.php is my test script above. ------------------------------------------------------------------------ [2017-01-14 12:39:03] nikic@php.net Can you do a run with -d opcache.protect_memory=1 and see if there's a consistent bus error? From a quick look, php_ldap_do_modify() is doing in-place string conversions on array elements, which may lead to SHM corruption of immutable arrays. If this is indeed the problem, this should be easy to fix by someone with a working ldap setup by replace convert_to_string_ex with zval_get_string. ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at https://bugs.php.net/bug.php?id=73933 -- Edit this bug report at https://bugs.php.net/bug.php?id=73933&edit=1

« previous php.bugs (#206668) next »