php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #81316 Segfault in getenv() during intl mshutdown caused by imap rshutdown failure
Submitted: 2021-07-30 20:07 UTC Modified: 2021-08-17 09:09 UTC
From: kontakt at xlu dot pl Assigned: nikic (profile)
Status: Closed Package: Scripting Engine problem
PHP Version: 7.4.22 OS: FreeBSD 12.2-RELEASE-p5
Private report: No CVE-ID: None
 [2021-07-30 20:07 UTC] kontakt at xlu dot pl
Description:
------------
After installation as per the guide:
https://github.com/BadChoice/handesk/tree/1.4.2

I am getting the problem:

$ php artisan handesk:parseNewEmails
In Mailbox.php line 67:
  Connection error: No such host as smtp.yourmail.com
Segmentation fault (core dumped)


TB:
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x0000000800b499e0 in strncmp () from /lib/libc.so.7
#0  0x0000000800b499e0 in strncmp () from /lib/libc.so.7
#1  0x0000000800b450e8 in getenv () from /lib/libc.so.7
#2  0x00000000004e0ae9 in module_destructor ()
#3  0x00000000004d7c11 in module_destructor_zval ()
#4  0x00000000004eac38 in zend_hash_graceful_reverse_destroy ()
#5  0x00000000004d7d14 in zend_shutdown ()
#6  0x0000000000473beb in php_module_shutdown ()
#7  0x0000000000591346 in main ()


The problem already without full configuration. Just crete database in .env and install on the official readme.
The code tested causes a segmentation fault for php versions: 7.2.x, 7.3.x, 7.4.x.


Test script:
---------------
https://github.com/BadChoice/handesk/tree/1.4.2


Actual result:
--------------
Segmentation Fault


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2021-07-30 21:10 UTC] hanskrentel at yahoo dot de
Please re-validate your report, At least the reference to the test-script looks disconnected to the test-tree given as

https://github.com/BadChoice/handesk/blob/1.4.2/app/Services/Pop3/Mailbox.php

has no line number 67.
 [2021-07-30 22:23 UTC] cmb@php.net
-Status: Open +Status: Feedback -Assigned To: +Assigned To: cmb
 [2021-08-02 19:01 UTC] kontakt at xlu dot pl
-Status: Feedback +Status: Assigned
 [2021-08-02 19:01 UTC] kontakt at xlu dot pl
I did it again with the correct SMTP address:

$ php artisan handesk:parseNewEmails
Done
Segmentation fault (core dumped)




Check composer package:

 ./vendor/php-imap/php-imap/src/PhpImap/Mailbox.php


Line:


      protected function initImapStream() {
                $imapStream = @imap_open($this->imapPath, $this->imapLogin, $this->imapPassword, $this->imapOptions, $this->imapRetriesNum, $this->imapParams);
                if(!$imapStream) {
                        throw new Exception('Connection error: ' . imap_last_error());
                }
                return $imapStream;
        }
 [2021-08-03 10:18 UTC] cmb@php.net
-Status: Assigned +Status: Feedback
 [2021-08-03 10:18 UTC] cmb@php.net
Okay, thanks for clarification.  So the connection error is
unrelated to the segfault which happens during shutdown.

Can you reproduce this with any of the actively supported PHP
versions[1]?  If so, please list all enabled extensions (php -m).

[1] <https://www.php.net/supported-versions.php>
 [2021-08-03 21:01 UTC] kontakt at xlu dot pl
-Status: Feedback +Status: Assigned
 [2021-08-03 21:01 UTC] kontakt at xlu dot pl
PHP v 7.3.29

php -m

[PHP Modules]
 Core
 date
 imap
 json
 libxml
 mbstring
 mysqlnd
 pcre
 PDO
 Reflection
 session
 SPL
 standard
 [Zend Modules]
 [2021-08-03 21:17 UTC] cmb@php.net
-Status: Assigned +Status: Feedback
 [2021-08-03 21:17 UTC] cmb@php.net
Thanks!  The loaded extensions are unlikely to be an issue per se,
but PHP 7.3.29 is no longer actively supported.  Please check with
PHP 7.4.22 or 8.0.9.
 [2021-08-03 21:54 UTC] kontakt at xlu dot pl
-Status: Feedback +Status: Assigned
 [2021-08-03 21:54 UTC] kontakt at xlu dot pl
the same problem exists on PHP 7.4.22

php -m [PHP Modules]
Core
date
hash
imap
json
libxml
mbstring
mysqlnd
pcre
PDO
Reflection
session
SPL
standard
[Zend Modules]


This script does not support PHP 8.0.9.
 [2021-08-04 10:39 UTC] cmb@php.net
-Status: Assigned +Status: Feedback -PHP Version: 7.3.29 +PHP Version: 7.4.22
 [2021-08-04 10:39 UTC] cmb@php.net
It took me a while to set up the test environment, but I cannot
reproduce the segfault.  Ideally, you would provide a short, self
containted example[1], or at least a backtrace with debug
symbols[2].

[1] <http://sscce.org/>
[2] <https://bugs.php.net/bugs-generating-backtrace.php>
 [2021-08-05 19:24 UTC] kontakt at xlu dot pl
-Status: Feedback +Status: Assigned
 [2021-08-05 19:24 UTC] 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.
 [2021-08-09 08:48 UTC] cmb@php.net
-Status: Assigned +Status: Open -Assigned To: cmb +Assigned To:
 [2021-08-09 08:48 UTC] 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-16 14:35 UTC] 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-16 15:05 UTC] nikic@php.net
-Summary: Segmentation fault +Summary: Segfault in getenv() during intl mshutdown caused by imap rshutdown failure -Status: Open +Status: Analyzed
 [2021-08-16 15:05 UTC] 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 16:14 UTC] 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-17 09:09 UTC] nikic@php.net
-Status: Analyzed +Status: Closed -Assigned To: +Assigned To: nikic
 [2021-08-17 09:09 UTC] nikic@php.net
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.
 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Sat Sep 25 18:05:31 2021 UTC