[php-src] Issue #21613: Crash when TLS authentication fails with verify_peer

[email protected] (bwoebi)
Newsgroups php.bugs
Message-ID <[email protected]>
Issue: https://github.com/php/php-src/issues/21613
Author: bwoebi

### Description

The following code:

```php
<?php

// Start a local "proxy" that answers CONNECT with 200 then closes immediately,
// causing the SSL handshake to fail on the client side.
$server = stream_socket_server("tcp://127.0.0.1:0", $errno, $errstr);
if (!$server) {
    die("Could not start proxy server: $errstr\n");
}
$proxyAddr = stream_socket_get_name($server, false);

$pid = pcntl_fork();
if ($pid === -1) {
    die("pcntl_fork failed\n");
}

if ($pid === 0) {
    // Child: minimal HTTP CONNECT proxy
    $conn = stream_socket_accept($server, 5);
    if ($conn) {
        // Drain the CONNECT request headers
        while (($line = fgets($conn)) !== false) {
            if (rtrim($line) === '') {
                break;
            }
        }
        // Acknowledge the tunnel — then immediately close.
        // The client will attempt the TLS handshake and fail.
        fwrite($conn, "HTTP/1.1 200 Connection established\r\n\r\n");
        fclose($conn);
    }
    exit(0);
}

// Parent: HTTPS request through the proxy.
// 'verify_peer' => true ensures reset_ssl_peer_name is set (peer_name not pre-set).
// No cafile needed; the TLS handshake itself will fail because the proxy closed.
$ctx = stream_context_create([
    'ssl' => [
        'verify_peer'      => true,
        'verify_peer_name' => true,
    ],
    'http' => [
        'proxy' => "tcp://$proxyAddr",
    ],
]);

// Suppress the expected PHP warning; we only care about the crash.
@file_get_contents("https://127.0.0.1/", false, $ctx);

pcntl_waitpid($pid, $status);
echo "Done (no crash)\n";
```

Resulted in this output:
```
     ==80357== Invalid read of size 8                                                                                       
     ==80357==    at 0x5980384: php_stream_url_wrap_http_ex (/usr/local/src/php/ext/standard/http_fopen_wrapper.c:580)       
     ==80357==    by 0x597F3AB: php_stream_url_wrap_http (/usr/local/src/php/ext/standard/http_fopen_wrapper.c:1204)       
     ==80357==    by 0xC5474B3: dd_stream_opener (handlers_httpstreams.c:112)             
     ==80357==    by 0xC546B7F: dd_stream_opener_https (handlers_httpstreams.c:130)
     ==80357==    by 0x5B5A657: _php_stream_open_wrapper_ex (/usr/local/src/php/main/streams/streams.c:2270)
     ==80357==    by 0x594B46F: zif_file_get_contents (/usr/local/src/php/ext/standard/file.c:409)
     ==80357==    by 0x57646DB: zif_phar_file_get_contents (/usr/local/src/php/ext/phar/func_interceptors.c:230)
     ==80357==    by 0x5D029FB: ZEND_DO_ICALL_SPEC_OBSERVER_HANDLER (zend_vm_execute.h:1487)
     ==80357==    by 0x5C7B50F: execute_ex (zend_vm_execute.h:116172)
     ==80357==    by 0x5C7B927: zend_execute (zend_vm_execute.h:121884)                                                                    
     ==80357==    by 0x5E09387: zend_execute_script (/usr/local/src/php/Zend/zend.c:1977)                                  
     ==80357==    by 0x5B23AE3: php_execute_script_ex (/usr/local/src/php/main/main.c:2641)
     ==80357==  Address 0x90 is not stack'd, malloc'd or (recently) free'd
```

### PHP Version

```plain
PHP 8.4+
```

### Operating System

_No response_
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.