Firefox · DOM
CVE-2026-16364
Logic Error in DOM
Overview
High
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifdom/media/platforms/android/AndroidDataEncoder.cpp |
modified | |
ifmobile/android/geckoview/src/main/java/org/mozilla/gecko/media/SampleBuffer.java |
modified |
Files Changed
dom/media/platforms/android/AndroidDataEncoder.cppdom/media/platforms/android/RemoteDataDecoder.cppmobile/android/geckoview/src/main/java/org/mozilla/gecko/media/SampleBuffer.java
Patch
diff --git a/dom/media/platforms/android/AndroidDataEncoder.cpp b/dom/media/platforms/android/AndroidDataEncoder.cpp
index 73d9e910b1e..01d98d729a6 100644
--- a/dom/media/platforms/android/AndroidDataEncoder.cpp
+++ b/dom/media/platforms/android/AndroidDataEncoder.cpp
@@ -276,8 +276,8 @@ static RefPtr<MediaByteBuffer> ExtractCodecConfig(
auto config = MakeRefPtr<MediaByteBuffer>(aSize);
config->SetLength(aSize);
NS_ENSURE_SUCCESS(
- aBuffer->NativeCopy(reinterpret_cast<jlong>(config->Elements()), aOffset,
- aSize),
+ aBuffer->NativeCopy(reinterpret_cast<jlong>(config->Elements()),
+ config->Length(), aOffset, aSize),
nullptr);
if (!aAsAVCC) {
return config;
@@ -385,7 +385,7 @@ RefPtr<MediaRawData> AndroidDataEncoder::GetOutputData(
}
NS_ENSURE_SUCCESS(aBuffer->NativeCopy(reinterpret_cast<jlong>(writer->Data()),
- aOffset, aSize),
+ writer->Size(), aOffset, aSize),
nullptr);
output->mKeyframe = aIsKeyFrame;
@@ -421,7 +421,7 @@ RefPtr<MediaRawData> AndroidDataEncoder::GetOutputDataH264(
NS_ENSURE_SUCCESS(
aBuffer->NativeCopy(reinterpret_cast<jlong>(writer->Data() + prependSize),
- aOffset, aSize),
+ writer->Size() - prependSize, aOffset, aSize),
nullptr);
if (asAVCC && !AnnexB::ConvertSampleToAVCC(output, avccHeader)) {
diff --git a/dom/media/platforms/android/RemoteDataDecoder.cpp b/dom/media/platforms/android/RemoteDataDecoder.cpp
index 01d57d39aae..9e0a1453558 100644
--- a/dom/media/platforms/android/RemoteDataDecoder.cpp
+++ b/dom/media/platforms/android/RemoteDataDecoder.cpp
@@ -842,8 +842,9 @@ class RemoteAudioDecoder final : public RemoteDataDecoder {
LOG("OOM while allocating temporary output buffer");
return;
}
- nsresult rv = aBuffer->NativeCopy(reinterpret_cast<jlong>(audio.get()),
- offset, size);
+ nsresult rv =
+ aBuffer->NativeCopy(reinterpret_cast<jlong>(audio.get()),
+ audio.Length() * sampleSize, offset, size);
if (NS_FAILED(rv)) {
LOG("Fail to copy audio buffer");
Error(MediaResult(rv, __func__));
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/SampleBuffer.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/SampleBuffer.java
index 62a9c38a559..e9d7cb60031 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/SampleBuffer.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/SampleBuffer.java
@@ -50,11 +50,27 @@ public final class SampleBuffer implements Parcelable {
return mSharedMem != null ? mSharedMem.getSize() : 0;
}
+ private void checkBounds(
+ final int offset, final int size, final int inCapacity, final int outCapacity)
+ throws IOException {
+ if (mSharedMem == null || !mSharedMem.isValid()) {
+ throw new IOException("Invalid state.");
+ }
+ if (offset < 0 || size < 0) {
+ throw new IOException("Illegal source offset/size");
+ }
+ final long inEnd = (long) offset + size;
+ if (inEnd > inCapacity || size > outCapacity) {
+ throw new IOException("Out-of-bound: buffer too small.");
+ }
+ }
+
public void readFromByteBuffer(final ByteBuffer src, final int offset, final int size)
throws IOException {
if (!src.isDirect()) {
throw new IOException("SharedMemBuffer only support reading from direct byte buffer.");
}
+ checkBounds(offset, size, src.capacity(), capacity());
try {
nativeReadFromDirectBuffer(src, mSharedMem.getPointer(), offset, size);
mSharedMem.flush();
@@ -72,6 +88,7 @@ public final class SampleBuffer implements Parcelable {
if (!dest.isDirect()) {
throw new IOException("SharedMemBuffer only support writing to direct byte buffer.");
}
+ checkBounds(offset, size, capacity(), dest.capacity());
try {
nativeWriteToDirectBuffer(mSharedMem.getPointer(), dest, offset, size);
} catch (final NullPointerException e) {
@@ -83,16 +100,18 @@ public final class SampleBuffer implements Parcelable {
long src, ByteBuffer dest, int offset, int size);
@WrapForJNI(exceptionMode = "nsresult")
- public void nativeCopy(final long dest, final int offset, final int size) throws IOException {
- if (mSharedMem == null || !mSharedMem.isValid()) {
- throw new IOException("Invalid state.");
- }
- if (offset + size > mSharedMem.getSize()) {
- throw new IOException("Out-of-bound: buffer too small.");
+ public void nativeCopy(final long dest, final int destCapacity, final int offset, final int size)
+ throws IOException {
+ if (dest == 0) {
+ throw new IOException("Null destination pointer.");
}
+ checkBounds(offset, size, capacity(), destCapacity);
try {
- final long src = mSharedMem.getPointer() + offset;
- nativeMemcpy(dest, src, size);
+ final long src = mSharedMem.getPointer();
+ if (src == 0) {
+ throw new IOException("Shared memory not mapped.");
+ }
+ nativeMemcpy(dest, src + offset, size);
} catch (final NullPointerException e) {
throw new IOException(e);
}
Loading diff…
References
On This Page