System Design

How does Rust stop memory bugs? Ownership, borrowing and real Android data

TL;DR

Rust checks memory safety at compile time through ownership, borrowing and lifetimes, with no garbage collector. With about 5 million lines of Rust, Android saw roughly 1000× lower memory vulnerability density and 4× fewer rollbacks; unsafe code and logic bugs still need watching.

If 70% of serious vulnerabilities come from memory bugs, the natural question is: is there a language as fast as C/C++ without that bug class? Java, Go and C# are memory-safe thanks to garbage collection, but at the cost of a runtime and unpredictable latency, unsuitable for OS kernels or codecs. Rust takes a different path: memory safety is checked at compile time, with no garbage collector. And there is now large-scale real-world data showing how well that works.

Three core rules

RuleWhat it saysWhat it prevents
OwnershipEvery value has exactly one owner; when the owner goes out of scope, memory is freed automaticallyDouble frees, forgotten frees
BorrowingAt any moment: either many read-only references or exactly one mutable referenceData races, mutating data while it's being read
LifetimesA reference can't outlive the data it points toUse-after-free, dangling pointers
let s = String::from("hello");
let r = &s;
drop(s);            // compile error: s is borrowed by r
println!("{}", r);

The equivalent C compiles and causes a use-after-free; in Rust, the compiler rejects it outright.

Other layers of protection

  • Bounds checks: out-of-range array access panics (a controlled stop) instead of reading or writing stray memory.
  • No null: possibly-absent values use Option, which forces you to handle both cases.
  • Mandatory initialisation: you can't read a variable that hasn't been assigned.
  • Thread safety: the type system (Send, Sync) prevents unsafe sharing of data across threads.

Real-world data from Android

Google published these numbers after putting around 5 million lines of Rust into the Android platform:

MetricRust vs C/C++
Memory safety vulnerability densityAbout 0.2 vs about 1,000 per million lines: roughly a 1000× reduction
Rollback rate (medium and large changes)About 4× lower
Time in code reviewAbout 25% less
Revisions before approvalAbout 20% fewer

The striking part: safer and faster, not a trade-off.

unsafe: a controlled escape hatch

Some things the compiler can't prove safe (calling C, touching hardware, special optimisations). Rust lets you mark an unsafe block. In Android, unsafe makes up about 4% of the code. Android's first Rust memory safety vulnerability (CVE-2025-48530, a buffer overflow in CrabbyAVIF) was in this kind of code; it was patched before release, and the Scudo allocator had made it non-exploitable. Google argues unsafe Rust is still less risky than C because unsafe blocks don't disable most checks, are encapsulated for local reasoning, and get extra review.

What Rust doesn't prevent

  • Logic bugs, broken authorisation, injection.
  • Memory leaks (considered "safe" by the language) and deadlocks.
  • Panics on out-of-bounds access: not exploitable, but they can still take a service down.
  • Bugs inside unsafe blocks and in C libraries called through FFI.

How to apply it

  • Dev: Learn ownership and borrowing first (chapter 4 of The Rust Book); it's where you "fight the compiler" at first, and it's the reason Rust is safe.
  • Tech Lead: Set review rules for every unsafe block: a required comment explaining why it's sound, kept small and encapsulated.
  • PM: Use Android's data (fewer rollbacks, faster reviews) to see Rust as a productivity gain, not just a security cost.

Sources & references

  1. Rust in Android: move fast and fix things — Google Security Blog
  2. What is Ownership? (The Rust Programming Language) — Rust Project