Sec Bug->Bug #55748 [Csd]: multiple NULL Pointer Dereference with zend_strndup()
| From: | stas@php.net | Date: | Fri, 18 Nov 2011 08:46:53 +0000 |
| Subject: | Sec Bug->Bug #55748 [Csd]: multiple NULL Pointer Dereference with zend_strndup() | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-165317@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=55748&edit=1
ID: 55748
Updated by: stas@php.net
Reported by: max at cxib dot net
Summary: multiple NULL Pointer Dereference with
zend_strndup()
Status: Closed
-Type: Security
+Type: Bug
Package: *General Issues
Operating System: *
PHP Version: 5.3SVN-2011-09-21 (SVN)
Assigned To: stas
Block user comment: N
Private report: Y
Previous Comments:
------------------------------------------------------------------------
[2011-11-18 07:12:16] stas@php.net
This bug has been fixed in SVN.
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.
------------------------------------------------------------------------
[2011-11-11 11:37:19] max at cxib dot net
use CVE-2011-4153
------------------------------------------------------------------------
[2011-09-21 03:54:24] max at cxib dot net
Description:
------------
multiple NULL Pointer Dereference with zend_strndup()
see zend_strndup()
-zend_alloca.c---
ZEND_API char *zend_strndup(const char *s, uint length)
{
char *p;
p = (char *) malloc(length+1);
if (UNEXPECTED(p == NULL)) {
return p;
}
if (length) {
memcpy(p, s, length);
}
p[length] = 0;
return p;
}
-zend_alloca.c---
in php code, many calls to zend_strndup() dosen't check returned values. In result, places
like:
-zend_builtin_functions.c---
ZEND_FUNCTION(define)
{
char *name;
int name_len;
zval *val;
zval *val_free = NULL;
zend_bool non_cs = 0;
int case_sensitive = CONST_CS;
zend_constant c;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|b", &name, &name_len,
&val, &non_cs) == FAILURE) {
return;
}
...
c.flags = case_sensitive; /* non persistent */
c.name = zend_strndup(name, name_len); <======== MAY RETURN NULL
c.name_len = name_len+1;
c.module_number = PHP_USER_CONSTANT;
if (zend_register_constant(&c TSRMLS_CC) == SUCCESS) {
RETURN_TRUE;
} else {
RETURN_FALSE;
}
}
-zend_builtin_functions.c---
[cx@82 /www]$ ulimit -a
socket buffer size (bytes, -b) unlimited
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) 524288
file size (blocks, -f) unlimited
max locked memory (kbytes, -l) unlimited
max memory size (kbytes, -m) 40000
open files (-n) 11095
pipe size (512 bytes, -p) 1
stack size (kbytes, -s) 65536
cpu time (seconds, -t) unlimited
max user processes (-u) 5547
virtual memory (kbytes, -v) 40000
swap size (kbytes, -w) unlimited
[cx@82 /www]$ cat define.php
<?php
define(str_repeat("A",$argv[1]),"a");
?>
to see difference
[cx@82 /www]$ php define.php 8999999
Out of memory
[cx@82 /www]$ php define.php 9999999
Segmentation fault: 11
(gdb) bt
#0 0x28745eb0 in strrchr () from /lib/libc.so.7
#1 0x0822d538 in zend_register_constant (c=0xbfbfcfb0)
at /usr/ports/lang/php5/work/php/Zend/zend_constants.c:429
#2 0x08251e0e in zif_define (ht=2, return_value=0x28825a98,
return_value_ptr=0x0, this_ptr=0x0, return_value_used=0)
at /usr/ports/lang/php5/work/php/Zend/zend_builtin_functions.c:688
#3 0x0826dba6 in zend_do_fcall_common_helper_SPEC (execute_data=0x29401040)
at zend_vm_execute.h:316
please see also
ext/soap/php_sdl.c
if (sdl->is_persistent) {
new_enc->details.ns = zend_strndup(ns, ns_len);
new_enc->details.type_str = strdup(new_enc->details.type_str);
} else {
new_enc->details.ns = estrndup(ns, ns_len);
new_enc->details.type_str = estrdup(new_enc->details.type_str);
}
ext/standard/syslog.c
BG(syslog_device) = zend_strndup(ident, ident_len);
openlog(BG(syslog_device), option, facility);
RETURN_TRUE;
ext/standard/browscap.c
} else { /* Other than true/false setting */
Z_STRVAL_P(new_property) = zend_strndup(Z_STRVAL_P(arg2), Z_STRLEN_P(arg2));
Z_STRLEN_P(new_property) = Z_STRLEN_P(arg2);
}
new_key = zend_strndup(Z_STRVAL_P(arg1), Z_STRLEN_P(arg1));
zend_str_tolower(new_key, Z_STRLEN_P(arg1));
zend_hash_update(Z_ARRVAL_P(current_section), new_key, Z_STRLEN_P(arg1) + 1, &new_property,
sizeof(zval *), NULL);
free(new_key);
ext/oci8/oci8.c
if (alloc_non_persistent) {
connection = (php_oci_connection *) ecalloc(1, sizeof(php_oci_connection));
connection->hash_key = estrndup(hashed_details.c, hashed_details.len);
connection->is_persistent = 0;
} else {
connection = (php_oci_connection *) calloc(1, sizeof(php_oci_connection));
connection->hash_key = zend_strndup(hashed_details.c, hashed_details.len);
connection->is_persistent = 1;
}
ext/com_dotnet/com_typeinfo.c
const_name = php_com_olestring_to_string(bstr_ids, &c.name_len, codepage TSRMLS_CC);
c.name = zend_strndup(const_name, c.name_len);
efree(const_name);
c.name_len++; /* include NUL */
SysFreeString(bstr_ids);
/* sanity check for the case where the constant is already defined */
if (zend_get_constant(c.name, c.name_len - 1, &exists TSRMLS_CC)) {
if (COMG(autoreg_verbose) && !compare_function(&results, &c.value, &exists
TSRMLS_CC)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type library constant %s is already
defined", c.name);
}
free(c.name);
ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc);
continue;
}
main/php_open_temporary_file.c
/* On Unix use the (usual) TMPDIR environment variable. */
{
char* s = getenv("TMPDIR");
if (s && *s) {
int len = strlen(s);
if (s[len - 1] == DEFAULT_SLASH) {
temporary_directory = zend_strndup(s, len - 1);
} else {
temporary_directory = zend_strndup(s, len);
}
return temporary_directory;
}
Test script:
---------------
<?php
define(str_repeat("A",$argv[1]),"a");
?>
Expected result:
----------------
[cx@82 /www]$ php define.php 8999999
Out of memory
Actual result:
--------------
[cx@82 /www]$ php define.php 9999999
Segmentation fault: 11
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=55748&edit=1