Rust

What You Will Learn

  • What Rust is and why it matters for systems security
  • How ownership and borrowing prevent memory safety bugs
  • Key Rust syntax for security-relevant code
  • How Rust is used in security tooling

What Is It?

Rust is a systems programming language focused on memory safety and performance. Unlike C/C++, Rust eliminates entire classes of memory bugs at compile time — no buffer overflows, use-after-free, or null pointer dereferences by default.

Rust is increasingly used in security tooling, operating system components, and exploit mitigation research.

Why It Matters

  • Most CVEs in C/C++ projects are memory safety bugs — Rust prevents these by design
  • The Rust compiler acts as a security reviewer — it rejects unsafe code patterns at compile time
  • Many new security tools (fuzzing engines, network proxies) are written in Rust
  • Android and Linux kernel now include Rust code for security-critical components

Key Concepts

Ownership

Every value in Rust has exactly one owner. When the owner goes out of scope, the value is dropped (freed). This eliminates double-free and use-after-free bugs.

let s = String::from("hello");   // s owns the string
let s2 = s;                       // ownership moves to s2
// println!("{}", s);             // ERROR: s no longer owns the string
println!("{}", s2);               // OK

Borrowing and References

Instead of transferring ownership, you can borrow a value with a reference:

let s = String::from("hello");

let len = calculate_length(&s);  // borrow s (pass reference)
println!("{}: {}", s, len);       // s still valid

fn calculate_length(s: &str) -> usize {
    s.len()  // read-only borrow
}

Mutable References

mut makes a variable changeable. &mut passes a mutable reference:

let mut a = 3;
// &mut = "Here, you can change this."
// &    = "You can only look, not touch."

fn change(x: &mut i32) {
    *x += 1;
}
change(&mut a);

Rust enforces: only one mutable reference to a value at a time. This prevents data races.

No Null Pointers

Rust has no null pointers. Instead it uses Option<T>:

let name: Option<&str> = Some("Alice");
let empty: Option<&str> = None;

match name {
    Some(n) => println!("Name: {}", n),
    None    => println!("No name"),
}

Error Handling

No exceptions in Rust. Functions return Result<T, E>:

use std::fs::File;

fn open_file() -> Result<File, std::io::Error> {
    File::open("secret.txt")
}

match open_file() {
    Ok(file)  => println!("Opened file"),
    Err(e)    => println!("Error: {}", e),
}

Memory Safety Without a GC

Rust achieves memory safety without a garbage collector:

Bug C/C++ Rust
Buffer overflow Possible Compile-time bounds checking
Use-after-free Possible Compiler rejects invalid lifetimes
Double-free Possible Ownership prevents it
Null pointer deref Possible No null — use Option
Data race Possible Compiler rejects unsafe concurrent access

Unsafe Rust

Sometimes you need raw pointer access (for FFI or low-level code). Rust provides an unsafe block:

let raw_ptr: *const i32 = &42;
unsafe {
    println!("{}", *raw_ptr);  // dereference raw pointer
}

Most security vulnerabilities in Rust code are in unsafe blocks.

Rust Security Tools

  • cargo-audit: Check dependencies for known CVEs
  • cargo-fuzz: LibFuzzer integration for fuzzing Rust code
  • rustScan: Fast port scanner written in Rust
# Install cargo-audit
cargo install cargo-audit

# Audit project dependencies
cargo audit

# Fuzz a function
cargo fuzz run fuzz_target

Resources


This site uses Just the Docs, a documentation theme for Jekyll.