How I Got --wait and --repeat Added to nvme-cli
By Yonas Abeselom — June 20, 2026
Two weeks ago I published a GitHub repository from Addis Ababa, Ethiopia. Today, the core idea behind it was merged into linux-nvme/nvme-cli master — the standard NVMe command-line tool that ships with virtually every Linux distribution.
This is the story of how that happened, and why it matters.
The problem I couldn't stop thinking about
When you sanitize an NVMe drive on Linux, the standard workflow looks like this:
nvme sanitize /dev/nvme0 --sanact=2
The command returns immediately. The drive acknowledges receipt. You move on.
But here is the thing: NVMe Sanitize (Opcode 0x84) is asynchronous. The drive accepts the command instantly and then performs the actual erasure in the background — sometimes for seconds, sometimes for minutes, depending on the drive's capacity and the sanitize action requested. The host has no idea whether the operation completed correctly, or at all, until it polls Log Page 0x81 (the Sanitize Status log page) and checks the SSTAT field.
The current nvme sanitize command does not do that polling. It fires the command and returns. Most operators never separately check completion.
I confirmed this on RFC #3415 with nvme-cli contributor ikegami-t, who verified: "The sanitize command does not poll the log page but just only submit the command and return the status if any error caused."
This is the fire-and-forget gap. And it has a real consequence: if drive firmware silently fails a sanitize operation — which Wei et al. documented happening in 3 of 12 drives they tested at USENIX FAST 2011 — the operator has no way to know. The command returned success. The log says success. The data is still there.
What Wei et al. actually found
The peer-reviewed foundation for this concern is a 2011 paper by Michael Wei, Laura Grupp, Frederick Spada, and Steven Swanson at UC San Diego: "Reliably Erasing Data from Flash-Based Solid State Drives," USENIX FAST 2011.
They tested 12 drives with built-in sanitize commands. Only 4 of 12 executed correctly. One drive reported the sanitize command completed successfully while all data remained completely intact. The drive lied.
Their conclusion was unambiguous: reliable SSD sanitization requires built-in, verifiable sanitize operations — not just operations that claim to verify themselves.
That paper is from 2011, on ATA/SCSI drives. NVMe has since replaced ATA as the dominant interface. But the firmware fault pattern Wei et al. documented is interface-agnostic — NVMe drive firmware can contain the same class of bugs. And until two weeks ago, the standard Linux NVMe tooling still had no mechanism for verifying that a sanitize operation actually completed.
What I built
I built AAD-50 (the Abeselom ASIC-Direct 50) — a 50-cycle NVMe sanitization framework that addresses the verification gap directly. The core architectural decision: after every single sanitize cycle, AAD-50 polls Log Page 0x81 and refuses to advance until SSTAT = 0x1 confirms hardware completion. If a cycle fails, the operation aborts immediately and writes a fault record to the audit log.
The full protocol runs a B → C → A phase matrix across 50 cycles: 40 cycles of physical NAND cell overwrite, 5 cycles of FTL translation map teardown, and 5 cycles of cryptographic media key destruction. It generates a SHA-256 tamper-evident audit chain and a PDF Certificate of Destruction for compliance purposes.
It is written entirely in Python — including the low-level IOCTL and NVMe passthrough work — and runs on both Linux and Windows. Everything is free and open source at github.com/yonasabeselom/aad50.
RFC #3415 — taking the idea to nvme-cli
On June 2, 2026 — the same day I published AAD-50 — I opened RFC #3415 on linux-nvme/nvme-cli proposing that the fire-and-forget gap be addressed natively in the tool.
The response was constructive and fast. ikegami-t confirmed the gap, verified the struct layout against kernel source, and within a week had opened PR #3438 implementing:
-
--wait— polls Log Page 0x81 after the sanitize command until SSTAT confirms hardware completion -
--repeat N— multi-cycle verified sanitization natively in nvme-cli - SANICAP pre-flight verification — checks drive capability before dispatching any cycle
The commit message for --repeat N was: "Make verified multi-cycle sanitization accessible without a separate tool."
Today, June 16, 2026 — 14 days after publication — Daniel Wagner (igaw), the primary nvme-cli maintainer, merged PR #3438 into linux-nvme/nvme-cli master (commit 84078fa, 30 of 31 checks passed).
What this means in practice
From the next nvme-cli release, Linux users will be able to run:
# Wait for sanitize completion — no more fire-and-forget
nvme sanitize /dev/nvme0 --sanact=2 --wait
# Multi-cycle verified sanitization
nvme sanitize /dev/nvme0 --sanact=2 --wait --repeat 10
The --wait flag is the critical one. It closes the gap Wei et al. identified in 2011: the difference between "the sanitize command was issued" and "the sanitize operation actually completed."
What AAD-50 still provides that nvme-cli does not
The nvme-cli merge validates the verification architecture. AAD-50 remains the complete compliance-grade implementation:
- The full B → C → A three-phase destruction matrix (overwrite, FTL teardown, crypto erase)
- Per-cycle hardware confirmation across all 50 cycles
- SHA-256 tamper-evident audit chain
- PDF Certificate of Destruction with operator name, drive serial number, and compliance alignment
- Windows GUI and standalone executable
- NIST SP 800-88 Rev.2 Purge alignment documentation
For anyone who needs to prove — not just assume — that a drive is forensically clean, AAD-50 provides the complete audit package. nvme-cli now provides the lightweight version of the same core idea.
A note on the peer engagement
I was not expecting the response this project received. In the two weeks since publication:
- Peter Gutmann (University of Auckland, author of the Gutmann 35-pass method) wrote two personal emails raising technical concerns about the specification — both of which improved it.
- Steven Swanson (UCSD, senior author of the Wei et al. 2011 paper) responded to a direct email with substantive feedback on the generalisability of his 2011 findings to modern NVMe drives.
- Keith Busch (primary nvme-cli maintainer) gave qualified personal approval for PR #3438.
- ikegami-t implemented the full verification stack in PR #3438.
- Daniel Wagner merged it into master.
- Guido van Rossum (creator of Python) looked at the implementation and called it "very cool."
- NVM Express initiated internal review of the specification.
I am an independent researcher working alone in Addis Ababa. The speed and seriousness of that engagement — from some of the most credentialed people in storage security and open source — was genuinely unexpected and genuinely gratifying.
What comes next
The USENIX submission is the next step — Gutmann suggested it, and the nvme-cli merge makes the case considerably stronger. Hardware testing across multiple NVMe drive manufacturers is the other priority — the specification's 40-cycle Phase B allocation is a conservative engineering default that needs empirical validation across drive models and NAND geometries.
If you have an NVMe drive you are retiring and want to contribute a hardware test report, the issue tracker is open: github.com/yonasabeselom/aad50/issues
Update — June 17, 2026
The day after the nvme-cli merge, I opened RFC #308 on hiyohiyo/CrystalDiskInfo — the most widely used Windows NVMe and disk health tool, with hundreds of millions of downloads — proposing the same Log Page 0x81 sanitize completion verification architecture for Windows.
This is the Windows equivalent of what RFC #3415 achieved on Linux. If accepted, the verification gap fix would reach mainstream Windows users through a tool already installed on an enormous number of machines worldwide.
RFC #308: github.com/hiyohiyo/CrystalDiskInfo/issues/308
Yonas Abeselom is an independent security researcher based in Addis Ababa, Ethiopia.
Contact: yonas_abeselom@protonmail.com
Repository: https://github.com/yonasabeselom/aad50
RFC #3415: https://github.com/linux-nvme/nvme-cli/issues/3415
PR #3438: https://github.com/linux-nvme/nvme-cli/pull/3438
Top comments (0)