Sven Erik Matzen

Software Architect | Cloud & Security Expert | AI-enabled Solutions

The Bug That Stops Being Created: Memory Safety and the Mathematics of Vulnerability Half-Life

🎧 Listen to this article

IT Security · 2026-11-04

EU label: fully AI-generated content Fully AI-generated article (no prior review).

The Hook: Measured Three Times Independently, Three Times the Same Number

There are not many numbers in software security that you can measure several times independently and get roughly the same answer. This is one of them.

Microsoft has triaged every reported security vulnerability in its own products since 2004. The result, published on the MSRC blog in 2019: around 70 percent of the vulnerabilities Microsoft assigns a CVE to each year are memory safety issues.

The Chromium project counts separately, in an entirely different codebase, with its own reporting process. The result: around 70 percent of its serious security bugs are memory safety problems. The basis is stated explicitly — 912 bugs rated "high" or "critical" since 2015, affecting the Stable channel. Half of them are use-after-free bugs.

Google's Project Zero counts something else again: not reported vulnerabilities, but ones demonstrably used in active attacks. For 2021, Maddie Stone documented 58 in-the-wild zero-days. Of those, 39 — 67 percent — were memory corruption vulnerabilities.

Three organizations, three counting methods, three time periods, three data sources. Roughly two-thirds to 70 percent. The December 2023 joint guide from CISA, the NSA, the FBI and the cyber authorities of Australia, Canada, the United Kingdom and New Zealand puts it this way in its conclusion: today, two-thirds of reported vulnerabilities in memory unsafe programming languages still relate to memory issues.

What makes this article worth your time is not that number. It has been known for years and gets quoted in every other conference talk. The interesting question is the one underneath it, and since roughly 2024 it has an empirically testable answer: if 70 percent of bugs come from a class that a language choice can rule out, why did the decline you would expect fail to arrive for three decades — and what changed so that it is arriving now?

The answer takes the form of an arithmetic argument, not a technology. And it is counterintuitive enough that in practice it regularly gets translated into the wrong course of action — namely "we have to rewrite everything," which is the precise opposite of what the data implies.


Part 1: What "Memory Safety" Technically Means

The Bug Class

Memory safety is not a feeling or a quality grade but a sharply bounded property: a program is memory safe if it cannot access memory it is not allowed to access. That can be violated along two axes.

Spatial: the access falls outside the bounds of the object that was meant. Buffer overflow when writing, out-of-bounds read when reading. The classic case: an array of length 16, an index of 17, and something else sitting behind it in memory.

Temporal: the access falls outside the object's lifetime. Use-after-free — a pointer is used after the memory has been released. Double free. A dangling pointer to a stack variable whose function returned long ago.

Add the side effects that are formally their own classes but land in the same bucket in practice: integer overflows that then corrupt a length calculation, uninitialized memory whose contents leak outward, and data races between threads where two writes overlap.

The severity of this class is the real point. A memory bug is rarely "just a crash." It is a primitive: a capability an attacker assembles into something larger. A controlled write to an address of the attacker's choosing leads, over several intermediate steps, to control of the control flow and thus to code execution. That is why the distribution across severity levels is not uniform. Google's Android team quantified this for 2022: memory safety bugs accounted for 35 percent of all Android vulnerabilities that year (the post gives 36 percent in one place) — but 86 percent of the vulnerabilities rated "critical," the highest rating, and 89 percent of the remotely exploitable ones. Over the preceding years, 78 percent of confirmed, actually exploited in-the-wild Android vulnerabilities fell into this class.

That is the asymmetry everything else rests on: a bug class that makes up a third of the reports supplies nearly nine-tenths of the dangerous cases.

Why C and C++ Allow Them

Not out of carelessness, but by construction. Both languages hand the programmer pointer arithmetic and in exchange forgo runtime checks that would cost cycles. A pointer in C is a number; the language does not know how large the object behind it is or whether it still exists. That knowledge lives only in the developer's head and in the documentation. Where it is wrong there, the compiler stays silent.

The CISA guide names C and C++ explicitly as examples of memory unsafe languages and notes in the same sentence that they remain among the most widely used languages today. That is the entire dilemma in one line: the bug class sits where the infrastructure is.

What Memory Safe Languages Guarantee — and How

The appendix of the CISA guide lists C#, Go, Java, Python, Rust and Swift. The mechanisms differ fundamentally, and the difference matters more in practice than the list does.

Runtime checking plus garbage collection (C#, Java, Go, Python): every array access is checked against the length, and object lifetime is managed by the runtime rather than the developer. Use-after-free is structurally impossible, because nothing is freed while a reference exists. The price is runtime and — more importantly — predictability. The CISA guide puts it precisely: garbage collection can introduce unpredictable latency that affects the application's overall performance characteristics; on modern hardware the effect is negligible, but not on constrained devices such as embedded systems.

Compile-time checking (Rust): a type system built on ownership plus a "borrow checker" ensures that at any point there is either one writing or arbitrarily many reading accesses to an object, and that no access outlives the object. That costs no runtime, but it costs compile time and a change of habits. The CISA guide describes the borrow checker as not perfect, but as a mechanism that goes a long way toward addressing memory safety issues at compile time.

To calibrate the Rust promise, it is worth looking at what has actually been proven — and what has not. In 2018 at POPL, Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers and Derek Dreyer presented the first formal, machine-checked safety proof in RustBelt: Securing the Foundations of the Rust Programming Language. The abstract's wording is careful: it is a proof for a language representing a realistic subset of Rust — not for Rust as a whole. The second half matters just as much: Rust extends its core type system through libraries that internally use unsafe features; the proof is constructed so that for each such library a verification condition can be stated whose satisfaction makes it a safe extension. The authors carried this out for some of the most important libraries in the ecosystem — not for all of them.

So the correct statement is not "Rust is proven safe" but: for a realistic formal subset of Rust there exists a machine-checked safety proof, and for libraries implemented with unsafe features there exists a criterion that has to be discharged individually. That is considerably more than any other systems language can show, and considerably less than a blanket guarantee.


Part 2: The Numbers — and What They Actually Count

The three 70 percent figures from the hook tend to get treated as one number. They are not. They measure different populations, and conflating them makes it easy to draw the wrong conclusions.

Source Population Period Value
Microsoft MSRC (2019) vulnerabilities assigned a CVE not stated in the post; CISA attributes the figure to 2006–2018 CVEs ~70 %
Chromium Security 912 "high"/"critical" bugs, Stable channel since 2015 ~70 %
Mozilla (via CISA, citing Hosfelt 2019) 34 "critical"/"high" bugs not stated 32 of 34
Project Zero (Stone 2022) 58 in-the-wild zero-days 2021 67 %
CISA conclusion (2023) reported vulnerabilities in memory unsafe languages as of 2023 ~two-thirds

Three things stand out.

First: the convergence is remarkable, but it is a convergence of independent estimates, not the measurement of a natural constant. Nobody has measured "70 percent of the world's software." What has been measured are large C/C++ codebases with professional security processes.

Second: the Project Zero figure is the most interesting and the least certain. It counts not reports but actual attacks — that is, the thing that matters. Stone names the limit herself, unambiguously: attackers who actively use zero-day exploits do not share which ones they use or what share is being missed, so we will never know exactly what proportion of zero-days is currently found and publicly disclosed. The sample is also small (58) and depends on vendors' reporting and annotation practices.

Third, and most important in practice: the number is a share, not a level. A share can fall because memory bugs become fewer — or because the other bugs become more numerous. Anyone basing a security strategy on a share has to look at both quantities side by side. That is exactly what makes Android's data series so unusually valuable: both are available there.


Part 3: Three Decades of Mitigation — and the Plateau

From 1995 to around 2019, the industry's answer to memory bugs was not the language but hardening. Stack canaries that detect an overwrite attempt. Non-executable memory (NX/DEP) so injected data cannot become code. Address space layout randomization (ASLR) so the attacker does not know where to aim. Control flow integrity. Hardened allocators such as Scudo. Sandboxing, process separation, privilege reduction.

These measures work. They raise the cost per exploitation considerably, and the CISA guide states explicitly that they remain valuable — especially in combination — to protect code that has not yet been, or cannot be, transitioned to memory safe languages.

What they do not do is reduce the number of bugs. They reduce the success rate per bug. And because codebases grew over the same period, the share of memory bugs stayed where it was — on the plateau of around 70 percent, for two decades, across the industry. The 2019 MSRC post puts it bluntly for Microsoft: as the codebase grows and more open-source software is used, the problem is not getting better, it is getting worse.

That is the state of play the story picks up in 2019: a known bug class, a known countermeasure, thirty years of work — and a flat line.

As an aside, the same hardening logic hits its limit wherever the source of the fault sits below the software. Speculative execution and physical disturbance effects in DRAM obey no bounds check; for the details, see When the Processor Guesses Too Much: Spectre, Meltdown, and the Sin of Speculative Execution and Bits That Flip on Their Own: Rowhammer and the Physical Weakness of Computer Memory.


Part 4: The Android Experiment

Android is by far the best documented large-scale trial of what happens when a big, grown, memory unsafe codebase starts writing new code in a memory safe language. By its own account, the Android team began prioritizing the shift of new development to memory safe languages around 2019. The numbers have appeared regularly ever since.

The Data Series

Year Memory safety share of Android's vulnerabilities Absolute number
2019 76 % 223
2022 35 % (given as 36 % in one place) 85
2024 24 % (extrapolated to the full year) 36 extrapolated; 27 after the September bulletin
2025 below 20 % for the first time not stated in the post

The absolute figures for 2019 and 2022 come from "Memory Safe Languages in Android 13" (Jeff Vander Stoep, December 1, 2022), the shares for 2024 from "Eliminating Memory Safety Vulnerabilities at the Source" (Jeff Vander Stoep and Alex Rebert, September 25, 2024), and the 2025 value from "Rust in Android: move fast and fix things" (Jeff Vander Stoep, November 13, 2025).

Two qualifications have to be read along with this. The 2024 value is an extrapolation; at the time of publication the count stood at 27, projected to 36. And the decline in the absolute number was not monotonic: in a footnote, Google concedes that the absolute number rose slightly in 2023 — reports were unusually high that year, which was in line with expectations given code growth — while the share continued to fall. So anyone saying the absolute number fell continuously is saying something Google itself corrects in a footnote.

The Rust Side of the Ledger

At the end of 2022 there were roughly 1.5 million lines of Rust in AOSP, and about 21 percent of all new native code (C/C++/Rust) in Android 13 was Rust — not 21 percent of all new code. The finding at the time: up to that point, not a single memory safety vulnerability had been discovered in Android's Rust code. Google added in the same breath that it did not expect that number to stay at zero forever.

Three years later, in November 2025, the ledger reads: roughly five million lines of Rust in the Android platform and one potential memory safety vulnerability, found and fixed pre-release (CVE-2025-48530). From that Google derives an estimated vulnerability density of 0.2 vulnerabilities per million lines of code and sets it against the historical density of its own C and C++ code, which it puts closer to 1,000 per million lines. The post describes the ratio as a reduction of more than 1000x.

This number is both the most quoted and the most in need of qualification in the whole topic, so explicitly: it is a density estimate whose numerator on the Rust side consists of a single find, labeled "potential" and never shipped. Google hedges consistently in the body ("roughly," "potential," "estimated," "closer to") and drops those hedges in its own introduction. The post also gives no time window for the count and does not say whether the C/C++ density counts bugs found or bugs shipped. The direction of the effect is independently supported by the share series; the precise figure of 1,000 is not.

The Unexpected Part: the Process Metrics

What gets lost in the security discussion is the second dataset. According to the Android team, Rust changes of medium and large size are rolled back about four times less often than comparable C++ changes; Rust changes spend about 25 percent less time in code review and, at similar size, need about 20 percent fewer revisions. Google itself calls these "modest productivity gains" and speculates that the marked improvement between 2023 and 2024 is due to increased Rust expertise on the Android team; for the causes overall there is no certainty, only a list of likely contributing factors.

The introduction of that same post states the fourfold lower rollback rate without the restriction to medium and large changes. Anyone quoting it should carry the restriction along.


Part 5: The Mathematics of Half-Life — and How Far It Carries

Here lies the real intellectual substance of the topic, and here too is where the popular account goes beyond what the sources support.

The Model

Google's 2024 argument is not a measurement but a simulation followed by a comparison with reality. The setup: a growing codebase, predominantly in memory unsafe languages, with a constant influx of new memory safety vulnerabilities. Now new functionality is gradually written in memory safe languages while the existing code is left mostly untouched except for bug fixes. Google states the parameters in a footnote: the codebase doubles every six years, the average lifetime of a vulnerability is 2.5 years, the transition to memory safe languages for new code takes ten years, and a sigmoid function models the transition.

The decisive building block is the assumption that vulnerabilities decay exponentially — that they have a half-life. Everything else follows almost mechanically: if the influx of new memory bugs dries up, the stock falls not linearly but exponentially. Google's own formulation is memorable: once you turn off the tap of new vulnerabilities, they decrease exponentially, making all of the code safer — even in large existing systems. For the consequence on the investment side, the post uses the formula that interoperability is the new rewrite.

Where the Model Rests on Evidence — and Where It Does Not

For the decay assumption, Google cites work from TU Darmstadt: Nikolaos Alexopoulos, Manuel Brack, Jan Philipp Wagner, Tim Grube and Max Mühlhäuser, How Long Do Vulnerabilities Live in the Code? A Large-Scale Empirical Measurement Study on FOSS Vulnerability Lifetimes, USENIX Security 2022. The study measures 5,914 CVEs across eleven widely used open-source projects (among them the Linux kernel, Firefox, Chromium, OpenSSL, PHP, FFmpeg, QEMU and PostgreSQL).

What the study does find: the average lifetime of a vulnerability is around four years, with wide variation between projects — about two years for Chromium, about seven for OpenSSL. And: the distribution of lifetimes can be approximately described by an exponential distribution. That is exactly the functional building block the model needs, and it is solidly established.

What the study does not find is the second, more popular half of the claim. Google's post presents the study as though the researchers had found that the vast majority of vulnerabilities reside in new or recently modified code. The paper contains no such finding. It measures lifetimes — the distance between the vulnerability-contributing commit and the fixing commit — not the distribution of vulnerabilities across code age brackets. Its stated research questions concern lifetimes throughout; a statement about vulnerability density by code age appears neither in the abstract nor in the methodological part of the paper. Its age-related findings in fact point the other way: vulnerabilities are getting older because the code overall is getting older, and vulnerable code lives less long than non-vulnerable code, which the authors read as a sign of a kind of maturity and therefore of quality.

There is also a tension in the numbers worth seeing: Google's simulation runs on a mean lifetime of 2.5 years, while the cited study reports around four years on average. A longer lifetime means slower decay within the same model — so the model is run with a parameter more favorable than the value in the work it invokes for its functional form.

None of this refutes the concentration of bugs in new code — it is simply supported differently than is usually claimed. Google itself had observed it for Android in 2021: the density of Android's memory safety bugs decreased with the age of the code and sat primarily in recent changes. And Google computes its own metric from lifetime figures: five-year-old code has a 3.4x (using the lifetimes from the study) to 7.4x (using the lifetimes observed in Android and Chromium) lower vulnerability density than new code. That is Google's derivation, not a finding of the study.

What Is Shown and What Is Not

A sober balance sheet:

Established. The lifetime distribution of vulnerabilities is approximately exponential (Alexopoulos et al. 2022). Android's memory safety share fell from 76 percent (2019) to below 20 percent (2025). The absolute number fell markedly over the same period, with a slight rise in 2023. Across five million lines of Rust in Android, one potential memory safety vulnerability has been found so far.

Modeled, not measured. That the observed trajectory follows causally from the language shift. Google is itself cautious here: the results align with the simulation and are even better, potentially as a result of parallel efforts to improve the safety of the memory unsafe code. On the role of mitigations, the post states explicitly that Android has no definitive answers. There is no control group — no second Android that ran on without a language shift. The conclusion rests on the fit between model and trajectory, not on an isolated effect.

I am of the opinion that this is enough to act on. The direction is supported by several independent data series, the mechanism is plausible, and the costs of being wrong are asymmetric: writing new code in a memory safe language costs little even if the effect turns out smaller than modeled. But it is a reasoned decision under uncertainty, not a proof — and selling it as a proof damages it.


Part 6: The Leaks in the Guarantee

A guarantee treated as absolute in the wrong place is more dangerous than no guarantee at all. Four places where it runs out.

1. The unsafe Keyword

Rust allows blocks of code to be marked unsafe, suspending certain checks. The CISA guide notes that the memory protection guarantees of some memory safe languages can be defeated this way, names legitimate reasons for it — such as interacting directly with the operating system — and adds the warning that developers should not use the keyword in a way that introduces memory safety vulnerabilities.

The magnitude in practice: Google's 2025 post identifies the primary security concern around Rust as the approximately 4 percent of code written inside unsafe{} blocks. And it adds a calculation worth reading: even the more conservative assumption that a line of unsafe Rust is as likely to contain a bug as a line of C or C++ significantly overestimates the risk of unsafe Rust, according to Google's data. The reason is structural: unsafe is a searchable, auditable, locally bounded marker — in C, every line is implicitly unsafe.

2. The Language Boundary

This is the underestimated leak. A mixed methods study by Ian McCormack, Tomás Dougan, Sam Estep, Hanan Hibshi, Jonathan Aldrich and Joshua Sunshine (Carnegie Mellon University and others; arXiv 2404.02230, v4 of February 18, 2026, DOI 10.1145/3798277) conducted semi-structured interviews with 19 developers and then reached an additional 160 via survey. The central finding: 70 percent of survey respondents used unsafe code to call foreign functions; the most common counterpart languages were C (90 percent), C++ (57 percent), JavaScript/TypeScript (22 percent), Assembly (21 percent) and Python (17 percent). Participants said they used unsafe code when they perceived no alternative and otherwise avoided it; limited tooling support for foreign function calls, however, left them uncertain about their own design choices. The authors name as a bias risk that recruitment via snowball sampling and online communities may skew results toward certain parts of the Rust community, and that committed Rust experts are likely overrepresented in the interview population.

The CISA guide says the same thing from a systems perspective: the memory safety guarantees offered by memory safe languages are qualified where data flows across such boundaries, and memory safe languages will almost certainly continue to rely on libraries written in languages such as C and C++. For the foreseeable future, most developers will work in a hybrid model of safe and unsafe languages.

This is the most important practical consequence of this article: the language boundary is the new attack surface. Anyone who says "we're on Rust/C#/Go" while binding a C library underneath has not eliminated the bug class but moved it to a place that is monitored less well — because the safe language's analysis tooling typically does not look there.

3. What Memory Safety Does Not Cover

The remaining 20 to 30 percent do not go away. Logic bugs, broken access control, injection, incorrect use of cryptography, insecure defaults, confusion about responsibilities in distributed systems — none of it is touched by a language choice. The CISA guide puts it curtly: memory safe languages are not free from other potential vulnerabilities of critical severity, and transitioning to them will not, by itself, halt or deter cybercrime or espionage. Likewise: no one memory safe language is right for all programming needs.

And an attack that goes through the supply chain takes no interest in memory safety at all — the XZ case is the textbook example: The Backdoor at the Heart of Linux: The XZ Attack and the Anatomy of a Supply-Chain Compromise.

4. The Operational Limits

Garbage collection latency on constrained devices was mentioned above. For operational technology, the CISA guide adds that any transition in OT systems will require a demonstration of performance, reliability and real-time guarantees.


Part 7: The Hardware Path

If code is going to remain memory unsafe for decades, the checking can also be pushed below the language. The CISA guide names two approaches in its section on future mitigations and characterizes the field as a promising area under active development.

CHERI (Capability Hardware Enhanced RISC Instructions) is a joint research project of SRI International and the University of Cambridge. The project page describes the approach as extending conventional instruction set architectures with new architectural features to enable fine-grained memory protection and highly scalable software compartmentalization; the model introduces architectural capabilities — hardware-supported descriptions of permissions — used in place of integer virtual addresses to refer to data, code and objects. The stated purpose is explicitly to let historically memory unsafe languages such as C and C++ be adapted to provide strong, compatible and efficient protection against many currently widely exploited vulnerabilities. According to the CISA guide, Arm shipped its CHERI-enabled Morello prototype processor, SoC and board in January 2022; the project page states that development has been supported by UKRI since 2019 under the Digital Security by Design programme. The project page gives no figure for runtime overhead.

ARM MTE (Memory Tagging Extension) tags memory regions and pointers and detects accesses where the tags do not match — typically use-after-free and out-of-bounds. Here the CISA guide cites an overhead estimate of 1 to 2 percent and attributes it explicitly to Arm itself; it is therefore the vendor's own figure, not an independent measurement.

The guide also records something easily overlooked: hardware features like MTE will be needed even in systems written in memory safe languages — Rust programmers can mark code as unsafe and benefit from hardware controls there. Hardware and language are not alternatives; they interlock at exactly the point Part 6 identified as the leak.


Part 8: What Follows From This in 2026

Prioritization — Explicitly Not a Rewrite

The most common fallacy drawn from the numbers in this article is "so rewrite everything." Both main sources say the opposite.

Google states as a lesson that it has become clear they do not need to throw away or rewrite all their existing memory unsafe code — and offers interoperability as the replacement strategy. The CISA guide gets more operational and names an order: start with new and smaller projects (rewriting existing code is a significant challenge, especially if the code already performs well and the organization lacks expertise in the chosen language); replace self-contained memory unsafe components; prioritize security-critical code — it names code that operates on user-generated content and code that handles secret keys, opens network connections, performs authentication and authorization, or operates at low levels such as firmware; and where a transition is not possible, wrap applications by writing an intermediary application in the safe language for all public interfaces. In its conclusion the guide names migrating security-critical components of existing codebases as the goal — not migrating all of them.

Taken together, that yields a clear rule: new code memory safe, old code only where it is exposed and security-critical, and the boundary between the two deliberately designed.

Decision Matrix

Situation Course of action Basis in the sources
New project, new component memory safe language, no debate bug density is highest in new code; this is where the influx originates
Existing C/C++ code, not exposed, stable leave it alone, harden it mature code has lower bug density; CISA warns against rewriting well-functioning code
Existing C/C++ code that parses foreign input replace or wrap as a priority CISA prioritizes code operating on user-generated content
C library bound in, caller is safe treat the boundary as its own risk, audit the boundary code 70 % of unsafe Rust use serves foreign calls; tooling does not look there
Embedded / real-time / OT evaluate languages without GC, demand evidence GC latency; CISA requires demonstrated real-time guarantees for OT
Transition technically impossible harden, sandbox, watch MTE/CHERI mitigations remain valuable for code that cannot be transitioned

And If You Already Work in a Memory Safe Language?

For anyone who spends the working day in C#, TypeScript, Python or Go, this topic looks at first like someone else's debate. That is a fallacy on three counts.

First, you are a consumer of this bug class even without producing it. Operating system, runtime, image libraries, parsers, drivers, TLS stacks — the attack surface beneath your own application is largely written in C and C++. The patch cadence for that layer is an operational discipline in its own right, not a side issue.

Second, the risk sits at the boundary, and you cross that boundary more often than you think: every P/Invoke, every native Node module, every Python wheel with a compiled extension, every outsourced image-processing step. Exactly the guarantee you are used to from your own language does not hold there — and your language's tooling does not check it there.

Third, your own bug distribution shifts accordingly. If you have structurally excluded the 70 percent, your bugs sit in the remaining 30 percent: logic, authorization, state, concurrency at the domain level. That is not relief but a relocation of where review effort belongs — code review and test design should look where the bugs can still be after the language shift, not where they were before it.

It is worth noting that regulatory pressure points the same way: the obligation to ship products without known exploitable vulnerabilities and to handle vulnerabilities across the lifecycle applies to manufacturers regardless of their language choice — see Security by Default: The EU Cyber Resilience Act and the End of the Insecure Product.


Part 9: The Underlying Principle

The real idea in this topic is more general than memory safety, and it rewards transfer.

For thirty years the strategy was to reduce the exploitability of existing bugs. That is work on the stock, and work on the stock scales with the stock — that is, with a growing quantity. The shift consisted in reducing the rate of creation instead. That is work on the influx, and it scales with new development, not with the legacy. Because the stock simultaneously decays on its own — bugs get found and fixed, code matures — time then works for you rather than against you.

You find this figure in many places once you have seen it: in every piece of technical debt where you stop fighting symptoms and shut off the source; in the decision to forbid an error-prone pattern in the linter rather than flagging it one by one in reviews; in every migration where the honest plan is not "convert everything" but "from today, nothing new in the old pattern." The cryptographic migration currently ahead of us follows the same logic — with the difference that there, a hard deadline comes from outside: Harvest Now, Decrypt Later: Post-Quantum Cryptography and the Race Against the Quantum Computer.

The Central Takeaway

Four points, each stated exactly as strongly as the sources support:

  1. Roughly two-thirds to 70 percent of serious vulnerabilities in large C/C++ codebases are memory bugs — measured three times independently (Microsoft, Chromium, Project Zero), each with its own population. It is a robust convergence, not a measured constant.
  2. The most effective measure concerns new code, not old. Android's share fell from 76 percent (2019) to below 20 percent (2025) while most of the code remained unsafe. That this trajectory follows causally from the language shift is supported by model fit, not demonstrated by an isolated effect — Google itself names parallel hardening work as a possible contributor.
  3. Do not rewrite; prioritize. Google and CISA both explicitly advise against a blanket overhaul: new code safe, existing code only where it is exposed and security-critical, otherwise harden and wrap.
  4. The language boundary is the new attack surface. Around 70 percent of the Rust developers surveyed use unsafe for foreign function calls, 90 percent of those toward C; CISA expects a hybrid model for the foreseeable future. The concrete action: know, name and specifically review every FFI and P/Invoke boundary in your own project — your language's guarantee does not hold there.

The smallest useful next step, if you want to take one today: write down the places where your own code crosses the boundary into native code. Not to eliminate them, but to know where you hold a guarantee that you do not actually hold.

A Question to Reflect On

The industry spent thirty years reducing the exploitability of a bug class whose creation it could have shut off with a tooling decision — and the data showing this was available the whole time. Which bug class in your own work are you currently fighting at the symptom level because the measure at the source would be inconvenient, expensive or politically difficult? And how would you notice that you have already been waiting thirty years too long?


Cross-References in the Vault


Fact Check

Checked: 31 verifiable claims, grouped into hard facts (18), quotations (3), source attributions (4) and synthesis claims (6). Each claim was checked against the primary source, which was itself opened during this run. Corrected or weakened: 7.

The three most important corrections:

  1. The attribution to the USENIX study was wrong and has been corrected. The draft had adopted Google's characterization that the work of Alexopoulos et al. (USENIX Security 2022) showed that the vast majority of vulnerabilities reside in new or recently modified code. The paper contains no such finding; it measures lifetimes, not the distribution of vulnerabilities by code age. What it does establish is only the exponential form of the lifetime distribution. The concentration in new code is now attributed in the article to Google's own 2021 Android observation and Google's own derivation (3.4x to 7.4x).

  2. The causal claim about Android's decline has been weakened. "The language shift caused the decline" became "the observed trajectory is consistent with the model, with no control group and with parallel hardening work as a possible contributor" — matching Google's own statement that it has no definitive answers about the role of mitigations.

  3. The 1000x figure has been marked as an estimate with a narrow base. It rests on a single find, labeled "potential" and fixed before release, across five million lines of Rust, with no stated time window. Further weakenings concerned the scope of the RustBelt proof (a realistic subset rather than "Rust is proven safe"), the fourfold lower rollback rate (medium and large changes only), the Arm MTE overhead figure of 1 to 2 percent (a vendor estimate, not an independent measurement) and Android's absolute count (slightly up in 2023, not monotonically falling).

Automated AI check against primary sources; no human expert review.


Sources and Further Reading

  1. Jeff Vander Stoep, Rust in Android: move fast and fix things, Google Security Blog / blog.google, November 13, 2025. https://blog.google/security/rust-in-android-move-fast-fix-things/
  2. Jeff Vander Stoep and Alex Rebert, Eliminating Memory Safety Vulnerabilities at the Source, Google Online Security Blog, September 25, 2024. https://security.googleblog.com/2024/09/eliminating-memory-safety-vulnerabilities-Android.html
  3. Jeff Vander Stoep, Memory Safe Languages in Android 13, Google Online Security Blog, December 1, 2022. https://security.googleblog.com/2022/12/memory-safe-languages-in-android-13.html
  4. CISA, NSA, FBI, ASD's ACSC, CCCS, NCSC-UK, NCSC-NZ, CERT-NZ, The Case for Memory Safe Roadmaps – Why Both C-Suite Executives and Technical Experts Need to Take Memory Safe Coding Seriously, December 2023. https://media.defense.gov/2023/Dec/06/2003352724/-1/-1/0/THE-CASE-FOR-MEMORY-SAFE-ROADMAPS-TLP-CLEAR.PDF
  5. Nikolaos Alexopoulos, Manuel Brack, Jan Philipp Wagner, Tim Grube, Max Mühlhäuser, How Long Do Vulnerabilities Live in the Code? A Large-Scale Empirical Measurement Study on FOSS Vulnerability Lifetimes, 31st USENIX Security Symposium (USENIX Security 22), Boston, pp. 359–376, August 2022. https://www.usenix.org/conference/usenixsecurity22/presentation/alexopoulos
  6. Chromium Security, Memory safety, Chromium project documentation. https://www.chromium.org/Home/chromium-security/memory-safety/
  7. Gavin Thomas / MSRC Team, A proactive approach to more secure code, Microsoft Security Response Center, July 16, 2019. https://www.microsoft.com/en-us/msrc/blog/2019/07/a-proactive-approach-to-more-secure-code
  8. Maddie Stone, The More You Know, The More You Know You Don't Know – A Year in Review of 0-days Used In-the-Wild in 2021, Google Project Zero, April 19, 2022. https://projectzero.google/2022/04/the-more-you-know-more-you-know-you.html
  9. Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers, Derek Dreyer, RustBelt: Securing the Foundations of the Rust Programming Language, POPL 2018. https://plv.mpi-sws.org/rustbelt/popl18/
  10. Ian McCormack, Tomás Dougan, Sam Estep, Hanan Hibshi, Jonathan Aldrich, Joshua Sunshine, A Mixed Methods Study on the Implications of Unsafe Rust for Interoperation, Encapsulation, and Tooling, arXiv:2404.02230 (v4, February 18, 2026), DOI 10.1145/3798277. https://arxiv.org/abs/2404.02230
  11. CHERI: Capability Hardware Enhanced RISC Instructions, University of Cambridge Computer Laboratory and SRI International. https://www.cl.cam.ac.uk/research/security/ctsrd/cheri/

← All articles