libwebm: Fix double free in mkvparser ContentEncoding

Origin: 6a7c84a244
Author: James Zern <jzern@google.com>

-----
This is a security fix for CVE-2019-2126. Godot currently contains a vulnerable
version of libwebm in its 3.x branch that is susceptible to a double free due
to a missing reset of a freed pointer. This commit corrects that issue.

(cherry picked from commit 53d8b958c5)
This commit is contained in:
John Breton 2025-06-20 15:38:56 -04:00 committed by Rémi Verschelde
parent d240313513
commit 49966f6927
No known key found for this signature in database
GPG key ID: C3336907360768E1
3 changed files with 44 additions and 1 deletions

View file

@ -220,6 +220,7 @@ Files extracted from upstream source:
Important: Some files have Godot-made changes. Important: Some files have Godot-made changes.
They are marked with `// -- GODOT start --` and `// -- GODOT end --` They are marked with `// -- GODOT start --` and `// -- GODOT end --`
comments. comments.
A patch is included to fix CVE-2019-2126 in libwebm.
## libtheora ## libtheora

View file

@ -4329,12 +4329,13 @@ long ContentEncoding::ParseCompressionEntry(long long start, long long size,
delete[] buf; delete[] buf;
return status; return status;
} }
// There should be only one settings element per content compression. // There should be only one settings element per content compression.
if (compression->settings != NULL) { if (compression->settings != NULL) {
delete[] buf; delete[] buf;
return E_FILE_FORMAT_INVALID; return E_FILE_FORMAT_INVALID;
} }
compression->settings = buf; compression->settings = buf;
compression->settings_len = buflen; compression->settings_len = buflen;
} }

View file

@ -0,0 +1,41 @@
diff --git a/thirdparty/libsimplewebm/libwebm/mkvparser/mkvparser.cc b/thirdparty/libsimplewebm/libwebm/mkvparser/mkvparser.cc
index e7b76f7da1..820ca28bf1 100644
--- a/thirdparty/libsimplewebm/libwebm/mkvparser/mkvparser.cc
+++ b/thirdparty/libsimplewebm/libwebm/mkvparser/mkvparser.cc
@@ -4232,6 +4232,7 @@ long ContentEncoding::ParseContentEncodingEntry(long long start, long long size,
new (std::nothrow) ContentEncryption*[encryption_count];
if (!encryption_entries_) {
delete[] compression_entries_;
+ compression_entries_ = NULL;
return -1;
}
encryption_entries_end_ = encryption_entries_;
@@ -4263,6 +4264,7 @@ long ContentEncoding::ParseContentEncodingEntry(long long start, long long size,
delete compression;
return status;
}
+ assert(compression_count > 0);
*compression_entries_end_++ = compression;
} else if (id == libwebm::kMkvContentEncryption) {
ContentEncryption* const encryption =
@@ -4275,6 +4277,7 @@ long ContentEncoding::ParseContentEncodingEntry(long long start, long long size,
delete encryption;
return status;
}
+ assert(encryption_count > 0);
*encryption_entries_end_++ = encryption;
}
@@ -4327,6 +4330,12 @@ long ContentEncoding::ParseCompressionEntry(long long start, long long size,
return status;
}
+ // There should be only one settings element per content compression.
+ if (compression->settings != NULL) {
+ delete[] buf;
+ return E_FILE_FORMAT_INVALID;
+ }
+
compression->settings = buf;
compression->settings_len = buflen;
}