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: 2019-07-17 15:24 UTC
From: theultramage at gmail dot com Assigned:
Status: Open Package: *General Issues
PHP Version: 7.3.7 OS: FreeBSD 12.0
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [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

Add a Patch

Pull Requests

Add a Pull Request

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...
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Wed Dec 11 22:01:24 2019 UTC