From 7fb38386741bd698f0496c169853a1ce8f66ca87 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+ndossche@users.noreply.github.com> Date: Fri, 23 Jan 2026 14:54:12 +0100 Subject: [PATCH] Fix crash when ASN1_STRING_to_UTF8() fails This function returns -1 on failure. Not checking this causes a segfault if `cert_name` is still NULL, i.e. if the failure happens on the first iteration. If the failure happens on the second iteration, we get a use-after-free. NULL deref example: ``` ==189347==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7f961f6f379d bp 0x7ffdc44afed0 sp 0x7ffdc44af658 T0) ==189347==The signal is caused by a READ memory access. ==189347==Hint: address points to the zero page. #0 0x7f961f6f379d (/lib/x86_64-linux-gnu/libc.so.6+0x18b79d) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) #1 0x7f9620217826 in strlen ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:389 #2 0x560faa92d119 in php_openssl_matches_san_list /work/php-src/ext/openssl/xp_ssl.c:478 #3 0x560faa92e912 in php_openssl_apply_peer_verification_policy /work/php-src/ext/openssl/xp_ssl.c:636 #4 0x560faa93565b in php_openssl_enable_crypto /work/php-src/ext/openssl/xp_ssl.c:1893 #5 0x560faa939c86 in php_openssl_sockop_set_option /work/php-src/ext/openssl/xp_ssl.c:2516 #6 0x560fab74c610 in _php_stream_set_option /work/php-src/main/streams/streams.c:1466 #7 0x560fab7557c1 in php_stream_xport_crypto_enable /work/php-src/main/streams/transports.c:387 #8 0x560faa939f29 in php_openssl_sockop_set_option /work/php-src/ext/openssl/xp_ssl.c:2541 #9 0x560fab74c610 in _php_stream_set_option /work/php-src/main/streams/streams.c:1466 #10 0x560fab754655 in php_stream_xport_connect /work/php-src/main/streams/transports.c:248 #11 0x560fab75365d in _php_stream_xport_create /work/php-src/main/streams/transports.c:145 #12 0x560fab54d725 in zif_stream_socket_client /work/php-src/ext/standard/streamsfuncs.c:158 #13 0x560fab6b7ed2 in zend_test_execute_internal /work/php-src/ext/zend_test/observer.c:306 #14 0x560fab9e024a in ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER /work/php-src/Zend/zend_vm_execute.h:2154 #15 0x560fabb40995 in execute_ex /work/php-src/Zend/zend_vm_execute.h:116519 #16 0x560fabb558b0 in zend_execute /work/php-src/Zend/zend_vm_execute.h:121962 #17 0x560fabcba0ab in zend_execute_script /work/php-src/Zend/zend.c:1980 #18 0x560fab6ec8bb in php_execute_script_ex /work/php-src/main/main.c:2645 #19 0x560fab6ecccb in php_execute_script /work/php-src/main/main.c:2685 #20 0x560fabcbfc16 in do_cli /work/php-src/sapi/cli/php_cli.c:951 #21 0x560fabcc21e3 in main /work/php-src/sapi/cli/php_cli.c:1362 #22 0x7f961f5921c9 (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) #23 0x7f961f59228a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) #24 0x560faa809b34 in _start (/work/php-src/build-dbg-asan/sapi/cli/php+0x609b34) (BuildId: aa149f943514fff0c491e1f199e30fed0e977f7c) ``` UAF example: ``` ==190632==ERROR: AddressSanitizer: heap-use-after-free on address 0x5020000690f0 at pc 0x7fc2cdb3596f bp 0x7ffce2ed98d0 sp 0x7ffce2ed9078 READ of size 3 at 0x5020000690f0 thread T0 #0 0x7fc2cdb3596e in strlen ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:391 #1 0x558b6eb2d119 in php_openssl_matches_san_list /work/php-src/ext/openssl/xp_ssl.c:478 #2 0x558b6eb2e912 in php_openssl_apply_peer_verification_policy /work/php-src/ext/openssl/xp_ssl.c:636 #3 0x558b6eb3565b in php_openssl_enable_crypto /work/php-src/ext/openssl/xp_ssl.c:1893 #4 0x558b6eb39c86 in php_openssl_sockop_set_option /work/php-src/ext/openssl/xp_ssl.c:2516 #5 0x558b6f94c610 in _php_stream_set_option /work/php-src/main/streams/streams.c:1466 #6 0x558b6f9557c1 in php_stream_xport_crypto_enable /work/php-src/main/streams/transports.c:387 #7 0x558b6eb39f29 in php_openssl_sockop_set_option /work/php-src/ext/openssl/xp_ssl.c:2541 #8 0x558b6f94c610 in _php_stream_set_option /work/php-src/main/streams/streams.c:1466 #9 0x558b6f954655 in php_stream_xport_connect /work/php-src/main/streams/transports.c:248 #10 0x558b6f95365d in _php_stream_xport_create /work/php-src/main/streams/transports.c:145 #11 0x558b6f74d725 in zif_stream_socket_client /work/php-src/ext/standard/streamsfuncs.c:158 #12 0x558b6f8b7ed2 in zend_test_execute_internal /work/php-src/ext/zend_test/observer.c:306 #13 0x558b6fbe024a in ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER /work/php-src/Zend/zend_vm_execute.h:2154 #14 0x558b6fd40995 in execute_ex /work/php-src/Zend/zend_vm_execute.h:116519 #15 0x558b6fd558b0 in zend_execute /work/php-src/Zend/zend_vm_execute.h:121962 #16 0x558b6feba0ab in zend_execute_script /work/php-src/Zend/zend.c:1980 #17 0x558b6f8ec8bb in php_execute_script_ex /work/php-src/main/main.c:2645 #18 0x558b6f8ecccb in php_execute_script /work/php-src/main/main.c:2685 #19 0x558b6febfc16 in do_cli /work/php-src/sapi/cli/php_cli.c:951 #20 0x558b6fec21e3 in main /work/php-src/sapi/cli/php_cli.c:1362 #21 0x7fc2cceb01c9 (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) #22 0x7fc2cceb028a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) #23 0x558b6ea09b34 in _start (/work/php-src/build-dbg-asan/sapi/cli/php+0x609b34) (BuildId: aa149f943514fff0c491e1f199e30fed0e977f7c) 0x5020000690f0 is located 0 bytes inside of 9-byte region [0x5020000690f0,0x5020000690f9) freed by thread T0 here: #0 0x7fc2cdbb44d8 in free ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:52 #1 0x558b6eb2d2fa in php_openssl_matches_san_list /work/php-src/ext/openssl/xp_ssl.c:496 #2 0x558b6eb2e912 in php_openssl_apply_peer_verification_policy /work/php-src/ext/openssl/xp_ssl.c:636 #3 0x558b6eb3565b in php_openssl_enable_crypto /work/php-src/ext/openssl/xp_ssl.c:1893 #4 0x558b6eb39c86 in php_openssl_sockop_set_option /work/php-src/ext/openssl/xp_ssl.c:2516 #5 0x558b6f94c610 in _php_stream_set_option /work/php-src/main/streams/streams.c:1466 #6 0x558b6f9557c1 in php_stream_xport_crypto_enable /work/php-src/main/streams/transports.c:387 #7 0x558b6eb39f29 in php_openssl_sockop_set_option /work/php-src/ext/openssl/xp_ssl.c:2541 #8 0x558b6f94c610 in _php_stream_set_option /work/php-src/main/streams/streams.c:1466 #9 0x558b6f954655 in php_stream_xport_connect /work/php-src/main/streams/transports.c:248 #10 0x558b6f95365d in _php_stream_xport_create /work/php-src/main/streams/transports.c:145 #11 0x558b6f74d725 in zif_stream_socket_client /work/php-src/ext/standard/streamsfuncs.c:158 #12 0x558b6f8b7ed2 in zend_test_execute_internal /work/php-src/ext/zend_test/observer.c:306 #13 0x558b6fbe024a in ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER /work/php-src/Zend/zend_vm_execute.h:2154 #14 0x558b6fd40995 in execute_ex /work/php-src/Zend/zend_vm_execute.h:116519 #15 0x558b6fd558b0 in zend_execute /work/php-src/Zend/zend_vm_execute.h:121962 #16 0x558b6feba0ab in zend_execute_script /work/php-src/Zend/zend.c:1980 #17 0x558b6f8ec8bb in php_execute_script_ex /work/php-src/main/main.c:2645 #18 0x558b6f8ecccb in php_execute_script /work/php-src/main/main.c:2685 #19 0x558b6febfc16 in do_cli /work/php-src/sapi/cli/php_cli.c:951 #20 0x558b6fec21e3 in main /work/php-src/sapi/cli/php_cli.c:1362 #21 0x7fc2cceb01c9 (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) #22 0x7fc2cceb028a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) #23 0x558b6ea09b34 in _start (/work/php-src/build-dbg-asan/sapi/cli/php+0x609b34) (BuildId: aa149f943514fff0c491e1f199e30fed0e977f7c) previously allocated by thread T0 here: #0 0x7fc2cdbb59c7 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69 #1 0x7fc2cd2faeab in ASN1_mbstring_ncopy (/lib/x86_64-linux-gnu/libcrypto.so.3+0xcceab) (BuildId: 0698e1ff610cb3c6993dccbd82c1281b1b4c5ade) #2 0x7fc2cd2fb2e5 in ASN1_mbstring_copy (/lib/x86_64-linux-gnu/libcrypto.so.3+0xcd2e5) (BuildId: 0698e1ff610cb3c6993dccbd82c1281b1b4c5ade) #3 0x7fc2cd2fe2a5 in ASN1_STRING_to_UTF8 (/lib/x86_64-linux-gnu/libcrypto.so.3+0xd02a5) (BuildId: 0698e1ff610cb3c6993dccbd82c1281b1b4c5ade) #4 0x558b6eb2d0a8 in php_openssl_matches_san_list /work/php-src/ext/openssl/xp_ssl.c:477 #5 0x558b6eb2e912 in php_openssl_apply_peer_verification_policy /work/php-src/ext/openssl/xp_ssl.c:636 #6 0x558b6eb3565b in php_openssl_enable_crypto /work/php-src/ext/openssl/xp_ssl.c:1893 #7 0x558b6eb39c86 in php_openssl_sockop_set_option /work/php-src/ext/openssl/xp_ssl.c:2516 #8 0x558b6f94c610 in _php_stream_set_option /work/php-src/main/streams/streams.c:1466 #9 0x558b6f9557c1 in php_stream_xport_crypto_enable /work/php-src/main/streams/transports.c:387 #10 0x558b6eb39f29 in php_openssl_sockop_set_option /work/php-src/ext/openssl/xp_ssl.c:2541 #11 0x558b6f94c610 in _php_stream_set_option /work/php-src/main/streams/streams.c:1466 #12 0x558b6f954655 in php_stream_xport_connect /work/php-src/main/streams/transports.c:248 #13 0x558b6f95365d in _php_stream_xport_create /work/php-src/main/streams/transports.c:145 #14 0x558b6f74d725 in zif_stream_socket_client /work/php-src/ext/standard/streamsfuncs.c:158 #15 0x558b6f8b7ed2 in zend_test_execute_internal /work/php-src/ext/zend_test/observer.c:306 #16 0x558b6fbe024a in ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER /work/php-src/Zend/zend_vm_execute.h:2154 #17 0x558b6fd40995 in execute_ex /work/php-src/Zend/zend_vm_execute.h:116519 #18 0x558b6fd558b0 in zend_execute /work/php-src/Zend/zend_vm_execute.h:121962 #19 0x558b6feba0ab in zend_execute_script /work/php-src/Zend/zend.c:1980 #20 0x558b6f8ec8bb in php_execute_script_ex /work/php-src/main/main.c:2645 #21 0x558b6f8ecccb in php_execute_script /work/php-src/main/main.c:2685 #22 0x558b6febfc16 in do_cli /work/php-src/sapi/cli/php_cli.c:951 #23 0x558b6fec21e3 in main /work/php-src/sapi/cli/php_cli.c:1362 #24 0x7fc2cceb01c9 (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) #25 0x7fc2cceb028a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) #26 0x558b6ea09b34 in _start (/work/php-src/build-dbg-asan/sapi/cli/php+0x609b34) (BuildId: aa149f943514fff0c491e1f199e30fed0e977f7c) ``` --- ext/openssl/xp_ssl.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c index 60477094a1b63..b4bbe9c112419 100644 --- a/ext/openssl/xp_ssl.c +++ b/ext/openssl/xp_ssl.c @@ -126,10 +126,6 @@ #define GET_VER_OPT_LONG(_name, _num) \ if (GET_VER_OPT(_name)) _num = zval_get_long(val) -/* Used for peer verification in windows */ -#define PHP_X509_NAME_ENTRY_TO_UTF8(ne, i, out) \ - ASN1_STRING_to_UTF8(&out, X509_NAME_ENTRY_get_data(X509_NAME_get_entry(ne, i))) - #ifdef HAVE_IPV6 /* Used for IPv6 Address peer verification */ #define EXPAND_IPV6_ADDRESS(_str, _bytes) \ @@ -476,7 +472,10 @@ static bool php_openssl_matches_san_list(X509 *peer, const char *subject_name) / GENERAL_NAME *san = sk_GENERAL_NAME_value(alt_names, i); if (san->type == GEN_DNS) { - ASN1_STRING_to_UTF8(&cert_name, san->d.dNSName); + if (ASN1_STRING_to_UTF8(&cert_name, san->d.dNSName) < 0) { + /* TODO: warn ? */ + continue; + } if ((size_t)ASN1_STRING_length(san->d.dNSName) != strlen((const char*)cert_name)) { OPENSSL_free(cert_name); /* prevent null-byte poisoning*/