Firefox · DOM
CVE-2026-8954
Integer Overflow in DOM
Overview
Medium
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifdom/media/AudioConverter.cpp |
modified | |
ifdom/media/AudioConverter.h |
modified |
Files Changed
dom/media/AudioConverter.cppdom/media/AudioConverter.h
Patch
diff --git a/dom/media/AudioConverter.cpp b/dom/media/AudioConverter.cpp
index fbd9b5243f4..bc2c4dbe3b0 100644
--- a/dom/media/AudioConverter.cpp
+++ b/dom/media/AudioConverter.cpp
@@ -9,6 +9,8 @@
#include <cmath>
+#include "mozilla/CheckedInt.h"
+
/*
* Parts derived from MythTV AudioConvert Class
* Created by Jean-Yves Avenard.
@@ -347,8 +349,15 @@ size_t AudioConverter::ResampleAudio(void* aOut, const void* aIn,
if (!mResampler) {
return 0;
}
- uint32_t outframes = ResampleRecipientFrames(aFrames);
- uint32_t inframes = aFrames;
+ uint32_t outframes;
+ if (!ResampleRecipientFrames(aFrames, &outframes)) {
+ return 0;
+ }
+ CheckedUint32 inframesChecked(aFrames);
+ if (!inframesChecked.isValid()) {
+ return 0;
+ }
+ uint32_t inframes = inframesChecked.value();
int error;
if (mOut.Format() == AudioConfig::FORMAT_FLT) {
@@ -371,7 +380,8 @@ size_t AudioConverter::ResampleAudio(void* aOut, const void* aIn,
mResampler = nullptr;
return 0;
}
- MOZ_ASSERT(inframes == aFrames, "Some frames will be dropped");
+ MOZ_ASSERT(static_cast<size_t>(inframes) == aFrames,
+ "Some frames will be dropped");
return outframes;
}
@@ -460,15 +470,27 @@ size_t AudioConverter::UpmixAudio(void* aOut, const void* aIn,
return aFrames;
}
-size_t AudioConverter::ResampleRecipientFrames(size_t aFrames) const {
+bool AudioConverter::ResampleRecipientFrames(size_t aFrames,
+ uint32_t* aOutFrames) const {
if (!aFrames && mIn.Rate() != mOut.Rate()) {
if (!mResampler) {
- return 0;
+ *aOutFrames = 0;
+ return true;
}
// We drain by pushing in get_input_latency() samples of 0
aFrames = speex_resampler_get_input_latency(mResampler);
}
- return (uint64_t)aFrames * mOut.Rate() / mIn.Rate() + 1;
+ CheckedInt<uint64_t> numerator = CheckedInt<uint64_t>(aFrames) * mOut.Rate();
+ if (!numerator.isValid()) {
+ return false;
+ }
+ CheckedUint32 outFrames(numerator.value() / mIn.Rate());
+ outFrames += 1u;
+ if (!outFrames.isValid()) {
+ return false;
+ }
+ *aOutFrames = outFrames.value();
+ return true;
}
size_t AudioConverter::FramesOutToSamples(size_t aFrames) const {
diff --git a/dom/media/AudioConverter.h b/dom/media/AudioConverter.h
index 8244ee250e9..3be9f457898 100644
--- a/dom/media/AudioConverter.h
+++ b/dom/media/AudioConverter.h
@@ -6,6 +6,7 @@
#define AudioConverter_h
#include "MediaInfo.h"
+#include "mozilla/CheckedInt.h"
// Forward declaration
typedef struct SpeexResamplerState_ SpeexResamplerState;
@@ -161,10 +162,15 @@ class AudioConverter {
AlignedBuffer<Value>* outputBuffer = &temp1;
AlignedBuffer<Value> temp2;
if (!frames || mOut.Rate() > mIn.Rate()) {
+ uint32_t resampledFrames;
// We are upsampling or about to drain, we can't work in place.
// Allocate another temporary buffer where the upsampling will occur.
- if (!temp2.SetLength(
- FramesOutToSamples(ResampleRecipientFrames(frames)))) {
+ if (!ResampleRecipientFrames(frames, &resampledFrames)) {
+ return AudioDataBuffer<Format, Value>(std::move(temp2));
+ }
+ CheckedInt<size_t> outputSamples =
+ CheckedInt<size_t>(resampledFrames) * mOut.Channels();
+ if (!outputSamples.isValid() || !temp2.SetLength(outputSamples.value())) {
return AudioDataBuffer<Format, Value>(std::move(temp2));
}
outputBuffer = &temp2;
@@ -210,11 +216,19 @@ class AudioConverter {
return frames;
}
// Prepare output in cases of drain or up-sampling
- if ((!frames || mOut.Rate() > mIn.Rate()) &&
- !aOutBuffer.SetLength(
- FramesOutToSamples(ResampleRecipientFrames(frames)))) {
- MOZ_ALWAYS_TRUE(aOutBuffer.SetLength(0));
- return 0;
+ if (!frames || mOut.Rate() > mIn.Rate()) {
+ uint32_t resampledFrames;
+ if (!ResampleRecipientFrames(frames, &resampledFrames)) {
+ MOZ_ALWAYS_TRUE(aOutBuffer.SetLength(0));
+ return 0;
+ }
+ CheckedInt<size_t> outputSamples =
+ CheckedInt<size_t>(resampledFrames) * mOut.Channels();
+ if (!outputSamples.isValid() ||
+ !aOutBuffer.SetLength(outputSamples.value())) {
+ MOZ_ALWAYS_TRUE(aOutBuffer.SetLength(0));
+ return 0;
+ }
}
if (!frames) {
frames = DrainResampler(aOutBuffer.Data());
@@ -264,7 +278,7 @@ class AudioConverter {
// Resampler context.
SpeexResamplerState* mResampler;
size_t ResampleAudio(void* aOut, const void* aIn, size_t aFrames);
- size_t ResampleRecipientFrames(size_t aFrames) const;
+ bool ResampleRecipientFrames(size_t aFrames, uint32_t* aOutFrames) const;
void RecreateResampler();
size_t DrainResampler(void* aOut);
};
Loading diff…
References
On This Page