php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #72708 php_snmp_parse_oid integer overflow in memory allocation
Submitted: 2016-07-29 17:34 UTC Modified: 2017-02-13 01:37 UTC
From: djodjo at gmail dot com Assigned: stas
Status: Closed Package: SNMP related
PHP Version: 5.6.24 OS:
Private report: No CVE-ID:
 [2016-07-29 17:34 UTC] djodjo at gmail dot com
Description:
------------
In the php_snmp_parse_oid function, when the oid argument is an array, an integer overflow is exploitable to trigger an out-of-bounds write on an allocated buffer. This is only exploitable on 32 bits installations.

The size of this buffer is the result of the multiplication of the number of elements in oid with sizeof(snmpobjarg), which is 528 on my 32 bits system:

1006         } else if (Z_TYPE_P(oid) == IS_ARRAY) { /* we got objid array */
...
1011                 objid_query->vars = (snmpobjarg *)emalloc(sizeof(snmpobjarg) * zend_hash_num_elements(Z_ARRVAL_P(oid)));

By providing an array of 8,134,408 elements, the multiplication overflows and only 128 bytes are allocated. The code then loops over all elements of oid, and writes to the buffer:

1018                 ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(oid), tmp_oid) {
1019                         convert_to_string_ex(tmp_oid);
1020                         objid_query->vars[objid_query->count].oid = Z_STRVAL_P(tmp_oid);
...
1071                         objid_query->count++;
1072                 } ZEND_HASH_FOREACH_END();

This code will write past the end of the allocated buffer (test script and backtrace provided below).

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

ini_set('memory_limit', '512M');
$arr = array();
for ($i = 0; $i < 8134408; $i++)
{
	$arr[$i] = $i;
}
snmp3_set("", "", "", "", "", "", "", $arr, "", "");

Expected result:
----------------
Error in allocation:

Fatal error: Possible integer overflow in memory allocation (8134408 * 528 + 0) in snmpset.php on line 9

Actual result:
--------------
Program received signal SIGSEGV, Segmentation fault.
php_snmp_parse_oid (value=0xb74131c0, type=0xb74131b0, oid=<optimized out>, objid_query=0xbfffbc7c, st=4, object=0x0) at ext/snmp/snmp.c:1023
1023				objid_query->vars[objid_query->count].oid = Z_STRVAL_P(tmp_oid);
(gdb) bt
#0  php_snmp_parse_oid (value=0xb74131c0, type=0xb74131b0, oid=<optimized out>, objid_query=0xbfffbc7c, st=4, object=0x0) at ext/snmp/snmp.c:1023
#1  php_snmp (execute_data=0xb7413100, return_value=0xb74130f0, st=4, version=3) at ext/snmp/snmp.c:1494
#2  0x0835bd5d in ZEND_DO_ICALL_SPEC_HANDLER () at Zend/zend_vm_execute.h:586
#3  0x0834e75a in execute_ex (ex=0xb7413020) at Zend/zend_vm_execute.h:414
#4  0x0839413d in zend_execute (op_array=op_array@entry=0xb74661e0, return_value=return_value@entry=0x0) at Zend/zend_vm_execute.h:458
#5  0x08315570 in zend_execute_scripts (type=type@entry=8, retval=retval@entry=0x0, file_count=file_count@entry=3) at Zend/zend.c:1427
#6  0x082b99db in php_execute_script (primary_file=primary_file@entry=0xbfffdfa8) at main/main.c:2494
#7  0x08395e8a in do_cli (argc=argc@entry=2, argv=argv@entry=0x88a9ec0) at sapi/cli/php_cli.c:974
#8  0x080707ed in main (argc=2, argv=0x88a9ec0) at sapi/cli/php_cli.c:1344


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-07-29 17:36 UTC] djodjo at gmail dot com
It seems I cannot add a patch file as the bug is private, so here it is:

diff --git a/ext/snmp/snmp.c b/ext/snmp/snmp.c
index b32b845..c4e9279 100644
--- a/ext/snmp/snmp.c
+++ b/ext/snmp/snmp.c
@@ -1008,7 +1008,7 @@ static int php_snmp_parse_oid(zval *object, int st, struct objid_query *objid_qu
 			php_error_docref(NULL, E_WARNING, "Got empty OID array");
 			return FALSE;
 		}
-		objid_query->vars = (snmpobjarg *)emalloc(sizeof(snmpobjarg) * zend_hash_num_elements(Z_ARRVAL_P(oid)));
+		objid_query->vars = (snmpobjarg *)safe_emalloc(zend_hash_num_elements(Z_ARRVAL_P(oid)), sizeof(snmpobjarg), 0);
 		if (objid_query->vars == NULL) {
 			php_error_docref(NULL, E_WARNING, "emalloc() failed while parsing oid array: %s", strerror(errno));
 			efree(objid_query->vars);
 [2016-08-04 05:38 UTC] stas@php.net
Fix as c3f6d6da100c6451a540680504de4105b8bed83c in security repo.
 [2016-08-04 05:39 UTC] stas@php.net
-PHP Version: 7.1Git-2016-07-29 (Git) +PHP Version: 5.6.24 -Assigned To: +Assigned To: stas
 [2016-08-17 05:57 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=da316b50bdad5850a18b1146f712395093c8f570
Log: Fix bug #72708 - php_snmp_parse_oid integer overflow in memory allocation
 [2016-08-17 05:57 UTC] stas@php.net
-Status: Assigned +Status: Closed
 [2016-08-17 08:23 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=da316b50bdad5850a18b1146f712395093c8f570
Log: Fix bug #72708 - php_snmp_parse_oid integer overflow in memory allocation
 [2016-08-17 08:23 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=b735a4419c1e796520b395a2aa0b6943d9157b73
Log: Fix bug #72708 - php_snmp_parse_oid integer overflow in memory allocation
 [2016-08-17 09:15 UTC] laruence@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=da316b50bdad5850a18b1146f712395093c8f570
Log: Fix bug #72708 - php_snmp_parse_oid integer overflow in memory allocation
 [2016-08-17 09:15 UTC] laruence@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=b735a4419c1e796520b395a2aa0b6943d9157b73
Log: Fix bug #72708 - php_snmp_parse_oid integer overflow in memory allocation
 [2016-08-17 12:04 UTC] ab@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=72d03f8aa460184930cbca3f61de3cec35128e2b
Log: Fix bug #72708 - php_snmp_parse_oid integer overflow in memory allocation
 [2016-08-18 11:15 UTC] tyrael@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=b9ab6e14ffd602d2020da53be44bf2e77aae7b55
Log: Fix bug #72708 - php_snmp_parse_oid integer overflow in memory allocation
 [2016-10-17 10:09 UTC] bwoebi@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=da316b50bdad5850a18b1146f712395093c8f570
Log: Fix bug #72708 - php_snmp_parse_oid integer overflow in memory allocation
 [2016-10-17 10:09 UTC] bwoebi@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=b735a4419c1e796520b395a2aa0b6943d9157b73
Log: Fix bug #72708 - php_snmp_parse_oid integer overflow in memory allocation
 [2017-02-13 01:37 UTC] stas@php.net
-Type: Security +Type: Bug
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Fri Jun 23 06:01:39 2017 UTC