Skip to content

SEGV on static build php >= 8.3 with gettext #17735

Closed
@crazywhalecc

Description

@crazywhalecc

Description

The following code:

<?php
assert(function_exists('gettext'));
assert(function_exists('bindtextdomain'));
assert(function_exists('textdomain'));

if (!is_dir('locale/en_US/LC_MESSAGES/')) {
    mkdir('locale/en_US/LC_MESSAGES/', 0755, true);
}
if (!file_exists('locale/en_US/LC_MESSAGES/test.mo')) {
    $mo = '3hIElQAAAAACAAAAHAAAACwAAAAFAAAAPAAAAAAAAABQAAAABgAAAFEAAAAXAQAAWAAAAAcAAABwAQAAAQAAAAAAAAAAAAAAAgAAAAAAAAAA56S65L6LAFByb2plY3QtSWQtVmVyc2lvbjogUEFDS0FHRSBWRVJTSU9OClJlcG9ydC1Nc2dpZC1CdWdzLVRvOiAKUE8tUmV2aXNpb24tRGF0ZTogWUVBUi1NTy1EQSBITzpNSStaT05FCkxhc3QtVHJhbnNsYXRvcjogRlVMTCBOQU1FIDxFTUFJTEBBRERSRVNTPgpMYW5ndWFnZS1UZWFtOiBMQU5HVUFHRSA8TExAbGkub3JnPgpMYW5ndWFnZTogCk1JTUUtVmVyc2lvbjogMS4wCkNvbnRlbnQtVHlwZTogdGV4dC9wbGFpbjsgY2hhcnNldD1VVEYtOApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiA4Yml0CgBFeGFtcGxlAA==';
    file_put_contents('locale/en_US/LC_MESSAGES/test.mo', base64_decode($mo));
}
putenv('LANG=en_US');
setlocale(LC_ALL, 'en_US');

$domain = 'test';
bindtextdomain($domain, 'locale/');
textdomain($domain);

assert(gettext(json_decode('"\u793a\u4f8b"', true)) === 'Example');

Resulted in this output:

[1]    1473892 segmentation fault  buildroot/bin/php src/globals/ext-tests/gettext.php

But I expected this output instead:

// no output, retcode is 0

Additional Information

The PHP build is from source and gettext is statically linked. This bug did not exist 2 months ago and only affected PHP 8.3 and 8.4.

  • Build version: 8.4.3-NTS
  • OS: Debian 12 x86_64
  • Build toolchain: musl-toolchain (ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, with debug_info, not stripped)

static-php-cli build command:

# static-php-cli has extension check, at this time it fails when checking for gettext and got segfault.
bin/spc build --build-cli gettext --no-strip

Build detail log:

This is static-php-cli build log that shows which build command used. If more details need, I'd like to show.

$ bin/spc build --build-cli gettext --no-strip   
     _        _   _                 _           
 ___| |_ __ _| |_(_) ___      _ __ | |__  _ __  
/ __| __/ _` | __| |/ __|____| '_ \| '_ \| '_ \ 
\__ \ || (_| | |_| | (_|_____| |_) | | | | |_) |
|___/\__\__,_|\__|_|\___|    | .__/|_| |_| .__/   v2.4.4
                             |_|         |_|    
[01:42:42] [INFO] Build OS:         Linux (x86_64)
[01:42:42] [INFO] Build SAPI:       cli
[01:42:42] [INFO] Extensions (1):   gettext
[01:42:42] [INFO] Libraries (2):    libiconv,gettext
[01:42:42] [INFO] Strip Binaries:   no
[01:42:42] [INFO] Enable ZTS:       no
[01:42:42] [INFO] Config File Path: /usr/local/etc/php
[01:42:42] [INFO] PHP Version:      8.4.1
[01:42:42] [NOTI] Build will start after 2s ...
[01:42:44] [INFO] extracting php-src source to /home/jerry/project/static-php-cli/source/php-src ...
[01:42:45] [INFO] Patched source [php-src] after extracted
[01:42:45] [INFO] extracting micro source to /home/jerry/project/static-php-cli/source/php-src/sapi/micro ...
[01:42:45] [INFO] Patching micro with sapi/micro/patches/static_extensions_win32_84.patch
patching file ext/fileinfo/config.w32
patching file ext/openssl/config.w32
[01:42:45] [INFO] Patching micro with sapi/micro/patches/cli_checks_84.patch
patching file TSRM/tsrm_win32.c
Hunk #1 succeeded at 531 (offset 1 line).
patching file ext/ffi/ffi.c
Hunk #1 succeeded at 5415 (offset 12 lines).
patching file ext/opcache/ZendAccelerator.c
Hunk #1 succeeded at 2842 (offset 20 lines).
Hunk #2 succeeded at 3154 (offset 20 lines).
Hunk #3 succeeded at 3166 (offset 20 lines).
Hunk #4 succeeded at 4716 (offset 31 lines).
patching file ext/pdo_sqlite/pdo_sqlite.c
patching file ext/readline/readline_cli.c
patching file ext/sqlite3/sqlite3.c
patching file ext/standard/php_fopen_wrapper.c
patching file ext/standard/proc_open.c
Hunk #1 succeeded at 1277 (offset 3 lines).
patching file main/main.c
Hunk #1 succeeded at 528 (offset 42 lines).
Hunk #2 succeeded at 1409 (offset 38 lines).
patching file win32/console.c
[01:42:45] [INFO] Patching micro with sapi/micro/patches/disable_huge_page_84.patch
patching file configure.ac
Hunk #1 succeeded at 1063 (offset -64 lines).
[01:42:45] [INFO] Patching micro with sapi/micro/patches/vcruntime140_80.patch
patching file win32/winutil.c
[01:42:45] [INFO] Patching micro with sapi/micro/patches/win32_82.patch
patching file win32/build/confutils.js
Hunk #1 succeeded at 3432 (offset -22 lines).
Hunk #2 succeeded at 3444 (offset -22 lines).
[01:42:45] [INFO] Patching micro with sapi/micro/patches/zend_stream.patch
patching file Zend/zend_stream.c
[01:42:45] [INFO] Patched source [micro] after extracted
[01:42:45] [INFO] Installing required library [pkg-config] from pre-built binaries
[01:42:45] [INFO] extracting pkg-config-x86_64-linux.txz package to /home/jerry/project/static-php-cli/buildroot ...
[01:42:45] [INFO] lib [pkg-config] setup success, took 0.01 s
[01:42:45] [INFO] Installing required library [libiconv] from pre-built binaries
[01:42:45] [INFO] extracting libiconv-x86_64-linux.txz package to /home/jerry/project/static-php-cli/buildroot ...
[01:42:45] [INFO] lib [libiconv] setup success, took 0.01 s
[01:42:45] [INFO] Building required library [gettext]
[01:42:45] [INFO] extracting gettext source to /home/jerry/project/static-php-cli/source/gettext ...
[01:42:45] [INFO] Entering dir: /home/jerry/project/static-php-cli/source/gettext
[01:42:45] [INFO] [EXEC]  ./configure --enable-static --disable-shared --disable-java --disable-c+ --with-included-gettext --with-libiconv-prefix=/home/jerry/project/static-php-cli/buildroot --prefix=/home/jerry/project/static-php-cli/buildroot
[01:43:45] [INFO] [EXEC]  make clean
[01:43:46] [INFO] [EXEC]  make -j16
[01:45:07] [INFO] [EXEC]  make install
[01:45:16] [INFO] lib [gettext] setup success, took 151.01 s
[01:45:16] [INFO] Extension [gettext] patched before buildconf
[01:45:16] [INFO] Entering dir: /home/jerry/project/static-php-cli/source/php-src
[01:45:16] [INFO] [EXEC] ./buildconf --force
[01:45:17] [INFO] Extension [gettext] patched before configure
[01:45:17] [INFO] Entering dir: /home/jerry/project/static-php-cli/source/php-src
[01:45:17] [INFO] gettext is using --with-gettext="/home/jerry/project/static-php-cli/buildroot" 
[01:45:17] [INFO] [EXEC] LD_LIBRARY_PATH=/usr/local/musl/x86_64-linux-musl/lib ./configure --prefix= --with-valgrind=no --enable-shared=no --enable-static=yes --disable-all --disable-cgi --disable-phpdbg --enable-cli --disable-fpm --disable-embed --disable-micro --with-config-file-path=/usr/local/etc/php --with-config-file-scan-dir=/usr/local/etc/php/conf.d --with-gettext="/home/jerry/project/static-php-cli/buildroot" CFLAGS='' CPPFLAGS='-I/home/jerry/project/static-php-cli/buildroot/include' LDFLAGS='-L/home/jerry/project/static-php-cli/buildroot/lib' LIBS='-ldl -lpthread -lm' 
[01:45:25] [INFO] cleaning up
[01:45:25] [INFO] Entering dir: /home/jerry/project/static-php-cli/source/php-src
[01:45:25] [INFO] [EXEC] make clean
[01:45:25] [INFO] building cli
[01:45:25] [INFO] Entering dir: /home/jerry/project/static-php-cli/source/php-src
[01:45:25] [INFO] [EXEC] sed -i "s|//lib|/lib|g" Makefile
[01:45:25] [INFO] [EXEC] $SPC_CMD_PREFIX_PHP_MAKE EXTRA_CFLAGS='-g -O0 -fno-ident -fPIE' EXTRA_LIBS='/home/jerry/project/static-php-cli/buildroot/lib/libintl.a /home/jerry/project/static-php-cli/buildroot/lib/libiconv.a /home/jerry/project/static-php-cli/buildroot/lib/libcharset.a  ' EXTRA_LDFLAGS_PROGRAM='-all-static -Wl,-O1 -pie' cli
[01:45:41] [INFO] Deploying cli file
[01:45:41] [INFO] [EXEC] cp '/home/jerry/project/static-php-cli/source/php-src/sapi/cli/php' '/home/jerry/project/static-php-cli/buildroot/bin/'
[01:45:41] [INFO] running cli sanity check
[01:45:41] [INFO] [EXEC] /home/jerry/project/static-php-cli/buildroot/bin/php -r "echo \"hello\";"
[01:45:41] [INFO] [EXEC] /home/jerry/project/static-php-cli/buildroot/bin/php -r "assert(function_exists('gettext'));assert(function_exists('bindtextdomain'));assert(function_exists('textdomain'));if ("'!'"is_dir('locale/en_US/LC_MESSAGES/')) {    mkdir('locale/en_US/LC_MESSAGES/', 0755, true);}if ("'!'"file_exists('locale/en_US/LC_MESSAGES/test.mo')) {    \$mo = '3hIElQAAAAACAAAAHAAAACwAAAAFAAAAPAAAAAAAAABQAAAABgAAAFEAAAAXAQAAWAAAAAcAAABwAQAAAQAAAAAAAAAAAAAAAgAAAAAAAAAA56S65L6LAFByb2plY3QtSWQtVmVyc2lvbjogUEFDS0FHRSBWRVJTSU9OClJlcG9ydC1Nc2dpZC1CdWdzLVRvOiAKUE8tUmV2aXNpb24tRGF0ZTogWUVBUi1NTy1EQSBITzpNSStaT05FCkxhc3QtVHJhbnNsYXRvcjogRlVMTCBOQU1FIDxFTUFJTEBBRERSRVNTPgpMYW5ndWFnZS1UZWFtOiBMQU5HVUFHRSA8TExAbGkub3JnPgpMYW5ndWFnZTogCk1JTUUtVmVyc2lvbjogMS4wCkNvbnRlbnQtVHlwZTogdGV4dC9wbGFpbjsgY2hhcnNldD1VVEYtOApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiA4Yml0CgBFeGFtcGxlAA==';    file_put_contents('locale/en_US/LC_MESSAGES/test.mo', base64_decode(\$mo));}putenv('LANG=en_US');setlocale(LC_ALL, 'en_US');\$domain = 'test';bindtextdomain(\$domain, 'locale/');textdomain(\$domain);assert(gettext(json_decode('\"\u793a\u4f8b\"', true)) === 'Example');"
Segmentation fault
[01:45:41] [CRIT] Build failed with SPC\exception\RuntimeException: extension gettext failed sanity check
[01:45:41] [CRIT] Please check with --debug option to see more details.

GDB debug log:

$ gdb buildroot/bin/php 
GNU gdb (Debian 13.1-3) 13.1
Copyright (C) 2023 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:
<https://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 buildroot/bin/php...
warning: File "/home/jerry/project/static-php-cli/buildroot/bin/php" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load".
To enable execution of this file add
	add-auto-load-safe-path /home/jerry/project/static-php-cli/buildroot/bin/php
line to your configuration file "/home/jerry/.config/gdb/gdbinit".
To completely disable this security protection add
	set auto-load safe-path /
line to your configuration file "/home/jerry/.config/gdb/gdbinit".
For more information about this security protection see the
"Auto-loading safe path" section in the GDB manual.  E.g., run from the shell:
	info "(gdb)Auto-loading safe path"
(gdb) run src/globals/ext-tests/gettext.php
Starting program: /home/jerry/project/static-php-cli/buildroot/bin/php src/globals/ext-tests/gettext.php

Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
(gdb) bt
#0  0x0000000000000000 in ?? ()
#1  0x0000000000b18691 in _libintl_rwlock_unlock_multithreaded (lock=0xe2ec60 <_libintl_state_lock>) at glthread/lock.c:494
#2  0x0000000000b149ad in set_binding_values (domainname=<optimized out>, dirnamep=dirnamep@entry=0x7fffffff5428, codesetp=codesetp@entry=0x0, wdirnamep=0x0) at ./bindtextdom.c:370
#3  0x0000000000b14d31 in set_binding_values (wdirnamep=0x0, codesetp=0x0, dirnamep=0x7fffffff5428, domainname=<optimized out>) at ./bindtextdom.c:82
#4  libintl_bindtextdomain (domainname=<optimized out>, dirname=<optimized out>) at ./bindtextdom.c:407
#5  0x000000000050f109 in zif_bindtextdomain (execute_data=0x7ffff7c14200, return_value=0x7fffffff6660) at /home/jerry/project/static-php-cli/source/php-src/ext/gettext/gettext.c:205
#6  0x0000000000a1babf in ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER () at /home/jerry/project/static-php-cli/source/php-src/Zend/zend_vm_execute.h:1287
#7  execute_ex (ex=0x7ffff7c14020) at /home/jerry/project/static-php-cli/source/php-src/Zend/zend_vm_execute.h:58804
#8  0x0000000000a386cd in zend_execute (op_array=0x7ffff7c8d000, return_value=0x0) at /home/jerry/project/static-php-cli/source/php-src/Zend/zend_vm_execute.h:64236
#9  0x0000000000b028ff in zend_execute_script (type=8, retval=0x0, file_handle=0x7fffffffdf10) at /home/jerry/project/static-php-cli/source/php-src/Zend/zend.c:1934
#10 0x000000000077510f in php_execute_script_ex (primary_file=0x7fffffffdf10, retval=0x0) at /home/jerry/project/static-php-cli/source/php-src/main/main.c:2575
#11 0x0000000000775235 in php_execute_script (primary_file=0x7fffffffdf10) at /home/jerry/project/static-php-cli/source/php-src/main/main.c:2615
#12 0x0000000000b04745 in do_cli (argc=2, argv=0x7ffff7ff85d0) at /home/jerry/project/static-php-cli/source/php-src/sapi/cli/php_cli.c:935
#13 0x0000000000b057c7 in main (argc=2, argv=0x7ffff7ff85d0) at /home/jerry/project/static-php-cli/source/php-src/sapi/cli/php_cli.c:1310

php.tgz

I'm not sure if it's a problem with PHP or gettext itself, I'll be happy to follow up with static-php-cli if any clues are available.

PHP Version

PHP 8.4.3

Operating System

Debian 12 x86_64

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions