From 2fe5ae29a5f6434ef456afe9673a4f400ec63848 Mon Sep 17 00:00:00 2001
From: Jean-Yves Avenard <jya@apple.com>
Date: Fri, 14 Jun 2024 16:08:19 -0700
Subject: [PATCH] Cherry-pick 272448.1085@safari-7618.3.10-branch
 (ff52ff7cb64e). https://bugs.webkit.org/show_bug.cgi?id=275431

HeapBufferOverflow in computeSampleUsingLinearInterpolation
https://bugs.webkit.org/show_bug.cgi?id=275431
rdar://125617812

Reviewed by Youenn Fablet.

Add boundary check.
This is a copy of blink code for that same function.
https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/modules/webaudio/audio_buffer_source_handler.cc;l=336-341

* LayoutTests/webaudio/crashtest/audiobuffer-sourcenode-resampler-crash-expected.txt: Added.
* LayoutTests/webaudio/crashtest/audiobuffer-sourcenode-resampler-crash.html: Added.
* Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp:
(WebCore::AudioBufferSourceNode::renderFromBuffer):

Canonical link: https://commits.webkit.org/274313.347@webkitglib/2.44

Upstream-Status: Backport [https://github.com/WebKit/WebKit/commit/2fe5ae29a5f6434ef456afe9673a4f400ec63848]
CVE: CVE-2024-40779
Signed-off-by: Vivek Kumbhar <vkumbhar@mvista.com>
---
 ...er-sourcenode-resampler-crash-expected.txt |  1 +
 ...udiobuffer-sourcenode-resampler-crash.html | 25 +++++++++++++++++++
 .../webaudio/AudioBufferSourceNode.cpp        |  6 +++++
 3 files changed, 32 insertions(+)
 create mode 100644 LayoutTests/webaudio/crashtest/audiobuffer-sourcenode-resampler-crash-expected.txt
 create mode 100644 LayoutTests/webaudio/crashtest/audiobuffer-sourcenode-resampler-crash.html

diff --git a/LayoutTests/webaudio/crashtest/audiobuffer-sourcenode-resampler-crash-expected.txt b/LayoutTests/webaudio/crashtest/audiobuffer-sourcenode-resampler-crash-expected.txt
new file mode 100644
index 00000000..654ddf7f
--- /dev/null
+++ b/LayoutTests/webaudio/crashtest/audiobuffer-sourcenode-resampler-crash-expected.txt
@@ -0,0 +1 @@
+This test passes if it does not crash.
diff --git a/LayoutTests/webaudio/crashtest/audiobuffer-sourcenode-resampler-crash.html b/LayoutTests/webaudio/crashtest/audiobuffer-sourcenode-resampler-crash.html
new file mode 100644
index 00000000..5fb2dd8c
--- /dev/null
+++ b/LayoutTests/webaudio/crashtest/audiobuffer-sourcenode-resampler-crash.html
@@ -0,0 +1,25 @@
+<html>
+<head>
+    <script>
+        async function main() {
+            var ctx = new AudioContext();
+            var src = new AudioBufferSourceNode(ctx);
+            src.buffer = ctx.createBuffer(1, 8192, 44100);
+            src.start(undefined, 0.5);
+            src.playbackRate.value = -1;
+            src.connect(ctx.destination, 0, 0);
+            if (window.testRunner)
+                testRunner.notifyDone();
+        }
+    </script>
+</head>
+<body onload="main()">
+    <p>This test passes if it does not crash.</p>
+    <script>
+    if (window.testRunner) {
+        testRunner.waitUntilDone();
+        testRunner.dumpAsText();
+    }
+    </script>
+</body>
+</html>
diff --git a/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp b/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp
index 35b8c818..689d37a1 100644
--- a/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp
+++ b/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp
@@ -342,6 +342,12 @@ bool AudioBufferSourceNode::renderFromBuffer(AudioBus* bus, unsigned destination
             if (readIndex2 >= maxFrame)
                 readIndex2 = m_isLooping ? minFrame : readIndex;

+            // Final sanity check on buffer access.
+            // FIXME: as an optimization, try to get rid of this inner-loop check and
+            // put assertions and guards before the loop.
+            if (readIndex >= bufferLength || readIndex2 >= bufferLength)
+                break;
+
             // Linear interpolation.
             for (unsigned i = 0; i < numberOfChannels; ++i) {
                 float* destination = destinationChannels[i];
--
2.34.1
