In February 2023, Google patched a serious vulnerability—CVE-2023-0928—in Chrome's SwiftShader component. This bug allowed remote attackers to take control of Chrome users' machines by exploiting a use-after-free issue via a crafted HTML page. In this post, we’ll break down what happened, the technical details (with code snippet!), and how attackers could abuse this vulnerability. We’ll keep the language simple and the details exclusive to help you fully grasp this high-severity Chromium flaw.
What Is SwiftShader?
SwiftShader is part of Chromium’s graphics pipeline—it’s an open-source software renderer that emulates GPU functionality in software. Chrome falls back to SwiftShader when no compatible hardware acceleration is available or in sandboxed contexts.
If there’s a bug in SwiftShader, it exposes a critical attack surface, because almost any webpage could trigger code running in this context.
What is a Use-After-Free?
Use-after-free (UAF) is a classic memory safety bug. It happens when code continues to use a pointer to a chunk of memory after it’s been freed. This allows attackers to manipulate what happens next: either by crashing the process or—if they’re really savvy—by crafting memory layouts and data that trick the app into executing arbitrary code.
In high-performance C++ code like Chrome’s rendering pipeline, UAF bugs can appear under subtle memory management errors.
Where Was the Bug?
The actual bug was in SwiftShader. A mismanaged resource in the graphics rendering code could, under certain circumstances, allow memory to be prematurely reclaimed, but still used afterward. The crafted HTML page needed to trick the rendering pipeline into releasing an object while it was still referenced elsewhere.
Official advisory:
- Chromium Security Advisory for CVE-2023-0928
- Full issue on Chromium Bug Tracker (restricted)
Let’s imagine a simplified C++ scenario similar to what the SwiftShader bug looked like
class Texture {
public:
Texture() {/*...*/}
~Texture() {/*...cleanup...*/}
void draw() {/*...*/}
};
void renderFrame(bool condition) {
Texture* tex = new Texture();
if (condition) {
delete tex; // tex is freed here!
}
tex->draw(); // Use-after-free if 'condition' is true!
}
If condition is true, the texture is deleted, but then draw() is called on the invalid pointer. Attackers can make 'condition' true at precisely the time they control, freeing tex but having a dangling pointer, then manipulating the memory heap to fill the freed slot with their own fake data.
In SwiftShader, the complexity is much higher, but the bug boils down to this same pattern: an object in the rendering pipeline was prematurely freed, but later operations still referenced it.
To exploit CVE-2023-0928, an attacker would
1. Craft a Malicious HTML Page: The attacker sets up a website that triggers specific rendering behaviors in Chrome, causing the buggy SwiftShader path to execute.
2. Heap Spraying and Memory Manipulation: By cleverly creating and freeing DOM elements, the attacker can control what replaces the freed memory.
3. Take Over Execution: If they’re able to overwrite pointers or objects referenced after free, they can potentially run arbitrary code with the privileges of the logged-in user.
In practical terms, an attacker could use this bug to run malware on your computer just by tricking you into opening their malicious site in Chrome.
Suppose the attacker constructs a webpage like this (simplified for illustration)
<script>
function triggerUseAfterFree() {
for (let i = ; i < 10000; i++) {
// Create graphics objects, e.g. canvas or WebGL
let canvas = document.createElement('canvas');
document.body.appendChild(canvas);
// Trigger fast resource allocation/free pattern
document.body.removeChild(canvas);
}
// Spray the heap with malicious objects
let arr = [];
for (let i = ; i < 10000; i++) {
let fakeObj = new ArrayBuffer(256); // Or a carefully crafted JS object
arr.push(fakeObj);
}
// Now, attempt to access the freed object via a subsequent draw/operation
}
window.onload = triggerUseAfterFree;
</script>
This code tries to rapidly allocate/free canvas elements to stimulate the SwiftShader bug, then sprays the heap to fill the memory with attacker-controlled data, hoping the renderer will use-after-free into the attacker’s fake object.
How Was It Fixed?
Google patched this bug by making sure once the resource is freed, any references elsewhere in the code are either cleared or correctly tracked, and no further use is possible after release.
Chrome version 110..5481.177 and later are immune. Update your browser!
Links
- Chromium Release Notes
- CVE Details for CVE-2023-0928
- SwiftShader Project
Takeaway: Keep Chrome Updated!
CVE-2023-0928 shows how high-stakes browser vulnerabilities can be. A simple click could let attackers execute code on your device. Always keep Chrome up to date, and avoid clicking suspicious links or attachments even if you think you’re fully patched.
Timeline
Published on: 02/22/2023 20:15:00 UTC
Last modified on: 02/28/2023 02:22:00 UTC