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
- Using
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
- Even when using:
- 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
- Welcome to Rust
- The Ownership System
- Reference Lifetimes
- Interior Mutability
- Unsafe
- Graphs
Acknowledgements
This talk draws heavily from the following talks:
-
"Guaranteeing Memory Safety in Rust"
- Niko Matsakis
-
"Rust: Unlocking Systems Programming"
- Aaron Turon
Memory Safety and Rust
By Alex Ozdemir
Memory Safety and Rust
- 510