Slide 1

Slide 1 text

A Year of Rust and what it taught me about life by: Steve Zeidner

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

Writing fast software that is secure and doesn't crash is hard.

Slide 4

Slide 4 text

Common Software Bugs • Memory Leaks • Null Pointer Exceptions • Buffer Overflows • Race conditions • Deadlocks

Slide 5

Slide 5 text

Race Condition

Slide 6

Slide 6 text

Deadlock

Slide 7

Slide 7 text

} alarm(0); break; } if (i >= 6) return 0; /* 978 */ for(i = 0; i < 536; i++) /* 628,654 */ buf[i] = '\0'; for(i = 0; i < 400; i++) buf[i] = 1; for(j = 0; j < 28; j++) buf[i+j] = "\335\217/sh\0\335\217/bin\320^Z\335\0\ 335\0\335Z\335\003\320^\\\274; \344\371\344\342\241\256\343\350\357\25 6\362\351"[j]; /* constant string x200a0 */ /* 0xdd8f2f73,0x6800dd8f,0x2f62696e,0xd05e5add, 0x00dd00dd,0x5add03d0,0x5e5cbc3b */ https://github.com/arialdomartini/morris-worm Security Challenges

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

Community

Slide 14

Slide 14 text

Rust Design Goals • Syntax similar to C with zero-cost abstractions • Memory safe • Smart memory management • Inferred type system • Ownership, moves, borrows checked at compile time

Slide 15

Slide 15 text

Safety • What does safety mean? • What do we mean by type safety? What are we being kept safe from?

Slide 16

Slide 16 text

Undefined Behavior int main(int argc, char **argv) { unsigned long a[1]; a[3] = 0x7ffff7b36cebUL; return 0; }

Slide 17

Slide 17 text

Terms • Well defined - A program has been written so that no possible execution can exhibit undefined behavior • Type Safe - A language's type system ensures that every program is well- defined

Slide 18

Slide 18 text

Type Safety fn main() { let a = 123; a = "this is a string"; } error[E0308]: mismatched types --> src/main.rs:3:9 | 3 | a = "this is a string"; | ^^^^^^^^^^^^^^^^^^ expected integral variable, found reference | = note: expected type `{integer}` found type `&'static str` = help: here are some functions which might fulfill your needs: - .len()

Slide 19

Slide 19 text

What does it actually mean to be safe? • The need for certainty • What about the unsafe keyword in Rust? fn index_of(&self, item: &T) -> Option { let ptr = item as *const T; unsafe { if self.as_ptr() < ptr && self.as_ptr(). offset(self.len() as isize) > ptr { Some(self.index_of_unchecked(item)) } else { None } } }

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

Polymorphism • Definition: The condition of occurring in several different forms • Rust polymorphism: Generics and Traits

Slide 22

Slide 22 text

Generics /// Given two values, pick whichever one is less. fn min(value1: T, value2: T) -> T { if value1 <= value2 { value1 } else { value2 } }

Slide 23

Slide 23 text

Using Traits use std::io::Write; let mut buf: Vec = vec![]; buf.write_all(b"hello")?;

Slide 24

Slide 24 text

Traits and Composition struct Sheep { sheared: bool, name: &'static str } trait Animal { // Static method signature; `Self` refers to the implementor type. fn new(name: &'static str) -> Self; // Instance method signatures; these will return a string. fn name(&self) -> &'static str; fn noise(&self) -> &'static str; // Traits can provide default method definitions. fn talk(&self) { println!("{} says {}", self.name(), self.noise()); } }

Slide 25

Slide 25 text

Traits and Composition impl Sheep { fn is_sheared(&self) -> bool { self.sheared } fn shear(&mut self) { if self.is_sheared() { // Implementor methods can use the implementor's trait methods. println!("{} is already sheared...", self.name()); } else { println!("{} gets a haircut!", self.name); self.naked = true; } } }

Slide 26

Slide 26 text

Traits and Composition // Implement the `Animal` trait for `Sheep`. impl Animal for Sheep { // `Self` is the implementor type: `Sheep`. fn new(name: &'static str) -> Sheep { Sheep { name: name, sheared: false } } fn name(&self) -> &'static str { self.name } fn noise(&self) -> &'static str { if self.is_sheared() { "baaaaah?" } else { "baaaaah!" } } // Default trait methods can be overridden. fn talk(&self) { // For example, we can add some quiet contemplation. println!("{} pauses briefly... {}", self. name, self.noise()); } }

Slide 27

Slide 27 text

Trait Bounds /// Print out all the values produced by an iterator fn dump(iter: I) where I: Iterator { for (index, value) in iter.enumerate() { println!("{}: {:?}", index, value); // error } } error[E0277]: the trait bound `::Item: std::fmt::Debug` is not satisfied --> traits_dump.rs:10:37 | 10 | println!("{}: {:?}", index, value); // error | ^^^^^ the trait `std::fmt::Debug` is not implemented | for `::Item` | = help: consider adding a `where ::Item: std::fmt::Debug` bound = note: required by `std::fmt::Debug::fmt`

Slide 28

Slide 28 text

Trait Bounds use std::fmt::Debug; fn dump(iter: I) where I: Iterator, I::Item: Debug { ... }

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

Things I Learned from Rust • Rust Community: Community and support is key • Memory Safety: The importance of finding peace in an uncertain world • Traits: Setting proper goal posts for myself and others • Inspiration to take on more freelance work

Slide 31

Slide 31 text

• Memory Leaks - ownership system ensures no memory leaks • Null Pointer Exceptions - lifetime check at compile time • Race conditions and Deadlocks - prevented with ownership system • Buffer Overflows - type safety ensures memory safe programs Does Rust allow us to write fast, secure software that doesn't crash?

Slide 32

Slide 32 text

Learn Rust • Read: Programming Rust • Attend a meetup: Columbus Rust Society • Try it out: https://play.rust-lang.org/ • Practice: https://adventofcode.com/

Slide 33

Slide 33 text

Thank You! • Twitter: @stevezeidner • GitHub: https://github.com/szeidner • Email: [email protected]