Skip to content

Commit 725438e

Browse files
authored
[MEDIUM] Patch tinyxml2 for CVE-2024-50615 (#13429)
1 parent af171d9 commit 725438e

File tree

2 files changed

+239
-1
lines changed

2 files changed

+239
-1
lines changed
Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
From 5be6d48c41d636826984605448dc8d4516f2b8ac Mon Sep 17 00:00:00 2001
2+
From: archana25-ms <v-shettigara@microsoft.com>
3+
Date: Wed, 16 Apr 2025 07:10:31 +0000
4+
Subject: [PATCH] Address CVE-2024-50615
5+
Upstream Patch Reference :
6+
1. https://github.com/leethomason/tinyxml2/commit/494735de30c946bc7d684c65ff8ece05beeb232d
7+
2. https://github.com/leethomason/tinyxml2/commit/4cbb25155cde261ccf868efb8ae29ad0eebea4d1
8+
9+
---
10+
tinyxml2.cpp | 129 +++++++++++++++++++++++----------------------------
11+
xmltest.cpp | 31 ++++++++++++-
12+
2 files changed, 89 insertions(+), 71 deletions(-)
13+
14+
diff --git a/tinyxml2.cpp b/tinyxml2.cpp
15+
index 9173467..b12112e 100755
16+
--- a/tinyxml2.cpp
17+
+++ b/tinyxml2.cpp
18+
@@ -467,102 +467,91 @@ void XMLUtil::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length
19+
}
20+
21+
22+
-const char* XMLUtil::GetCharacterRef( const char* p, char* value, int* length )
23+
+const char* XMLUtil::GetCharacterRef(const char* p, char* value, int* length)
24+
{
25+
- // Presume an entity, and pull it out.
26+
+ // Assume an entity, and pull it out.
27+
*length = 0;
28+
29+
+ static const uint32_t MAX_CODE_POINT = 0x10FFFF;
30+
+
31+
if ( *(p+1) == '#' && *(p+2) ) {
32+
- unsigned long ucs = 0;
33+
- TIXMLASSERT( sizeof( ucs ) >= 4 );
34+
+ uint32_t ucs = 0;
35+
ptrdiff_t delta = 0;
36+
- unsigned mult = 1;
37+
+ uint32_t mult = 1;
38+
static const char SEMICOLON = ';';
39+
40+
- if ( *(p+2) == 'x' ) {
41+
+ bool hex = false;
42+
+ uint32_t radix = 10;
43+
+ const char* q = 0;
44+
+ char terminator = '#';
45+
+
46+
+ if (*(p + 2) == 'x') {
47+
// Hexadecimal.
48+
- const char* q = p+3;
49+
- if ( !(*q) ) {
50+
- return 0;
51+
- }
52+
+ hex = true;
53+
+ radix = 16;
54+
+ terminator = 'x';
55+
56+
- q = strchr( q, SEMICOLON );
57+
+ q = p + 3;
58+
+ q = p + 3;
59+
+ }
60+
+ else {
61+
+ // Decimal.
62+
+ q = p + 2;
63+
+ }
64+
+ if (!(*q)) {
65+
+ return 0;
66+
+ }
67+
68+
- if ( !q ) {
69+
- return 0;
70+
- }
71+
- TIXMLASSERT( *q == SEMICOLON );
72+
73+
- delta = q-p;
74+
- --q;
75+
+ q = strchr(q, SEMICOLON);
76+
+ if (!q) {
77+
+ return 0;
78+
+ }
79+
+ TIXMLASSERT(*q == SEMICOLON);
80+
+ delta = q - p;
81+
+ --q;
82+
83+
- while ( *q != 'x' ) {
84+
- unsigned int digit = 0;
85+
+ while (*q != terminator) {
86+
+ uint32_t digit = 0;
87+
88+
- if ( *q >= '0' && *q <= '9' ) {
89+
- digit = *q - '0';
90+
- }
91+
- else if ( *q >= 'a' && *q <= 'f' ) {
92+
- digit = *q - 'a' + 10;
93+
- }
94+
- else if ( *q >= 'A' && *q <= 'F' ) {
95+
- digit = *q - 'A' + 10;
96+
- }
97+
- else {
98+
- return 0;
99+
- }
100+
- TIXMLASSERT( digit < 16 );
101+
- TIXMLASSERT( digit == 0 || mult <= UINT_MAX / digit );
102+
- const unsigned int digitScaled = mult * digit;
103+
- TIXMLASSERT( ucs <= ULONG_MAX - digitScaled );
104+
- ucs += digitScaled;
105+
- TIXMLASSERT( mult <= UINT_MAX / 16 );
106+
- mult *= 16;
107+
- --q;
108+
+ if (*q >= '0' && *q <= '9') {
109+
+ digit = *q - '0';
110+
}
111+
- }
112+
- else {
113+
- // Decimal.
114+
- const char* q = p+2;
115+
- if ( !(*q) ) {
116+
- return 0;
117+
+ else if (hex && (*q >= 'a' && *q <= 'f')) {
118+
+ digit = *q - 'a' + 10;
119+
}
120+
-
121+
- q = strchr( q, SEMICOLON );
122+
-
123+
- if ( !q ) {
124+
+ else if (hex && (*q >= 'A' && *q <= 'F')) {
125+
+ digit = *q - 'A' + 10;
126+
+ }
127+
+ else {
128+
return 0;
129+
}
130+
- TIXMLASSERT( *q == SEMICOLON );
131+
+ TIXMLASSERT(digit < radix);
132+
133+
- delta = q-p;
134+
- --q;
135+
+ const unsigned int digitScaled = mult * digit;
136+
+ ucs += digitScaled;
137+
+ mult *= radix;
138+
139+
- while ( *q != '#' ) {
140+
- if ( *q >= '0' && *q <= '9' ) {
141+
- const unsigned int digit = *q - '0';
142+
- TIXMLASSERT( digit < 10 );
143+
- TIXMLASSERT( digit == 0 || mult <= UINT_MAX / digit );
144+
- const unsigned int digitScaled = mult * digit;
145+
- TIXMLASSERT( ucs <= ULONG_MAX - digitScaled );
146+
- ucs += digitScaled;
147+
- }
148+
- else {
149+
- return 0;
150+
- }
151+
- TIXMLASSERT( mult <= UINT_MAX / 10 );
152+
- mult *= 10;
153+
- --q;
154+
+ // Security check: could a value exist that is out of range?
155+
+ // Easily; limit to the MAX_CODE_POINT, which also allows for a
156+
+ // bunch of leading zeroes.
157+
+ if (mult > MAX_CODE_POINT) {
158+
+ mult = MAX_CODE_POINT;
159+
}
160+
+ --q;
161+
+ }
162+
+ // Out of range:
163+
+ if (ucs > MAX_CODE_POINT) {
164+
+ return 0;
165+
}
166+
// convert the UCS to UTF-8
167+
- ConvertUTF32ToUTF8( ucs, value, length );
168+
+ TIXMLASSERT(ucs <= MAX_CODE_POINT);
169+
+ ConvertUTF32ToUTF8(ucs, value, length);
170+
return p + delta + 1;
171+
}
172+
- return p+1;
173+
+ return p + 1;
174+
}
175+
176+
-
177+
void XMLUtil::ToStr( int v, char* buffer, int bufferSize )
178+
{
179+
TIXML_SNPRINTF( buffer, bufferSize, "%d", v );
180+
diff --git a/xmltest.cpp b/xmltest.cpp
181+
index d5a1ce3..50afcbd 100755
182+
--- a/xmltest.cpp
183+
+++ b/xmltest.cpp
184+
@@ -1642,7 +1642,7 @@ int main( int argc, const char ** argv )
185+
186+
static const char* result = "\xef\xbb\xbf<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
187+
XMLTest( "BOM and default declaration", result, printer.CStr(), false );
188+
- XMLTest( "CStrSize", 42, printer.CStrSize(), false );
189+
+ XMLTest( "CStrSize", true, printer.CStrSize() == 42, false );
190+
}
191+
{
192+
const char* xml = "<ipxml ws='1'><info bla=' /></ipxml>";
193+
@@ -2488,6 +2488,35 @@ int main( int argc, const char ** argv )
194+
doc.PrintError();
195+
}
196+
197+
+ // ---------- CVE-2024-50615 -----------
198+
+ {
199+
+ const char* xml = "<Hello value='12&#65;34' value2='56&#x42;78'>Text</Hello>";
200+
+ XMLDocument doc;
201+
+ doc.Parse(xml);
202+
+ const char* value = doc.FirstChildElement()->Attribute("value");
203+
+ const char* value2 = doc.FirstChildElement()->Attribute("value2");
204+
+ XMLTest("Test attribute encode", false, doc.Error());
205+
+ XMLTest("Test decimal value", value, "12A34");
206+
+ XMLTest("Test hex encode", value2, "56B78");
207+
+ }
208+
+
209+
+ {
210+
+ const char* xml = "<Hello value='&#ABC9000000065;' value2='&#xffffffff;' value3='&#5000000000;' value4='&#x00000045;' value5='&#x000000000000000021;'>Text</Hello>";
211+
+ XMLDocument doc;
212+
+ doc.Parse(xml);
213+
+ const char* value = doc.FirstChildElement()->Attribute("value");
214+
+ const char* value2 = doc.FirstChildElement()->Attribute("value2");
215+
+ const char* value3 = doc.FirstChildElement()->Attribute("value3");
216+
+ const char* value4 = doc.FirstChildElement()->Attribute("value4");
217+
+ const char* value5 = doc.FirstChildElement()->Attribute("value5");
218+
+ XMLTest("Test attribute encode", false, doc.Error());
219+
+ XMLTest("Test attribute encode too long value", value, "&#ABC9000000065;"); // test long value
220+
+ XMLTest("Test attribute encode out of unicode range", value2, "&#xffffffff;"); // out of unicode range
221+
+ XMLTest("Test attribute encode out of int max value", value3, "&#5000000000;"); // out of int max value
222+
+ XMLTest("Test attribute encode with a Hex value", value4, "E"); // hex value in unicode value
223+
+ XMLTest("Test attribute encode with a Hex value", value5, "!"); // hex value in unicode value
224+
+ }
225+
+
226+
// ----------- Performance tracking --------------
227+
{
228+
#if defined( _MSC_VER )
229+
--
230+
2.45.3
231+

SPECS/tinyxml2/tinyxml2.spec

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
Summary: Simple, small, efficient, C++ XML parser that can be easily integrated into other programs.
22
Name: tinyxml2
33
Version: 9.0.0
4-
Release: 1%{?dist}
4+
Release: 2%{?dist}
55
License: zlib
66
Vendor: Microsoft Corporation
77
Distribution: Mariner
88
URL: https://github.com/leethomason/tinyxml2/
99
Source0: https://github.com/leethomason/%{name}/archive/%{version}.tar.gz#/%{name}-%{version}.tar.gz
10+
# CVE-2024-50614 fixed along with CVE-2024-50615
11+
Patch1: CVE-2024-50615.patch
1012
BuildRequires: build-essential
1113
BuildRequires: cmake
1214

@@ -22,6 +24,8 @@ Development files for %{name}
2224

2325
%prep
2426
%setup -q
27+
sed -i 's/\r$//' *.cpp
28+
%autopatch -p1
2529

2630
%build
2731
mkdir build
@@ -48,6 +52,9 @@ make install DESTDIR=%{buildroot}
4852
%{_lib64dir}/pkgconfig/tinyxml2.pc
4953

5054
%changelog
55+
* Wed Apr 16 2025 Archana Shettigar <v-shettigara@microsoft.com> - 9.0.0-2
56+
- Patch for CVE-2024-50615.
57+
5158
* Wed Jan 05 2022 Neha Agarwal <nehaagarwal@microsoft.com> - 9.0.0-1
5259
- Update to version 9.0.0.
5360

0 commit comments

Comments
 (0)