6 ms·
To my knowledge, no one in the Rust or greater memory-safe programming language community would claim: Using <$LANG> prevents leakage of secrets! When put lik
by saidajigumi 12y ago
To my knowledge, no one in the Rust or greater memory-safe programming language community would claim:
Using <$LANG> prevents leakage of secrets!
When put like that, it sounds like a straw-man argument. In my own words, the narrower and stronger claim being made is that the specific and important avenue by which Heartbleed leaked secrets is not possible without unsafe code in Rust.
So if you're going to claim that Ted "isn't wrong", but on terms that no one was originally arguing... I don't even know what to say.
- wglb 12y agoSo if you're going to claim that Ted "isn't wrong", but on terms that no one was originally arguing... Perhaps I am taking a more general implication of this than "Rust would not have exactly reproduced the Heartbleed problem". I infer the overall meaning of Ted's argument, and the general discussion that "Memory safe languages do not prevent information leakage". To me that is what the argument is about.
- danudey 12y agoNothing 'prevents' information leakage other than writing perfect code 100% of the time. If the argument is that you can write a program in Rust that tells someone something they shouldn't know… is that… what's even the argument here? Is that even a question? But in that case, comparing against Heartbleed is pointless. Why not ask about SQL injection attacks? Or directory traversal attacks? Or OS privilege escalation attacks? Or listening on a port that isn't correctly firewalled? Rust won't prevent any of those either, because none of them have anything to do with the language being used. Arguing that it's possible to write code that does the wrong thing is so pointless that I can't understand why this article was written other than as some kind of half-assed hatchet job.
- lmm 12y agoI would claim that using Scala (and presumably Haskell) gives you the tools to make it impossible to leak secrets, if you want to. You could use a path-dependent container type to ensure that content was associated with a particular connection and never passed off to a different connection; if you tried to do something like reusing a buffer, it would be a compile failure. There would be costs to this - both in runtime performance (presumably you wanted to reuse buffers for a reason) and in program complexity. And of course it's possible to make an error in your type definitions (though you have to make two errors to be exploitable - one in the types and one in the values - and the types are shorter and much easier to audit than the full program code). But it absolutely is possible, and I think that pretty soon we'll reach the point where it becomes worthwhile for security-critical code.
- steveklabnik 12y agoYeah but even Haskell (and I'm assuming Scala has something similar) has unsafePerformIO...
- codygman 12y agoBut there is a compiler flag -XSafe which could guarantee none of your code uses it, meaning GP's answer could be yes.
- steveklabnik 12y agoWe have that switch in Rust as well.
- olavk 12y agoAs far as I understand, unsafePerformIO is not unsafe in relation to memory safety issues. It is just unsafe in that it circumvents the IO monad, which means order of execution is not guaranteed.
- steveklabnik 12y agoIt's a different kind of unsafe, but my point is that it violates the normal guarantees of the language.
- dbaupp 12y agoThe Haskell 2010 standard includes Foreign.Ptr which allows direct, unsafe manipulation of memory: https://www.haskell.org/onlinereport/haskell2010/haskellch35.html https://www.haskell.org/onlinereport/haskell2010/haskellch35...
- mzs 12y agoDisabled swap? Disabled coredumps? Used the right madvise-a-like for each OS?
- tedunangst 12y agoIf you really wanted, you could do this in C with a fork+exec. FWIW, sshd does do this, for a couple reasons.
- deleted 12y ago[deleted]
- tedunangst 12y ago> specific and important avenue by which Heartbleed leaked secrets is not possible without unsafe code in Rust. Alright. Please clarify. What is the specific and important avenue by which Heartbleed leaked secrets?
- TheDong 12y agoBy allowing an attacker to read arbitrary memory of the process that linked against the library In rust, if I write code where I store my secrets in two variables which I pass into my ssl constructor, but retain single ownership of (such that the ssl library may not retain references to them after the constructor exits), there is no way for those exact memory addresses to be read and returned via that library, excepting unsafe. If you say "ah, but the constructor could take a copy and leak that", then that's a different class of vulnerability. It could, but then it would be leaking its memory, not mine.
- tedunangst 12y agoAre we now redefining plaintext passwords and cookies as "not secret"? OpenSSL stored them in the same variable as heartbeat payloads.
- TheDong 12y agoless secret than tls keys, yes. However, that completely does not relate to your question. I'm not saying that they both aren't security vulns, they both are. You asked how heartbleed leaked secrets (implicitly how it was different from the rust code), and I told you how it differs. Where the secrets are stored is different. One is user-supplied secrets only, the other is arbitrary secrets within the process, user-supplied or otherwise. Yes this is different. Your response here is simply moving the goalposts.
- tedunangst 12y agoTo move the goalposts back to position, I'll answer my own question. The specific and important avenue by which Heartbleed leaked secrets was reusing secret containing buffers and miscalculating the initialized length.
- MichaelGG 12y agoMy original comment said that even with a custom allocator, Rust would refuse to compile code that could lead to Heartbleed. This was technically not accurate. (I thought HB was just out of bounds+uninitialized behavior.) I think the real key is that in C, this leak can happen with just malloc+forgetting a memset, no explicit buffer reuse required. Whereas in Rust, you'd need to explicitly reuse the buffer.
- tedunangst 12y agoThe not compiling part was really what piqued my interest. :)
- MichaelGG 12y agoTo be fair, the equivalent of malloc(x) plus a read of x+n bytes wouldn't compile, even with a custom allocator.
- camgunz 12y agoI know next to nothing about rust, but can't you do pretty much whatever you want when you implement a custom allocator? Including allocate a giant buffer ahead of time and reuse stuff with no safety whatsoever?
- MichaelGG 12y agoI'm not sure custom allocators exist. But assuming they did, sure you can. But in that case you're explicitly opting into unsafe code to use uninitialized memory. And, even if you did have such an allocator, you still can't read past the end of the allocation. So if you ask for a 16 byte buffer and attempt to read 17, it'll fail.