Commit f92d54b6b52 for php.net

commit f92d54b6b527ea730583af5a2cf9e506eca7ed0d
Author: ndossche <7771979+ndossche@users.noreply.github.com>
Date:   Fri Mar 6 17:59:36 2026 +0100

    openssl: Fix missing error propagation for BIO_printf() calls

    Since these go through a file, this can fail.
    For some of these, the error is already checked but not propagated to
    userland, causing a "true" return value but an incomplete file.
    For others, the error is not checked and can also lead to an incomplete
    file.
    Solve this by always propagating failure, especially as the other write
    calls are already checked for failure.

    Closes GH-21360.

diff --git a/NEWS b/NEWS
index a5605382424..c94a84b1911 100644
--- a/NEWS
+++ b/NEWS
@@ -23,6 +23,7 @@ PHP                                                                        NEWS
 - OpenSSL:
   . Fixed bug GH-21083 (Skip private_key_bits validation for EC/curve-based
     keys). (iliaal)
+  . Fix missing error propagation for BIO_printf() calls. (ndossche)

 - PCRE:
   . Fixed re-entrancy issue on php_pcre_match_impl, php_pcre_replace_impl,
diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c
index 7e2b9568325..1c1073345a1 100644
--- a/ext/openssl/openssl.c
+++ b/ext/openssl/openssl.c
@@ -5900,16 +5900,21 @@ PHP_FUNCTION(openssl_pkcs7_encrypt)
 	/* tack on extra headers */
 	if (zheaders) {
 		ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(zheaders), strindex, zcertval) {
+			int ret;
 			zend_string *str = zval_try_get_string(zcertval);
 			if (UNEXPECTED(!str)) {
 				goto clean_exit;
 			}
 			if (strindex) {
-				BIO_printf(outfile, "%s: %s\n", ZSTR_VAL(strindex), ZSTR_VAL(str));
+				ret = BIO_printf(outfile, "%s: %s\n", ZSTR_VAL(strindex), ZSTR_VAL(str));
 			} else {
-				BIO_printf(outfile, "%s\n", ZSTR_VAL(str));
+				ret = BIO_printf(outfile, "%s\n", ZSTR_VAL(str));
 			}
 			zend_string_release(str);
+			if (ret < 0) {
+				php_openssl_store_errors();
+				goto clean_exit;
+			}
 		} ZEND_HASH_FOREACH_END();
 	}

@@ -6128,6 +6133,7 @@ PHP_FUNCTION(openssl_pkcs7_sign)
 			zend_string_release(str);
 			if (ret < 0) {
 				php_openssl_store_errors();
+				goto clean_exit;
 			}
 		} ZEND_HASH_FOREACH_END();
 	}
@@ -6518,16 +6524,21 @@ PHP_FUNCTION(openssl_cms_encrypt)
 	/* tack on extra headers */
 	if (zheaders && encoding == ENCODING_SMIME) {
 		ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(zheaders), strindex, zcertval) {
+			int ret;
 			zend_string *str = zval_try_get_string(zcertval);
 			if (UNEXPECTED(!str)) {
 				goto clean_exit;
 			}
 			if (strindex) {
-				BIO_printf(outfile, "%s: %s\n", ZSTR_VAL(strindex), ZSTR_VAL(str));
+				ret = BIO_printf(outfile, "%s: %s\n", ZSTR_VAL(strindex), ZSTR_VAL(str));
 			} else {
-				BIO_printf(outfile, "%s\n", ZSTR_VAL(str));
+				ret = BIO_printf(outfile, "%s\n", ZSTR_VAL(str));
 			}
 			zend_string_release(str);
+			if (ret < 0) {
+				php_openssl_store_errors();
+				goto clean_exit;
+			}
 		} ZEND_HASH_FOREACH_END();
 	}

@@ -6807,6 +6818,7 @@ PHP_FUNCTION(openssl_cms_sign)
 			zend_string_release(str);
 			if (ret < 0) {
 				php_openssl_store_errors();
+				goto clean_exit;
 			}
 		} ZEND_HASH_FOREACH_END();
 	}