# CVE-2026-98398: locking/lockdep: Invalidate stale class_cache entries for zapped classes

> A use-after-free vulnerability in the Linux kernel lockdep subsystem allows attackers to trigger a kernel warning or potential crash via network traffic.

- **Severity:** Not scored
- **Exploited in the wild:** Not known
- **Login needed:** Not needed
- **Attackable:** Over the internet
- **Victim action needed:** Not needed
- **Fix available:** Yes
- **Published:** 14 Oct 2026
- **Updated:** 19 Oct 2026
- **Also known as:** AZL-108176, BELL-CVE-2026-98398, DEBIAN-CVE-2026-98398, GHSA-qfc6-3g3r-6rjj, UBUNTU-CVE-2026-98398

## What is CVE-2026-98398?

CVE-2026-98398 is an use after free vulnerability in Linux, published on 14 Oct 2026. An attacker can exploit it over the internet without logging in, with no action from the victim.

### Official description

In the Linux kernel, the following vulnerability has been resolved:

locking/lockdep: Invalidate stale class_cache entries for zapped classes

syzbot reported a lockdep splat hitting DEBUG_LOCKS_WARN_ON(1) in
hlock_class() due to an invalid class_idx:

  WARNING: kernel/locking/lockdep.c:238 at __lock_acquire+0x382/0x2cf0 kernel/locking/lockdep.c:5203
  Workqueue: wg-crypt-wg0 wg_packet_tx_worker
  RIP: 0010:hlock_class kernel/locking/lockdep.c:238 [inline]
  RIP: 0010:check_wait_context kernel/locking/lockdep.c:4870 [inline]
  RIP: 0010:__lock_acquire+0x389/0x2cf0 kernel/locking/lockdep.c:5203
  Call Trace:
   <IRQ>
   lock_acquire+0x106/0x350 kernel/locking/lockdep.c:5886
   _raw_spin_lock+0x2e/0x40 kernel/locking/spinlock.c:173
   tcp_tsq_handler+0x29/0x200 net/ipv4/tcp_output.c:1291
   tcp_tsq_workfn+0x384/0x410 net/ipv4/tcp_output.c:1325
   ...

When a lock class is zapped (e.g. during module unload or key
unregistration), zap_class() clears the class's bit in
lock_classes_in_use and removes it from the class hash table.
However, existing lockdep_map instances embedded in data structures
may still retain a pointer to the zapped class in their class_cache[]
array.

When __lock_acquire() subsequently runs on such a lock, it finds
lock->class_cache[subclass] != NULL, skipping register_lock_class()
and assigning hlock->class_idx to the index of the zapped class. When
check_wait_context() or hlock_class() inspects the held_lock, it finds
!test_bit(class_idx, lock_classes_in_use) and warns. Furthermore, if
the zapped slot is subsequently re-allocated to an unrelated lock key,
the stale class_cache entry would erroneously match the unrelated
class (ABA issue).

Add lock_class_cache_is_valid() to validate that the cached class is
within lock_classes bounds, still allocated in lock_classes_in_use
(using uninstrumented arch_test_bit() in __always_inline context so it
is safe in noinstr contexts like match_held_lock()), and that
class->key matches the expected subkey (taking lockdep_set_subclass()
overrides into account). Also use READ_ONCE()/WRITE_ONCE() when
accessing class_cache[].  If the entry is invalid or stale, fall back
to register_lock_class() / look_up_lock_class().

## Which versions are affected by CVE-2026-98398?


## How do I fix CVE-2026-98398?

Apply the vendor's patch.

## Is CVE-2026-98398 being exploited?

There is no known exploitation of CVE-2026-98398 in the wild and no public exploit code.

## Fix prompt for AI coding agents

```text
Check this codebase for CVE-2026-98398 and fix it if it is affected.

What it is: CVE-2026-98398 is an use after free vulnerability in Linux, published on 14 Oct 2026. An attacker can exploit it over the internet without logging in, with no action from the victim.
Exploitation: There is no known exploitation of CVE-2026-98398 in the wild and no public exploit code.

Affected product: Linux. No package-level version data is available, so check the vendor advisory linked from the reference page.

Task:
1. Search the dependency manifests and lockfiles (for example package.json, package-lock.json, requirements.txt, poetry.lock, uv.lock, pom.xml, build.gradle, go.mod, Cargo.lock, Gemfile.lock) and any Dockerfiles for the affected packages, including transitive dependencies.
2. If an affected version is in use, upgrade it to the fixed version for its release line with the project's package manager, so the lockfile is regenerated. Prefer the smallest upgrade that fixes it.
3. If there is no fix, or the upgrade would break the build, do not guess: explain the risk and the safest workaround instead.
4. Run the tests and summarise what changed and why.
5. If nothing in the project is affected, say so and change nothing.

Reference: https://insights.sbomify.com/CVE-2026-98398/ (Markdown: https://insights.sbomify.com/CVE-2026-98398/index.md)
```

## Sources

- CVE record: https://www.cve.org/CVERecord?id=CVE-2026-98398
- NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-98398
- OSV: https://osv.dev/vulnerability/CVE-2026-98398

---
From sbomify Insights: https://insights.sbomify.com/CVE-2026-98398/
Summaries are generated and may contain mistakes; the official description above is the record.
