Commit 8c113709746 for php.net

commit 8c1137097468b993d3264c8159db81d71515672b
Author: Nora Dossche <7771979+ndossche@users.noreply.github.com>
Date:   Fri Jan 23 14:54:12 2026 +0100

    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)
    ```

    Closes GH-21017.

diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c
index c4423ce2041..88c75253aba 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*/