<Gets out his 'Memory Safe Languages Comment Thread Bingo Card' and a giant comedy marker>
<Opens popcorn>
<Waits>
The US Cybersecurity and Infrastructure Security Agency (CISA) and the National Security Agency (NSA) this week published guidance urging software developers to adopt memory-safe programming languages. "The importance of memory safety cannot be overstated," the inter-agency report [PDF] says. The importance of memory safety …
Dear Mr Shepilov
I note with regret that your absence for rest and recuperation during our glorious summer days here in St. Petersburg has not improved your output very much. Even the dumbest LLM our agency for research on the internet subscribes can do better than the following:
> Rust is not fit for purpose.
> These people are not fit for purpose.
> OneWeb is not fit for purpose.
If I did need to return Madam your mother's favors I would follow the advice of your colleagues Boris and Sasha and send you back to putting computer printouts in the recycling room, which is about as much affinity as you seem to have with both information technology and influencing.
Yours, Ilya Abramovich.
... is a good thing.
That said, I don't understand why so many people are maligning the C programming language simply because it is easy to make memory reference/pointer errors using it. C is just a high-level assembly language. Do people malign assembly language simply because it is easy to make memory reference/pointer errors using it? No, they do not. Assrmbly languages and C are not languages which can be effectively and safely wielded by just anybody. This may strike people as eliteism. Tough noogies; it's a fact. (For the record, I consider myself just nominally competent in those languages.) Thankfully, surgeons' scalpels are not banned just because babies can fatally cut themselves or others with them. We mitigate the risks by keeping the scalpels locked away from non-medical staff.
So, generally, we ought use something else. There are tons of choices. Forth? Ha-ha: if C is a scalpel, Forth is a double-ended vibro-shiv. The supposed-to-be-good-for-everything-under-the-sun, safe, committee-created, Department of Defence-mandated language, Ada? We have compilers for it, but do we yet have a clear and concise language definition for it? How about Java? It has garbage collection, yet still is not "safe". Lisp? Too visually-ugly. Rust? Even more visually-ugly. Python? A programmer will choke on the sheer massiveness of the package library (many of those packages flawed, some out-and-out malware), and will not enjoy rewriting their code when yet another take-me-where-the-wind-blows language redefinition breaks backward compatibility. Perl, or Tcl/Tk? Maybe, but AFAIK, there are no true compilers for them. Dot-Net-free, multi-OS, not-yet-created Visual BASIC v7?
I'm open to suggestions.
This post has been deleted by its author
" Ada? We have compilers for it, but do we yet have a clear and concise language definition for it?"
AdaCore's Ada subset SPARK would likely meet most of these criteria.
Bertrand Meyer's Eiffel uses garbage collection and I presume is also memory safe.
If the current farce that passes for the US administration pisses off the Europeans much more, the EU might mandate its use within its† borders. ;)
† that is Eiffel not the farcical US administration.
I think that comparing C to assembly language is very misleading. C is a high level programming language. There are a lot of low level things you can't do in C because the language simply doesn't have the concepts for them. If you have ever done any work with SIMD using compiler extensions you will have run into this quite a few times.
The reason that C and C++ get mentioned so many times in this sort of discussion is because they are the dominant languages which Rust is trying to replace, and let's face it, this is all about Rust. Anything that can be written in Java or Python is already being written in Java or Python for other reasons.
The real problem is that there is no clear path from A to B in all this, just hopes that everyone, everywhere will rewrite all their software, which is unlikely to happen. The realistic answer is to have something based closely on C and C++, as Rust is not even vaguely C-like.
Years ago the US government tried to get everyone to switch to Ada as that was supposed to address the then perceived issues with software bugs. That went along for a while, but eventually it faded out as it became apparent that the benefits of Ada were not outweighed by the cost of a complete break in compatibility with existing software bases and development systems. At the present time Rust looks like the new Ada.
I think that comparing C to assembly language is very misleading. C is a high level programming language.
I prefer to think of C as the universal assembler...
There are a lot of low level things you can't do in C because the language simply doesn't have the concepts for them.
True, but many C compilers support __asm or equivalent constructors if you want to get really dirty and intimate with your CPU. But the flip side is most other languages don't support that for various reasons, one being the lack of portability and the other being the even greater foot-shooting opportunity that it opens up.
Still, your point is very valid - if you can use python then its available, if you need to make use of existing code bases of which a tonne of code is in, or developer skills, the replacement of C/C++ with any other language is just not easy. More work on a safe-C/C++ mode for compilers and profiling tools would have been nice to see!
"C is a high level programming language."
You'll pardon my skepticism. Is a language where the integer size is a consequence of the underlying architecture really high level? Is a language with manual memory managmen really high level? Is a language with the most primitive native string handling really high level? Is a language with pointers as a key feature really high level?
Let's be serious. C is a higher level language than Assembler, but this is a very low bar.
Unless you're just trying to be provoative, in which case may I offer my congratulations.
We mitigate the risks by keeping the scalpels locked away from non-medical staff
Not so, anyone who can prove they are an adult can buy a scalpel. But the law says that no person may use a scalpel to cut into a human unless they are proven competent to do so, which requires many hoops of education, training and peer assessment.
My analogy is the bridge parapet. Most of us can walk in a straight line and cross a bridge, we have no need of a parapet. But you wouldn't build a major bridge without a parapet. If a person wanted to jump off the bridge, then a parapet wouldn't stop them, but it will help to prevent it happening by mistake. In the countryside there are little bridges without parapets, but usually the only consequences of falling off those is wet feet.
No, it is not - otherwise today noone would still use it - how many software is today written in hand-crafted assembly? A lot of CP/M and DOS applications were. As soon as it became not viable programmers switched to other languages.
And were is writtent that C should not evolve to tackle big issues that arose in the past 50 years?
Were is written, for example, that C should not have a managed "sting" type and MUST only use pointers to characters arrays? And one doesn't exclude the other. Just this change would kill a huge class of vulnerabilities. And for a lot of tasks, dabbling with pointers to characters is useless.
Sure, character arrays may have been all you needed when your "UI" were punched cards and teletypes, and most data to be processed were just numbers. That era is gone, long ago. As soon as software became truly interactive, and text processing became more and more complex, that model became utterly inadequate.
This mentality - "never change anything, never improve anything, because I do not want to learn anything new, and don't want to change the way I write code" - is what made IT an incredibile field for profits by criminals.
Let me once again educate you all on the differences between Systems Programming Languages and Application Programming Languages. The C language is originally a Systems Programming Language for developing operating systems and low-level code. Its lack of safety features isn't an oversight. It's by design!!!
The problem is that we're using Systems Programming Languages as Application Programming Languages and therefore inherit its lack of safety features found in modern Application Programming Languages like garbage collection and ownership.
Every time I hear about memory safety I think of all vulnerabilities I've seen from injection, abuse of features, forgetting to check authentication, logging passwords, incorrect data modeling, hard-coded salt, and disabling SSL fingerprinting because somebody thinks it's too hard. Sometimes they're from poor skills. Sometimes they're placed there intentionally.
There are certainly other classes of bug, but when credible sources? say that the vast majority of security vulnerabilities are due to memory safety issues, it's probably worth taking some time to address them.
It's progress. Without progress we'd all be knitting core rope memory, and that isn't very appealing to me.
Rust may not be the answer, but that doesn't mean it isn't worth asking the question.
Because the only thing you need is garbage collection to be entirely "memory safe". Ignore memory exhaustion by keeping old, uncollectable, references in some array you've forgotten you created.
Meanwhile, all those comparisons still pass without complaint from the interpreter, as it forces the variable types in peculiar ways; there are no complaints, but the code still does the opposite of what you think it does (because of the possibility of doing [https://jsfuck.com stuff like this] by accident).
that one in the corner said: Because the only thing you need is garbage collection to be entirely "memory safe".
Python uses reference counting as its primary memory management system, not garbage collection. There is a garbage collection system, but it runs only occasionally to deal with corner cases such as circular references.
So with Python there are in fact two different memory management systems which work together to cover different situations, not one.
This is the classic "we can fix all the existing problems by throwing out everything we have and starting over again from scratch" syndrome. It sounds nice in theory, but it doesn't address the real problem.
The real problem is that we have a huge base of existing software that we would like to improve. Saying "re-write all your software" simply means putting the whole question off until some time in the indefinite future, as rewriting of stuff that works is going to happen very slowly, if at all, except for things which are small enough to be someone's hobbyist project.
Things that can be written in languages like Java are already being written in those languages, mainly for reasons other than "memory safety". That whole area is a red herring.
The real problem is mainly at the "infrastructure" level of things like operating systems, databases, web browers, GUIs, and things like that. These also tend to be things that have been around for several decades and will still be around several decades from now in more or less their current form. Re-writing these from scratch isn't a realistic option if the real goal is to improve security.
The realistic approach is to develop something which is mostly backwards compatible with C and C++ and goes forward from there. Memory "unsafe" features could be gradually deprecated, giving people time to re-write just those specific bits of their programs that need re-writing.
This is a good example of an area where "worse is better". A 90% solution today is better than a 100% solution 20 years from now.
I have learned probably a couple of dozen languages well enough over the years to write useful software in them. Personally, I'm not a fan of C or C++. However, I use them because they are the tools that I need to use to work with existing software.
Picking a language is a purely pragmatic solution for me, and I value results over theoretical purity. What I would like to see is an 80 or 90 percent solution that will produce results today rather than a 100 percent solution that may, possibly, produce results years from now if somehow enough resources can be freed up to make use of it.
The suggested approach to Rust is not to do a "big bang" rewrite of your big software. That's doomed to failure, for any large software.
Instead, the approach people are trying to take is to let people use Rust for writing new features. Then port some existing code to Rust. Then gradually repeat until all code is Rust.
For example, the aim with the Linux kernel was to first allow writing new drivers in Rust. That would allow the kernel folks to get some experience with Rust, and to prove whether or not Rust works well in the kernel. If successful, then, over time, more code could have been moved to Rust, until eventually the majority of the kernel was written in Rust. This would have taken years, possibly decades. However, there has been significant pushback to that plan, so I'm not sure if it's going to happen.
Another example is some of the basic Linux command-line applications. Since each app is so small, it can be rewritten in Rust. Over time, more of the essential Linux userspace apps can be made available in Rust versions.
As an alternative, there is some work being done on a memory-safe subset of C++. That may work better for some people. However, it's still a work in progress. (I say "subset", but the idea is actually to first extend C++ with a few small features, and then define a subset of that which is memory-safe. And standardise both the C++ extensions, and the subset, in future versions of the C++ standard. The extensions would be available to all C++ code, so the memory-safe subset would be a true subset of normal C++).
> For example, the aim with the Linux kernel
Not every software is as modular as the Linux kernel.
> However, there has been significant pushback to that plan
Yes, and part of that pushback has to do with the exact problems outlined in the above post. Writing NEW stuff in another language is cool and exciting. Rewriting old stuff, or changing old stuff to accommodate the new stuff, is hard, tediuos, risky work. But someone would need to do that, or the new stuff won't happen either. And someone will need to maintain that limbo-state in the old stuff, until the transition is complete. Which is a tall order, when the deadline for that happening might be: Never.
Nit-pick: C++ has had a memory-safe subset since day one. The various projects alluded to in the article concern ways of statically enforcing the use of that subset.
The main reason that most real projects go outside that subset is that the interface to the OS is not memory-safe. This is because that interface is a C interface and C++ can use that interface directly.
With most other languages, that's hard-to-impossible so someone actually bothers to wrap a usefully large chunk of the OS interface for the new language.
The same problem also applies to many domain-specific libraries. The "official" interface is a C interface and a binding for your favourite language is your problem. Python's utterly massive collection of libraries is actually a huge feature in this respect. It represents a massive amount of work by many people and yet it is just there for the average Pythonista. In comparison, most other memory-safe languages have a fuckton of catching up to do before they are serious options for writing non-trivial apps.
THANK YOU!
Software isn't gonna be rewritten, not on a large scale at least, and most certainly not at the infrastructure level. Some new stuff might get built in Rust or another memory-safe language. But not at scale, and not the core pieces of our software ecosystems. That's a fact, and the sooner people realize that, the sooner we can move on from this endless discussion.
Something else: Even IF we could rewrite every browser, database, os, driver, network equipment firmware, etc. we would not make things "safer" ... quite the opposite in fact. We may fix memory safety issues, sure. But something people tend to forget, is that these decades old codebases also contain endless fixes for logic errors, security loopholes that have nothing do with memory safety, authentication mishaps, patching problems, and so on and so forth. If we rewrite all that from scratch, what do we get? Bingo!; codebases that will also rediscover many many many of these errors that we already fixed! And it would again take decades to get them to the point our existing software is at now.
"When someone builds a bridge, he uses engineers who have been certified as knowing what they are doing. Yet when someone builds you a software program, he has no similar certification, even though your safety may be just as dependent upon that software working as it is upon the bridge supporting your weight."
...and, just as importantly, if not more so...
"There are no standards for computer programmers and no group to certify them."
---David L. Parnas
Businesses will "take that risk" (and frantically deny, deflect, and avoid responsibility for the consequences) of having poorly-trained, and even incompetent programmers producing software for them and their customers, because businesses do not want to pay more money for software.
Establishing a P E. program for computer professionals would sharply reduce the number of new "qualified" pros entering the workforce, and drive up salaries. Many businesses oppose this.
"Well there is the BCS, which can award Chartered Engineer status..."
'BCS', whoever they are, will award you anything you're willing to pay for; you can probably get them to change the names of the "awards" / "certifications" to any title whatever which you may desire, and one which you think sounds better than their 'off-the rack' "certifications"(!). Simply read their glitzy website.
...Seems that you don't understand that David Parnas, in his famous quotes about software 'engineers' / coders (a much better job description) was absolutely referring to credible certifying organizations / bodies which do not have an agenda.