Skip to contentSkip to conversation

TID v2.0: kernel module for cache-line zeroization against Flush+Reload (CLFLUSHOPT + LFENCE + REP STOSQ)

RFC Ahmed Hassan 2 participants 6 messages May 18 – Jun 28

Subsystems (5)
lore
Share & tools
lore
#0 lore raw

Hi kernel developers,

I am sharing TID (The Instant Destroyer) v2.0, a Linux kernel module written in C that addresses a specific gap in existing security
libraries: none of them (libsodium, OpenSSL, glibc memzero_explicit) flush CPU cache lines after memory zeroization.

== Problem ==

Standard zeroization functions (explicit_bzero, sodium_memzero, OPENSSL_cleanse) prevent the compiler from eliding the wipe, but do not evict CPU cache lines (L1/L2/L3). This leaves residual key material measurable via Flush+Reload (Yarom & Falkner, 2014) after data use ends.

== Approach: PROTECT+ZERO Protocol ==

TID combines three instructions in a single kernel module:

Phase 1 - PROTECT (before data use):
LFENCE <- close speculative execution window
MFENCE <- ensure all prior writes are complete

Phase 2 - ZERO (after data use):
LFENCE <- close speculation window
REP STOSQ <- compiler-resistant wipe
CLFLUSHOPT <- evict all cache lines (L1/L2/L3)
MFENCE <- ensure eviction is complete
LFENCE <- close the far-side window

This follows directly the Intel Spectre Mitigation Guide (2018) and AMD Speculative Execution Software Techniques (2018).

== Benchmark Results (AMD EPYC 9B14, Linux 6.14.11) ==

Without TID : attacker measures ~78 cycles (Cache HIT) With TID v2 : attacker measures ~286 cycles (Cache MISS)
Ratio : 3.7x latency increase -- attack defeated

Physical lower bound confirmed:
LFENCE (~40ns) + REP STOSQ (~50ns) + CLFLUSHOPT (~150ns)
+ MFENCE (~40ns) + LFENCE (~40ns) = ~320ns (measured: 290-372ns)

== What Distinguishes TID ==

No major security library implements CLFLUSHOPT post-wipe eviction. TID is the only known kernel-module-level implementation of the PROTECT+ZERO protocol.

== Known Limitations ==

- A 372ns window during data use remains (physical lower bound); v3.0 target via Intel CAT integration
- Requires same-machine attacker model (shared memory)
- Does not protect against cold-boot attacks
- Not a replacement for disk encryption

== Project Details ==

License : AGPL-3.0
Hardware : AMD EPYC 9B14 (Zen 4), x86_64
Kernel : Linux 6.14.11
DOI : https://doi.org/10.5281/zenodo.17585929
GitHub : https://github.com/ahmaaaaadbntaaaaa-byte/The-Instant-Destroyer

Comments and technical criticism are welcome.

Regards,
Ahmad Qasim Mohammad Hassan
Independent Hardware Security Researcher
ORCID: 0009-0001-4360-0802
Ahmed Hassan

#1 lore raw
Quoted 9 lines · Ahmed Hassan

Hi kernel developers,

I am sharing TID (The Instant Destroyer) v2.0, a Linux kernel module written in C that addresses a specific gap in existing security
libraries: none of them (libsodium, OpenSSL, glibc memzero_explicit) flush CPU cache lines after memory zeroization.

Quoted 7 lines

== Problem ==

Standard zeroization functions (explicit_bzero, sodium_memzero, OPENSSL_cleanse) prevent the compiler from eliding the wipe, but do not evict CPU cache lines (L1/L2/L3). This leaves residual key material measurable via Flush+Reload (Yarom & Falkner, 2014) after data use ends.

The thing you're talking about isn't really related to the Flush+Reload side channel attack, right? You're just talking about flushing cache lines.

In what threat model would this be an issue? Normally, the goal of memory zeroing is to ensure that sensitive data is wiped before an attacker has a chance to physically pull out the RAM from a machine and plug it into another device that can reveal RAM contents, or before an attacker gains physical control of a locked device and can connect malicious peripherals to it, or such.

So for this to be an actual security problem, the device would have to keep running in a sufficiently high power state that data caches are not discarded, and at the same time not perform enough memory accesses to cause this memory to be discarded...

Assuming that this is an actual problem, why are you using a kernel module for this? At least on x86, CLFLUSH is unprivileged, so crypto libraries should be able to just use that directly. (There is the caveat of what happens when the kernel migrates pages or kills a process, but that's a larger problem.)

#2 lore raw

Thank you for your questions. I'll address each one:

== 1. Threat Model ==

The target scenario is a same-machine attacker in multi-tenant/cloud environments where two processes share physical L3 cache.

Example: a cryptographic service and a malicious process running on the same host. The attacker uses Flush+Reload to measure cache access timing after every encryption operation — no physical access required.

This is documented with real measurements:
- Without TID: 78 cycles (Cache HIT — key pattern visible)
- With TID v2.0: 286 cycles (Cache MISS — attack defeated)

The 78-cycle result proves the data remains in cache after memzero. If cache eviction happened automatically, we would always see 286 cycles.

Full threat model: Section 2.1 of the paper. Timing analysis: Section 5.2.

== 2. Why Kernel Module and not userspace? ==

You are correct that CLFLUSHOPT does not require Ring 0. However, userspace execution can be interrupted by a Context Switch, which expands the timing window from 372ns to 36,640ns — making the attack significantly easier.

The Kernel Module guarantees:
- Non-preemption during the PROTECT+ZERO sequence
- Atomic execution across wipe + flush + barrier
- Reliable page locking via pin_user_pages_fast

This is documented in Section 5.2 and Section 5.4.

A userspace library implementation is a valid alternative and is noted as future work — the goal is eventually integrating CLFLUSHOPT directly into libsodium and OpenSSL.

== 3. Why not add this directly to libraries? ==

No major security library implements CLFLUSHOPT after wiping — not OpenSSL, not libsodium, not glibc, not memzero_explicit. This gap has existed since Flush+Reload was published in 2014.

TID is a proof of concept that demonstrates the PROTECT+ZERO protocol works. The next step is proposing integration into existing libraries.

Full comparison table: Section 2.3 of the paper.

== References ==

DOI: https://doi.org/10.5281/zenodo.17585929
GitHub: https://github.com/ahmaaaaadbntaaaaa-byte/
TID-The-Instant-Destroyer

Sections 2.1, 2.3, 5.2, 5.4 address your points in detail.

Regards,
Ahmad Qasim Mohammad Hassan
Independent Hardware Security Researcher
ORCID: 0009-0001-4360-0802

في الثلاثاء، ١٩ مايو ٢٠٢٦, ٧:٤٧ م Jann Horn <[email protected]> كتب:

Quoted 41 lines
Quoted 9 lines · Ahmed Hassan

Hi kernel developers,

I am sharing TID (The Instant Destroyer) v2.0, a Linux kernel module written in C that addresses a specific gap in existing security
libraries: none of them (libsodium, OpenSSL, glibc memzero_explicit) flush CPU cache lines after memory zeroization.

Quoted 7 lines

== Problem ==

Standard zeroization functions (explicit_bzero, sodium_memzero, OPENSSL_cleanse) prevent the compiler from eliding the wipe, but do not evict CPU cache lines (L1/L2/L3). This leaves residual key material measurable via Flush+Reload (Yarom & Falkner, 2014) after data use ends.

The thing you're talking about isn't really related to the Flush+Reload side channel attack, right? You're just talking about flushing cache lines.

In what threat model would this be an issue? Normally, the goal of memory zeroing is to ensure that sensitive data is wiped before an attacker has a chance to physically pull out the RAM from a machine and plug it into another device that can reveal RAM contents, or before an attacker gains physical control of a locked device and can connect malicious peripherals to it, or such.

So for this to be an actual security problem, the device would have to keep running in a sufficiently high power state that data caches are not discarded, and at the same time not perform enough memory accesses to cause this memory to be discarded...

Assuming that this is an actual problem, why are you using a kernel module for this? At least on x86, CLFLUSH is unprivileged, so crypto libraries should be able to just use that directly. (There is the caveat of what happens when the kernel migrates pages or kills a process, but that's a larger problem.)

#3 lore raw
Quoted 14 lines · Ahmad Hasan

Thank you for your questions. I'll address each one:

== 1. Threat Model ==

The target scenario is a same-machine attacker in multi-tenant/cloud environments where two processes share physical L3 cache.

Example: a cryptographic service and a malicious process running on the same host. The attacker uses Flush+Reload to measure cache access timing after every encryption operation — no physical access required.

Quoted 3 lines

This is documented with real measurements:
- Without TID: 78 cycles (Cache HIT — key pattern visible)
- With TID v2.0: 286 cycles (Cache MISS — attack defeated)

So you're assuming that the cryptographic code leaks secrets through a cache-based side channel? That would be a vulnerability in the crypto code.

Quoted 7 lines

== 2. Why Kernel Module and not userspace? ==

You are correct that CLFLUSHOPT does not require Ring 0. However, userspace execution can be interrupted by a Context Switch, which expands the timing window from 372ns to 36,640ns — making the attack significantly easier.

Why does it matter how many hundreds of nanoseconds it takes to wipe the data from memory? You can also have a context switch directly before you enter your cache-wiping syscall, or in the middle of a crypto operation.

Quoted 6 lines

== 3. Why not add this directly to libraries? ==

No major security library implements CLFLUSHOPT after wiping — not OpenSSL, not libsodium, not glibc, not memzero_explicit. This gap has existed since Flush+Reload was published in 2014.

I don't think that's a gap, because the standard approach to mitigating cache-based side channels such as FLUSH+RELOAD is to not access memory at secret-dependent indices in the first place.

#4 lore raw

Thank you for your response.

I want to clarify one point:

TID does not address what happens during key usage. TID addresses what happens after:

After any sensitive data (keys, passwords, tokens) is used and memory is wiped — the residual data still exists in CPU cache (L1/L2/L3). This is what TID eliminates.

This is a different problem from what you are describing.

The full threat model, attack simulation, and benchmark results are documented in the research paper and repository:

DOI: https://doi.org/10.5281/zenodo.17585929
GitHub: https://github.com/ahmaaaaadbntaaaaa-byte/TID-The-Instant-Destroyer

I welcome continuing this discussion after reviewing the research.

Regards,
Ahmad Qasim Mohammad Hassan
ORCID: 0009-0001-4360-0802

في الأربعاء، ٢٠ مايو ٢٠٢٦, ١٢:٤٢ ص Jann Horn <[email protected]> كتب:

Quoted 48 lines
Quoted 14 lines · Ahmad Hasan

Thank you for your questions. I'll address each one:

== 1. Threat Model ==

The target scenario is a same-machine attacker in multi-tenant/cloud environments where two processes share physical L3 cache.

Example: a cryptographic service and a malicious process running on the same host. The attacker uses Flush+Reload to measure cache access timing after every encryption operation — no physical access required.

Quoted 3 lines

This is documented with real measurements:
- Without TID: 78 cycles (Cache HIT — key pattern visible)
- With TID v2.0: 286 cycles (Cache MISS — attack defeated)

So you're assuming that the cryptographic code leaks secrets through a cache-based side channel? That would be a vulnerability in the crypto code.

Quoted 7 lines

== 2. Why Kernel Module and not userspace? ==

You are correct that CLFLUSHOPT does not require Ring 0. However, userspace execution can be interrupted by a Context Switch, which expands the timing window from 372ns to 36,640ns — making the attack significantly easier.

Why does it matter how many hundreds of nanoseconds it takes to wipe the data from memory? You can also have a context switch directly before you enter your cache-wiping syscall, or in the middle of a crypto operation.

Quoted 6 lines

== 3. Why not add this directly to libraries? ==

No major security library implements CLFLUSHOPT after wiping — not OpenSSL, not libsodium, not glibc, not memzero_explicit. This gap has existed since Flush+Reload was published in 2014.

I don't think that's a gap, because the standard approach to mitigating cache-based side channels such as FLUSH+RELOAD is to not access memory at secret-dependent indices in the first place.

#5 lore raw

A relevant point Scientific excellence in AI research needs a parallel technical track translating the EU AI Act's technical provisions into verifiable requirements, grounded in peer-reviewed science rather than general policy language
Article 5 — the absolute red line: eight prohibited practices, no exceptions Articles 9–15 — mandatory requirements for high-risk systems: risk management, data governance, documentation, record-keeping, transparency, human oversight, accuracy
Article 50 — transparency toward the user: AI interaction notice, watermarking
Article 53 — obligations of GPAI providers: documentation, copyright, downstream information
Article 55 — GPAI with systemic risks: evaluation, adversarial testing, incident reporting
Without that translation governance stays conceptual and never reaches an implementable form
Available at https://lnkd.in/dKx7cW5R
Those who agree with me that solutions will remain mere marketing until 2030 if they aren't implemented according to the law won't establish standards because there are variables in artificial intelligence systems. Some talk about emotions some about the role of the CEO some about infrastructure, and some about governance. You'll remain stuck in a marketing cycle for years

في الأربعاء، ٢٠ مايو ٢٠٢٦, ٢:٠٠ ص Ahmad Hasan <[email protected]> كتب:

Quoted 81 lines

Thank you for your response.

I want to clarify one point:

TID does not address what happens during key usage. TID addresses what happens after:

After any sensitive data (keys, passwords, tokens) is used and memory is wiped — the residual data still exists in CPU cache (L1/L2/L3). This is what TID eliminates.

This is a different problem from what you are describing.

The full threat model, attack simulation, and benchmark results are documented in the research paper and repository:

DOI: https://doi.org/10.5281/zenodo.17585929
GitHub:
https://github.com/ahmaaaaadbntaaaaa-byte/TID-The-Instant-Destroyer

I welcome continuing this discussion after reviewing the research.

Regards,
Ahmad Qasim Mohammad Hassan
ORCID: 0009-0001-4360-0802

في الأربعاء، ٢٠ مايو ٢٠٢٦, ١٢:٤٢ ص Jann Horn <[email protected]> كتب:

Quoted 48 lines
Quoted 14 lines · Ahmad Hasan

Thank you for your questions. I'll address each one:

== 1. Threat Model ==

The target scenario is a same-machine attacker in multi-tenant/cloud environments where two processes share physical L3 cache.

Example: a cryptographic service and a malicious process running on the same host. The attacker uses Flush+Reload to measure cache access timing after every encryption operation — no physical access required.

Quoted 3 lines

This is documented with real measurements:
- Without TID: 78 cycles (Cache HIT — key pattern visible)
- With TID v2.0: 286 cycles (Cache MISS — attack defeated)

So you're assuming that the cryptographic code leaks secrets through a cache-based side channel? That would be a vulnerability in the crypto code.

Quoted 7 lines

== 2. Why Kernel Module and not userspace? ==

You are correct that CLFLUSHOPT does not require Ring 0. However, userspace execution can be interrupted by a Context Switch, which expands the timing window from 372ns to 36,640ns — making the attack significantly easier.

Why does it matter how many hundreds of nanoseconds it takes to wipe the data from memory? You can also have a context switch directly before you enter your cache-wiping syscall, or in the middle of a crypto operation.

Quoted 6 lines

== 3. Why not add this directly to libraries? ==

No major security library implements CLFLUSHOPT after wiping — not OpenSSL, not libsodium, not glibc, not memzero_explicit. This gap has existed since Flush+Reload was published in 2014.

I don't think that's a gap, because the standard approach to mitigating cache-based side channels such as FLUSH+RELOAD is to not access memory at secret-dependent indices in the first place.