4 ms·
What went wrong - Issue #0: The library was not re-written in a language that prevents undefined behavior (UB).
by mleonhard 5y ago
What went wrong - Issue #0: The library was not re-written in a language that prevents undefined behavior (UB).
- tialaramex 5y agoI don't think there are any general purpose programming languages with decent performance which outright "prevent undefined behaviour" in something like NSS. Rust, for example, does not. safe Rust doesn't have undefined behaviour but of course you can (and a large project like this will) use unsafe Rust and then you need the same precautions for that code. This sharply reduces your exposure if you're doing a decent job - and is therefore worthwhile but it is not a silver bullet. Outright preventing undefined behaviour is hard. Java outlaws it, but probably not successfully (I believe it's a bug if your Java VM exhibits undefined behaviour, but you may find that unless it was trivial to exploit it goes in the pile of known bugs and nobody is jumping up and down to fix it). Go explains in its deeper documentation that concurrent Go is unsafe (this is one of the places where Rust is safer, safe Rust is still safe concurrently). Something like WUFFS prevents undefined behaviour and has excellent performance but it has a deliberately limited domain rather than being a general purpose language. Perhaps a language like WUFFS should exist for much of the work NSS does. But Rust does exist, it was created at Mozilla where NSS lives, and NSS wasn't rewritten in Rust so why should we expect it to be rewritten in this hypothetical Wrangling Untrusted Cryptographic Data Safely language?
- mleonhard 5y ago> I don't think there are any general purpose programming languages with decent performance which outright "prevent undefined behaviour" in something like NSS. Rust, for example, does not. You know what I meant by "a language that prevents UB". Your comment argues semantics. That's not nice. Please stop. > safe Rust doesn't have undefined behaviour but of course you can (and a large project like this will) use unsafe Rust and then you need the same precautions for that code. How can that can be true? A large Rust project uses unsafe only because its authors don't care enough. Instead of spending the effort to make the safe code fast enough, they resort to using `unsafe`. It's the same reason that people add code without tests or add APIs without docs. A special purpose language for writing cryptography code is a terrible idea. Once we have a language suitable for handling untrusted data, we should make it good enough to use for everything and then use it for everything. I have put some effort into making safe Rust usable for everything. I wrote a safe regex library [0] and a safe async library [1]. I plan to put more effort into these and other libraries. For example, I am working on safe Rust TLS and HTTP libraries. Eventually, safe Rust will be production quality and fast enough for most use-cases. [0] https://crates.io/crates/safe-regex https://crates.io/crates/safe-regex [1] https://crates.io/crates/safina https://crates.io/crates/safina
- burntsushi 5y ago> A large Rust project uses unsafe only because its authors don't care enough. This is not true. That might account for some aspects of why there are some uses of 'unsafe', but it is not true of all uses of 'unsafe'. The existence of 'unsafe' is itself the clearest demonstration of why you're wrong on this point. Its existence is a practical trade off that acknowledges it is sometimes necessary to use 'unsafe' to accomplish some goal, and that there is a long tail of such uses. Too long to feasibly build and enumerate every such case into the language. The goals might be rooted in functionality or performance or possibly other things.
- dralley 5y ago> A large Rust project uses unsafe only because its authors don't care enough. This is not true at all. There are plenty of reasons to occasionally use unsafe code, even if your bar for "is it really worth it" is quite high. One reason, if you're writing a crypto library, is that certain kinds of timing attacks are pretty much impossible to prevent without inline assembly.
- mleonhard 5y agoPreventing timing leaks requires unsafe code because the Rust compiler lacks support for constant-runtime code [0]. Adding that support is one step in making it "good enough to use for everything". What are several more of the "plenty of reasons to occasionally use unsafe code"? I can think of only one: interfacing with hardware or unsafe OSes that control access to the hardware. [0] https://github.com/rust-lang/rfcs/issues/2533 https://github.com/rust-lang/rfcs/issues/2533
- varajelle 5y ago> safe Rust doesn't have undefined behaviour but of course you can (and a large project like this will) use unsafe Rust and then you need the same precautions for that code. It's the difference between crossing a minefield with 1000 hidden mines that blow off if you happen to step on them, or a clean field with a single hole with a big warning sign next to it. Sure, none prevent you from injuries crossing it, but don't tell me it's the same risk