Bug #81316 [Ana->Csd]: Segfault in getenv() during intl mshutdown caused by imap rshutdown failure
| From: | nikic@php.net | Date: | Tue, 17 Aug 2021 09:09:14 +0000 |
| Subject: | Bug #81316 [Ana->Csd]: Segfault in getenv() during intl mshutdown caused by imap rshutdown failure | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-235892@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=81316&edit=1
ID: 81316
Updated by: nikic@php.net
Reported by: kontakt at xlu dot pl
Summary: Segfault in getenv() during intl mshutdown caused by
imap rshutdown failure
-Status: Analyzed
+Status: Closed
Type: Bug
Package: Scripting Engine problem
Operating System: FreeBSD 12.2-RELEASE-p5
PHP Version: 7.4.22
-Assigned To:
+Assigned To: nikic
Block user comment: N
Private report: N
New Comment:
For PHP 7.4, I've applied a basic mitigation in https://github.com/php/php-src/commit/bcc2f0705d92f39a9936794880453c84088dea88.
For master, I've also changed shutdown to always run all RSHUTDOWN handlers, even if one of
them fails: https://github.com/php/php-src/commit/cf6c354e1f0dd1fd66101ea89eccec3ca9c87b0c
Finally, https://github.com/php/php-src/commit/b56699b8f085a5ae441b08e2d2230221b4ad882c
changes the putenv_string to use the system allocator, so that even if we don't restore the
environment, things will at least not crash.
Previous Comments:
------------------------------------------------------------------------
[2021-08-16 16:14:41] nikic@php.net
To add two more alternatives: putenv could use system allocated strings, so they at least remain
valid if the environment is not reset. And imap could catch bailouts from error reporting -- and
possibly there shouldn't be a bailout here in the first place.
Or some combination of all the above.
------------------------------------------------------------------------
[2021-08-16 15:05:35] nikic@php.net
The problem is that https://github.com/php/php-src/blob/cecea72a10aa6470b3426a8d2f905f5ef2fe29b3/ext/imap/php_imap.c#L709
throws an error, which is converted into an exception by a custom error handler, which results in an
uncaught exception, which results in a bailout, which results in remaining RSHUTDOWN handlers being
skipped.
This includes the RSHUTDOWN for basic, which will restore the environment. This means that environ
now points to ZMM allocated strings, which get released on request shutdown.
Now on module shutdown, intl uses getenv() and tries to read the deallocated strings.
I'm not entirely sure what the correct way to address this is. Probably we should be running
all RSHUTDOWN handlers even if one fails.
------------------------------------------------------------------------
[2021-08-16 14:35:36] nikic@php.net
I can reproduce the segfault:
#0 0x00007ffff68b00cd in getenv () from /usr/lib/x86_64-linux-gnu/libc.so.6
#1 0x0000555555871bc6 in zm_shutdown_intl (type=1, module_number=26)
at /home/nikic/php/php-7.4/ext/intl/php_intl.c:998
#2 0x0000555555cc004e in module_destructor (module=0x555556a6f210)
at /home/nikic/php/php-7.4/Zend/zend_API.c:2563
#3 0x0000555555cb29c4 in module_destructor_zval (zv=0x7fffffffdb20)
at /home/nikic/php/php-7.4/Zend/zend.c:768
#4 0x0000555555ccc352 in _zend_hash_del_el_ex (ht=0x555556a2ce00 <module_registry>, idx=25,
p=0x555556a76b70, prev=0x0) at /home/nikic/php/php-7.4/Zend/zend_hash.c:1305
#5 0x0000555555ccc431 in _zend_hash_del_el (ht=0x555556a2ce00 <module_registry>, idx=25,
p=0x555556a76b70) at /home/nikic/php/php-7.4/Zend/zend_hash.c:1328
#6 0x0000555555ccdd5d in zend_hash_graceful_reverse_destroy (ht=0x555556a2ce00
<module_registry>)
at /home/nikic/php/php-7.4/Zend/zend_hash.c:1782
#7 0x0000555555cbdb08 in zend_destroy_modules () at /home/nikic/php/php-7.4/Zend/zend_API.c:1995
#8 0x0000555555cb3181 in zend_shutdown () at /home/nikic/php/php-7.4/Zend/zend.c:1055
#9 0x0000555555c1476b in php_module_shutdown () at /home/nikic/php/php-7.4/main/main.c:2518
#10 0x0000555555d9e7b7 in main (argc=3, argv=0x555556a67c10)
at /home/nikic/php/php-7.4/sapi/cli/php_cli.c:1375
------------------------------------------------------------------------
[2021-08-09 08:48:18] cmb@php.net
Thanks for the further info! I still can't reproduce the
segfault, though. From looking at the backtrace, it happens
during shutdown, and I guess the memory corruption happened
earlier, and only manifests there.
------------------------------------------------------------------------
[2021-08-05 19:24:40] kontakt at xlu dot pl
I performed tests on php 7.4.22:
php -v
PHP 7.4.22 (cli) (built: Aug 5 2021 17:05:59) ( NTS DEBUG )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
php -m
[PHP Modules]
Core
ctype
curl
date
dom
fileinfo
filter
hash
iconv
imap
json
libxml
mbstring
mysqli
mysqlnd
openssl
pcre
PDO
pdo_sqlite
Phar
posix
Reflection
session
SimpleXML
SPL
sqlite3
standard
tokenizer
xml
xmlreader
xmlwriter
[Zend Modules]
Config .env file:
MAIL_FETCH_HOST=imap.gmail.com
MAIL_FETCH_PORT=995
MAIL_FETCH_USERNAME=test@gmail.com
MAIL_FETCH_PASSWORD=BADpassword
MAIL_FETCH_OPTIONS=/pop3
MAIL_FETCH_USE_SSL=true
I got the result:
php artisan handesk:parseNewEmails
In Mailbox.php line 67:
Connection error: Can not authenticate to POP3 server: [AUTH] Username and password not accepted.
zend_mm_heap corrupted
Segmentation fault (core dumped)
GDB tests:
myusername@myusername-laptop:~/handesk/handesk-1.4.2$ gdb php
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from php...
(gdb) run artisan handesk:parseNewEmails
Starting program: /home/myusername/bin/php artisan handesk:parseNewEmails
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
In Mailbox.php line 67:
Connection error: Can not authenticate to POP3 server: [AUTH] Authentication failed.
zend_mm_heap corrupted
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff73f355b in kill () at ../sysdeps/unix/syscall-template.S:78
78 ../sysdeps/unix/syscall-template.S: Nie ma takiego pliku ani katalogu.
(gdb) bt
#0 0x00007ffff73f355b in kill () at ../sysdeps/unix/syscall-template.S:78
#1 0x0000555555af42ec in zend_mm_panic (message=0x555556571c2d "zend_mm_heap corrupted")
at /home/myusername/php/php-7.4.22/Zend/zend_alloc.c:364
#2 0x0000555555af6131 in zend_mm_free_heap (heap=0x7ffff4600040, ptr=0x7ffff30be3f0,
__zend_filename=0x555555eb39a8 "/home/myusername/php/php-7.4.22/ext/date/lib/timelib.c",
__zend_lineno=164, __zend_orig_filename=0x0, __zend_orig_lineno=0) at
/home/myusername/php/php-7.4.22/Zend/zend_alloc.c:1368
#3 0x0000555555af8d51 in _efree (ptr=0x7ffff30be3f0, __zend_filename=0x555555eb39a8
"/home/myusername/php/php-7.4.22/ext/date/lib/timelib.c", __zend_lineno=164,
__zend_orig_filename=0x0,
__zend_orig_lineno=0) at /home/myusername/php/php-7.4.22/Zend/zend_alloc.c:2550
#4 0x0000555555661a88 in timelib_error_container_dtor (errors=0x7ffff30be3f0) at
/home/myusername/php/php-7.4.22/ext/date/lib/timelib.c:164
#5 0x000055555560a72b in zm_shutdown_date (type=1, module_number=2) at
/home/myusername/php/php-7.4.22/ext/date/php_date.c:927
#6 0x0000555555b3fdbc in module_destructor (module=0x555556a7f1a0) at
/home/myusername/php/php-7.4.22/Zend/zend_API.c:2563
#7 0x0000555555b3272c in module_destructor_zval (zv=0x7fffffffdbc0) at
/home/myusername/php/php-7.4.22/Zend/zend.c:768
#8 0x0000555555b4c079 in _zend_hash_del_el_ex (ht=0x555556a25e20 <module_registry>, idx=1,
p=0x555556a67700, prev=0x0) at /home/myusername/php/php-7.4.22/Zend/zend_hash.c:1305
#9 0x0000555555b4c159 in _zend_hash_del_el (ht=0x555556a25e20 <module_registry>, idx=1,
p=0x555556a67700) at /home/myusername/php/php-7.4.22/Zend/zend_hash.c:1328
#10 0x0000555555b4da8d in zend_hash_graceful_reverse_destroy (ht=0x555556a25e20
<module_registry>) at /home/myusername/php/php-7.4.22/Zend/zend_hash.c:1782
#11 0x0000555555b3d872 in zend_destroy_modules () at
/home/myusername/php/php-7.4.22/Zend/zend_API.c:1995
#12 0x0000555555b32ee9 in zend_shutdown () at /home/myusername/php/php-7.4.22/Zend/zend.c:1055
#13 0x0000555555a917b8 in php_module_shutdown () at /home/myusername/php/php-7.4.22/main/main.c:2518
#14 0x0000555555c1e29e in main (argc=3, argv=0x555556a59670) at
/home/myusername/php/php-7.4.22/sapi/cli/php_cli.c:1375
(gdb)
The problem appears when the "MAIL_FETCH" configuration in .env is incorrect or using port
110 and nonssl.
------------------------------------------------------------------------
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=81316
--
Edit this bug report at https://bugs.php.net/bug.php?id=81316&edit=1