summaryrefslogtreecommitdiffstats
path: root/php-cve-2025-6491.patch
blob: ec8ce61578a2cf7c76d2a75af030c17158fc380b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
From c13a3b2a3710c66231f0cad16ff74ef75c8672a7 Mon Sep 17 00:00:00 2001
From: Ahmed Lekssays <lekssaysahmed@gmail.com>
Date: Tue, 3 Jun 2025 09:00:55 +0000
Subject: [PATCH 1/4] Fix GHSA-453j-q27h-5p8x

Libxml versions prior to 2.13 cannot correctly handle a call to
xmlNodeSetName() with a name longer than 2G. It will leave the node
object in an invalid state with a NULL name. This later causes a NULL
pointer dereference when using the name during message serialization.

To solve this, implement a workaround that resets the name to the
sentinel name if this situation arises.

Versions of libxml of 2.13 and higher are not affected.

This can be exploited if a SoapVar is created with a fully qualified
name that is longer than 2G. This would be possible if some application
code uses a namespace prefix from an untrusted source like from a remote
SOAP service.

Co-authored-by: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
(cherry picked from commit 9cb3d8d200f0c822b17bda35a2a67a97b039d3e1)
(cherry picked from commit 1b7410a57f8a5fd1dd43854bcf7b9200517c9fd2)
---
 ext/soap/soap.c                      |  6 ++--
 ext/soap/tests/soap_qname_crash.phpt | 48 ++++++++++++++++++++++++++++
 2 files changed, 52 insertions(+), 2 deletions(-)
 create mode 100644 ext/soap/tests/soap_qname_crash.phpt

diff --git a/ext/soap/soap.c b/ext/soap/soap.c
index 7429aebbf70..94f1db526c6 100644
--- a/ext/soap/soap.c
+++ b/ext/soap/soap.c
@@ -4457,8 +4457,10 @@ static xmlNodePtr serialize_zval(zval *val, sdlParamPtr param, char *paramName,
 	}
 	xmlParam = master_to_xml(enc, val, style, parent);
 	zval_ptr_dtor(&defval);
-	if (!strcmp((char*)xmlParam->name, "BOGUS")) {
-		xmlNodeSetName(xmlParam, BAD_CAST(paramName));
+	if (xmlParam != NULL) { 
+		if (xmlParam->name == NULL || strcmp((char*)xmlParam->name, "BOGUS") == 0) {
+			xmlNodeSetName(xmlParam, BAD_CAST(paramName));
+		}
 	}
 	return xmlParam;
 }
diff --git a/ext/soap/tests/soap_qname_crash.phpt b/ext/soap/tests/soap_qname_crash.phpt
new file mode 100644
index 00000000000..7a1bf026022
--- /dev/null
+++ b/ext/soap/tests/soap_qname_crash.phpt
@@ -0,0 +1,48 @@
+--TEST--
+Test SoapClient with excessively large QName prefix in SoapVar
+--EXTENSIONS--
+soap
+--SKIPIF--
+<?php
+if (PHP_INT_SIZE != 8) die("skip: 64-bit only");
+?>
+--INI--
+memory_limit=8G
+--FILE--
+<?php
+
+class TestSoapClient extends SoapClient {
+    public function __doRequest(
+        $request,
+        $location,
+        $action,
+        $version,
+        $one_way = false
+    ): ?string {
+        die($request);
+    }
+}
+
+$prefix = str_repeat("A", 2 * 1024 * 1024 * 1024);
+$qname = "{$prefix}:tag";
+
+echo "Attempting to create SoapVar with very large QName\n";
+
+$var = new SoapVar("value", XSD_QNAME, null, null, $qname);
+
+echo "Attempting encoding\n";
+
+$options = [
+    'location' => 'http://127.0.0.1/',
+    'uri' => 'urn:dummy',
+    'trace' => 1,
+    'exceptions' => true,
+];
+$client = new TestSoapClient(null, $options);
+$client->__soapCall("DummyFunction", [$var]);
+?>
+--EXPECT--
+Attempting to create SoapVar with very large QName
+Attempting encoding
+<?xml version="1.0" encoding="UTF-8"?>
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:dummy" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:DummyFunction><param0 xsi:type="xsd:QName">value</param0></ns1:DummyFunction></SOAP-ENV:Body></SOAP-ENV:Envelope>
-- 
2.50.0