Prechádzať zdrojové kódy

libwebm: Fix double free in mkvparser ContentEncoding

Origin: https://github.com/webmproject/libvpx/commit/6a7c84a2449dcc70de2525df209afea908622399
Author: James Zern <[email protected]>

-----
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 53d8b958c5237e685b20ed24fbe85289099ea70e)
John Breton 1 mesiac pred
rodič
commit
49966f6927

+ 1 - 0
thirdparty/README.md

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

+ 2 - 1
thirdparty/libsimplewebm/libwebm/mkvparser/mkvparser.cc

@@ -4329,12 +4329,13 @@ long ContentEncoding::ParseCompressionEntry(long long start, long long size,
         delete[] buf;
         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;
     }

+ 41 - 0
thirdparty/libsimplewebm/patches/libwebm-CVE-2019-2126.patch

@@ -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;
+     }