back to article CISA looked at C/C++ projects and found a lot of C/C++ code. Wanna redo any of it in Rust?

The US government's Cybersecurity and Infrastructure Security Agency (CISA) has analyzed 172 critical open source projects and found that more than half contain code written in languages like C and C++ that are not naturally memory safe. What's more, projects written in memory-safe languages may still be exposed to memory …

  1. Dostoevsky Bronze badge

    The Rust Evangelism Strike Force...

    ...endorses this post.

    Joking aside, this was a reasoned take, IMO. The quote at the end is a good reminder that non-memory-safe, legacy languages are not going away. Compare all the COBOL that w̶a̶s̶ ̶r̶e̶t̶i̶r̶e̶d̶ is still running in production.

    Also not sure whether LLVM, GCC, and OpenJDK are places where memory safety is a huge issue... I can see concerns about the JVM, but how can a buggy compiler hurt me? Have there been examples of memory safety issues in these projects that enabled a cyberattack?

    1. Paul Crawford Silver badge

      Re: The Rust Evangelism Strike Force...

      a good reminder that non-memory-safe, legacy languages are not going away

      Very much so! While it might have been better not to have written some projects in low-level languages, they exist and re-writing is a massive undertaking that may well introduce other logic bugs. Better use of development effort would be tools and actually using them to fix some of the critical existing code out there.

    2. teknopaul

      Re: The Rust Evangelism Strike Force...

      If compiling has an atackable bug GitHub probably has a risk because they run lots of compile jobs nowadays.

      Any dsl that needs a compiler might be at risk.

    3. Blazde Silver badge

      Re: The Rust Evangelism Strike Force...

      Also not sure whether LLVM, GCC, and OpenJDK are places where memory safety is a huge issue... I can see concerns about the JVM, but how can a buggy compiler hurt me? Have there been examples of memory safety issues in these projects that enabled a cyberattack?

      It depends what you mean by buggy compiler. There're numerous cases of runtime systems having memory safety bugs, and then you get vulnerabilities in your binaries. Arguably that's not the compiler itself, but it's bad news. Years ago MSVC used to make exception handling exploitable in many cases where an attacker could cause a stack overflow, and that ended up in innumerable binaries. I don't know the exact source but that may have been a bit closer to a being a pure compiler bug.

      Sandboxing compilers is pretty common now, as mentioned a above.

      And lastly if someone wanted to backdoor a compiler (in order to backdoor binaries it created) then it's a bit easier to obfuscate it if they have subtle memory un-safety at their disposal.

    4. Phil O'Sophical Silver badge

      Re: The Rust Evangelism Strike Force...

      how can a buggy compiler hurt me?

      Ever read Ken Thompson's Reflections on Trusting Trust?

      1. jake Silver badge

        Re: The Rust Evangelism Strike Force...

        ken's hypothetical compiler didn't have a bug.

        It had a feature.

        Mine might have undocumented compiler flags ...

    5. bazza Silver badge

      Re: The Rust Evangelism Strike Force...

      If a compiler isn’t conforming to the language specification exactly then the code you end up running isn’t the code you thought it would be, given your source code.

      This isn’t terribly uncommon. GCC doesn’t necessarily conform to ANSI C/C++. And in the early days it wouldn’t necessarily stick to its own language specification. Since then GCC has been carefully looked at and is generally considered to do what its docs says it does.

      An interesting C/C++ compiler is the Greenhills compiler. This was the first “properly” written compiler and library, in that there was formal documentation for the code design and test. Back in the 1990s you used it for code that mattered, and is still in use today. The key thing is that the library code is equally formally developed, so printf really does do what the spec says it does.

      In my time I’ve seen some terrible standard library implementations for C/C++, often costing money. These are often overlooked by people auditing code.

      1. Anonymous Coward
        Anonymous Coward

        Re: The Rust Evangelism Strike Force...

        And the Greenhills compilers had their fair share of faults - including silent faulty target code (correct source code compiled to incorrect target code). They did publish "known errors" - which is good - but sometimes were not as helpful as I would have liked.

        However, I don't think the compilation errors were caused by memory-safety errors in the compiler source (no evidence, just my feeling based on how the compiler screwed up and how the problem was reported in the known errors list).

      2. ZX8301

        Re: The Rust Evangelism Strike Force...

        My last encounter with the Green Hills compiler was when porting Codemasters’ Neon Engine to the Nintendo Wii-U, my first decades earlier as chunks of the Amiga Kickstart ROM depended upon it. Solid, indeed. Wonder what’s still using it but not secret?

        1. bazza Silver badge

          Re: The Rust Evangelism Strike Force...

          Most commercial airliners I think; I've heard that their INTEGRITY OS is used by both Airbus and Boeing.

          1. picturethis

            Re: The Rust Evangelism Strike Force...

            As one who used to work with GreenHills compiler and their "Spotlight" debugger (via serial port) on pSOS systems running on all kinds of processors, it kind of was a real PIA to set up and get running. But at the time, it was cutting edge to be able to debug on an embedded system (at least in the commercial market). I was writing BSPs (Board support packages) for both pSOS and VxWorks at the time.

            Up until maybe 2 years ago, I was still getting emails from them. Haven't seen any since then, I guess I must have fallen off their email list.

            Now for deeply embedded micro-controllers it's mostly FreeRTOS. Anything above that I see mostly linux now, but I don't work with any safety critical systems much nowadays.

            Have an up-vote.

            1. bazza Silver badge

              Re: The Rust Evangelism Strike Force...

              There's still safety critical systems out there to be worked on!

              The Greenhills dev tools I've always thought of as solidly functional, not necessarily pretty to look at. Never mind, I'm not pretty to look at either. Like the tools you get with VxWorks you can get some really solid, excellent views of what's going on in a system. I always felt that the time saved in having good tooling saved more money than the cost of the tools. Kernelshark for Linux is what finally made (for me) Linux the equal of INTEGRITY and VxWorks, allowing a very detailed view of what the hell is going on.

              I've never liked FreeRTOS, or other things like it. If you need a scheduler, get a proper preemptive scheduler. Writing code like its the 1980s but trying to give it 21st century attributes is daft, and ignores what available in the 21st century (like, indeed, Linux). And calling it an RTOS is nuts; it's cooperatively multitasked, meaning it's only capable of meeting external timing demands if all your code is written that way. RTOS indeed... And its memory management! Well, fair enough, it's running on a microcontroller, but it's asking for trouble if you're trying to manage memory like you have a microprocessor+mmu but in fact you're on a ucontroller. In short, I wish it would go away!

              The worst of it is there's no growth path. If you're targeting some micro and written against FreeRTOS, and then need to upgrade to a proper operating system (or, just run it on a PC), you're stuck; it's not POSIX compliant, so you're re-writing.

              Far better in this day and age I say to have Linux + PREEMPT_RT on an embedded ARM (NXP do some really good fully featured cheap small ones), get all the software dev benefits and relax.

    6. doublelayer Silver badge

      Re: The Rust Evangelism Strike Force...

      "how can a buggy compiler hurt me?"

      A lot of the answers you've gotten have considered intentional flaws in a compiler or bugs that generate the wrong result, but if you specifically mean memory safety issues, it could still allow an attacker to generate code which executes something when you compile it. The risk is not as high as some other things, since if you are compiling code, you'll probably run it yourself later, but it might be another attack method, for instance one that can infect a build server rather than your development machine. I agree with you though that, as memory safety vulnerabilities go, there are things that are a lot worse than a compiler you run manually.

      1. Roland6 Silver badge

        Re: The Rust Evangelism Strike Force...

        I think the real isssue is a (malicious) program compiling a carefully crafted piece of code that causes the compiler to glitch and so enable the malicious program to gain elevated privileges etc.

        On a standalone dev system this probably isn’t a big matter, on a production system (it’s surprising how many production systems have a fully operational dev environment) this could be different, on a cloud service like Git …

        1. bazza Silver badge

          Re: The Rust Evangelism Strike Force...

          Sort of like a carefully-crafted garbage in, exploitable garbage (but, running) code out? Possible I guess, but could be difficult to pull off without it being somehow very obvious in the compiler's own source code.

          I'd worry more about a piece of software's own build scripts doing nasty things to the source at the point of compilation (which is what someone did to libzma to plant a cunning backdoor in opensshd).

          First rule of productions systems: have no development environments on it, lest non-privileged malicious code uses them to build a binary to exploit a known flaw. This is a bit tricky in Linux, because Python is pretty much an inherent part of your average distro, and if your hardware setup has - say - NVIDIA drivers (which seem to get built on site rather than pre-built and downloaded in an apt package) you end up need to have a c/c++ build system available too. Running production in containers is a good idea (which is what lies behind things like Ubuntu's snap, for example), but that doesn't prevent rotten admins innocently importing attack source code and building it in situ, rather than just downloading it off the Web.

          Other OSes that don't inherently feature python or other powerful arbitrary code generation / execution environments have a bit of a head start in this regard. Windows is nominally one of them, though if there's a .NET installation hanging around I've got a nasty feeling that includes a C/C++ compiler tool chain... Do Mac's have a python as standard?

        2. doublelayer Silver badge

          Re: The Rust Evangelism Strike Force...

          While possible, it is unlikely to give you privilege escalation because GCC doesn't need to run with elevated permissions, is not a suid, and therefore probably doesn't have any more access than the program calling it. If you're already running and you want to elevate, you need a vulnerability in the kernel or something that already has those privileges, and those would be more dangerous targets than a compiler. That doesn't make the compiler bugs completely safe, just less important than a kernel bug or one in utilities that run with different privileges. The one situation that makes sense to me is running on a different machine, so a malicious program could spread itself to a machine on which you compiled code.

    7. martinusher Silver badge

      Re: The Rust Evangelism Strike Force...

      The joke here is that COBOL is likely to be "memory safe". But don't tell anyone.....

      1. bazza Silver badge

        Re: The Rust Evangelism Strike Force...

        Probably Visual Basic too! And one can write that inside any Office program too!

        (Horridly enough, I've had to do this recently. I wanted to programatically build a PowerPoint slide. I decided to do this in the modern, correct way, downloaded all the C# packages to allow manipulation of PowerPoint slides, and set to work. And then stopped, when the true horror of what that entailed dawned. It was going to be a vast amount of code.

        I ended up doing it with 6 lines of VBA macro. I've never felt so dirty in all my life, but it did work...)

    8. bombastic bob Silver badge
      Devil

      Re: The Rust Evangelism Strike Force...

      From article: "Memory-safe languages, like C#, Go, Java, Python, Rust, and Swift, handle memory management for the developer"

      Handling memory management for the developer INEFFICIENTLY via GARBAGE {stall} COLLECTION...

      {stall} {stutter} How's that responsiveness and performance working out for ya??? Even on the highest end platform a garbage collection stall/stutter can INFURIATE just about ANY user!!! Computing like it's 1999 with 4Mb RAM on Windows 98!!! (actually that probably did BETTER)!

      NOT an improvement. Leave a web browser open for a week and check its memory footprint, if you do not believe me. But you'll have to use Linux or FreeBSD for that [not with Wayland] as OTHER configs are likely to crash+burn way before you can watch it happening. Yeah, when swap space usage maxes out for no reason other than GARBAGE COLLECTION MEMORY "MANAGEMENT", and applications go "non-resident" and respond like CRAP because SOMETHING ELSE ate up all of the virtual memory!

      PROPER memory management in C is EASY. Just clean up before you leave (a function) and assign pointers to NULL after freeing them if there is a chance they''l be re-used. And for C++, do not go crazy with the 'new' and 'malloc'.

      REAL coders do not need mommy and daddy to do things FOR them.

  2. david1024

    Sounds like a job for ... AI

    We can let ai rewrite all the libraries every update and recompile everything.

    1. Dagg Silver badge

      Re: Sounds like a job for ... AI

      You forgot the <Sarcasm> tags

    2. steelpillow Silver badge
      Joke

      Re: Sounds like a job for ... AI

      First up, AI rewriting its own code to fix its own vulnerabilities, right Vladimir? .... Damn! too late!

  3. Alan Mackenzie

    Rust, or ....

    For security's sake, is it more important to get away from C and C++, or would avoiding Microsoft Windows be a more productive first step?

    And the very best of luck to anybody ?seriously proposing rewriting Linux in Rust.

    1. Dostoevsky Bronze badge

      Re: Rust, or ....

      Just important core items like schedulers and things. Not the whole shebang.

    2. abend0c4 Silver badge

      Re: Rust, or ....

      The thing that's getting overlooked here is why most of this software was written in C in the first place - portability. It's not just that we're using elderly programming languages, we're effectively doing it specifically to lever the standard C library which is ubiquitous - but equally archaic. The runtimes for other languages inevitably wrap around the C library. And each of these is a separate world - there's a Rust world and a Go world and while there are mechanisms to access the C world, their mutual visibility is rather limited. In the context of secure programming I've just been reading a terrifying article by someone determined to call Rust code from Go by reverse engineering the calling conventions and sidestepping the runtimes: make something hard and someone will always resort to an unsafe alternative.

      I don't think we can create safe software by having isolated islands for each language, nor do we want a monoculture in which only one prevails. In the real world, software interfaces to other software (including the operating system whatever it may be) and we need to think about how to safely bridge those boundaries in a portable fashion.

      1. steelpillow Silver badge
        Pint

        Re: Rust, or ....

        @abend0c4 One of the best posts I've seen here in a long time.

        1. James Anderson Silver badge

          Re: Rust, or ....

          Just twigged the posters handle.

          Flashback to being called into the machine room at 4am to debug the dreaded 0C4 while half asleep.

      2. Anonymous Coward
        Anonymous Coward

        Re: Rust, or ....

        Not just the libraries. Given a new embedded processor (or micro-controller or some other new chip), chances are good that the manufacturer has a C compiler for it. Chances are not good that the manufacturer has ported rust to it.

      3. bazza Silver badge

        Re: Rust, or ....

        It used to be possible for Pascal to call C, vice versa, on some platforms at any rate. There's horrid things like SWIG, that don't really quite do the whole job even at the best of times.

        The ways to allow calling between language islands already exists. Trouble is it exists in multiple incompatible forms. Linux has dBus. Windows has COM. There was CORBA, and other attempts at cross-platform standards, but they've not taken off.

        dBus is relatively successful on Linux, but it's a bit of a bodge. They've done the critical part reasonably well, but unfortunately they chose to handcraft it within their project rather than use a pre-existing standard. I'm talking about how you write an XML schema and then use that to build serialisers (marshallers) for dBus messages for your programming language. They invented their own schema standard, and built their own code generation tools. These work, but unfortunately they took it only to a primitive minimum.

        Had they picked up a more mature, complete serialisation standard, dBus would automatically have some very useful traits. XSD (XML) schemas have "constraints", as do JSON and ASN.1 schemas. Code generated *properly* from such schemas ends up have code to check objects against the constraints, so if something is too long or out of the declared valid range, the object is automatically rejected. Having automatic content inspection as part of a remote calling interface, automatically enforced, would enrich dBus quite substantially. The reason they hand spun their own serialisation standard is because "free" was a big driver.

        This kind of thing is what plagues the software industry, developers large and small generally take things only as far as minimally necessary. It's the "that'll do" attitude, meaning that just enough functionality to be dangerous gets implemented, with no one doing the thinking of might be transformatively better. Take Google Protocol Buffers. It's fairly effective, but has no way of expressing contraints. It's useful for exchanging data between different languages, but if you care about data validity you still have to have a meeting, a document, code review, all the nausiating unreliable methods of ensuring that one dev fully understands what another dev has done. There are 3rd party projects to add constraints syntax and code generation to Google Protocol Buffer, and I wish Google would adopt that and make it mainstream. Worse, Google chose to develop their own thing from scratch - and came up with something that is incomplete - having never used their own search engine to search for tools / standards that already did what they wanted. Had they done so, they'd have come across ASN.1 and maybe just bought one of the existing vendors and OSS it.

        I build large heterogenous systems (different languages, different OSes, different CPUs) stringing processes together using something like ZeroMQ (which is very admirably multi-platform and multi-language) and ASN.1, using good tools provided by one of the better commercial tools providers. I end up being limited to languages like C, C++, C#, Java, Python and Go, but never mind. Doing systems this way it becomes possible to make most aspects of systems integration a matter for the system designer, rather than something developers do. Developers effectively get a pre-implemented interface, all they have to do is use it. And if they get it wrong, then the interface implementation they've been given refuses to handle their garbage. This way, an interface owner can really own and control it; the devs are hard-pushed to mis-use it. It also makes it very easy to be agile with interface definitions, very late into a project.

        Another really nice aspect is that because ASN.1 is polyglottal when it comes to wireformats, you can shift data around in whatever form suits, e.g. compact binary representations for low bandwidth links, or JSON / XML where you perhaps want something semi-readable, or more verbose binary formats when you want more flexibility in what is sent and when. It's perfectly possible to have a program spitting out XML or JSON, and the recipient need not know how the XML or JSON was generated in the first place.

      4. Locomotion69 Bronze badge

        Re: Rust, or ....

        I agree, and there is another important aspect: a domain experienced software engineer in C/C++ needs to be trained in using Rust for that domain - that takes time and effort.

        An experienced software engineer in Rust needs domain expertise - same challenge.

        I am sure many companies are looking into the transition, but in the meantime they still have to make their production targets.

    3. Roland6 Silver badge

      Re: Rust, or ....

      > And the very best of luck to anybody ?seriously proposing rewriting Linux in Rust.

      Do we really want a rewrite of an OS with all the baggage of C and Unix?

      Perhaps we need to redesign starting from somewhere different. Suggest get the design objectives nailed, like The UK government did when it wanted a supersonic nuclear bomber, or NASA has done in recent years, and throw some serious money at it, with the condition the final product will be open sourced under a suitable licence.

    4. Abominator

      Re: Rust, or ....

      Get away from Microsoft first. Windows is an enormous bag of shit along with Teams, Outlook etc.

    5. bombastic bob Silver badge
      Unhappy

      Re: Rust, or ....

      It is likely that the vast majority of Windows is already in C-pound and only the kernel remains in C.

      This would explain why Win98 on a Pentium-I performs as well as (or better than) Win-10-nic on a bleeding edge processor, for basic UI responsiveness, program load/startup, and other "user perception" things.

      So much for 16GB RAM and 4Ghz clock and multi-core if the DAMNED PROGRAMMING LINGO is THAT FORNICATING PIGGY! And I'm talking PISS POOR INEFFICIENT GARBAGE COLLECTION MEMORY "MANAGEMENT"!!!

  4. Bebu
    Windows

    Choices

    Memory safetly at least in preventing buffer overflows (range errors) and use after free would appear to reduce to the choices of automatic memory management (garbage collection) or the overt gymnastics of guaranteeing memory safety properties in Rust (and other languages?)

    Automatic memory management in languages like Go, Java etc etc are fairly undemanding on the average code monkey but can have performance problems and greater resource requirements.

    Rust requires a great deal more from the developer / software engineer of whom there really are very few sufficiently skilled individuals to fully leverage Rust's benefits which will always be a contraint.

    [If they were really clever rather than than believing they were clever, they wouldn't be here. Archchancellor Ridcully? ;)]

    The realpolitik is that critical systems (or those parts that are critical) will be (re)writen in Rust etc, with the less performance limited parts in Go etc and the rest with the usual suspects C/C++ etc etc

    So I imagine there will be really expensive and proprietary systems and components used by military, goverment and financial institutions and the polloi will get the existing tat.

    I cannot help thinking that the US DOD has already been down this road with ADA which was mandated for DOD projects but of course a case of "more observed in the breach." From memory ADA was a fairly memory safe language and the ADA based SPARK language provides a lot more than the safety guarantees of Rust but of course at a cost.

    Of the Five Eyes I know AU spent a lot on formal verification of their then new diplomatic communications systems (1990s) so there is some form there. Doesn't mean much if some of those protected communications end up on a US army corporal's memory stick. :(

    Programming has more cardinal sins than just those related to memory which are probably better addressed by languages like SPARK or possibly, for those with more than a five minute attention span, Eiffel.

    1. Anonymous Coward
      Anonymous Coward

      Re: Choices

      Automatic memory management in languages like Go, Java etc etc are fairly undemanding on the average code monkey but can have performance problems and greater resource requirements.

      To avoid "performance problems" and "greater resource requirements" can be demanding depending upon the task at hand. Without careful thought and planning, there can be "live" objects containing references to objects no longer needed, but since they are being referenced, are still therefore "live" (*). Not a perfect analogy but we could also remove all free statements from a C program to solve the dangling pointer problem - also resulting in performance problems and greater resource requirements.

      (*not talking about loops of dead objects, mem mgrs can solve that already).

      1. bombastic bob Silver badge
        FAIL

        Re: Choices

        Simple solutions and I have implemented them where not implemented before:

        * Use ref counts. The final 'Release' deletes the object and frees memory.

        * Show some coding discipline

        * ONLY use string/memory/IO functions that check buffer length like strncpy, snprintf fgets etc.

        * enable format warnings for printf-like function calls and FIX THEM

        * assign global scope pointers to NULL after freeing memory (and similar inside functions). Make it a macro, even

        . #define FREE(X) { free(X); X=NULL; }

        * synchronization via mutex etc. when using threads

        and so on. too easy, so WHY a NEW LINGO except JUNIOR CODERS wanting an edge over THE EXPERIENCED???

    2. el_oscuro

      Re: Choices

      In my C++ based web front end (which was used a few billion times in the 10 years it was in prod), I never mucked around with memory management. I just used the AnsiString library which handled it for me.

  5. Anonymous Coward
    Anonymous Coward

    Yees but ..

    Memory safe languages can still leak memory. Not releasing references to objects when you are finished with them is really easy, particularly unpleasant when that happens in someone elses library and sometimes amazingly difficult to find and fix even if it;s your code.

    C in comparison (and C++ to a lesser extent) tend to create simple problems and ones that are relatively easy to fix, O.K. you still need a decent test suite but once all that is valgrind clean then keeping it under control and taking care of any new faults is relatively easy. You DO add a test case for anything new you add don't you ?

    Not so familiar with Rust, but Java coders were ******* for using every library they could find, not understanding what they were using and creating really horrible to find memory eating leaks because of that problem. They didn't care, test cases still ran on their machines but with enterprise level software any problems got multiplied up and that excess memory use would still kill systems.

    Note. I'm not dissing Rust per-se just that dangling reference thing is as far as I know still an issue and it's a lot harder to track down than a simple buffer overrun.

    1. Dagg Silver badge

      Re: Yees but ..

      Memory safe languages can still leak memory.

      YES!!! I've seen this in C# and Java especially in threading.

    2. sammystag

      Re: Yees but ..

      That's true and I've seen Java code that had to be restarted every day to avoid OutOfMemoryErrors. Almost always as a result of caching in my experience. I've not seen it create a security problem though, rather reliability problems

      1. Anonymous Coward
        Anonymous Coward

        Re: Yees but ..

        Could be an avenue for DoS attacks

      2. el_oscuro

        Re: Yees but ..

        I have seen that with Oracle PL/SQL. One developer wanted to run a process in a loop, kind of like a cron.hourly. Sure enough, when we tested it, it leaked memory.

  6. Dagg Silver badge

    Run away - Don't walk

    Seriously, if it still works don't touch. This would be a bit like a 737 jet, flying in an old 737 is still safe, a new one not so much.

    Do the original requirements documents still exist for the original code and have they been updated with all the new requirements. This code has been well tested by time. Can you guarantee the brand new replacement code will be a 100% fully functional safe replacement.

    By all means create all new software using the latest you beaut language.

    Like sleeping dogs it is always good idea to leave them (or the old code) alone.

    1. rafff

      Re: Run away - Don't walk

      "Do the original requirements documents still exist for the original code and have they been updated with all the new requirements."

      Did the requirements documents ever exist? 50+ years of experience tells me that frequently all that ever existed was a bit of hand waving.

    2. Roland6 Silver badge

      Re: Run away - Don't walk

      > Can you guarantee the brand new replacement code will be a 100% fully functional safe replacement.

      That requirement potentially rules out the use of Rust; until such time as Rust has a formal language description that can be tested against…

  7. sitta_europea Silver badge

    My dad always used to say "A poor workman always blames his tools."

    It is perfectly possible to write memory safe code in C, but it does take some skill.

    It is perfectly possible to write faulty code in *any* language. It's not the fault of the tools if the code is faulty, it's the fault of the workman.

    If I were a carpenter and you told me that I shouldn't use a chisel because it has a dangerously sharp edge, my response would be that the sharper it is, the better it will do the job.

    We don't need blunt tools and poor workmen. We need sharp tools and good workmen.

    It starts with documenting the issues. The EU has started to lay the foundations:

    https://ec.europa.eu/info/law/better-regulation/have-your-say/initiatives/14241-Cybersecurity-risk-management-reporting-obligations-for-digital-infrastructure-providers-and-ICT-service-managers_en

    1. Anonymous Coward
      Anonymous Coward

      The tools are wrong.

      The trouble is that we know what is wrong with C/C++, but we are not fixing them. Mostly *refusing* to fix them.

      String handling in C is garbage, unless you are working with 16k of RAM. We could just copy the Java/CSharp String APIs into C, but they refuse to.

      C++ could have a memory safe/garbage collected mode. Like Managed C++ did. But they refuse to. And C++ has EVERYTHING else in the universe and the kitchen sink...

      1. that one in the corner Silver badge

        Re: The tools are wrong.

        > The tools are wrong

        Are you sure you have actually gone out and got yourself a proper set of tools for the job? Are you expecting that somebody else to do that for you?

        > String handling in C is garbage, unless you are working with 16k of RAM.

        String handling in C is entirely down to which library *you* decide to use - with the sole exception that statically declared strings are defined to be simple null-terminated character arrays[1] (the compiler has to do *something* if you insist on putting static strings into your code).

        Yes, every implementation does provide you with, at a minimum, the really simple (dare I say it, simplistic) set of routines in the C standard library (which were originally written when 16KWords of RAM was all you got, on a very good day).

        But you do *not* have to use those oldie-stylie routines - barring a few edge cases (i.e. printing out the word "ABEND") you don't *need* to have and compiler-generated null-terminated "unsafe" strings either (just load 'em from files with "My Best String Lib", which also helps you change 'em for I18N).

        > We could just copy the Java/CSharp String APIs into C

        Hmm, not sure I'm loving the idea of copying those *specific* APIs[1] but alternate string handling libraries exist in C (I'm not going to recommend a specific one, I don't know your requirements - and see [2])

        > but they refuse to

        Who is "they" here? Presumably, you mean the devs you work with, because the selection of libraries is up to them (or whoever dictates to them). So, go give them a stern talking to.

        If "they" are some other set of devs then - go give them a stern talking to (actually, best to ask first why they aren't using a better library, and then give them a stern talking to).

        If by "they" you mean the C compiler writers - well, there are lots of libraries they don't supply, that isn't really their job (and also see [2]) [3].

        Bottom line: as others have said, it is possible to do The Best Thing w.r.t. memory (even strings!) in C and C++; it is entirely down to the devs to learn how and bother to do it. Or admit they are not a good fit for that project and go work on something else. If you are affected by people not doing that - give them a stern talking to.

        > C++ could have a memory safe/garbage collected mode. Like Managed C++ did. But they refuse to.

        They refuse to because it would break the tenets of C++ (and the existing code written in C++). As you say, there are things that do GC and you are at liberty to use those languages

        [1] Which is also the case in C++ (the only reason C++ "has better strings than plain old C" is because you are using libraries that provide them; yes, more of these libs are provided "by default" with your C++ compiler, which makes them easier to find, but they are still just a set of libs and you are perfectly able to use a different set if they are a better fit to your needs)

        [2] in large part because to my mind they are just as incomplete as the old-fashioned C standard library, because there is no such thing as *one* string representation that is fit for all purposes yet, IIRC, both the Java and C# APIs promote just one representation each. As it appears does every other "standard library" (but I shall start to get ranty here, so shall stop).

        [3] Although C++ has gone down the prescriptive "we have done it all for you" route, when STL - a neat idea - metastasised into "Boost *is* standard C++" and "modern C++", which is still not a panacea.

        1. Anonymous Coward
          Anonymous Coward

          Re: The tools are wrong.

          People like you are exactly why C and C++ will never get fixed. It's perfect the way it is.

          1. that one in the corner Silver badge

            Re: The tools are wrong.

            > People like you are exactly why C and C++ will never get fixed.

            Hmm, your point about C was:

            >>> String handling in C is garbage, unless you are working with 16k of RAM

            My response was:

            >> alternate string handling libraries exist in C

            I.e. the string handling in C *is* fixed. More than once. If you don't trust yourself to not use the "bad" stuff, just - delete them from your copy of the tools!

            > It's perfect the way it is.

            Never said that. Did say you have to put some effort into it be look for the correct solution (e.g. string representation) to suit your current requirements.

            Beginning to think *your* idea of "perfect" means "I don't have to bother trying to do a good job, the tooling will do it all for me" - but no matter what tools do, you have to do your bit. "Rust is crap - it didn't stop me coding Bubble Sort and applying it to 200,000 records."

            Trying to make enough "fixes" to C or C++ to satisfy you and it won't be C or C++ any more - and won't be called that anymore (not without being ridiculed). So you just want to go off and use those other languages, whatever they happen to be. If you don't trust yourself with C or C++, you should just not use them. If you don't trust anyone else with C or C++, you should just not use their code.

            1. SCP

              Re: The tools are wrong.

              And there are languages you can choose that simply do not have the problem.

              Bringing a library in can lead to a whole load of opaque code that you now have to trust or validate.

              Why are you so averse to fixing problems? In any system, relying on the user not to trigger a problem is the least desirable approach to ensuring system safety.

              For the 1970's C filled a need on computer systems that were quite constrained in their capabilities. In the intervening 50 years things have moved on [mostly].

            2. martinusher Silver badge

              Re: The tools are wrong.

              ...and there's your problem (guv) -- most programmers can't tell the difference between "language" and "libraries". C at least is explicit in this regard.

              C is also memory safe provided you don't (ab)use pointers. You really don't need to (ab(use pointers or standard libraries in order to write useful things in C, its just that most nebes only know writing code for a PC or similar, either for its command line or for a GUI or the Web. There's a world of other applications out there, and few need to constantly reference a memory pool.

        2. An_Old_Dog Silver badge

          Devs Don't Exist in a Vacuum

          Managers, who allocate corporate devs' time, will frequently say something like, "&#@4)+/!! no, we're not gonna spend the time and money to rewrite all that!"

          Corporate devs frequently do not have their choice of software "tools".

          So don't go indiscriminately slap-happy on the devs over this issue!

          1. that one in the corner Silver badge

            Re: Devs Don't Exist in a Vacuum

            > Corporate devs frequently do not have their choice of software "tools".

            Indeed; been there, done that, got the technical debt.

            > So don't go indiscriminately slap-happy on the devs over this issue!

            >> go give them a stern talking to (actually, best to ask first why they aren't using a better library, and then give them a stern talking to).

            Hmm, if the "why" is "because Corporate is making us" then the last "them" in the parentheses would be Corporate. Not sure how I could have worded it to make that more explicit without causing that parathentical to blossom out of control and overtake the rest of the comment.

            Still, I did at least only recommend a stern talking to, rather than doing anything dreadful to their nadgers. Which is on my mind as the only proper response to the AC who seems to think it is possible to magically change C into Rust/Java/C# and still having it be C - or something.

        3. doublelayer Silver badge

          Re: The tools are wrong.

          The difference between a string library of your choice in C and strings in the standard library of a different language is that strings are very common types that lots of things use. Yes, when the code is entirely mine, I can use the library and be completely covered. When I have to connect to other libraries, they will not be using my library of choice. Likely, they won't be using any library at all, because they don't want the dependency risk, meaning that many parts of the program will be using the basic subset included in the C standard library. Is this necessarily a problem that we need to solve? I don't think so, but when you make a statement like "String handling in C is entirely down to which library *you* decide to use", it does not help when it's wrong.

      2. Richard 12 Silver badge

        Re: The tools are wrong.

        C++ does have a memory safe mode. Most of it predates and is almost identical to Rust in design. Eg 'borrowing' is simply const & and &, both of which long existed in C++.

        The only real difference is that C++ has grown over time, adding memory safe options for more use cases, so doesn't use a single "unsafe" keyword to mark a block of code as using the higher risk constructions - which are mostly bare pointers.

        Your build tools and IDE can warn you about the higher risk constructions, if you wish. Existing projects can port over to the "memory safe" constructions piecemeal, it doesn't require a full ground-up rewrite and most do not have any runtime cost. (Though they do have a compile-time cost, of course, and to be fair C++ compilation is slow)

        C++ also has garbage collected 'modes' if you want, there are several libraries and toolchains - though in my experience they're rarely used, probably because of performance though possibly vendor lock-in.

        C is an entirely different language.

        Lumping it together with C++ is nonsensical, like saying motorbikes are cars but SUVs are not.

        1. Anonymous Coward
          Anonymous Coward

          Re: The tools are wrong.

          "C++ does have a memory safe mode. Most of it predates and is almost identical to Rust in design"

          Wow... not starting well.

          1. that one in the corner Silver badge

            Re: The tools are wrong.

            (about to make an assumption about continuity of AC here, but it seems a safe one)

            >>> We could just copy the Java/CSharp String APIs into C

            >>> C++ could have a memory safe/garbage collected mode. Like Managed C++ did

            >> C++ does have a memory safe mode. Most of it predates and is almost identical to Rust in design

            > Wow... not starting well

            Look, if you don't like Rust either and think we should all just be using Managed C++ and C# (and the other .Net languages as well? F#?), just say so.

          2. Richard 12 Silver badge

            Re: The tools are wrong.

            Wow... not starting well

            Then please, enlighten me. What does Rust actually have that isn't covered by C++14, let alone C++23?

            Give examples, then they can be fixed. If you simply wail that "they aren't fixing it", you are the problem.

            C++23 is much improved from C++98.

      3. el_oscuro

        Re: The tools are wrong.

        I wrote critical production web C++ code at the turn of the century (that was used at least a few billion times over its 10 year time in prod). And how did I manage memory? I didn't. I just used the ANSI string library which wasn't even really new then.

      4. This post has been deleted by its author

      5. Abominator

        Re: The tools are wrong.

        Modern ISO C++ can be used to write completely memory safe code and the compiler will verify it for you. What's wrong with that?

        https://www.theregister.com/2022/09/20/rust_microsoft_c/

        Stroustrup got back to us, defending the language he invented.

        "We can now achieve guaranteed perfect type and memory safety in ISO C++. That is, every object is used according to the type it was defined with. That implies that we eliminate uses of dangling pointers, catch range errors, and eliminate data races. Note that every 'safe' language, including Rust, has loopholes allowing unsafe code."

        The thing is you can write unsafe code in Rust and when I look at all the interesting low level stuff around allocators....it's all unsafe code!!!!!

    2. doublelayer Silver badge

      "A poor workman always blames his tools", but it does not follow that "he who blames his tools is a bad workman". It may also be that he who blames his tools has bad tools. Of course, the statement worked a bit better when workmen chose their tools, rather than having about three that are capable of doing the job and the selection among them was often made long ago. Dismissing every argument about improving the tools with this logic simply guarantees that our tools, whether they're good or bad, will not improve.

      1. that one in the corner Silver badge

        > Dismissing every argument about improving the tools with this logic simply guarantees that our tools, whether they're good or bad, will not improve.

        True enough.

        So it is a very Good Thing that software has never lacked, and will never lack, for people working on improvements to its tools[1].

        Of course, the corollary to these improving tools is that we will therefore always have a pile of stuff created right up until the day before the new tool appeared[2].

        > It may also be that he who blames his tools has bad tools

        One day, there will be an article about how we must all stop using Rust because it just does not help with the errors that are causing so many systems to go wrong, errors that the Verdigris compiler catches automatically. A government study will demand to know how this parlous state of affairs was allowed to happen. The comments will be full of people praising Verdigris and complaining that it was always obvious that Rust wasn't good enough and why did we ever use such a rubbish tool; which complaints will be picked apart, line by line, by other commentards.

        [1] some days the temptation to improve the tools even gets in the way of actually, you know, using them!

        [2] and as TFA talks about the problems that causes (should we rewrite it? Now? Or tomorrow? Or will that make it worse?), maybe we *should* have a moratorium on creating the better tools? (Tongue firmly in cheek, ahem).

        1. Anonymous Coward
          Anonymous Coward

          You conveniently ignored the possibility of improving the existing languages. That we've got to the point where we need to replace C and C++ is completely damning.

          1. This post has been deleted by its author

          2. that one in the corner Silver badge

            > You conveniently ignored the possibility of improving the existing languages

            You keep ignoring the fact that if we "improve the existing languages" the way you seem to want[1], we will just end up with - one of the other languages that already exist, the one you've just copied the features from. And we already have that.

            C *has* been improved (more than once); one of the winners in that competition was C++; and we still have C as well (even if it did nick some bits from C++, causing older code to not compile with that version of C, requiring rewrites). If we improve upon C++ then we will have yet another programming language - and we will still have C++.

            Starting to think that you have a magical idea that C and C++ compilers can be "improved" (in ways you can not explain, as you have rejected the extant facilities) and all the old code recompiled without being rewritten and *poof* all their problems will be gone.

            If this is *not* an accurate description of what you believe is possible, PLEASE explain what it is you think can actually be done. Give us a concrete example of how you believe C and/or C++ can be improved which won't just end with us pointing out that all you want is to use a.n.other language in the first place.

            [1] well, also ignoring that things you want do already exist, but somehow not in a way that is good enough for you, for some unexplained reason.

            1. Paul Crawford Silver badge

              C *has* been improved (more than once); one of the winners in that competition was C++;

              I would argue that improvements in compilers and test tools are as significant if anyone actually uses them. gcc has flags that make it very verbose about possible risks, they are helpful (if occasionally wrong/irrelevant) in finding mistakes, much as lint and similar tools would do. Probably the most useful these days is the ability fo check printf() strings match the arguments and the ability to also apply that checking to variable-length functions of your own.

              https://gcc.gnu.org/onlinedocs/gcc-9.2.0/gcc/Common-Function-Attributes.html#index-Wformat-3

              And yes, that variable-length stuff is a suspect construct but so often is needed, at least for maintaining code.

              The other tools are the likes of valgrind and the electric-fence library to dynamically check for memory abuse. If you can run your code's test suite with either of them, and said test suite has your Bobby Tables gibberish inputs as well, you are well on your way to avoiding memory bugs.

              But remember boys and girls, there are so many other bugs out there to try! How many CVE are down to hard-coded passwords or other lack of input sanitation style of errors?

          3. Roland6 Silver badge

            Perhaps a big improvement would be to start using something other than a single stack, Rust for all its claims still uses a single stack frame that combines code and data…

            1. Daniel Pfeiffer

              Rust does not put code on the stack

              You can pass closures (lambdas) to functions. But that doesn’t mean they’re on the stack. On the contrary, they may well have been merged into the inlined function. When compiling Rust in release mode it optimises very well.

        2. doublelayer Silver badge

          Yes, that is a good thing. My statement doesn't mean that all suggested improvements are necessarily better. There are many valid reasons to suggest that C is fit for purpose, and they can be debated. That's not what I was objecting to. I was objecting to the simplistic logic that any vulnerability in a C program is the total and undivided fault of the programmer that wrote it, and therefore that there is no reason to consider changing it.

    3. abend0c4 Silver badge

      but it does take some skill

      Unfortunately, the majority of software developers, like the majority of drivers, believe their own "skills" are significantly above average...

      1. yetanotheraoc Silver badge

        Pay no attention to Dunning and Kruger

        Just as unfortunately the prevailing mindset is we are going to use technology to solve the problem. Instead of training people to be better drivers, better developers, better workers (from "the poor workman" post), etc.

        "The value of experience is I recognize my mistakes every time I repeat them." --by I forget who.

        I'm forever weighing the pros and cons of different languages, but practicality is uppermost in my mind. For my current personal project I did the prototype in awk and version 0.1 will be in C. I doubt Rust would be a good fit _now_. Maybe (if I ever release the code) when it reaches version 2.0 someone will complain about the C, but it will be too late then. Tough cookies.

        1. doublelayer Silver badge

          Re: Pay no attention to Dunning and Kruger

          Relying on the user to solve the problem isn't always the right approach either. Imagine that I built a car with a little switch that would lock the steering wheel at an extreme point, so if you twisted it too far, it would get stuck and send your car in circles if you didn't flip over. People ended up buying these, making a mistake, and crashing into things. I responded by saying that, if they were better drivers, this wouldn't have happened, and I'm right. You still might decide that my car design was more at fault than the drivers were.

          We try to improve the quality or safety of things made by tools all the time, and it doesn't always take the form of telling the users of the existing tools to be better and blaming them when anything went wrong. Sometimes, we tried to improve the products by improving the tools, and sometimes, defects were more due to tool problems than user problems. We can't expect that every problem can be fixed by having a better tool, nor can we expect that all problems can or should be resolved by chastising the users.

    4. rg287 Silver badge

      We don't need blunt tools and poor workmen. We need sharp tools and good workmen.

      Presumably you don't wear a seatbelt because you are a good driver and the overwhelming majority of other drivers will be licensed, implying that they are also "good" drivers(!). Why would you need one? You're not going to cause an accident and it's very unlikely anyone would crash into you. And if they do it will be their fault and their insurance (covering your err, funeral expenses).

      Fact is, humans are humans. Even experienced carpenters sometimes cut themselves. An analogy which is somewhat misplaced because a sharper chisel requires less effort and force to use than a blunt one, and is thereby more dangerous to the user. You would be hard pressed to argue that Rust is inherently harder or requires more effort to use than C/C++.

      In any case, it's a matter of harm and scale. We mandate safety guards on machine tools because the alternative is losing a finger (or more). Steps to head off common (but sometimes obscure) bugs that can lead to memory safety issues are worth doing for popular software because the harm that arises from something like Heartbleed or an RCE bug being deployed to a billion systems could be quite significant.

      Simply saying "can't everyone be better at their job?" is to wilfully ignore the reality of the world.

  8. Anonymous Coward
    Anonymous Coward

    The problem with Git jokes is that everyone has their own version. And so it is with rust.

    Create a professional, technical standard (think ANSI, or ISO C) and then the means to start migrating over is in place. K+R's book was the starting block for a C standard, though still took half a decade to get standardised.

    C really exploded in popularity once standards were produced.

    Id love to get David Brabens take on Rust. He's long been critical of older development tools, but his outfit still sure as hell uses C/C++.

  9. Charlie Clark Silver badge

    Who will do the work?

    The report says nothing we didn't already know. What we still don't know is who's supposed to do all the work?

  10. Abominator

    Massive yawn.

    People have had years to write things in languages like Java etc that are 'memory safe' according to their marketing teams. Yet they also continue to have horrible vulnerabilities. I'm thinking the entire Atlassian suite of software which is fully Java based. Poorly trained developers generally write bad code. There are very much limits to stopping human stupidity.

    I have regular seen memory leaks in C# code, VBA etc. Circular object references and more.

    Calls to rewrite everything of what is probably highly tested code because of more a religious agenda to use Rust is just going to put people off. Also the language is not even ISO standardised.

  11. Daniel Pfeiffer
    IT Angle

    Java is NOT memory safe

    Java is not memory-manipulation safe: One huge progress of Rust is its borrow checker. It operates on the simple rule “One writer XOR many readers” for each bit of memory. This prevents competing writes through different routes. Java will happily allow you to write spaghetti code of tangled access patterns. Even concurrent unprotected multi-threaded access is fine with the Java compiler. On unlucky timing it will at least crash out of your computation with a ConcurrentModificationException. (Exceptions being more spaghetti, since throw is just a goto by another name. But that’s a different can of worms.)

    Java is only memory-management safe: Through its slightly expensive synchronised reference counting and dreaded garbage (collector.) For this, Rust has lifetimes so as to know when to drop what. Both avoid dangling references, use-after-free and double-free. Only Rust takes that burden off run time, knowing what to drop when at compile time.

  12. jeremya
    Alert

    Not seeing the forest for the trees

    The discussion comes down to: Yeah we know that hardware is exploitable, and that machine language is exploitable, and we know that the processes where machine language is generated (compliers linkers etc) are exploitable, and we know that any time data is in transit it is exploitable, but we'll complain about memory allocation in the high-level language and the problem will go away.

    Instead, what the IT industry has done for many decades is to put in processes to first of all identify coding or system problems, eg using valgrind, and more importantly mitigate the effect of any failure by system design and monitoring e.g. stateful packet inspection on firewalls or advanced process monitors.

    Also, manufacturers don't seem particularly interested in changing the processor architectures to make exploits at any stage improbable. e.g. implementing key functionality such as threading in silicon, or at least microcode. There are 'proven' secure microkernels such as SEL4 but none I can find that are entirely silicon.

  13. JoeCool Silver badge

    Yeah so, actually read a bit of the report

    And their methodology is to use CLOC, so as the Reg is accurately reporting they found lines of c-code.

    They didn't even bother with the most rudimentary of checks - like static code checker, or grep for "malloc".

    This is barely worth writing up, much less using for serious discussion.

  14. karlkarl Silver badge

    Safety isn't entirely down to the language

    Microsoft's C, C++ compiler with the /clr:safe flag that runs on a .NET VM is what is commonly known as "safe".

    Emscripten (/clang) with the WebAssembly output that runs on a JS/ASM.js/WASM runtime is what is commonly known as "safe".

    However, both run into the same issue as Rust. You spend your time writing / maintaining generated bindings and juggling dependencies rather than actually solving the problem.

    (Trading some safety with direct native interop with Microsoft's cl /clr is pretty good. Shame the damn compiler is proprietary and from a single vendor!)

  15. halfstackdev

    Some tooling red flags

    Some general traits in dev tooling that should be red flags for the probability of producing reliable and maintainable software

    - Is the code easy to read ?

    - Can you tell what the code is doing by taking a part of it in isolation, or do you need to read wider implementation to see whats going on ?

    - Can you tell by looking at the code where it grabs resources, and where it releases them (from file handles to memory allocation) ?

    - Can you tell by looking at a function where it returns, or are there hidden control flow mechanics to jump out early ?

    - Does the tooling make it so easy to pile on 3rd party libs as dependencies, that its idiomatic to just pull in a dependency rather than do a trivial implementation inline ?

    - Is the tooling backed by a massive marketing machine that makes bullshit promises along the lines that "now anyone can produce perfect code without any experience or skill"

    - Are the in-company people that promote these tools obnoxious and humourless assholes with personality defects that make it impossible for them to ingest any critique at all ?

    - Are these same people even aware of better alternative tools, or do they dismiss them out of hand, because reasons ?

    I don't know of many tools that tick a lot of those boxes. ... but if I did start to see one that scored highly on the above list being pushed into use in an organisation, it would be easy to predict that the product would be s**t, the company culture would be s**t, and the people who had to maintain the pile of s**t would have no work life balance, leading to a collapse of the product in the near term.

POST COMMENT House rules

Not a member of The Register? Create a new account here.

  • Enter your comment

  • Add an icon

Anonymous cowards cannot choose their icon

Other stories you might like