Live data from Hacker News

Heartbleed in Rust

tedunangst.com

41–50 of 140 posts

Re: Heartbleed in Rust

#41
post #38
post #32

Earlier quoted context omitted.

An allocator like that would require unsafe code to write and could not expose a safe interface unless it couldn't be used to read uninitialized memory. `Vec::with_capacity` would still not let you read the data even if you had a custom allocator.

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.

I'd be interested to see an actual implementation of such an allocator in Rust that exposed a safe interface. You could do it in the specific case of chunks of predefined sizes, and maybe even for all byte arrays, but to allow arbitrary types in the allocator I do not think you could expose a safe interface without requiring initialization.

Again: I'm quite confident you could reproduce this specific vulnerability. You would just have to go out of your way to do it and the benefits of managing a free list yourself aren't really there (jemalloc is quite good at large allocations).

Re: Heartbleed in Rust

#42
post #14

I 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…

>I wonder what the author means by "Survey says no true C programmer

I think he is being sarcastic. I.e. the idea that "no true C programmer" would write code like that is nonsense, since we have all seen C code like that. Therefore the idea that "no true Rust programmer" would write the Rust snippet is not a valid defence, because bad programmers gonna program.

Re: Heartbleed in Rust

#43
post #38
post #32

Earlier quoted context omitted.

An allocator like that would require unsafe code to write and could not expose a safe interface unless it couldn't be used to read uninitialized memory. `Vec::with_capacity` would still not let you read the data even if you had a custom allocator.

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 language or a library construct.

The real question is how much harder Rust makes that which is often frustratingly trivial to sneak into C code.

Re: Heartbleed in Rust

#44
post #14

I 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…

>I wonder what the author means by "Survey says no true C programmer I think he is being sarcastic. I.e. the idea that "no true C programmer" would write code like that is nonsense, since we have all seen C code like that. Therefore the idea that "no true Rust programmer" would write the Rust snippet is not a valid defence, because bad programmers gonna program.

Yes. It's an instance of the No True Scotsman Fallacy.

https://en.wikipedia.org/wiki/No_true_Scotsman

Re: Heartbleed in Rust

#45
post #2

My take-away: Low-level code will burn you eventually, and unnecessarily low-level code will burn you unnecessarily

And I would add: A programming language that only allows low-level code only allows buggy code.

Re: Heartbleed in Rust

#46
post #39

"Code no true C programmer would write", eh? And yet one did, in a high-profile, security-critical library. When you find Rust code like this in the wild, I'll start to believe in some kind of equivalence.

I guess we're going to get into a "No True Scotsman" situation, but given the OpenSSL codebase, I don't think the OpenBSD folks regard them as "true C programmers". Rust is only being used by enthusiasts currently, so I'm sure we will see code like that once it gets into the general population.

Re: Heartbleed in Rust

#47
As the offending commentor, I apologize. Particularly to the Rust team for generating this negative publicity, and to the person I replied to, for asserting a lie.

I misunderstood Heartbleed, exactly as Ted summarizes. I've no excuse other than commenting when I shouldn't. I am happy though to have my idiocy corrected as I'll comment better in the future.

The rest of the original thread does point out that I did examine every security advisory published by Microsoft over a year or two span, and that, from the descriptions, Rust would have prevented basically every serious (code exec) one. (Notable exceptions being failures in the sandboxed code loading, similar to the various Java in browser bugs.)

Re: Heartbleed in Rust

#48
post #14

I 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…

Having not done much Rust due to the volatility, I still have to give it credit here for a few more reasons:

* I assume old_io is going away. That is why it is old, after all. Is this still possible in the new_io? If they made this not doable anymore that means they fixed the bug. * The compiler spat out a warning. Maybe it should have been "you dumb fuck why are you doing raw buffer reads and writes" but at least it said "old_io is bad". * I don't see much in the C version that would generate any warnings or errors under any compiler flags. That should be the take away, in my book.

When I do my own projects I almost always go for maximum warnings and errors, and don't call it done until the compiler stops generating them.

Re: Heartbleed in Rust

#49
post #36
post #30

Earlier quoted context omitted.

Is this logic error or just misuse of memory? (The buffer array)

The latter. It's trivial to reuse buffers in Rust while avoiding this issue, for example `Vec` has a `clear` method that sets the length to 0 while keeping the allocation. But AFAICT, in C it didn't even have the same buffer by design , it was reading uninitialized memory from whatever `malloc` gave it back - which is equivalent to allocating a new buffer in Rust.

It was actually using a custom allocator, not the system malloc, which exacerbated the problem. System malloc could still have this problem, but for example OpenBSD has mitigations for this sort of data leakage in their malloc implementation, which OpenSSL then bypassed by using their own allocator.

This is a problem for any "this would never happen in Better Language X" claim regarding Heartbleed. If you decide you want to write your own buffer reuse system for whatever reason, you can pretty easily write this sort of bug in any language.

Re: Heartbleed in Rust

#50
post #43
post #38

Earlier 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…

You would have to go out of your way to write your own custom allocator instead of just calling malloc and free, but that's what the OpenSSL folks did.
Post reply on HN