← All issues

[7] GPU process dangling span in RemoteGraphicsContext::drawGlyphs

Severity: High | Component: GPU Process graphics layer — RemoteGraphicsContext | 6aacf62

Rated High because the observable effect is a dangling span read in the GPU process — which operates outside the WebContent sandbox — where glyph data from IPC message backing storage is passed to a rendering call without ownership transfer, and the asymmetry (one span copied, one not) confirms an oversight rather than a design choice.

Copy the glyph buffer in RemoteGraphicsContext::drawGlyphs to avoid a dangling span from IPC message backing storage.

Source/WebKit/GPUProcess/graphics/RemoteGraphicsContext.cpp

- context().drawGlyphs(*font, glyphsAdvances.span<0>(), Vector<GlyphBufferAdvance>(glyphsAdvances.span<1>()), localAnchor, fontSmoothingMode);
+ Vector<GlyphBufferGlyph, 128> glyphs { glyphsAdvances.span<0>() };
+ Vector<GlyphBufferAdvance, 128> advances { glyphsAdvances.span<1>() };
+ context().drawGlyphs(*font, glyphs.span(), advances.span(), localAnchor, fontSmoothingMode);

The fix copies both glyph and advance spans from the IPC-deserialized glyphsAdvances parameter into local Vector objects before passing them to context().drawGlyphs(). The inline capacity of 128 keeps small glyph buffers on the stack. Before the fix, span<0>() (the glyphs) was passed directly as a span reference while span<1>() (the advances) was already copied into a temporary Vector — an asymmetry that highlights the oversight.

Use of a non-owning span reference to IPC message data across a call boundary where the backing buffer's lifetime is not guaranteed.

WebKit's GPU process architecture offloads graphics operations (including text rendering) from the sandboxed WebContent process to a separate GPU process via IPC. RemoteGraphicsContext receives serialized drawing commands over IPC and replays them against a real GraphicsContext. Parameters like glyph buffers arrive as serialized data in IPC message buffers; spans obtained from the deserialized message point directly into this backing storage. GlyphBufferGlyph and GlyphBufferAdvance are the per-glyph data types used by WebCore's text rendering pipeline.

Before the fix, RemoteGraphicsContext::drawGlyphs passed glyphsAdvances.span<0>() directly to context().drawGlyphs() as a span reference. This span points into the IPC message's backing storage (if the IPC deserialization model produces non-owning views, as the fix pattern strongly implies). If the IPC buffer's lifetime does not extend through the entire execution of context().drawGlyphs() — for example, if the message buffer is freed or recycled during glyph rendering — the span becomes dangling, and the GPU process reads freed or stale memory. Only the glyphs span was vulnerable; the advances span was already copied.

🔒

Explores the IPC buffer lifetime model and whether the dangling span could be weaponized for controlled reads in the GPU process

Subscribe to read more

🔒

Multiple audit patterns identified for IPC span handling across the GPU process boundary, with concrete search targets

Subscribe to read more