[PHP-CVS] [php-src] PHP-8.5: openssl: Check return value of SSL_CTX_set_alpn_protos() (#22996)
[email protected] (Nora Dossche via ndossche) Tue, 4 Aug 2026 06:19:50 +0000
| Newsgroups | php.cvs |
|---|---|
| Message-ID | <[email protected]> |
Author: Nora Dossche (ndossche)
Committer: ndossche (ndossche)
Date: 2026-08-04T08:18:37+02:00
Commit: https://github.com/php/php-src/commit/5c9a67b8a9c25477cc1de40b0ab9ba8977fe8981
Raw diff: https://github.com/php/php-src/commit/5c9a67b8a9c25477cc1de40b0ab9ba8977fe8981.diff
openssl: Check return value of SSL_CTX_set_alpn_protos() (#22996)
Discovered by ESSS.
Closes GH-23009.
Changed paths:
A ext/openssl/tests/alpn_protocols_invalid.phpt
M NEWS
M ext/openssl/xp_ssl.c
Diff:
diff --git a/NEWS b/NEWS
index e69a9f31b2c6..378643836c80 100644
--- a/NEWS
+++ b/NEWS
@@ -22,6 +22,9 @@ PHP NEWS
. Fixed bug GH-22857 (Function JIT emits wrong code for FETCH_OBJ_FUNC_ARG on a
property hook getter, losing register-held variables). (Zhao Hao)
+- OpenSSL:
+ . Fix missing error check on invalid alpn protocols. (ndossche)
+
- PCRE:
. Fixed bug GH-21134 (Crash with \C + UTF-8). Using \C in UTF-8 patterns is
now forbidden. (Arnaud)
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--
+<?php
+if (OPENSSL_VERSION_NUMBER < 0x30000000) die('skip For OpenSSL >= 3.0');
+?>
+--FILE--
+<?php
+$server = stream_socket_server('tcp://127.0.0.1:0', $errno, $errstr);
+$address = stream_socket_get_name($server, false);
+
+function try_alpn($protocols, $streamOptions): void {
+ global $address;
+
+ $context = stream_context_create([
+ 'ssl' => ['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;