From b427d363810ba76db47b77338c21a3db5c80d322 Mon Sep 17 00:00:00 2001 From: Nora Dossche <7771979+ndossche@users.noreply.github.com> Date: Mon, 3 Aug 2026 22:53:52 +0200 Subject: [PATCH] openssl: Check return value of SSL_CTX_set_alpn_protos() (#22996) Discovered by ESSS. --- ext/openssl/tests/alpn_protocols_invalid.phpt | 49 +++++++++++++++++++ ext/openssl/xp_ssl.c | 8 ++- 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 ext/openssl/tests/alpn_protocols_invalid.phpt diff --git a/ext/openssl/tests/alpn_protocols_invalid.phpt b/ext/openssl/tests/alpn_protocols_invalid.phpt new file mode 100644 index 000000000000..0d35b850d198 --- /dev/null +++ b/ext/openssl/tests/alpn_protocols_invalid.phpt @@ -0,0 +1,49 @@ +--TEST-- +Setting an invalid TLS ALPN protocol list on a client stream fails +--EXTENSIONS-- +openssl +--SKIPIF-- += 3.0'); +?> +--FILE-- + ['alpn_protocols' => $protocols, 'verify_peer' => false], + 'stream' => $streamOptions, + ]); + $client = stream_socket_client("tcp://$address", $errno, $errstr, 1, STREAM_CLIENT_CONNECT, $context); + var_dump(stream_socket_enable_crypto($client, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)); + fclose($client); +} + +foreach (['', ',', 'h2,', ',h2', 'h2,,http/1.1'] as $protocols) { + try_alpn($protocols, []); +} + +try_alpn('', []); +?> +--EXPECTF-- +Warning: stream_socket_enable_crypto(): Failed setting TLS ALPN protocols, protocol names must not be empty in %s on line %d +bool(false) + +Warning: stream_socket_enable_crypto(): Failed setting TLS ALPN protocols, protocol names must not be empty in %s on line %d +bool(false) + +Warning: stream_socket_enable_crypto(): Failed setting TLS ALPN protocols, protocol names must not be empty in %s on line %d +bool(false) + +Warning: stream_socket_enable_crypto(): Failed setting TLS ALPN protocols, protocol names must not be empty in %s on line %d +bool(false) + +Warning: stream_socket_enable_crypto(): Failed setting TLS ALPN protocols, protocol names must not be empty in %s on line %d +bool(false) + +Warning: stream_socket_enable_crypto(): Failed setting TLS ALPN protocols, protocol names must not be empty in %s on line %d +bool(false) diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c index 77c98f65b518..56d372c6fe0c 100644 --- a/ext/openssl/xp_ssl.c +++ b/ext/openssl/xp_ssl.c @@ -1775,7 +1775,13 @@ static zend_result php_openssl_setup_crypto(php_stream *stream, return FAILURE; } if (sslsock->is_client) { - SSL_CTX_set_alpn_protos(sslsock->ctx, alpn, alpn_len); + if (SSL_CTX_set_alpn_protos(sslsock->ctx, alpn, alpn_len)) { + php_error_docref(NULL, E_WARNING, "Failed setting TLS ALPN protocols, protocol names must not be empty"); + efree(alpn); + SSL_CTX_free(sslsock->ctx); + sslsock->ctx = NULL; + return FAILURE; + } } else { sslsock->alpn_ctx.data = (unsigned char *) pestrndup((const char*)alpn, alpn_len, php_stream_is_persistent(stream)); sslsock->alpn_ctx.len = alpn_len;