summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaymond Toy <rtoy@chromium.org>2020-01-24 18:04:19 +0000
committerMichael BrĂ¼ning <michael.bruning@qt.io>2020-03-02 12:25:41 +0000
commit5887eeff3a3f11be694eb3e94b6f3c211d1cb82f (patch)
tree61b5f0bab540057ec3167c2e42e0c06233db201e
parentca787f956d866ab1d72e9d2eba5a063404480a86 (diff)
downloadqtwebengine-chromium-5887eeff3a3f11be694eb3e94b6f3c211d1cb82f.tar.gz
[Backport] CVE-2020-6388 - Out of bounds memory access in WebAudio
Manual backport of patch originally reviewed on https://chromium-review.googlesource.com/c/chromium/src/+/2011132: Always allocate extra space for alignment of AudioArrays Instead of trying an allocation to see if it's aligned, just always allocate extra space for alignment. We waste a bit of space, but this should not be huge. Arrays are typically at least 128 floats or more (the render size), and we need 16-byte alignment so we'll only waste 3% worst case. This simplifies the algorithm too. This means we don't need the static int that leads to data races. (cherry picked from commit 7760babc3a1cf49af1f12bad772abfdab2dcbfd8) Bug: 1042879 Change-Id: I8b820a207d13ebb0680c67bae60f4db2a45700b4 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/audio_array.h41
1 files changed, 15 insertions, 26 deletions
diff --git a/chromium/third_party/blink/renderer/platform/audio/audio_array.h b/chromium/third_party/blink/renderer/platform/audio/audio_array.h
index 7ff276e5b9e..0a8c263eb67 100644
--- a/chromium/third_party/blink/renderer/platform/audio/audio_array.h
+++ b/chromium/third_party/blink/renderer/platform/audio/audio_array.h
@@ -62,6 +62,8 @@ class AudioArray {
CHECK_LE(n, std::numeric_limits<unsigned>::max() / sizeof(T));
uint32_t initial_size = static_cast<uint32_t>(sizeof(T) * n);
+ // Minimmum alignment requirements for arrays so that we can use
+ // SIMD.
#if defined(ARCH_CPU_X86_FAMILY) || defined(WTF_USE_WEBAUDIO_FFMPEG)
const unsigned kAlignment = 32;
#else
@@ -71,32 +73,17 @@ class AudioArray {
if (allocation_)
WTF::Partitions::FastFree(allocation_);
- bool is_allocation_good = false;
-
- while (!is_allocation_good) {
- // Initially we try to allocate the exact size, but if it's not aligned
- // then we'll have to reallocate and from then on allocate extra.
- static unsigned extra_allocation_bytes = 0;
-
- unsigned total =
- base::CheckAdd(initial_size, extra_allocation_bytes).ValueOrDie();
- T* allocation = static_cast<T*>(WTF::Partitions::FastZeroedMalloc(
- total, WTF_HEAP_PROFILER_TYPE_NAME(AudioArray<T>)));
- CHECK(allocation);
-
- T* aligned_data = AlignedAddress(allocation, kAlignment);
-
- if (aligned_data == allocation || extra_allocation_bytes == kAlignment) {
- allocation_ = allocation;
- aligned_data_ = aligned_data;
- size_ = static_cast<uint32_t>(n);
- is_allocation_good = true;
- } else {
- // always allocate extra after the first alignment failure.
- extra_allocation_bytes = kAlignment;
- WTF::Partitions::FastFree(allocation);
- }
- }
+ // Always allocate extra space so that we are guaranteed to get
+ // the desired alignment. Some memory is wasted, but it should be
+ // small since most arrays are probably at least 128 floats (or
+ // doubles).
+ unsigned total = base::CheckAdd(initial_size, kAlignment).ValueOrDie();
+ allocation_ = static_cast<T*>(WTF::Partitions::FastZeroedMalloc(
+ total, WTF_HEAP_PROFILER_TYPE_NAME(AudioArray<T>)));
+ CHECK(allocation_);
+
+ aligned_data_ = AlignedAddress(allocation_, kAlignment);
+ size_ = static_cast<uint32_t>(n);
}
T* Data() { return aligned_data_; }
@@ -140,6 +127,8 @@ class AudioArray {
}
private:
+ // Return an address that is aligned to an |alignment| boundary.
+ // |alignment| MUST be a power of two!
static T* AlignedAddress(T* address, intptr_t alignment) {
intptr_t value = reinterpret_cast<intptr_t>(address);
return reinterpret_cast<T*>((value + alignment - 1) & ~(alignment - 1));