RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of...

67
RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers, Derek Dreyer POPL in Los Angeles, USA Max Planck Institute for Software Systems (MPI-SWS), TU Delft

Transcript of RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of...

Page 1: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

RustBelt: Securing theFoundations of the RustProgramming Language

Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,Derek DreyerPOPL 2018 in Los Angeles, USAMax Planck Institute for Software Systems (MPI-SWS), TU Delft

1

Page 2: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Rust – Mozilla’s replacement for C/C++

A safe & modern systems PL

• First-class functions• Polymorphism/generics• Traits ≈ Type classes incl.associated types• Control over resource management(e.g., memory allocation and data layout)• Strong type system guarantees:

• Type & memory safety; absence of data races

Goal of RustBelt project:Prove safety of Rust and its

standard library.

2

Page 3: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Rust – Mozilla’s replacement for C/C++

A safe & modern systems PL• First-class functions• Polymorphism/generics• Traits ≈ Type classes incl.associated types

• Control over resource management(e.g., memory allocation and data layout)• Strong type system guarantees:

• Type & memory safety; absence of data races

Goal of RustBelt project:Prove safety of Rust and its

standard library.

2

Page 4: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Rust – Mozilla’s replacement for C/C++

A safe & modern systems PL• First-class functions• Polymorphism/generics• Traits ≈ Type classes incl.associated types• Control over resource management(e.g., memory allocation and data layout)

• Strong type system guarantees:• Type & memory safety; absence of data races

Goal of RustBelt project:Prove safety of Rust and its

standard library.

2

Page 5: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Rust – Mozilla’s replacement for C/C++

A safe & modern systems PL• First-class functions• Polymorphism/generics• Traits ≈ Type classes incl.associated types• Control over resource management(e.g., memory allocation and data layout)• Strong type system guarantees:

• Type & memory safety; absence of data races

Goal of RustBelt project:Prove safety of Rust and its

standard library.

2

Page 6: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Rust – Mozilla’s replacement for C/C++

A safe & modern systems PL• First-class functions• Polymorphism/generics• Traits ≈ Type classes incl.associated types• Control over resource management(e.g., memory allocation and data layout)• Strong type system guarantees:

• Type & memory safety; absence of data races

Goal of RustBelt project:Prove safety of Rust and its

standard library.

2

Page 7: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Contributions

• λRust: Core calculus representing a fragmentof Rust and its type system• Semantic soundness proof using logicalrelation in Iris• Safety proof of some important unsafelibraries

3

Page 8: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Rust 101

4

Page 9: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Rust 101

Aliasing+

Mutation

4

Page 10: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Ownership

// Allocate v on the heap

let mut v : Vec<i32> = vec![1, 2, 3];

v.push(4);

5

Page 11: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Ownership

// Allocate v on the heap

let mut v : Vec<i32> = vec![1, 2, 3];

v.push(4);

// Send v to another thread

send(v);

Ownership transferred to send:

fn send(Vec<i32>)

5

Page 12: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Ownership

// Allocate v on the heap

let mut v : Vec<i32> = vec![1, 2, 3];

v.push(4);

// Send v to another thread

send(v);

// Let's try to use v again

v.push(5);

Potentially racing access!

Error: v has been moved.Prevents possible data race.

5

Page 13: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Ownership

// Allocate v on the heap

let mut v : Vec<i32> = vec![1, 2, 3];

v.push(4);

// Send v to another thread

send(v);

x: T expresses ownership of x at type T

• Mutation allowed, no aliasing• We can deallocate x

Why is v not moved?

5

Page 14: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Ownership

// Allocate v on the heap

let mut v : Vec<i32> = vec![1, 2, 3];

v.push(4);

// Send v to another thread

send(v);

x: T expresses ownership of x at type T

• Mutation allowed, no aliasing• We can deallocate x

Why is v not moved?

5

Page 15: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Borrowing and lifetimes

// Allocate v on the heap

let mut v : Vec<i32> = vec![1, 2, 3];

Vec::push(&mut v, 4);

// Send v to another thread

send(v);

Method call was just sugar.&mut v creates a reference.

Pass-by-reference: Vec::push borrows ownership temporarily

Pass-by-value: Ownership moved to send permanentlyType of push:fn Vec::push<'a>(&'a mut Vec<i32>, i32)

Lifetime 'a is inferred by Rust.

&mut x creates amutable reference of type &'a mut T:• Ownership temporarily borrowed• Borrow lasts for inferred lifetime 'a

• Mutation, no aliasing• Unique pointer

6

Page 16: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Borrowing and lifetimes

// Allocate v on the heap

let mut v : Vec<i32> = vec![1, 2, 3];

Vec::push(&mut v, 4);

// Send v to another thread

send(v);

Method call was just sugar.&mut v creates a reference.

Pass-by-reference: Vec::push borrows ownership temporarily

Pass-by-value: Ownership moved to send permanently

Type of push:fn Vec::push<'a>(&'a mut Vec<i32>, i32)

Lifetime 'a is inferred by Rust.

&mut x creates amutable reference of type &'a mut T:• Ownership temporarily borrowed• Borrow lasts for inferred lifetime 'a

• Mutation, no aliasing• Unique pointer

6

Page 17: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Borrowing and lifetimes

// Allocate v on the heap

let mut v : Vec<i32> = vec![1, 2, 3];

Vec::push(&mut v, 4);

// Send v to another thread

send(v);

Method call was just sugar.&mut v creates a reference.

Pass-by-reference: Vec::push borrows ownership temporarily

Pass-by-value: Ownership moved to send permanentlyType of push:fn Vec::push<'a>(&'a mut Vec<i32>, i32)

Lifetime 'a is inferred by Rust.

&mut x creates amutable reference of type &'a mut T:• Ownership temporarily borrowed• Borrow lasts for inferred lifetime 'a

• Mutation, no aliasing• Unique pointer

6

Page 18: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Borrowing and lifetimes

// Allocate v on the heap

let mut v : Vec<i32> = vec![1, 2, 3];

Vec::push(&mut v, 4);

// Send v to another thread

send(v);

Method call was just sugar.&mut v creates a reference.

Pass-by-reference: Vec::push borrows ownership temporarily

Pass-by-value: Ownership moved to send permanently

Type of push:fn Vec::push<'a>(&'a mut Vec<i32>, i32)

Lifetime 'a is inferred by Rust.

&mut x creates amutable reference of type &'a mut T:• Ownership temporarily borrowed• Borrow lasts for inferred lifetime 'a

• Mutation, no aliasing• Unique pointer

6

Page 19: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Borrowing and lifetimes

// Allocate v on the heap

let mut v : Vec<i32> = vec![1, 2, 3];

Vec::push(&mut v, 4);

// Send v to another thread

send(v);

Method call was just sugar.&mut v creates a reference.

Pass-by-reference: Vec::push borrows ownership temporarily

Pass-by-value: Ownership moved to send permanently

Type of push:fn Vec::push<'a>(&'a mut Vec<i32>, i32)

Lifetime 'a is inferred by Rust.

&mut x creates amutable reference of type &'a mut T:• Ownership temporarily borrowed• Borrow lasts for inferred lifetime 'a

• Mutation, no aliasing• Unique pointer

6

Page 20: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Borrowing and lifetimes

// Allocate v on the heap

let mut v : Vec<i32> = vec![1, 2, 3];

Vec::push(&mut v, 4);

// Send v to another thread

send(v);

Method call was just sugar.&mut v creates a reference.

Pass-by-reference: Vec::push borrows ownership temporarily

Pass-by-value: Ownership moved to send permanentlyType of push:fn Vec::push<'a>(&'a mut Vec<i32>, i32)

Lifetime 'a is inferred by Rust.

&mut x creates amutable reference of type &'a mut T:• Ownership temporarily borrowed• Borrow lasts for inferred lifetime 'a

• Mutation, no aliasing• Unique pointer

6

Page 21: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Shared Borrowing

let mut x = 1;

join (|| println!("Thread 1: {}", &x),

|| println!("Thread 2: {}", &x);)

x = 2;

&x creates a shared reference of type &'a T

• Ownership borrowed for lifetime 'a

• Can be aliased• Does not allow mutation

After 'a has ended, x is writeable again.

7

Page 22: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Shared Borrowing

let mut x = 1;

join (|| println!("Thread 1: {}", &x),

|| println!("Thread 2: {}", &x));

x = 2;

&x creates a shared reference of type &'a T

• Ownership borrowed for lifetime 'a

• Can be aliased• Does not allow mutation

After 'a has ended, x is writeable again.

7

Page 23: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Shared Borrowing

let mut x = 1;

join (|| println!("Thread 1: {}", &x),

|| println!("Thread 2: {}", &x));

x = 2;

&x creates a shared reference of type &'a T

• Ownership borrowed for lifetime 'a

• Can be aliased• Does not allow mutation

After 'a has ended, x is writeable again.

7

Page 24: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Rust’s type system is basedon ownership:1. Full ownership: T2. Mutable borrowedreference: &'a mut T

3. Shared borrowedreference: &'a T

Lifetimes 'a decide howlong borrows last.

Aliasing+

Mutation

8

Page 25: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

But what if I needaliased mutable state?

Synchronization mechanisms:• Locks, channels, . . .

Memory management:• Reference counting, . . .

9

Page 26: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

let m = Mutex::new(1); // m : Mutex<i32>

// Concurrent increment:

// Acquire lock, mutate, release (implicit)

join (|| *(&m).lock().unwrap() += 1,

|| *(&m).lock().unwrap() += 1);

// Unique owner: no need to lock

println!("{}", m.get_mut().unwrap())

Type of lock:

fn lock<'a>(&'a Mutex<i32>)

-> LockResult<MutexGuard<'a, i32>>

Type of lock:

fn lock<'a>(&'a Mutex<i32>)

-> &'a mut i32

10

Page 27: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

let m = Mutex::new(1); // m : Mutex<i32>

// Concurrent increment:

// Acquire lock, mutate, release (implicit)

join (|| *(&m).lock().unwrap() += 1,

|| *(&m).lock().unwrap() += 1);

// Unique owner: no need to lock

println!("{}", m.get_mut().unwrap())

Type of lock:

fn lock<'a>(&'a Mutex<i32>)

-> LockResult<MutexGuard<'a, i32>>

Type of lock:

fn lock<'a>(&'a Mutex<i32>)

-> &'a mut i32

10

Page 28: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

let m = Mutex::new(1); // m : Mutex<i32>

// Concurrent increment:

// Acquire lock, mutate, release (implicit)

join (|| *(&m).lock().unwrap() += 1,

|| *(&m).lock().unwrap() += 1);

// Unique owner: no need to lock

println!("{}", m.get_mut().unwrap())

Type of lock:

fn lock<'a>(&'a Mutex<i32>)

-> LockResult<MutexGuard<'a, i32>>

Type of lock:

fn lock<'a>(&'a Mutex<i32>)

-> &'a mut i32

10

Page 29: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

let m = Mutex::new(1); // m : Mutex<i32>

// Concurrent increment:

// Acquire lock, mutate, release (implicit)

join (|| *(&m).lock().unwrap() += 1,

|| *(&m).lock().unwrap() += 1);

// Unique owner: no need to lock

println!("{}", m.get_mut().unwrap())

Type of lock:

fn lock<'a>(&'a Mutex<i32>)

-> LockResult<MutexGuard<'a, i32>>

Type of lock:

fn lock<'a>(&'a Mutex<i32>)

-> &'a mut i32

Interior mutability

10

Page 30: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

let m = Mutex::new(1); // m : Mutex<i32>

// Concurrent increment:

// Acquire lock, mutate, release (implicit)

join (|| *(&m).lock().unwrap() += 1,

|| *(&m).lock().unwrap() += 1);

// Unique owner: no need to lock

println!("{}", m.get_mut().unwrap())

Type of lock:

fn lock<'a>(&'a Mutex<i32>)

-> LockResult<MutexGuard<'a, i32>>

Type of lock:

fn lock<'a>(&'a Mutex<i32>)

-> &'a mut i32

Interior mutability

Aliasing+

Mutation?

10

Page 31: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

unsafe

fn lock<'a>(&'a self) -> LockResult<MutexGuard<'a, T>>

{

unsafe {

libc::pthread_mutex_lock(self.inner.get());

MutexGuard::new(self)

}

}

Mutex has an unsafe implementation. Butthe interface (API) is safe:fn lock<'a>(&'a Mutex<i32>) -> &'a mut T

11

Page 32: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

unsafe

fn lock<'a>(&'a self) -> LockResult<MutexGuard<'a, T>>

{

unsafe {

libc::pthread_mutex_lock(self.inner.get());

MutexGuard::new(self)

}

}

Mutex has an unsafe implementation. Butthe interface (API) is safe:fn lock<'a>(&'a Mutex<i32>) -> &'a mut T

11

Page 33: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

unsafe

fn lock<'a>(&'a self) -> LockResult<MutexGuard<'a, T>>

{

unsafe {

libc::pthread_mutex_lock(self.inner.get());

MutexGuard::new(self)

}

}

Mutex has an unsafe implementation. Butthe interface (API) is safe:fn lock<'a>(&'a Mutex<i32>) -> &'a mut T

Similar for join: unsafely implemented userlibrary, safe interface.

11

Page 34: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Goal: Prove safety of Rust and itsstandard library.

Safety proof needs to be extensible.12

Page 35: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

The λRust type system

τ ::= bool | int | ownn τ | &κmut τ | &κ

shr τ | Πτ | Στ | . . .

T ::= ∅ | T,p C τ | . . .

Typing context assigns types to paths p(denoting �elds of structures)

Core substructural typing judgments:

Γ | E; L | T1 ` I a x. T2 Γ | E; L | K, T ` F

Typing individual instructions I(E and L track lifetimes)

Typing whole functions F(K tracks continuations)

13

Page 36: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

The λRust type system

τ ::= bool | int | ownn τ | &κmut τ | &κ

shr τ | Πτ | Στ | . . .T ::= ∅ | T,p C τ | . . .

Typing context assigns types to paths p(denoting �elds of structures)

Core substructural typing judgments:

Γ | E; L | T1 ` I a x. T2 Γ | E; L | K, T ` F

Typing individual instructions I(E and L track lifetimes)

Typing whole functions F(K tracks continuations)

13

Page 37: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

The λRust type system

τ ::= bool | int | ownn τ | &κmut τ | &κ

shr τ | Πτ | Στ | . . .T ::= ∅ | T,p C τ | . . .

Typing context assigns types to paths p(denoting �elds of structures)

Core substructural typing judgments:

Γ | E; L | T1 ` I a x. T2 Γ | E; L | K, T ` F

Typing individual instructions I(E and L track lifetimes)

Typing whole functions F(K tracks continuations)

13

Page 38: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

The λRust type system

τ ::= bool | int | ownn τ | &κmut τ | &κ

shr τ | Πτ | Στ | . . .T ::= ∅ | T,p C τ | . . .

Typing context assigns types to paths p(denoting �elds of structures)

Core substructural typing judgments:

Γ | E; L | T1 ` I a x. T2 Γ | E; L | K, T ` F

Typing individual instructions I(E and L track lifetimes)

Typing whole functions F(K tracks continuations)

13

Page 39: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

The λRust type system

τ ::= bool | int | ownn τ | &κmut τ | &κ

shr τ | Πτ | Στ | . . .T ::= ∅ | T,p C τ | . . .

Typing context assigns types to paths p(denoting �elds of structures)

Core substructural typing judgments:

Γ | E; L | T1 ` I a x. T2 Γ | E; L | K, T ` F

Typing individual instructions I(E and L track lifetimes)

Typing whole functions F(K tracks continuations)

13

Page 40: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Syntactic type safety

E; L | K, T ` F =⇒ F is safe

Usually proven by progress and preservation.

But what about unsafe code?

Use a semantic approach based on logical relations.

14

Page 41: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Syntactic type safety

E; L | K, T ` F =⇒ F is safe

Usually proven by progress and preservation.

But what about unsafe code?

Use a semantic approach based on logical relations.

14

Page 42: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

The logical relation

Ownership predicate for every type τ :

JτK.own(t, v)

Owning thread’s ID Data in memory

15

Page 43: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

The logical relation

Ownership predicate for every type τ :

JτK.own(t, v)

Owning thread’s ID Data in memory

15

Page 44: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

The logical relation

Ownership predicate for every type τ :

JτK.own(t, v)

Owning thread’s ID Data in memory

We use Iris to de�ne ownership:• Concurrent separation logic• Designed to derive new reasoningprinciples inside the logic

15

Page 45: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

The logical relation

Ownership predicate for every type τ :

JτK.own(t, v)

Owning thread’s ID Data in memory

Lift to semantic contexts JTK(t):

Jp1 C τ1,p2 C τ2K(t) :=

Jτ1K.own(t, [p1]) ∗ Jτ2K.own(t, [p2])

Separating conjunction

15

Page 46: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

The logical relation

Ownership predicate for every type τ :

JτK.own(t, v)

Owning thread’s ID Data in memory

Lift to semantic contexts JTK(t):

Jp1 C τ1,p2 C τ2K(t) :=

Jτ1K.own(t, [p1]) ∗ Jτ2K.own(t, [p2])

Separating conjunction

15

Page 47: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

The logical relation

Ownership predicate for every type τ :

JτK.own(t, v)

Owning thread’s ID Data in memory

Lift to semantic typing judgments:

E; L | T1 |= I |=T2 :=

∀t. {JEK ∗ JLK ∗ JT1K(t)} I {JEK ∗ JLK ∗ JT2K(t)}

15

Page 48: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Compatibility lemmas

Connect logical relation to type system:Semantic versions of all syntactic typing rules.

Γ | E; L ` κ aliveΓ | E; L | p1 C &κ

mut τ,p2 C τ ` p1 := p2 a p1 C &κmut τ

E; L | T1 ` I a x. T2 E; L | K; T2, T ` FE; L | K; T1, T ` let x = I in F

Well-typed programs can’t go wrong• No data race• No invalid memory access

16

Page 49: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Compatibility lemmas

Connect logical relation to type system:Semantic versions of all syntactic typing rules.

Γ | E; L |= κ aliveΓ | E; L | p1 C &κ

mut τ,p2 C τ |= p1 := p2 |=p1 C &κmut τ

E; L | T1 |= I |=x. T2 E; L | K; T2, T |= FE; L | K; T1, T |= let x = I in F

Well-typed programs can’t go wrong• No data race• No invalid memory access

16

Page 50: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Compatibility lemmas

Connect logical relation to type system:Semantic versions of all syntactic typing rules.

Γ | E; L |= κ aliveΓ | E; L | p1 C &κ

mut τ,p2 C τ |= p1 := p2 |=p1 C &κmut τ

E; L | T1 |= I |=x. T2 E; L | K; T2, T |= FE; L | K; T1, T |= let x = I in F

Well-typed programs can’t go wrong• No data race• No invalid memory access

16

Page 51: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Linking with unsafe code

` ` ```

`unsafe

00

0

The whole program is safe ifthe unsafe pieces are safe!

17

Page 52: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Linking with unsafe code

` ` ```

`unsafe�

��

The whole program is safe ifthe unsafe pieces are safe!

17

Page 53: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Linking with unsafe code

` ` ```

`unsafe�

��

The whole program is safe ifthe unsafe pieces are safe!

17

Page 54: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

How do we de�neJτK.own(t,v)?

18

Page 55: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Jownn τK.own(t, v) :=

∃`. v = [`] ∗ .(∃w. ` 7→ w ∗ JτK.own(t,w)

)∗ . . .

J&κmut τK.own(t, v) :=

∃`. v = [`] ∗ &κfull

(∃w. ` 7→ w ∗ JτK.own(t,w)

)

Lifetime logic connective

19

Page 56: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Jownn τK.own(t, v) :=

∃`. v = [`] ∗ .(∃w. ` 7→ w ∗ JτK.own(t,w)

)∗ . . .

J&κmut τK.own(t, v) :=

∃`. v = [`] ∗ &κfull

(∃w. ` 7→ w ∗ JτK.own(t,w)

)

Lifetime logic connective

19

Page 57: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Jownn τK.own(t, v) :=

∃`. v = [`] ∗ .(∃w. ` 7→ w ∗ JτK.own(t,w)

)∗ . . .

J&κmut τK.own(t, v) :=

∃`. v = [`] ∗ &κfull

(∃w. ` 7→ w ∗ JτK.own(t,w)

)

Lifetime logic connective

19

Page 58: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Jownn τK.own(t, v) :=

∃`. v = [`] ∗ .(∃w. ` 7→ w ∗ JτK.own(t,w)

)∗ . . .

J&κmut τK.own(t, v) :=

∃`. v = [`] ∗ &κfull

(∃w. ` 7→ w ∗ JτK.own(t,w)

)Lifetime logic connective

19

Page 59: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Traditionally, P ∗ Q splitsownership in space.

Lifetime logic allowssplitting ownership in time!

20

Page 60: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

P V &κfull P ∗

([†κ]V P

)now [†κ]

time

κ alive κ dead

Access to P while κ lastsAccess to P when κ has endedThe lifetime logic has been

fully derived inside Iris.

21

Page 61: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

P V &κfull P ∗

([†κ]V P

)

now [†κ]

time

Access to P while κ lasts

Access to P when κ has endedThe lifetime logic has beenfully derived inside Iris.

21

Page 62: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

P V &κfull P ∗

([†κ]V P

)

now [†κ]

time

Access to P while κ lastsAccess to P when κ has ended

The lifetime logic has beenfully derived inside Iris.

21

Page 63: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

P V &κfull P ∗

([†κ]V P

)

now [†κ]

time

Access to P while κ lastsAccess to P when κ has endedThe lifetime logic has been

fully derived inside Iris.

21

Page 64: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

What else is in the paper?• More details about λRust, the type system, andthe lifetime logic

• How to handle interior mutability that is safe forsubtle reasons (e.g., mutual exclusion)

• Mutex<T>, Cell<T>

, RefCell<T>, Rc<T>, Arc<T>,RwLock<T> (found a bug), . . .

Still missing from RustBelt:• Trait objects (existential types), weak memory,drop, . . .

22

Page 65: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

What else is in the paper?• More details about λRust, the type system, andthe lifetime logic

• How to handle interior mutability that is safe forsubtle reasons (e.g., mutual exclusion)

• Mutex<T>, Cell<T>, RefCell<T>, Rc<T>, Arc<T>,RwLock<T> (found a bug), . . .

Still missing from RustBelt:• Trait objects (existential types), weak memory,drop, . . .

22

Page 66: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

What else is in the paper?• More details about λRust, the type system, andthe lifetime logic

• How to handle interior mutability that is safe forsubtle reasons (e.g., mutual exclusion)

• Mutex<T>, Cell<T>, RefCell<T>, Rc<T>, Arc<T>,RwLock<T> (found a bug), . . .

Still missing from RustBelt:• Trait objects (existential types), weak memory,drop, . . .

22

Page 67: RustBelt: Securing the Foundations of the Rust Programming ...RustBelt: Securing the Foundations of the Rust Programming Language Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers,

Logical relations can be used to prove safetyof languages with unsafe operations.

Advances in separation logic (as embodied inIris) make this possible for even a language

as sophisticated as Rust!

https://plv.mpi-sws.org/rustbelt

23