You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
php-cli core dump calling a badly formed function #8841
$ rpm -q php-cli
php-cli-8.1.4-1.el8.remi.x86_64
$ php -n -dauto_prepend_file= -a
Interactive shell
php > echo phpversion();
8.1.4
php > function f ($x): void { return $x;}
Fatal error: A void function must not return a value in php shell code on line 1
php > f(10);
Segmentation fault (core dumped)
Resulted in this output:
Segmentation fault (core dumped)
But I expected this output instead:
Warning: Uncaught Error: Call to undefined function f() in php shell code:1
Well anything but a core dump.
This happens in PHP 7.4 too so it is not a PHP 8.1 regression.
php > var_dump(function_exists("f"));
bool(false)
php > function f ($x): void { return $x;}
Fatal error: A void function must not return a value in php shell code on line 1
php > var_dump(function_exists("f"));
bool(true)
php >
Indeed! When a global function is compiled, it is entered in the global function_table early, and is not removed if the compilation fails. That is usually not an issue, but for the interactive mode it is (might also be an issue for the embed SAPI).
Glad you guys had fun with this one. I thought of this problem generally as one of not making sure that all allocated objects are in some well defined state even in the smallest unit of allocation. It is especially problematic in real-time
garbage collected languages with multiple threads. It is too bad that valgrind does not seem to pick up on this problem at the point of allocation. Here are two tests with valgrind, one with USE_ZEND_ALLOC=0. Now maybe one of the gnu malloc debug options would help detect this at time of allocation, but possibly this kind of check would go too far with PHP.
[webphp-php8gcarrette-dsm1]$ valgrind php -a
==249867== Memcheck, a memory error detector
==249867== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==249867== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==249867== Command: php -a
==249867==
==249867== Warning: set address range perms: large range [0x2415a000, 0x4415a000) (defined)
==249867== Warning: set address range perms: large range [0x59ea1000, 0x79ea1000) (defined)
==249867== Warning: set address range perms: large range [0x59ea1000, 0x79ea1000) (noaccess)
==249867== Warning: set address range perms: large range [0x59ea1000, 0x79ea1000) (defined)
Interactive shell
php > function f($x): void { return $x;}
PHP Fatal error: A void function must not return a value in php shell code on line 1
Fatal error: A void function must not return a value in php shell code on line 1
php > f(10);
==249867== Jump to the invalid address stated on the next line
==249867== at 0x6F20736572756769: ???
==249867== Address 0x6f20736572756769 is not stack'd, malloc'd or (recently) free'd
==249867==
==249867==
==249867== Process terminating with default action of signal 11 (SIGSEGV)
==249867== Bad permissions for mapped region at address 0x6F20736572756769
==249867== at 0x6F20736572756769: ???
==249867==
==249867== HEAP SUMMARY:
==249867== in use at exit: 7,308,710 bytes in 54,023 blocks
==249867== total heap usage: 90,926 allocs, 36,903 frees, 13,148,235 bytes allocated
==249867==
==249867== LEAK SUMMARY:
==249867== definitely lost: 39,272 bytes in 1,226 blocks
==249867== indirectly lost: 40 bytes in 1 blocks
==249867== possibly lost: 5,496,243 bytes in 42,600 blocks
==249867== still reachable: 1,773,155 bytes in 10,196 blocks
==249867== suppressed: 0 bytes in 0 blocks
==249867== Rerun with --leak-check=full to see details of leaked memory
==249867==
==249867== For lists of detected and suppressed errors, rerun with: -s
==249867== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)
Segmentation fault (core dumped)
With USE_ZEND_ALLOC=0
php > f(10);
==250881== Use of uninitialised value of size 8
==250881== at 0x447960: execute_ex (in /usr/bin/php)
==250881== by 0x447BAB: zend_execute (in /usr/bin/php)
==250881== by 0x3C8683: zend_eval_stringl (in /usr/bin/php)
==250881== by 0x2B014D: ??? (in /usr/bin/php)
==250881== by 0x4BF8F5: ??? (in /usr/bin/php)
==250881== by 0x2217C2: ??? (in /usr/bin/php)
==250881== by 0x7F53CA2: (below main) (in /usr/lib64/libc-2.28.so)
==250881==
==250881== Jump to the invalid address stated on the next line
==250881== at 0x0: ???
==250881== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==250881==
==250881==
==250881== Process terminating with default action of signal 11 (SIGSEGV)
==250881== Bad permissions for mapped region at address 0x0
==250881== at 0x0: ???
==250881==
From a quick thinking I'd say it should be up to the SAPI to handle this - not sure if there's much point to handle it for all SAPI's if it's irrelevant for them. So labeling that as cli sapi bug.
Activity
cmb69 commentedon Jun 21, 2022
Probably relevant:
cmb69 commentedon Jun 23, 2022
Indeed! When a global function is compiled, it is entered in the global
function_tableearly, and is not removed if the compilation fails. That is usually not an issue, but for the interactive mode it is (might also be an issue for the embed SAPI).Fix phpGH-8841: error on return type check of func declaration isn't …
gjcarrette commentedon Jul 12, 2022
Glad you guys had fun with this one. I thought of this problem generally as one of not making sure that all allocated objects are in some well defined state even in the smallest unit of allocation. It is especially problematic in real-time
garbage collected languages with multiple threads. It is too bad that valgrind does not seem to pick up on this problem at the point of allocation. Here are two tests with valgrind, one with USE_ZEND_ALLOC=0. Now maybe one of the gnu malloc debug options would help detect this at time of allocation, but possibly this kind of check would go too far with PHP.
With USE_ZEND_ALLOC=0
lucaswerkmeister commentedon Aug 29, 2022
Another way to create a badly formed function is to use the array append operator in an invalid way:
bukka commentedon Sep 8, 2022
From a quick thinking I'd say it should be up to the SAPI to handle this - not sure if there's much point to handle it for all SAPI's if it's irrelevant for them. So labeling that as cli sapi bug.
Fix phpGH-8841: error on return type check of func declaration isn't …
Fix phpGH-8841: php-cli core dump calling a badly formed function
Fix GH-8841: php-cli core dump calling a badly formed function
Merge branch 'PHP-8.1' into PHP-8.2
Merge branch 'PHP-8.2'