# CVE-2023-6345: Integer overflow in Skia MeshOp::onCombineIfPossible

Integer overflow in Skia MeshOp::onCombineIfPossible lets a crafted .skp overflow fVertexCount, causing heap OOB write in the GPU renderer, exploited as a Chrome sandbox escape.

- Payout: Real-world hack
- Severity: high
- Program: Google Chrome
- Credited: Benoît Sevens and Clement Lecigne
- Disclosed: 2023-11-28
- CVE: CVE-2023-6345
- Write-up quality: 9/10
- Original: https://github.com/googleprojectzero/0days-in-the-wild/blob/main/0day-RCAs/2023/CVE-2023-6345.md
- Library page: https://bugbountylibrary.com/r/p0%3ACVE-2023-6345
- Tags: domain:browser impact:rce kind:incident platform:project-zero sev:high tech:chromium technique:chained technique:source-review vuln:dos vuln:memory-corruption

**Target:** Skia GPU MeshOp / DrawVertices picture playback
**Root cause:** MeshOp::onCombineIfPossible adds fVertexCount of combined ops without overflow check; the wrapped int sizes the vertex buffer allocation, but per-mesh writeVertices writes the true vertex counts, overflowing the buffer.
**Steps:**
1. Craft .skp with two vertices buffers: first fVertexCount=A, second B, and N DRAW_VERTICES_OBJECT ops referencing B.
2. Choose A,B,N so (A + N*B) % INT_MAX < A, making allocated size smaller than bytes written by first writeVertices.
3. Heap groom so the undersized vertex buffer lands adjacent to target object.
4. Play back picture in Chrome renderer via DrawSlugOp to trigger MeshOp::onCombineIfPossible and onPrepareDraws.
5. OOB write corrupts neighboring object; SkASSERT bounds check is compiled out in release builds.
**How found:** Analysis of an in-the-wild exploit sample; root cause traced to missing overflow check in MeshOp::onCombineIfPossible, with the same DrawSlugOp reachability technique as CVE-2023-2136.
**Exploitation:** Attacker supplies a malicious Skia picture rendered in the Chrome GPU process; two vertex buffers with tuned counts cause the combined fVertexCount to wrap, allocating an undersized vertex buffer. Heap grooming places a victim object after it, and writeVertices overflows into it, yielding a controlled heap OOB write used as a sandbox escape.
**Escalation:** Chained with a renderer exploit before and an LPE exploit after to escape the Chrome sandbox.
**Insight:** Audit onCombine* merge functions for unchecked integer accumulation of counts that later size allocations while writes use per-element counts; the mismatch between allocation-time and write-time counts is the exploitable primitive.
