MallocSpan crash in GPUQueue::copyExternalImageToTexture
In WebGPU's image upload, zero bytes per pixel meant no upper bound at all.
Component: WebGPU | 9197450
LayoutTests/fast/webgpu/copy-external-image-video-frame-odd-width.html
copyExternalImageToTexture() uploads pixels from an image, canvas or VideoFrame into a GPUTexture. Without a GPU-side fast path, WebKit reads pixels back on the CPU through CoreGraphics or vImage and swizzles channels, computing strides, channel counts and loop bounds from CGImage-reported properties that are not guaranteed to agree with the buffer the provider returns. The source can be a BitmapImage, SVGImage or PDFDocumentImage; the code assumed only the first two.
The fix hardens that readback path. An unhandled bits-per-component left clipTo8bitsPerChannel() with an empty span, so bytesPerPixel computed to 0 and maxChannelIndex = bpp - 1 underflowed to SIZE_MAX, letting the pixel loop read past the buffer. Now the clip returns false and the copy is rejected, bytesPerPixel derives from bits-per-pixel over bits-per-component, and loop bounds are checked against the provider's data length with CheckedSize. It also fixes a null deref on <img> holding a PDFDocumentImage, a bytesPerPixel miscalculation on padded rows, an alpha-info switch fall-through, and stride/length checks on the video frame path.
Significance
A web-reachable WebGPU API could be driven into an out-of-bounds read and a null deref by image properties the page influences. Metadata-derived sizes are replaced with bounds checked against the bytes actually returned.
Audit directions
- Metadata trusted over actual buffer length. Look for the same
CGImageGet*-over-provider-length pattern in sibling upload paths: canvas,ImageBitmap, and WebGLtexImageupload. - Uncovered pixel formats. Exercise 16-bit, float, indexed and CMYK bits-per-component combinations that reach the fast path or the channel-mapping lambda, and confirm the new bounds checks cover every read including origin offsets and copy extents.
- Video frame strides. Verify 32bpp and stride assumptions for every
VideoFramepixel format, including odd-width and CoreVideo-padded frames. - Unchecked
Imagedowncasts. Remaining code that readsPDFDocumentImageor other non-BitmapImagesubclasses through unchecked downcasts is the same null-deref shape.