diff mbox series

[kirkstone] webkitgtk: Security fix for CVE-2024-40776 and CVE-2024-40780

Message ID 20250103052753.7418-1-rsangam@mvista.com
State Under Review
Delegated to: Steve Sakoman
Headers show
Series [kirkstone] webkitgtk: Security fix for CVE-2024-40776 and CVE-2024-40780 | expand

Commit Message

Rohini Sangam Jan. 3, 2025, 5:27 a.m. UTC
CVE fixed:
- CVE-2024-40776 webkitgtk: Use after free may lead to Remote Code Execution
- CVE-2024-40780 webkitgtk: Out-of-bounds read was addressed with improved bounds checking

Upstream-Status: Backport from https://github.com/WebKit/WebKit/commit/b951404ea74ae432312a83138f5c8945a0d09e1b and https://github.com/WebKit/WebKit/commit/e83e4c7460972898dc06a5f5ab36eed7c6b101b5

Signed-off-by: Rohini Sangam <rsangam@mvista.com>
Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
---
 .../webkit/webkitgtk/CVE-2024-40776.patch     | 141 ++++++++++++++++++
 .../webkit/webkitgtk/CVE-2024-40780.patch     |  94 ++++++++++++
 meta/recipes-sato/webkit/webkitgtk_2.36.8.bb  |   2 +
 3 files changed, 237 insertions(+)
 create mode 100644 meta/recipes-sato/webkit/webkitgtk/CVE-2024-40776.patch
 create mode 100644 meta/recipes-sato/webkit/webkitgtk/CVE-2024-40780.patch
diff mbox series

Patch

diff --git a/meta/recipes-sato/webkit/webkitgtk/CVE-2024-40776.patch b/meta/recipes-sato/webkit/webkitgtk/CVE-2024-40776.patch
new file mode 100644
index 0000000000..60f18168fe
--- /dev/null
+++ b/meta/recipes-sato/webkit/webkitgtk/CVE-2024-40776.patch
@@ -0,0 +1,141 @@ 
+From b951404ea74ae432312a83138f5c8945a0d09e1b Mon Sep 17 00:00:00 2001
+From: Jean-Yves Avenard <jya@apple.com>
+Date: Wed, 24 Apr 2024 19:01:06 -0700
+Subject: [PATCH] CVE-2024-40776: Always copy all audio channels to the AudioBus 
+to guarantee data lifetime.
+
+Upstream-Status: Backport from https://github.com/WebKit/WebKit/commit/b951404ea74ae432312a83138f5c8945a0d09e1b
+CVE: CVE-2024-40776
+
+Signed-off-by: Rohini Sangam <rsangam@mvista.com>
+---
+ ...et-concurrent-resampler-crash-expected.txt |  1 +
+ ...dioworklet-concurrent-resampler-crash.html | 44 +++++++++++++++++++
+ .../platform/audio/MultiChannelResampler.cpp  | 21 ++-------
+ .../platform/audio/MultiChannelResampler.h    |  2 -
+ 4 files changed, 48 insertions(+), 20 deletions(-)
+ create mode 100644 LayoutTests/webaudio/crashtest/audioworklet-concurrent-resampler-crash-expected.txt
+ create mode 100644 LayoutTests/webaudio/crashtest/audioworklet-concurrent-resampler-crash.html
+
+diff --git a/LayoutTests/webaudio/crashtest/audioworklet-concurrent-resampler-crash-expected.txt b/LayoutTests/webaudio/crashtest/audioworklet-concurrent-resampler-crash-expected.txt
+new file mode 100644
+index 00000000..654ddf7f
+--- /dev/null
++++ b/LayoutTests/webaudio/crashtest/audioworklet-concurrent-resampler-crash-expected.txt
+@@ -0,0 +1 @@
++This test passes if it does not crash.
+diff --git a/LayoutTests/webaudio/crashtest/audioworklet-concurrent-resampler-crash.html b/LayoutTests/webaudio/crashtest/audioworklet-concurrent-resampler-crash.html
+new file mode 100644
+index 00000000..b3ab181d
+--- /dev/null
++++ b/LayoutTests/webaudio/crashtest/audioworklet-concurrent-resampler-crash.html
+@@ -0,0 +1,44 @@
++<html>
++<head>
++    <script>
++        let worklet_source = `
++            class Processor extends AudioWorkletProcessor {
++                process(inputs, outputs, parameters) {
++                    return true;
++                }
++            }
++            registerProcessor('P2', Processor);
++        `;
++
++        let blob = new Blob([worklet_source], { type: 'application/javascript' });
++        let worklet = URL.createObjectURL(blob);
++
++        var ctx = new AudioContext({ sampleRate: 44100});
++        const dest = ctx.destination;
++        dest.channelCountMode = "max";
++
++        async function main() {
++            await ctx.audioWorklet.addModule(worklet);
++            var script_processor = ctx.createScriptProcessor();
++            script_processor.onaudioprocess = function() {
++                dest.channelCount = 1;
++                audio_worklet.disconnect();
++                if (window.testRunner)
++                    testRunner.notifyDone();
++            }
++            var audio_worklet = new AudioWorkletNode(ctx, "P2");
++            script_processor.connect(audio_worklet);
++            audio_worklet.connect(dest);
++        }
++    </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/platform/audio/MultiChannelResampler.cpp b/Source/WebCore/platform/audio/MultiChannelResampler.cpp
+index 1dadc58c..13db6f26 100644
+--- a/Source/WebCore/platform/audio/MultiChannelResampler.cpp
++++ b/Source/WebCore/platform/audio/MultiChannelResampler.cpp
+@@ -41,18 +41,8 @@ namespace WebCore {
+ MultiChannelResampler::MultiChannelResampler(double scaleFactor, unsigned numberOfChannels, unsigned requestFrames, Function<void(AudioBus*, size_t framesToProcess)>&& provideInput)
+     : m_numberOfChannels(numberOfChannels)
+     , m_provideInput(WTFMove(provideInput))
+-    , m_multiChannelBus(AudioBus::create(numberOfChannels, requestFrames, false))
++    , m_multiChannelBus(AudioBus::create(numberOfChannels, requestFrames))
+ {
+-    // As an optimization, we will use the buffer passed to provideInputForChannel() as channel memory for the first channel so we
+-    // only need to allocate memory if there is more than one channel.
+-    if (numberOfChannels > 1) {
+-        m_channelsMemory.reserveInitialCapacity(numberOfChannels - 1);
+-        for (unsigned channelIndex = 1; channelIndex < numberOfChannels; ++channelIndex) {
+-            m_channelsMemory.uncheckedAppend(makeUnique<AudioFloatArray>(requestFrames));
+-            m_multiChannelBus->setChannelMemory(channelIndex, m_channelsMemory.last()->data(), requestFrames);
+-        }
+-    }
+-
+     // Create each channel's resampler.
+     for (unsigned channelIndex = 0; channelIndex < numberOfChannels; ++channelIndex)
+         m_kernels.append(makeUnique<SincResampler>(scaleFactor, requestFrames, std::bind(&MultiChannelResampler::provideInputForChannel, this, std::placeholders::_1, std::placeholders::_2, channelIndex)));
+@@ -89,15 +79,10 @@ void MultiChannelResampler::process(AudioBus* destination, size_t framesToProces
+ void MultiChannelResampler::provideInputForChannel(float* buffer, size_t framesToProcess, unsigned channelIndex)
+ {
+     ASSERT(channelIndex < m_multiChannelBus->numberOfChannels());
+-    ASSERT(framesToProcess == m_multiChannelBus->length());
++    ASSERT(framesToProcess <= m_multiChannelBus->length());
+ 
+-    if (!channelIndex) {
+-        // As an optimization, we use the provided buffer as memory for the first channel in the AudioBus. This avoids
+-        // having to memcpy() for the first channel.
+-        m_multiChannelBus->setChannelMemory(0, buffer, framesToProcess);
++    if (!channelIndex)
+         m_provideInput(m_multiChannelBus.get(), framesToProcess);
+-        return;
+-    }
+ 
+     // Copy the channel data from what we received from m_multiChannelProvider.
+     memcpy(buffer, m_multiChannelBus->channel(channelIndex)->data(), sizeof(float) * framesToProcess);
+diff --git a/Source/WebCore/platform/audio/MultiChannelResampler.h b/Source/WebCore/platform/audio/MultiChannelResampler.h
+index e96cc56b..274fe364 100644
+--- a/Source/WebCore/platform/audio/MultiChannelResampler.h
++++ b/Source/WebCore/platform/audio/MultiChannelResampler.h
+@@ -29,7 +29,6 @@
+ #ifndef MultiChannelResampler_h
+ #define MultiChannelResampler_h
+ 
+-#include "AudioArray.h"
+ #include <memory>
+ #include <wtf/Function.h>
+ #include <wtf/Vector.h>
+@@ -62,7 +61,6 @@ private:
+     size_t m_outputFramesReady { 0 };
+     Function<void(AudioBus*, size_t framesToProcess)> m_provideInput;
+     RefPtr<AudioBus> m_multiChannelBus;
+-    Vector<std::unique_ptr<AudioFloatArray>> m_channelsMemory;
+ };
+ 
+ } // namespace WebCore
+-- 
+2.35.7
+
diff --git a/meta/recipes-sato/webkit/webkitgtk/CVE-2024-40780.patch b/meta/recipes-sato/webkit/webkitgtk/CVE-2024-40780.patch
new file mode 100644
index 0000000000..ab41213d7d
--- /dev/null
+++ b/meta/recipes-sato/webkit/webkitgtk/CVE-2024-40780.patch
@@ -0,0 +1,94 @@ 
+From e83e4c7460972898dc06a5f5ab36eed7c6b101b5 Mon Sep 17 00:00:00 2001
+From: Jer Noble <jer.noble@apple.com>
+Date: Tue, 11 Jun 2024 11:54:06 -0700
+Subject: [PATCH] CVE-2024-40780: Add check in AudioBufferSourceNode::renderFromBuffer() 
+when detune is set to large negative value
+
+Upstream-Status: Backport from https://github.com/WebKit/WebKit/commit/e83e4c7460972898dc06a5f5ab36eed7c6b101b5
+CVE: CVE-2024-40780
+
+Signed-off-by: Rohini Sangam <rsangam@mvista.com>
+---
+ ...buffersourcenode-detune-crash-expected.txt | 10 +++++++
+ .../audiobuffersourcenode-detune-crash.html   | 30 +++++++++++++++++++
+ .../webaudio/AudioBufferSourceNode.cpp        |  7 +++++
+ 3 files changed, 47 insertions(+)
+ create mode 100644 LayoutTests/webaudio/audiobuffersourcenode-detune-crash-expected.txt
+ create mode 100644 LayoutTests/webaudio/audiobuffersourcenode-detune-crash.html
+
+diff --git a/LayoutTests/webaudio/audiobuffersourcenode-detune-crash-expected.txt b/LayoutTests/webaudio/audiobuffersourcenode-detune-crash-expected.txt
+new file mode 100644
+index 00000000..914ba0b1
+--- /dev/null
++++ b/LayoutTests/webaudio/audiobuffersourcenode-detune-crash-expected.txt
+@@ -0,0 +1,10 @@
++Attempting to create a AudioBufferSourceNode with a large negative detune value should not crash.
++
++On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
++
++
++PASS Test passed because it did not crash.
++PASS successfullyParsed is true
++
++TEST COMPLETE
++
+diff --git a/LayoutTests/webaudio/audiobuffersourcenode-detune-crash.html b/LayoutTests/webaudio/audiobuffersourcenode-detune-crash.html
+new file mode 100644
+index 00000000..e8af579d
+--- /dev/null
++++ b/LayoutTests/webaudio/audiobuffersourcenode-detune-crash.html
+@@ -0,0 +1,30 @@
++<!DOCTYPE html>
++<html>
++    <head>
++    <script src="../resources/js-test-pre.js"></script>
++    <script src="resources/audio-testing.js"></script>
++    </head>
++    <body>
++        <script>
++            description("Attempting to create a AudioBufferSourceNode with a large negative detune value should not crash.");
++
++            jsTestIsAsync = true;
++
++            var context = new AudioContext();
++            var src = context.createBufferSource();
++            var buffer = context.createBuffer(1, 256, 44100);
++            src.buffer = buffer;
++            src.start(undefined, 1);
++            src.connect(context.listener.positionX, 0);
++            var panner = context.createPanner();
++            src.detune.value = -0xffffff;
++            panner.connect(context.destination);
++            setTimeout(() => {
++                testPassed("Test passed because it did not crash.");
++                finishJSTest();
++            }, 100);
++        </script>
++
++        <script src="../resources/js-test-post.js"></script>
++    </body>
++</html>
+diff --git a/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp b/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp
+index 689d37a1..f68e7ff5 100644
+--- a/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp
++++ b/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp
+@@ -327,9 +327,16 @@ bool AudioBufferSourceNode::renderFromBuffer(AudioBus* bus, unsigned destination
+         virtualReadIndex = readIndex;
+     } else if (!pitchRate) {
+         unsigned readIndex = static_cast<unsigned>(virtualReadIndex);
++        int deltaFrames = static_cast<int>(virtualDeltaFrames);
++        maxFrame = static_cast<unsigned>(virtualMaxFrame);
++
++        if (readIndex >= maxFrame)
++            readIndex -= deltaFrames;
+ 
+         for (unsigned i = 0; i < numberOfChannels; ++i)
+             std::fill_n(destinationChannels[i] + writeIndex, framesToProcess, sourceChannels[i][readIndex]);
++
++        virtualReadIndex = readIndex;
+     } else if (reverse) {
+         unsigned maxFrame = static_cast<unsigned>(virtualMaxFrame);
+         unsigned minFrame = static_cast<unsigned>(floorf(virtualMinFrame));
+-- 
+2.35.7
+
diff --git a/meta/recipes-sato/webkit/webkitgtk_2.36.8.bb b/meta/recipes-sato/webkit/webkitgtk_2.36.8.bb
index 4849ee50ff..2006d1d55e 100644
--- a/meta/recipes-sato/webkit/webkitgtk_2.36.8.bb
+++ b/meta/recipes-sato/webkit/webkitgtk_2.36.8.bb
@@ -26,6 +26,8 @@  SRC_URI = "https://www.webkitgtk.org/releases/${BP}.tar.xz \
            file://CVE-2023-32439.patch \
            file://CVE-2024-40779.patch \
            file://0d3344e17d258106617b0e6d783d073b188a2548.patch \
+           file://CVE-2024-40776.patch \
+           file://CVE-2024-40780.patch \
            "
 SRC_URI[sha256sum] = "0ad9fb6bf28308fe3889faf184bd179d13ac1b46835d2136edbab2c133d00437"