This is why I get a little uncomfortable when people suggest Rust fixes tons of security issues. Yes, it will fix some of them. No, just because a Rust program compiles doesn't mean that it won't have problems. Rust is _memory safe_. Nothing more, nothing less.
I feel like you're undervaluing memory safety. Memory safety prevents most (all?) exploits that lead to remote code execution. There can still be high level vulnerabilities, but guaranteed memory safety is a huge improvement. Rust's type system can be used to prevent high level attacks too. For instance, if an sql library is set up properly, it can prevent sql injection by requiring inputs be properly sanitized.
Heartbleed in Rust
51–60 of 140 posts
Re: Heartbleed in Rust
#52My take-away: Low-level code will burn you eventually, and unnecessarily low-level code will burn you unnecessarily
Re: Heartbleed in Rust
#53A bit more serious, I wonder which security problems Rust would have, if it would be as well studied as C.
Re: Heartbleed in Rust
#54My take-away: Low-level code will burn you eventually, and unnecessarily low-level code will burn you unnecessarily
It's not low level, though, that was my original misunderstanding. Heartbleed was not a memory safety issue like I incorrectly assumed. It could happen in, say, C#, or Java. In fact, there's probably existing code with the same bug. It's not uncommon to reuse objects in managed code as a performance hack.
Honestly, if the end of your collection is beyond the addresses of that collection's valid data then you've just malloc'ed. Is it worth the bugs?
How to malloc in a high-level language(assuming a typecast always succeeds): 1. Make a reference in main (this way it's object will never be garbage collected) 2. Make this reference to an array of objects(hereafter referred to as the "block"), where each object holds n integers. 3. Whenever you wish to save an object to the block, cast it to the class which the block contains and cast from that class when you want to retrieve one.
Is the above idea good for performance? Possibly. Does it belong in a cryptography library/program? Nope.
Re: Heartbleed in Rust
#55Earlier quoted context omitted.
You could write a custom "allocator" that created a pool of zeroed buffers initially, gave out buffers from that pool and accepted buffers back into that pool, and just didn't zero them in between. That would be perfectly "safe" as far as the language was concerned, and would allow you to reproduce the problem.
You would have to go out of your way to do so and handing out buffers that allow reading them without initialization would be a huge warning sign IMO. If you want performance, you don't have to worry about zeroing anything, just call `.clear()` on a `Vec`. Nobody is saying you can't reproduce Heartbleed's effect in Rust, you just have to actually design for it, be it maliciously or out of misunderstanding of the lang…
So was doing that in the original C code, but no-one noticed.
Re: Heartbleed in Rust
#56I mostly agree with the premise: logic errors are always going to be there, at least until the compiler is an IA strong enough to catch them for us (and by then we probably won't need coders anyway...). There's no silver bullet, bad coders are always going to produce. And I also don't like it when people claim that bug X or vulnerability Y wouldn't have happened if they had been technology Z, they're just begging for…
This raises some interesting philosophical questions: will the ultimate judge of correctness be a human or machine? If it's a machine, what is to say that its definition of "correct" is what humans want?
For some reason, this quote comes to mind: "Freedom is not worth having if it does not include the freedom to make mistakes."
Re: Heartbleed in Rust
#57Some people wrote a completly new TLS Stack in Ocaml to combat this problem: http://openmirage.org/blog/introducing-ocaml-tls Here a Video about Mirage OS and this TLS Stack from the 31C3. Trustworthy secure modular operating system engineering - http://media.ccc.de/browse/congress/2014/31c3_-_6443_-_en_-_... There goal is to reduce the trusted computing base to a minimal. Rust could deliver some of the same benefits…
I guess more than just me assumed Heartbleed was a typical blindly allocate and read, going past the buffer bound. But that's not what happened. Writing the same thing is totally possible in OCaml. And in a safe language with GC, it's not unheard of to reuse objects for performance. So in fact it's perhaps even somewhat probable to end up with a Heartbleed-like bug.
Re: Heartbleed in Rust
#58 // Rust
let len = buffer[0] as usize;
// C
size_t len = buffer[0];
I'm no Rust hacker, but can I expect the Rust type system to be able to encode some form of tainting? Making the leaky sequence illegal: let len = buffer[0] as usize;
// ERROR ERROR ERROR using unscrubbed user input ERROR ERROR ERROR
buffer[0 .. len]
How exactly to encode tainting is left as an exercise to the reader :) But ideally it should be able to identify that the buffer is reused between 2 different requests, and that data tainted from second request is used to index an array tainted with data from first request. This seems eery up Rust's alley, given the concurrency / allocation disambiguation support I've read (alas superficially) elsewhere.Re: Heartbleed in Rust
#59Slightly OT: while trying to understand the vulnerability I came across a Rust question. Why can you do this? let mut outfd = File::create(&outpath); match outfd.write_all(&buffer[0 .. len]) { ... } According to `old_io::File`'s doc[0] it returns an `IoResult ` which is an alias `type IoResult = Result ` i.e. `Result `. How come you can do `write_all` directly on a `Result ` without unwrapping the `File` first? The e…
The explanation is at http://doc.rust-lang.org/std/old_io/#error-handling : IoResult implements a bunch of IO traits so you don't need to unwrap it before using it: > Common traits are implemented for IoResult, e.g. impl Reader for IoResult , so that error values do not have to be 'unwrapped' before use.
Re: Heartbleed in Rust
#60Earlier quoted context omitted.
I feel like you're undervaluing memory safety. Memory safety prevents most (all?) exploits that lead to remote code execution. There can still be high level vulnerabilities, but guaranteed memory safety is a huge improvement. Rust's type system can be used to prevent high level attacks too. For instance, if an sql library is set up properly, it can prevent sql injection by requiring inputs be properly sanitized.
I value it very highly, otherwise, I wouldn't work on Rust. :) I'm just very careful to not suggest that memory safety is the end-all, be-all of errors. The Rust compiler will help you out, but it's certainly not perfect.