4 ms·
One of the better known buffer overruns (Heartbleed) was build on top of what boiled down to buffer reuse, which is common even in memory safe languages.
by josefx 4y ago
One of the better known buffer overruns (Heartbleed) was build on top of what boiled down to buffer reuse, which is common even in memory safe languages.
- tialaramex 4y agoThere's no obvious way to write the Heartbleed mistake in Safe Rust. In C it's really easy, a trivial mistake, you just don't check the payload length and copy blindly, but in Rust you can't write this mistake at all, so you'd need to re-architect the system to make it possible to leak this data or else (if you're not actively trying to leak data) you just don't do this and you can't be attacked this way. The closest analogue, Rust's [T].copy_from_slice wants a slice of the same size, so if we try to make the mistake OpenSSL made where we just forget to check, that means the slices are the wrong size and we panic, it's a Denial of Service but nothing more. If the slice is the right size that's a normal heartbeat, everything works as intended.
- uecker 4y agoIt is also really easy in C to have a safe abstraction for buffers that check payload length and does not copy blindly. Why so few people use such abstractions I do not know, but I guess once Rust is more widely deployed, we will also see a lot of unsafe Rust where people did not have enough time or energy to do things properly.
- tialaramex 4y ago> I guess once Rust is more widely deployed, we will also see a lot of unsafe Rust where people did not have enough time or energy to do things properly. This doesn't make a whole lot of sense. If you lack "time or energy" you're not going to put the extra work in to write unsafe code. In C this bug was much easier to write than the correct thing, whereas I explained in Rust the bug is much harder to write than the correct thing. Humans are lazy so they're going to tend to do the thing that's easier, and here (and in many cases) that's the more correct thing in Rust but not in C. This is just ergonomics. Notice how crash bars work on fire exits for example. Even people who are panicked and just running into the doors will trigger them to safely open outwards. You get incident reports where operators locked the fire doors, trapping people, or incidents where there are just too many people to evacuate despite the fire doors working for those who reached them, but you don't get incidents where people are like "Huh, I have no idea how to open this door, these crash bars are too difficult for me to understand".
- uecker 4y agoYou are right that one problem in C is that it is too inconvenient to do the right thing. A safe buffer abstraction should be included in the standard library. Still, I already saw bad Rust code using unsafe. I wonder how it came into existence when not by lazyness?
- josefx 4y agoI am far from a rust expert, but from a short look at stackoverflow copying between two slices of different sizes seems to be a for loop away and I saw no mention of unsafe. > so you'd need to re-architect the system to make it possible to leak this data or else (if you're not actively trying to leak data) OpenSSL called, your standard library sucks and it is going to provide its own significantly worse replacement for everything you can think of and at least ten things more. > you just don't do this and you can't be attacked this way. So it is a drop in C replacement.
- tialaramex 4y ago> I am far from a rust expert, but from a short look at stackoverflow copying between two slices of different sizes seems to be a for loop away and I saw no mention of unsafe. You can do this, but, what are you copying and why? The C code is just trying to copy the expected amount of data from the receive buffer into the send buffer. Under attack the receive buffer is actually nowhere near big enough to do that, but C doesn't care, which is why Heartbleed exists. You can't write that mistake in Rust, even if you insist on painstakingly writing it out as a for loop, if we have a 20 byte receive slice, and we ask for receive[1000] that'll panic To leak the data in Rust, you need to re-architect the software, you need to consciously plan for leaking the data in your software. "This code is to help us leak important secrets, and then this structure here enables the leaked data to be fed into data sent to an attacker".