php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #78303 repeating crashes in php_basename with event-mpm+mod_php
Submitted: 2019-07-17 09:07 UTC Modified: 2021-03-07 04:22 UTC
From: theultramage at gmail dot com Assigned: nikita (profile)
Status: No Feedback Package: *General Issues
PHP Version: 7.3.7 OS: FreeBSD 12.0
Private report: No CVE-ID: None
 [2019-07-17 09:07 UTC] theultramage at gmail dot com
Description:
------------
All components have been built with whatever thread safety flags were available.  However, there seems to be a multithreading issue in the way freebsd's libc is invoked, resulting in a null pointer call. This same crash happens randomly, usually once every few days.

#0  0x0000000000000000 in ?? ()
#1  0x0000000800505e28 in mblen (s=0x8042d223b "p", n=1) at /usr/src/lib/libc/locale/mblen.c:53
#2  0x0000000801663697 in php_basename () from /usr/local/libexec/apache24/libphp7.so
#3  0x000000080166383d in php_basename () from /usr/local/libexec/apache24/libphp7.so
#4  0x00000008017d3de1 in zend_execute () from /usr/local/libexec/apache24/libphp7.so
#5  0x000000080178061b in execute_ex () from /usr/local/libexec/apache24/libphp7.so
#6  0x00000008017808b6 in zend_execute () from /usr/local/libexec/apache24/libphp7.so
#7  0x0000000801733894 in zend_execute_scripts () from /usr/local/libexec/apache24/libphp7.so
#8  0x00000008016c02b9 in php_execute_script () from /usr/local/libexec/apache24/libphp7.so
#9  0x0000000801801808 in zend_check_arg_type () from /usr/local/libexec/apache24/libphp7.so
#10 0x000000000025a5f9 in ap_invoke_handler ()
#11 0x0000000000295c1f in ap_process_async_request ()
#12 0x000000000029254d in ap_process_http_connection ()
#13 0x0000000000272bf9 in ap_run_process_connection ()
#14 0x000000000029fb61 in process_socket ()
#15 0x000000000029f6d7 in worker_thread ()
#16 0x0000000800450767 in thread_start (curthread=0x803153000) at /usr/src/lib/libthr/thread/thr_create.c:292
        set = {__bits = 0x7fffdfdfcfc8}

int mblen(const char *s, size_t n)
{
	return mblen_l(s, n, __get_locale());
}

int mblen_l(const char *s, size_t n, locale_t locale)
{
...
	rval = XLOCALE_CTYPE(locale)->__mbrtowc(NULL, s, n, &locale->mblen);
...
}



Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-07-17 09:20 UTC] nikic@php.net
PHP will use the thread-safe mbrlen() if it is available -- and per https://www.freebsd.org/cgi/man.cgi?query=mbrlen&sektion=3&apropos=0&manpath=FreeBSD+12.0-RELEASE+and+Ports it should be on FreeBSD. Could you check your config.log to see why the mbrlen check fails?
 [2019-07-17 10:31 UTC] theultramage at gmail dot com
mbrlen is available according to config.log.
I dug a bit deeper and found that php's /ext/standard/php_string.h does a weird thing:

#elif defined(_REENTRANT) && defined(HAVE_MBRLEN) && defined(HAVE_MBSTATE_T)
# define php_mblen(ptr, len) ((int) mbrlen(ptr, len, &BG(mblen_state)))

Instead of letting configure do the work, it instead relies on an obsolete internal flag '_REENTRANT'.
Earlier I wasn't specific enough. By 'whatever thread safety flags available' I meant all the ones supplied by the freebsd ports system. That is, one just adds -lpthread and the other adds --enable-maintainer-zts and pthreads_working="yes".

Possible scenarios to investigate: clang not automatically defining _REENTRANT. Inclusion of libpthread not automatically defining _REENTRANT. Header/include ordering issue resulting in _REENTRANT not propagating properly.
 [2019-07-17 10:45 UTC] nikic@php.net
-D_REENTRANT should be added by configure in https://github.com/php/php-src/blob/master/TSRM/threads.m4#L44 ... but looks like it's only added to CPPFLAGS, not CFLAGS in https://github.com/php/php-src/blob/master/TSRM/threads.m4#L58.
 [2019-07-17 10:52 UTC] theultramage at gmail dot com
Good catch. On my end, I found a stackoverflow post, stating "Use g++ -pthread, it is equivalent to g++ -lpthread -D_REENTRANT". So gcc (and it seems clang as well) have this fancy helper parameter. The freebsd ports makefile only does "LIBS += -lpthread" and thus apparently does not invoke this mechanism. I'll correct it from this end and see if it changes anything.
 [2019-07-17 11:03 UTC] nikic@php.net
I got confused here and mixed up CPPFLAGS and CXXFLAGS... adding to CPPFLAGS is right and should work, so I'm not sure why it isn't happening.
 [2019-07-17 11:46 UTC] theultramage at gmail dot com
The usage of the routines in the autoconf module you referenced, PTHREADS_FLAGS and PTHREADS_CHECK, has been deliberately patched out in the freebsd ports tree. This is why the flag isn't being applied.

I traced the port's svn history and it goes back all the way to 2004 and php 4.3.9. It says "Fix compilation of thread-safe PHP after the PTHREAD_LIBS change" which might be referring to some sort of systems code restructuring effort.

Originally, they just removed the freebsd piece of code in PTHREADS_FLAGS:
https://svnweb.freebsd.org/ports/head/lang/php4/files/patch-configure?revision=118610&view=markup&pathrev=160333

It was then changed to remove the invocation of the autoconf macros:
https://svnweb.freebsd.org/ports/head/lang/php4/files/patch-configure.in?revision=161492&view=markup&pathrev=170333
 [2019-07-17 15:24 UTC] nikic@php.net
If it's possible to restore that code in the FreeBSD port, that would be good. We should probably also change the check on our side from defined(_REENTRANT) to defined(ZTS), as we perform the availability check without _REENTRANT and I don't believe this symbol has a dependence on it. The absence of _REENTRANT might affect other things as well though...
 [2021-02-23 11:25 UTC] cmb@php.net
-Status: Open +Status: Feedback -Assigned To: +Assigned To: nikita
 [2021-02-23 11:25 UTC] cmb@php.net
Any update here?  Has this been fixed in the FreeBSD ports?  Do we
still want to apply an improvement to php-src?
 [2021-02-23 13:20 UTC] theultramage at gmail dot com
Ah, it's been a while. Back then I did contact the maintainer and they did undo the most problematic edit, but left in the disabling of PTHREADS_CHECK section because it was supposedly malfunctioning and aborting for php74. The patch is still there for php80. Afterwards the segfaults still kept happening, just in other places, so I gave up.

The most recent version I've been running is PHP 7.3.20 with ZTS and DEBUG. Since aug6 I have logged a segfault on aug8, oct1, oct12, oct17, nov22. None since then. There have been no changes to the system or my usage pattern since aug6, so I cannot give effective feedback on why it seemingly stopped crashing. Either it's just luck, or whatever crawler or exploitbot was directly causing the crash or causing cpu load that was triggering a race condition, has stopped targeting the server.

At this point in time, the version numbers have gone up a bit, and this report might not be relevant anymore. I will add a plan to ugprade to 8.0 (as long as everything installed is confirmed compatible), but it will take time to get results (or lack of thereof).
 [2021-03-07 04:22 UTC] php-bugs at lists dot php dot net
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Re-Opened". Thank you.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 15:01:29 2024 UTC