Memory Safety & Rust

Alex Ozdemir

Goals in Language Design

  • Speed
  • Control
  • Safety (Memory, Type, ...)
  • Expressiveness
    • Concision
  • Portability

Goals in Language Design

  • Speed
  • Control
  • Safety (Memory, Type, ...)
  • Expressiveness
    • Concision
  • Portability

Control vs. Safety

Safety

Control

Haskell

C/C++

ML

Java

Browsers

Graphics

Operating Systems

Safety Matters

  • 50% of Firefox bugs are safety violations
  • Safety-related vulnerabilities are on the rise
  • Memory safety errors are time-consuming to debug

Vulnerabilities originating as Buffer Errors

-- NVD

Control

// C++

int main() {
    vector<string> vec;
    vec.push_back("Hi");
    auto& elem = vec[0];

    // State of memory ->
}

Stack

Heap

data

length

capacity

vec[0]

elem

vec

Control

// C++

int main() {
    vector<string> vec;
    vec.push_back("Hi");
    auto& elem = vec[0];

    vec.push_back("there!");

    // State of memory ->
    cout << elem << endl;
}

Stack

Heap

data

length

capacity

vec[0]

elem

vec

vec[0]

vec[1]

Safety

// Java

public static void main(String[] args) {
    ArrayList<String> vec = 
        new ArrayList<String>();
    vec.add("Hi");
    String elem = vec.get(0);
    vec.add("there!");

    // State of memory
    System.out.println(elem);
}

Stack

Heap

elem

data

length

capacity

vec

vec[0]

vec[1]

Safety

Most languages achieve it through:

  • Indirection
  • Garbage Collection
// C++

int main() {
    vector<string> vec;

    // populate the vector
    for (auto& elem : vec) {
        if (elem > "hi") {
            vec.erase(elem)
        }
    }

}

Iterator Invalidation

  • Java tries to throw a runtime exception

How much safety is really achieved though?

Summary

  • Systems languages grant control but sacrifice memory safety
  • Other languages guarantee safety
    • Using
      • Indirection
      • Garbage Collection
    • At the expense of
      • Control
      • Performance

Rust

Safety

Control

Haskell

C/C++

ML

Java

Rust

Safety

Control

Haskell

C/C++

ML

Java

How do programmers write C/C++?

Example: Get Address Information

int getaddrinfo(const char *node, const char *service,
                const struct addrinfo *hints,
                struct addrinfo **res);
void freeaddrinfo(struct addrinfo *res);
The getaddrinfo() function allocates and initializes a linked list of addrinfo structures, one for each network address that matches node and service, subject to any restrictions imposed by hints, and returns a pointer to the start of the list in res. The itemsin the linked list are linked by the ai_next field.
...
The freeaddrinfo() function frees the memory that was allocated for the dynamically allocated linked list res.

Ownership Semantics

Programmers reason about who owns data:

  • who has unconditional access to it
  • who has responsibility for freeing it.

Ownership Semantics in C++

These ideas ultimately made their way into the C++ STL:

  • unique_ptr<T>
  • shared_ptr<T>
  • weak_ptr<T>
  • auto_ptr<T>

Issues with Ownership in C++

int main() {
    int* raw_p = nullptr;

    {

        unique_ptr<int> p = make_unique<int>(4);
        cout << *p << endl;
        raw_p = p.get(); // Get the underlying ptr

    } // The destructor for `p` runs, freeing `*raw_p`

    cout << *raw_p << endl;
    // ^ Cry
}

C++ allows for ownership semantics, but cannot enforce them.

Rust

  • Statically enforces ownership semantics
  • Statically reasons about reference lifetimes

In order to:

  • Preserve performance
    • Even when using:
      • Closures
      • Iterators
      • Generics
  • Guarantee memory safety
  • Prevent data races

Memory Safety

A course embedded in Programming Practicum

Course Idea

Learn about Memory Safety through Rust.

Course Rythm

  • A lecture on one facet of Memory Management
  • A programming assignment that highlights that concept
  • A student presentation on an issue raised by the previous assignment

Course Outline

  1. Welcome to Rust
  2. The Ownership System
  3. Reference Lifetimes
  4. Interior Mutability
  5. Unsafe
  6. Graphs

Acknowledgements

This talk draws heavily from the following talks:

Memory Safety and Rust

By Alex Ozdemir

Memory Safety and Rust

  • 402