Earlier quoted context omitted.
The whole post is a giant blinking red sign that says (or should say) "Fuzzing is a horribly ineffective workaround for a treacherous language." No offense to the many bright and capable people who have worked hard on the C/C++ language, tools, compilers, libraries, kernels, etc over the years, but we will someday look back on it as asbestos and wonder why we kept at it for so damn long .
No issue with the first sentence of your message at all, but... > No offense to the many bright and capable people who have worked hard on the C/C++ language, tools, compilers, libraries, kernels, etc over the years, but we will someday look back on it as asbestos and wonder why we kept at it for so damn long. We won't wonder at all. We will understand that those people are the ONLY ones that stepped up to the task o…
This shouldn't have happened: A vulnerability postmortem
481–490 of 499 posts
Re: This shouldn't have happened: A vulnerability postmortem
#482Earlier quoted context omitted.
The Windows meta-API thing is done: https://lib.rs/windows We'll probably continue using C headers as a poor ABI definition format, even without writing programs in C. Sort-of like JSON used outside of JavaScript, or M4 known as autoconf syntax, rather than a standalone language. But C headers as an ABI definition format are overcomplicated and fragile (e.g. dependent on system headers, compiler-specific built-in def…
Not disagreeing about the issues of header files and the difficulty of consuming them from other languages (which was my point). But regarding ABI definitions, I suspect that introducing "thread-safety information, machine-readable memory management, explicit feature flags" will make interopability at the binary level difficult or impossible, which is even worse.
Re: This shouldn't have happened: A vulnerability postmortem
#483Earlier quoted context omitted.
The memory corruption would happen in the C code though. By the time that the program is actually affected by the memory error it could be much later, back in Rust code, and now you don't have any tools for debugging memory corruption because "that never happens in Rust".
The very first thing you would do is audit for 'unsafe' though.
On the other hand, something like Java via JNI wouldn't, because it copies the data to a different address space as it goes through the language boundary. Horribly inefficient, but at least the C code only causes security issues in the C regions. By the time it gets back into Java it either crashes or it's safe again, no undefined behaviour leaks through the API boundary.
Re: This shouldn't have happened: A vulnerability postmortem
#484Earlier quoted context omitted.
No issue with the first sentence of your message at all, but... > No offense to the many bright and capable people who have worked hard on the C/C++ language, tools, compilers, libraries, kernels, etc over the years, but we will someday look back on it as asbestos and wonder why we kept at it for so damn long. We won't wonder at all. We will understand that those people are the ONLY ones that stepped up to the task o…
I don't think this paints an accurate picture. This sort of presupposes that C/C++ were a first iteration, but that's not true. People chose C and C++ for bad reasons, even with historic context. Languages used to be more correct. Algol2 used to validate array subscribting and not have null etc. It was C programmers who pushed languages to be worse because it made it easier to write code. They very much created this…
Quite a bit of the original Unix's were written in assembler. There were good reasons for that - memory and CPU cycles were very scarce back then. I don't know if you have written assembler, but it takes about 5..10 times more lines of code than any high level language, and it isn't the nicest thing to read and isn't exactly portable between architectures.
C is an assembler without those problems, while retaining the speed. Admittedly t achieves that where Alogo60 didn't that by dropping minor things like bounds checking. But to give you a feel for the tradeoff, I could tell you what instructions the compiler would emit for most lines of C code. Best of luck doing that with an Alogo60 thunk.
C hit a sweet spot in other words and Algo60 didn't. C++ was originally called "C with classes". I was there at the time. The magic was Stroustrup's vtables, which gave C programmers OOP (which was all the rage at the time after Simula made it popular, and to be fair was a huge improvement on the abstractions C provided). It was that almost the same speed as C and to achieve it came with all the same disadvantages. But to Stroustrup's credit he did what he could - added stricter type checking (like function prototypes). It was an reasonable improvement. Many of Stroustrup's ideas were back ported to C, and C is a much better language for it.
Then Stroustrup added templates. In hindsight perhaps that's where the rot set in, but templates gave us zero cost abstractions that were at least as type safe as the original. It was an impressive achievement. But then there were hints of the darkness that was to fall upon us, with library after library using templates in novel very useful ways. Stdio was made typesafe. In so many ways.
C++ kept organically growing like that, into the nightmare it is today. I gather no C++ shop uses all of C++ now - all use some subset they can cope with. I lost interest ages ago, as did a lot of other people. They rebelled with against the complexity and lack of safety with things like Java. Microsoft rebelled against Java with C#. Those did solve the memory, type safety footguns and complexity of C++, but at the cost of the one thing about C that made it so attractive - low run time overhead and predictability.
In the mean time the ivory towers played with things like ML and Haskell, which with the benefit of hindsight was truly awesome work but unfortunately for those of us who work close to the metal are less practical than Java, C# and Javascript.
And then out of the swamp rose Rust, a language that has the speed of C and the type safety of ML and Haskell. Well sort of.
I still remember when I first read the Rust spec and thought they were kidding themselves - it promised so much and sounded so improbable it looked like a crypto ponzi scheme. Type inference,memory and thread saftey and no GC, what was this heresy? Then I dabbled, wrote a few Rust programs, fought the borrow checker until we make an accommodation, read the standard library and saw all those unsafes - and realised it was real. It was not perfect, but all those compromises to make it work is what reality looks like.
Where were we. Oh yes:
> Things could have been a lot better.
Things _are_ a lot better my friend. It just took us longer than expected to get there.
That wasn't because people made bad choices. They made a whole pile of small choices that solved their particular problem. It pains me to say this now, but after dealing with C++ for years anything would look good, and Java 1.0 did look very good to me. Admittedly it only looked good for a while, but I would never say the people who picked Java up at the time made a bad choice, just like I would never say the people who chose C over assembler made a bad choice.
Re: This shouldn't have happened: A vulnerability postmortem
#485Earlier quoted context omitted.
It's typical for very large C projects to have perhaps 2-5 dependencies that aren't libc, often something very basic such as zlib, curl or openssl. A rust CSV parser has 8 dependencies?
Three of those dependencies are not entirely unreasonable: one is the actual "core" CSV implementation (with one recursive dependency), one is the dependency for the standard "this interface allows you to serialize/deserialize arbitrary data to arbitrary formats", and one crate that adds traits to make &[u8]/Vec work much more like &str/String (which has 4 recursive dependencies, although two of those are already men…
I take your point that NIH is a large thing driving this sort of divergence in many languages, with some (such as Common Lisp, and C) being more notorious than others.
But I'd say it's just as common in other languages for programmers to pile on needless dependencies. E.g. how many Rust/Node.js/Java etc. projects are using some "standard library++" to e.g. get better memory behavior for strings, but for whom string allocation overhead is never ever going to be an issue?
It would be an interesting metric to check what % of the code in a given library is commonly used by its consumers across languages. Even if you only used 1% you're implicitly assuming some of the maintenance overhead for 100% of it. E.g. if it won't build on an older toolchain that's now a hassle for someone packaging your program, even if it's in the 99% you don't use.
Re: This shouldn't have happened: A vulnerability postmortem
#486Earlier quoted context omitted.
You need to read the list more carefully. • The list is not for Rust itself, but every program ever written in Rust. By itself it doesn't mean much, unless you compare prevalence of issues among Rust programs to prevalence of issues among C programs. Rust doesn't promise to be bug-free, but merely catch certain classes of bugs in programs that don't opt out of that. And it delivers: see how memory unsafety is rare co…
> The list is not for Rust itself, but every program ever written in Rust. This is, I think, obvious unless you are talking about C/C++ compiler bugs (which I am not). But if you think it that way, the same happens with C/C++! Besides compiler bugs, the published CVEs for C/C++ "are not for C/C++ itself, but every program ever written in C/C++". Still, potential severe vulnerabilities in Rust stdlib can happen too (…
A few bugs in std happened, but they're also mostly in edge-case situations that in C/C++ would be either straight-up UB or "you're bad for even trying this", like integer overflow, throwing an exception from a destructor, or implementing operator overloading that gives randomized results.
Re: This shouldn't have happened: A vulnerability postmortem
#487Earlier quoted context omitted.
> The list is not for Rust itself, but every program ever written in Rust. This is, I think, obvious unless you are talking about C/C++ compiler bugs (which I am not). But if you think it that way, the same happens with C/C++! Besides compiler bugs, the published CVEs for C/C++ "are not for C/C++ itself, but every program ever written in C/C++". Still, potential severe vulnerabilities in Rust stdlib can happen too (…
Mitre doesn't tag every program written in C with the C tag. A few bugs in std happened, but they're also mostly in edge-case situations that in C/C++ would be either straight-up UB or "you're bad for even trying this", like integer overflow, throwing an exception from a destructor, or implementing operator overloading that gives randomized results.
And yes, edge-cases are the worst. The only concern is that these vulnerabilities were introduced by people who know the language more than anyone (I'd like to think that patches mainlined into std are written, revised and maintained by the best Rust developers). I'm afraid to imagine what kind of vulnerabilities could a person like me introduce in my own Rust programs.
Re: This shouldn't have happened: A vulnerability postmortem
#488Earlier quoted context omitted.
How is memory safety not a compelling argument when we're literally in a thread about memory unsafety leading to security exploits?
> How is memory safety not a compelling argument when we're literally in a thread about memory unsafety leading to security exploits? The ratio of { memory-safety-bugs-in-code : bugs-in-code } is too small in many cases to warrant redoing the entire project. My last C (and C++) role: over the course of 3 years, a large C++ project had over 1000 bug reports closed, of which one turned out to be a memory safety issue t…
Also, you don’t have to rewrite your code base immediately, or at all: just build new parts in Rust or another compatible memory-safe language.
Re: This shouldn't have happened: A vulnerability postmortem
#489Earlier quoted context omitted.
Mitre doesn't tag every program written in C with the C tag. A few bugs in std happened, but they're also mostly in edge-case situations that in C/C++ would be either straight-up UB or "you're bad for even trying this", like integer overflow, throwing an exception from a destructor, or implementing operator overloading that gives randomized results.
It's not a tag but a keyword search. I don't know projects entirely written in Rust (other than single crates) to look for (by name). So probably there are more Rust-based vulnerabilities around than the ones from the Mitre query from the link. And yes, edge-cases are the worst. The only concern is that these vulnerabilities were introduced by people who know the language more than anyone (I'd like to think that patc…
Also keep in mind that std is in unusual position, because it provides the unsafe foundation for safe programs. For example, you as a Rust user can't cause any memory unsafety when using the String type, but std had to define it for you from unsafe primitives. This concept of building safe abstraction from unsafe primitives is similar to Python: CPython is written in an unsafe language, but this unsafety is hidden from Python programs.
Re: This shouldn't have happened: A vulnerability postmortem
#490Earlier quoted context omitted.
The very first thing you would do is audit for 'unsafe' though.
Assuming you ever encounter the issue, sure. But this bug was only triggered by long keys, which are outside of the normal operating paradigms. So your Rust code calling into a C API would have had exactly the same security vulnerability as C++. On the other hand, something like Java via JNI wouldn't, because it copies the data to a different address space as it goes through the language boundary. Horribly inefficien…