A reactionary take on memory safety
lcamtuf.substack.com
lcamtuf.substack.com
Albeit modulated since I'm sure lcamtuf is not actively advocating for memory unsafety the way I'm sure some people are.
But I don't understand why anyone is bothering to state any objections to memory safety. Modulo the issue of old code bases in memory unsafe languages that can not be simply discarded or rewritten... I personally have done translation projects between languages, I am well aware of the costs involved and freely acknowledge them... there simply isn't any argument in favor of memory unsafety. There's no benefit to having memory unsafety around. If anything memory safety is a positive benefit, or to put it another way, programming in a memory unsafe language is positively harder than a memory safe language.
The proof of this is the existence of the "unsafe" package/module/library/whatever that exists in your language, meaning that you can selectively call out to it whenever you do in fact need to. That means the rest of the time you don't.
So why give any cover to memory unsafe languages? There's simply no argument for them. You do not need a language that lets you access outside of array bounds. You do not need a language that lets you run a pointer everywhere without regard for bounds. Even if you need bounds check removed or something, you only need it in a particular tight loop, not pervasively throughout your language. There is nothing, no positive advantage they offer that overcomes the overwhelming, massive costs they've concretely imposed on society as a whole.
And I'm Mr. Everything Has Costs And Benefits. But the benefits are so, so wispy here and the costs so large and concrete.
Yes, use memory-safe languages for new projects. But don’t lie to yourself and everyone else and say that they will come anywhere close to making a significant dent in the rate of security bugs.
Hard to count, but, excluding webapps, maybe 98% (or more) of generally used software has a basis in c/c++. Your fridge, watch, computer, car, phone. clang, gcc, photoshop, your browser, almost any desktop app, your 3d games. The remaining 2% (or less), is maybe even majority written in assembly, forth, etc, in your calculator and toaster
So to agree with you, I would need an explanation of why such wispy benefits led to such a large effect
Oberon existed, pascal, ada, they are excellent and safe, why then were they not popular?
Note: Easy to disagree with that percentage, but the effect is enormous, and as far as I understand, not explained by the current bandwagon
So C and C++ won out as the systems languages. Not because of quality, but price and politics.
EDIT: I mean Unix broadly, there were obviously non-free commercial Unixes.
Moreover, C and C++ are the world we live in in which CVEs flow like water, where our systems crash routinely, where we have the problems that are making us have this discussion in the first place.
If you think this is all just fantastic, that there isn't any option of doing better, we just have to live with the effects of memory unsafety, and there's no point even trying to improve the quality of our base level tools, then honestly all I can say to such a battered spouse syndrome sufferer is that we're going to have to agree to disagree.
Note that c/c++ can be made safe, for instance tcc adds runtime bounds checking. Memory could simply be runtime checked. Problem solved
You make a good point as to why we don't. Ada has done exceptionally well at doing what you ask for a very long time. It is not hard. But we don't
Hubris is maybe the right reply
People deliver code without full line and fuzz tests: probability of code being correct; low-to-zero. This is independent of 'seems to work' c/c++ memory safety. It suggests the problem is deeper
We just assume we're safe and correct, and know best; and then live as battered spouses of our own hubris
Alternative POV: we allow sharp knives in kitchens. Kitchens are unsafe as a result. It is maybe unavoidable. Road safety causes more deaths than code safety. We allow it. A lack of safety is inherent in any complex system
Spark, Coq, provers are great. But unbounded systems quickly become unprovable. Unbounded memory allocation is one of those -- whether 'safe' or not
I think this is a major reason missing from the debate. Safety hinders and complete safety is completely impossible
However the truth probably lies somewhere in the middle
Since you are right: computers are fast enough that even 3d games could often have memory safety
In conclusion
The current memory safe languages remove more from the table than I think you expect; and that is why I would suggest most important software has been written in 'unsafe' languages
For instance, servo arguably demonstrates that. A surprizingly small amount of firefox has been replaced by rust, and not due to lack of effort
But also we simply don't care about correctness enough to get closer to it. So I would say it is good you ask for that
But too often, to me, the debate looks like we swap one blindness for another
The article also rides on the contempt for PHP to make migration from C/C++ sound stupid, but PHP is not a real contender for systems programming, and isn’t on the list of recommended memory safe languages. It’s a “but what about all the other bugs”, as if having memory unsafety bugs somehow prevented all other kinds of bugs. It plays on the trope that real programmers use C++, and won't write bugs like the amateurs using blub languages.
The memo recognizes that CVE counting is problematic and calls for research into better vulnerability tracking and evaluation to get a better picture of actual risks, and address overall quality issues, not just memory safety.
Maybe not outlaw, but I think in the long term the outcome will be similar. Memory unsafe? No government contract for you! Credit cards details leaked? Well not being memory safe was negligent, no insurance payout for you.
I think eventually all criticial infrastructure (including their dependencies, including libraries but also OS) will be be basically required to be memory safe.
Ring 0 may get smaller and smaller but it’s still there.
That's exactly what the GP pointed that isn't on the memo.
But if you insist on using unsafe languages, and not using any of the tools and procedures available for making those safer, then yes, no contract money for you, and no insurance if something happens.
Currently people are making very pragmatic changes that doesn't require an impossible retooling of the entire area. The direction is clearly against carefree software, but nobody seems to be moving any fast on that way.
We don't even know if people will hold that direction on the long term. This is not the first pro-security cultural change that happened in computing, and it's not even touching the fact that the computers themselves are not secure.
Does anyone in 2024 still want to make a greenfield C++ project? I don't. Nothing really to do with memory safety, it's mainly just tooling.
I also think the build system and dependency management could probably use at least as much attention as memory safety, though maybe there's some convention that's emerged lately which brings it in line with more recent languages.
Thinking about this example, it seems like the other problem is that even when bounds-checked, C++ code handles out-of-bounds conditions by throwing exceptions, which seem to have a bad rap in C++.
I think it's very difficult to do the same with plain C. It's probably possible to make it less painful with macros, but doing so builds something more like a DSL atop of C, and would frustrate IDEs that don't understand the conventions.
In practical terms, no, it cannot. Even C codebases held to very high standards tend to have memory-safety issues.
> memory safe languages can be written in C
That says nothing about the safety of the C language.
Anyone who's read more than a few write ups of exploit chains wouldn't post something this ignorant. I'm not sure how to interpret this whole post in good faith unless it's satire.
Just go read some posts off project zero.
He has taken to posting mildly trollish stuff ("poasting") on Xitter, but this seems like a well reasoned reply to "Is rewriting entire codebases in a different language worth it?"
Unfortunately, for whatever reasons, large bureaucracies seem to have decided that, after doing the same thing to network engineering and systems administration, computer security is just a dump profession in which you put slightly dim people who are only good at repeating mantras.
For every pen tester or true security expert who breaks things for fun in their spare time, I've run into far too many more of the "just make the vulnerability scanner turn green" type. It's quite unfair actually that they get lumped together.
Some subset of the industry having "bad opinions" also does not mean their work suddenly has no value or they're not trying hard. To me this approach to the hard work of real experts is immediately disqualifying for someone's opinions. They can think it, but if they want to say it they should be prepared to not be taken seriously.
Ignore efficiency and all that. If you don't support `union` and `va_list`, you're never going to replace C. It's okay to mark them as deprecated, but you need to support them to provide a migration path.
The fact that C allows hand-written `memcpy`-style loops is another major concern in theory, but it is one that is much easier to port. Laundering pointers through non-process memory is rare enough that an explicit API is reasonable to require.
And yes, it is possible to support all these things with perfect dynamic memory safety and without increasing pointer size!
You had me up to this point. A memory-safe union is a discriminated union, which needs extra information (a discriminator) to tell which case is currently active. That doesn't necessarily increase pointer size, but it does break ABI compatibility.
Kind of like how ASAN works, but with typing info instead of just validity info.
Now yes, for performance you don't want to do this ... but it can be just one step of the migration.
The same cannot be said for varargs, though.
Yes, it is possible to refactor things like `SDL_Event` to use subclasses instead of unions. But the point is - you shouldn't have to, not at first. And of course, you need to be able to use a union to perform a bitwise cast between float and int. Not some other ad-hoc API; it needs to be trivial to port from C regardless of what the context looks like.
I'm also not sure why it's necessary to use a union for bitwise conversions. Java and Go, off the top of my head, have safe functions for bitwise int<->float (int32<->float32 in Go) and long<->double (int64<->float64 in Go). Moreover, if I remember correctly, you are only actually allowed to use one case at a time in a C union. If I'm right, then using a union to do bitwise casts is actually undefined behavior in C, even if it almost always works. Put simpler, you cannot write one type into a union then read a different type; you must always read the last type that was written.
edit: I dug up my copy of K&R 2/e and yeah, unions are not meant to be used for things like casts. Some supporting text:
> A union is a variable that may hold (at different times) objects of different types and sizes, .... (Sec 6.8, p. 147)
> Any one of these types may be assigned to u and then used in expressions, so long as the usage is consistent: the type retrieved must be the type most recently stored. It is the programmer's responsibility to keep track of which type is currently stored in a union; the results are implementation-dependent if something is stored as one type and extracted as another. (Sec 6.8, pp. 147-148)
In the case of SDL_Event, there actually is a discriminator of sorts. Every case of the union starts with `Uint32 type` and I don't think any case breaks 4-byte alignment on most platforms. With a little compiler support, it would probably be possible to support SDL_Event variables directly in a memory-safe language.
C would be safer if it had memory safe casts.
C would be safer if we forced compilers to implement Walter Brights suggestion about array arguments.
C would be better if it had stdslice.h
Programs would be safer if the cultural prohibition against passing and returning structs was exterminated.
The lack of a single, dominant, consistently high-quality C compiler likely caused this problem. As long as `int foo(struct{int x; int y})` doesn't optimize down to `int foo(int x, int y)` there are significant performance issues with struct passing. The return situation is especially problematic since C doesn't have multiple-valued return to begin with, so structs become a special case.
I guess GCC attributes could do that too, but I don't think they have.
There is a reason vulnerabilities come with Vulnerability Scores and Risk Assessment.
Memory based attacks just aren't a relevant enough vector compared to other lower hanging fruit like misconfigurations or lax resource governance.
This isn't to say memory attacks aren't a vector (they absolutely are), but deciding which vector is higher priority is heavily organization dependent.
Also, the Shirky's Principle is pop business "knowledge" like the "Conjoined Triangles of Success" or the "Hype Cycle".
Memory safety is where it is because of misquotes and misinterpretations.
Here are the incorrect quotes:
"70% of all security vulnerabilities were caused by memory safety issues" https://en.wikipedia.org/wiki/Memory_safety In 2019, a Microsoft security engineer reported that 70% of all security vulnerabilities were caused by memory safety issues. In 2020, a team at Google similarly reported that 70% of all "severe security bugs" in Chromium were caused by memory safety problems.
"Microsoft: 70 percent of all security bugs are memory safety issues " https://www.zdnet.com/article/microsoft-70-percent-of-all-se...
The actual quote from Matt Miller is this (quoted from the SAME article that has a false headline above) https://www.zdnet.com/article/microsoft-70-percent-of-all-se...
"Microsoft security engineer Matt Miller said that over the last 12 years, around 70 percent of all Microsoft patches were fixes for memory safety bugs."
So it is FALSE that "70% of all security vulnerabilities were caused by memory safety issues".
What Matt Miller said is that "70% of all Microsoft patches were fixes for memory safety bugs" - that is VERY different.
As a result, the fiction that "70% of all security vulnerabilities were caused by memory safety issues" has become real to many people thus they are focusing their security effort on memory safety when that is not even the primary security issue and certainly not 70% of all security issues.
It’s actually quite easy to find a primary source here because the slides from the talk that the article is based on are available: https://github.com/microsoft/MSRC-Security-Research/blob/mas...
To quote from those slides: „~70% of the vulnerabilities addressed through a security update each year continue to be memory safety issues“.
It directly attributes Matt Miller.
And the point is that this percentage quoted is the flaws in Microsoft products, not all security vulnerabilities as is falsely claimed.
Don't get me wrong, memory safety is a vector, but can be remediated against with stronger platform architecture (eg. Network Access Control, Identity Management, Asset Governance), which is where most companies stumble.
Having a memory safe application doesn't matter if you didn't properly segment your environment so a misconfigured IoT had open external and internal access.
[0] not really but scope is contained.