php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #79812 Potential integer overflow in pcntl_exec()
Submitted: 2020-07-08 22:54 UTC Modified: 2021-04-08 16:04 UTC
Votes:1
Avg. Score:3.0 ± 0.0
Reproduced:0 of 0 (0.0%)
From: grigoritchy at gmail dot com Assigned: cmb (profile)
Status: Closed Package: PCNTL related
PHP Version: 7.4.7 OS: Unix
Private report: No CVE-ID: None
 [2020-07-08 22:54 UTC] grigoritchy at gmail dot com
Description:
------------
There is integer overflow vulnerability in pcntl_exec function when the string length of env key and element are added.

----- ext/pcntl/pcntl.c -----
PHP_FUNCTION(pcntl_exec)
{
	...
	int pair_length;
	...
	if ( ZEND_NUM_ARGS() == 3 ) {
	...
		ZEND_HASH_FOREACH_KEY_VAL(envs_hash, key_num, key, element) {
			...
			pair_length = Z_STRLEN_P(element) + ZSTR_LEN(key) + 2;
			*pair = emalloc(pair_length);
			strlcpy(*pair, ZSTR_VAL(key), ZSTR_LEN(key) + 1);
			strlcat(*pair, "=", pair_length);
			strlcat(*pair, Z_STRVAL_P(element), pair_length);

			/* Cleanup */
			zend_string_release_ex(key, 0);
			envi++;
			pair++;
		} ZEND_HASH_FOREACH_END();
		...
---------------------------

pcntl_exec function get string path and optinal arugments array of path and environment array from user. If the function argument have environment array, it tries to save key-value pair of enviornment array at the `pair` 2d array variable.

But since `pair_length` variable that added by string length of key-value pair type is signed 32bit integer, it can happens integer overflow if the result of `Z_STRLEN_P(element) + ZSTR_LEN(key) + 2` is larger than 0xffffffff. So when `emalloc(pair_length)` allocate the heap with integer overflown `pair_length` variable, it will allocates the heap less than expected key-value pair length. 
Then by next third lines of code that call strlcpy, strlcat used `*pair` as destination, it will leads to heap buffer overflow.


Test script:
---------------
<?php
   ini_set('memory_limit', -1);
   pcntl_exec("/bin/ls", [], [str_repeat("A", 0xffffffff)=>"val"]);
?>


Expected result:
----------------
No Segmentation Fault

Actual result:
--------------
# gdb `which php` -q
Reading symbols from /usr/local/bin/php...done.
(gdb) r poc.php
Starting program: /usr/local/bin/php poc.php
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x0000555555864ead in php_strlcpy (dst=0x7ffff3c00001 <error: Cannot access memory at address 0x7ffff3c00001>, src=0x7ffef3779011 'A' <repeats 200 times>..., src@entry=0x7ffef3600018 'A' <repeats 200 times>..., siz=<optimized out>)
    at /home/ubuntu/php-7.4.7/main/strlcpy.c:75
75				if ((*dst++ = *src++) == 0)
(gdb) bt
#0  0x0000555555864ead in php_strlcpy (dst=0x7ffff3c00001 <error: Cannot access memory at address 0x7ffff3c00001>, src=0x7ffef3779011 'A' <repeats 200 times>..., src@entry=0x7ffef3600018 'A' <repeats 200 times>..., siz=<optimized out>)
    at /home/ubuntu/php-7.4.7/main/strlcpy.c:75
#1  0x00005555557493f2 in zif_pcntl_exec (execute_data=<optimized out>, return_value=0x7fffffffac00) at /home/ubuntu/php-7.4.7/ext/pcntl/pcntl.c:1020
#2  0x000055555593ef87 in ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER () at /home/ubuntu/php-7.4.7/Zend/zend_vm_execute.h:1269
#3  execute_ex (ex=0x7ffff3c00001) at /home/ubuntu/php-7.4.7/Zend/zend_vm_execute.h:53802
#4  0x0000555555945ef4 in zend_execute (op_array=0x7ffff3a7c2a0, return_value=<optimized out>) at /home/ubuntu/php-7.4.7/Zend/zend_vm_execute.h:57922
#5  0x00005555558ba8f2 in zend_execute_scripts (type=type@entry=8, retval=0x7ffff3a8d1a0, retval@entry=0x0, file_count=-207540192, file_count@entry=3) at /home/ubuntu/php-7.4.7/Zend/zend.c:1672
#6  0x0000555555859770 in php_execute_script (primary_file=0x7fffffffd1c0) at /home/ubuntu/php-7.4.7/main/main.c:2621
#7  0x0000555555947ee3 in do_cli (argc=2, argv=0x5555563869d0) at /home/ubuntu/php-7.4.7/sapi/cli/php_cli.c:961
#8  0x0000555555651e46 in main (argc=2, argv=0x5555563869d0) at /home/ubuntu/php-7.4.7/sapi/cli/php_cli.c:1356


Patches

Add a Patch

Pull Requests

Pull requests:

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-07-08 23:03 UTC] stas@php.net
-Type: Security +Type: Bug
 [2021-04-08 16:04 UTC] cmb@php.net
-Summary: Integer overflow in pcntl_exec that lead to heap buffer overflow +Summary: Potential integer overflow in pcntl_exec() -Status: Open +Status: Verified -Assigned To: +Assigned To: cmb
 [2021-04-08 16:05 UTC] cmb@php.net
The following pull request has been associated:

Patch Name: Fix #79812: Potential integer overflow in pcntl_exec()
On GitHub:  https://github.com/php/php-src/pull/6845
Patch:      https://github.com/php/php-src/pull/6845.patch
 [2021-04-12 10:18 UTC] git@php.net
Automatic comment on behalf of cmb69
Revision: https://github.com/php/php-src/commit/0a36d417e87680afcd9d3108650aaa287524ce30
Log: Fix #79812: Potential integer overflow in pcntl_exec()
 [2021-04-12 10:18 UTC] git@php.net
-Status: Verified +Status: Closed
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Mar 28 14:01:29 2024 UTC