Commit a0434fdc241 for php
commit a0434fdc2412e0c4857a9f954cafae02cfcabb43
Author: David Carlier <devnexen@gmail.com>
Date: Tue Oct 6 19:08:12 2026 +0100
ext/soap: fix use of uninitialized func in do_request() on OOM bailout
Follow-up to GH-22592: an OOM while copying the trace request or
allocating the __doRequest function name leaves func uninitialized
before the cleanup path destroys it. Also backport the GH-22585 test.
Close GH-24167
diff --git a/NEWS b/NEWS
index 72ed4ce12b6..e8b86a95e07 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,10 @@ PHP NEWS
. Fixed bug GH-20890 (Segfault in zval_undefined_cv with non-simple property
hook with minimal tracing JIT). (ndossche)
+- SOAP:
+ . Fixed use of uninitialized func in do_request() on OOM bailout.
+ (David Carlier)
+
- Standard:
. Fixed chown() and lchown() failing to resolve user names in ZTS builds
when getpwnam_r() needs a larger buffer. (Ilia Alshanetsky)
diff --git a/ext/soap/soap.c b/ext/soap/soap.c
index 431329d40ef..74e6422d70c 100644
--- a/ext/soap/soap.c
+++ b/ext/soap/soap.c
@@ -2240,6 +2240,7 @@ static bool do_request(zval *this_ptr, xmlDoc *request, const char *location, co
return false;
}
+ ZVAL_UNDEF(&func);
ZVAL_UNDEF(¶ms[0]);
ZVAL_UNDEF(¶ms[1]);
ZVAL_UNDEF(¶ms[2]);
diff --git a/ext/soap/tests/gh22585.phpt b/ext/soap/tests/gh22585.phpt
new file mode 100644
index 00000000000..9d007d012b4
--- /dev/null
+++ b/ext/soap/tests/gh22585.phpt
@@ -0,0 +1,39 @@
+--TEST--
+GH-22585 (Use of uninitialized params in do_request() on out-of-memory bailout)
+--EXTENSIONS--
+soap
+--INI--
+soap.wsdl_cache_enabled=0
+memory_limit=64M
+--FILE--
+<?php
+/* Deep recursion that keeps issuing SOAP calls until memory is exhausted while
+ * do_request() is only part-way through initializing its params array. The
+ * cleanup path must not touch the uninitialized slots. Depending on the
+ * environment the run ends either by the recursion limit (reaching "Done") or
+ * by the memory-exhaustion fatal; both are fine, a crash/UB abort is not. */
+try {
+ class MySoapClient extends SoapClient {
+ public function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string {
+ return '';
+ }
+ }
+
+ function main() {
+ for (;;) {
+ $soap = new MySoapClient(
+ null,
+ ['location' => "http://localhost/soap.php", 'uri' => "http://localhost/"]
+ );
+ $soap->call(1.1);
+ main();
+ }
+ }
+
+ main();
+} catch (\Throwable $e) {
+}
+echo "Done" . PHP_EOL;
+?>
+--EXPECTREGEX--
+(?s)(Done|.*Allowed memory size of \d+ bytes exhausted.*)