In early 2022, Mozilla patched a critical vulnerability affecting Firefox browsers before version 98. Known as CVE-2022-26385, this bug had the potential to let hackers execute code or crash the browser on your computer. In this post, we’ll break down what the vulnerability is, show you how it could be exploited, and explain why it was a big deal—with examples and code snippets.

What Was CVE-2022-26385?

Firefox, like many web browsers, uses lots of threads (think of them like workers carrying out small jobs) for things like rendering pages, running scripts, or managing downloads. Each thread has a manager telling it what to do.

But in rare situations—such as when shutting down, or during a "race condition"—a worker thread might outlive its manager. The manager gets destroyed, but the thread keeps running. If that thread tries to access its former manager, it can cause a "use-after-free" bug, where the program uses memory that's already been given away. This can lead to crashes, or, with some effort, even let an attacker run their own code.

Where Did This Happen in Firefox?

The bug was in the shutdown code for Firefox's nsThreadManager component, which manages background threads. If one of these threads kept running after the manager had shut down and deleted itself, the thread might try to call back into the manager, leading to a use-after-free.

You can see the affected code (before the patch) in this commit on Mozilla’s GitHub:

void
nsThreadManager::Shutdown()
{
  // ... some code ...
  mMainThread = nullptr;
  mThreadByPRThread.Clear();
  mCurThreadInfo.Clear();
  // ... thread shutting down ...
}

If a thread was still active at this point and called back into nsThreadManager, it would access freed memory.

Step 1: Trigger a Long-Lived Thread

An attacker might use web content to trigger some JavaScript or WebAssembly code that creates heavy processing or networking threads.

Step 2: Interfere With Shutdown

Next, they'd try to race the browser's main thread shutdown—say, by closing a window or tab at just the right time—and keep their thread alive as long as possible.

Step 3: Cause Use-After-Free

Once the nsThreadManager is destroyed but before the thread is done, any calls from the still-active thread back to the manager would use invalid memory (freed memory). In best cases, this causes a crash (Denial of Service). In worse cases, carefully set-up memory can be hijacked and used to execute malicious code.

Here’s a *simplified* pseudocode example showing what the bug looked like

class ThreadManager {
public:
    void shutdown() {
        delete this; // Manager gone!
    }
    void use() {
        // Do something...
    }
};

void worker(ThreadManager* manager) {
    // ...some work...
    manager->use(); // If manager was deleted, this is use-after-free!
}

// Somewhere else:
ThreadManager* tm = new ThreadManager();
// Run worker in another thread...
tm->shutdown();

If the worker is still running after shutdown(), it will call use() on a pointer to deleted memory. An attacker can try to control *what* is now at the location where ThreadManager used to reside.

Read or write code in memory (far more dangerous)

- If the attacker arranges memory just right (spray), remotely execute code—this could let hackers install malware just by tricking you into visiting a web page.

How Was It Fixed?

Firefox 98 and later fixed this by making sure threads are properly stopped before the manager is destroyed, so a thread can't "outlive" its boss.

You can check the fix in the Mozilla bug tracker, Bugzilla #1758019, and read the official Mozilla security advisory.

There’s no public universal exploit, but the general approach is

1. Create web-worker or other threads via JavaScript

let worker = new Worker(URL.createObjectURL(new Blob([`
  setInterval(() => {
    // Do some expensive computation
  }, 1);
`])));

2. Trigger heavy shutdown by closing windows/tabs or reloading at a critical point.

3. Best case for attacker: use heap spraying to control newly allocated memory, potentially hijacking program flow.

Remember: Modern browsers include many extra memory protections, making exploitation harder. But crashes can still happen.

References

- Official CVE Description at NVD
- Mozilla Security Advisory 2022-09
- Bugzilla Report
- Mozilla gecko-dev commit

In Summary

CVE-2022-26385 was a subtle but dangerous bug. It shows that even the cleverest browser engineers have to watch out for rare timing issues—especially around memory and threads. As always, keeping your browser up to date is your best defense. Stay safe!

Timeline

Published on: 12/22/2022 20:15:00 UTC
Last modified on: 12/30/2022 15:05:00 UTC