Summary
CefLayeredWindowUpdaterOSR::OnAllocatedSharedMemory does not check the size of the shared memory, which leads to out-of-bounds read outside the sandbox.
Details
CefLayeredWindowUpdaterOSR::OnAllocatedSharedMemory stores the shared memory and the window size received from GPU Process when OSR is enabled. viz::ResourceSizes::MaybeSizeInBytes checks pixel_size does not cause an integer overflow and stores the expected buffer size in expected_bytes. However, it does not check whether the shared memory buffer is large enough and just maps it directly [2]. Finally, CefLayeredWindowUpdaterOSR::Draw will call view_->OnPaint to read from the shared memory [3].
A compromised GPU process can send a malicious region, whose size is smaller than the expected_bytes, finally leading to out-of-bounds read.
// libcef/browser/osr/host_display_client_osr.cc
void CefLayeredWindowUpdaterOSR::OnAllocatedSharedMemory(
const gfx::Size& pixel_size,
base::UnsafeSharedMemoryRegion region) {
// Make sure |pixel_size| is sane.
size_t expected_bytes;
bool size_result = viz::ResourceSizes::MaybeSizeInBytes(
pixel_size, viz::SinglePlaneFormat::kRGBA_8888, &expected_bytes); // [1]
if (!size_result) {
return;
}
pixel_size_ = pixel_size;
shared_memory_ = region.Map(); // [2]
DCHECK(shared_memory_.IsValid());
}
void CefLayeredWindowUpdaterOSR::Draw(const gfx::Rect& damage_rect,
DrawCallback draw_callback) {
if (active_) {
const void* memory = GetPixelMemory();
if (memory) {
view_->OnPaint(damage_rect, pixel_size_, memory); // [3]
} else {
LOG(WARNING) << "Failed to read pixels";
}
}
std::move(draw_callback).Run();
}
VERSION: latest (121.0.0-HEAD.2874+ge4acace+chromium-121.0.6167.0)
SUGGESTED FIX
Check if shared_memory_.size() is larger than expected_bytes.
Summary
CefLayeredWindowUpdaterOSR::OnAllocatedSharedMemorydoes not check the size of the shared memory, which leads to out-of-bounds read outside the sandbox.Details
CefLayeredWindowUpdaterOSR::OnAllocatedSharedMemorystores the shared memory and the window size received from GPU Process when OSR is enabled.viz::ResourceSizes::MaybeSizeInBytescheckspixel_sizedoes not cause an integer overflow and stores the expected buffer size inexpected_bytes. However, it does not check whether the shared memory buffer is large enough and just maps it directly [2]. Finally,CefLayeredWindowUpdaterOSR::Drawwill callview_->OnPaintto read from the shared memory [3].A compromised GPU process can send a malicious
region, whose size is smaller than theexpected_bytes, finally leading to out-of-bounds read.VERSION: latest (121.0.0-HEAD.2874+ge4acace+chromium-121.0.6167.0)
SUGGESTED FIX
Check if
shared_memory_.size()is larger thanexpected_bytes.