When we announced the security flaw CVE-2024-11053 on December 11, 2024 together with the release of curl 8.11.1 we fixed a security bug that was introduced in a curl release 9039 days ago. That is close to twenty-five years.
The previous record holder was CVE-2022-35252 at 8729 days.
↫ Daniel Stenberg
Ir’s really quite fascinating to see details like this about such a widepsread and widely used tool like curl. The bug in question was a logic error, which made Stenberg detail how any modern language like Rust, instead of C, would not have prevented this issue. Still, about 40% of all security issues in curl stem from not using a memory-safe language, or about 50% of all high/critical severity ones. I understand that jumping on every bandwagon and rewriting everything in a memory-safe language is a lot harder than it sounds, but I also feel like it’s getting harder and harder to keep justifying using old languages like C.
I really don’t know why people get so incredibly upset at the cold, hard data about this.
Anyway, the issue that sparked this post is fixed in curl 8.11.1.
People understandably gets incredibly irritated about the push for rewriting existing code, more specifically “already debugged code”.
As this story points out, not all errors are memory related, and rewriting code will inevitably introduce logic errors.
IMHO the general rule should be: use newer tooling/languages in new projects, but don’t rewrite already debugged old projects just because of the new tooling/languages.
Note that there are times that accrued technical debt in a codebase makes it easier to rewrite than to shoehorn new features in there. But that is independent of the tooling/languages used.
Antartica_,
It may be a logical contradiction when “debugged code” still has bugs, but it happens to the best of us. Large code bases become larger than human capacity to certify there are no errors.
This is true. It might be hard to justify rewriting code in safer languages in the short term. However over the long term the opportunity cost of sticking with insecure C code always gets worse. We could subject ourselves to these memory faults ad infinitum on the basis that we don’t want to be inconvenienced and burdened with rewrites today. However if only we can get it done we’d save future generations from the many flaws that insecure languages have exhibited for half a century and counting.
Ah hypothetical dilemmas…in reality most of society is motivated by short term agendas at the expense of future progress.
I think this is the best we can expect too. However it’s not necessarily ideal because incumbents can and often do use their market dominance to impede better alternatives, for better or worse. Just the way it goes I suppose.
Indeed. This rings true for many of the corporate projects that I work on. Even so, I don’t see much risk of them getting displaced any time soon. Managers in many organizations take pride in their existing code bases even when it’s very costly and difficult to maintain and modernize them. Look at mainframes, haha. Suggesting their past investments need to be thrown away often puts executives off even if it’s warranted by facts on the ground.
Certainly long-lived, big and complex codebases are difficult to renew.
I feel lucky to work mainly with heavily distributed systems in which no part is too big. Being distributed means that the boundaries are well defined, at minimum in machine-to-machine protocols, and if the protocol and config files are keep intact, components can be rewritten/replaced pieacemeal.
More generally, I think that is a strength of Zig versus Rust; at the cost of losing idiomatic interfaces, you can replace a codebase in “sourcefile increments”.
” I also feel like it’s getting harder and harder to keep justifying using old languages like C.”
Well they do say it’s a logic error, not a language-caused one:
” This bug is not considered a C mistake. It is not likely to have been avoided had we not been using C.”
ChodaSly,
That’s exactly what Thom Holwerda said.
Anyway, while it is true that memory safe languages don’t fix logic bugs in semantically correct code, I don’t think this is a great excuse for dismissing memory safe languages. Consider this parallel: The vast majority of airline accidents aren’t related to MCAS, but that’s no excuse for not fixing MCAS.
https://en.wikipedia.org/wiki/Maneuvering_Characteristics_Augmentation_System
I feel the same way about software engineering. C is hard to replace, but this still has to happen for the software industry to solve the systemic memory problems of the past 5 decades.
I see the importance of replacing C, although I sympathize with those who don’t like rust’s syntax…neither do I. So many languages have a C-like syntax…even javascript. I think a familiar syntax would have made these code migrations more palatable.
But he admits 40-50% of security bugs could have been prevented via memory safe languages. So that seems obvious if you’re doing a rewrite to not use c. It doesn’t mean you won’t screw up some other way., but the lack of a perfect language that prevents any developer from ever introducing a bug shouldn’t stop one from using the best one available today.
But what about using ADA/SPARK? Supposedly SPARK catches those kinds of errors.
jgfenix,
Yeah, ADA and Pascal are definitely safer than C at picking up overflow errors especially compared to C arrays. Although rustlang is more sophisticated than those two at other kinds of memory faults. I vaguely remember looking at Spark too…
Ah here it is:
https://www.osnews.com/story/138705/rust-for-embedded-systems-current-state-challenges-and-open-problems/#comments
Spark was inspired by rustlang and introduces more memory verification to ADA. I haven’t used it though so I can’t offer much of a comparison. It might be a decent candidate but IMHO it faced the same popularity battle as every other challenger to C’s incumbency over the years.
For better or worse FOSS and commercial software alike (on windows and linux) are heavily C oriented. and it’s not for the lack of merit from other languages, but rather the critical mass advantages of C.
Many project managers are partial to the C code that they originally wrote and will continue to resist change. We are notoriously stubborn 🙂 I suspect that many will have to retire before the needle will really budge towards embracing newer paradigms. It takes a few generations, but some day the new generations who actually learned on memory safe languages in school may have a better opportunity to implement them when their generation eventually replaces the older generations.
ADA had big designs on replacing C and failed because it’s a PITA to write performance oriented code in ADA. According to the cool kids these days, Rust will replace C. That remains to be seen. However, all of your posts on Rust seem to assume everyone’s main goal is safety. That’s often not the case. Why get all obsessed with safety for performance oriented non-privileged applications? You’re shooting yourself in the foot while hand-waving about features some applications do not need.
aliver,
…aaaaand as usual a non-coder tech-hack like Thom “just cannot understand” why we all don’t switch to Rust, Swift, Go, etc… Well, you aren’t going to understand because it’s easy to hand wave about solutions to problems in someone else’s work in an infuriating European snob-way. However, one super-easy thing to understand is that you need to stop ignoring the fact that secure ***compilers*** and flags for C already exist and are super easy to re-tool for without re-writing or re-debugging. They ***absolutely do** solve the same problems as Rust. Stop pushing people to learn new languages and have them simply learn to use the compilers better and you get to the same point quite easily. I code for a living. I code in C, I’m not just spouting bullshit, I’m surviving security reviews and actual audits on my code. So, before you call bullshit, let’s talk about your resume to even make the critique.
aliver,
He’s not a coder, but I’m pretty sure the source he cited is and Thom’s words seem to be a good faith representation of not only the article but also several of us who are coders. There’s room do disagree, but calling Thom a “European snob” seems more snobbish to me than than anything Thom wrote IMHO.
They do not. There are linting tools that might be affective at catching some kinds of runtime faults using special allocators and guard pages, however this is a far cry from languages that prevent memory faults from being compiled altogether. Lint tools like valgrind can be helpful for c programmers, but they are not foolproof and cannot definitively catch memory faults like rust can. For example the granularity of checks can be somewhat imprecise and subjected to architectural limitations. Also you may not be triggering the exact code paths that generate the faults. So even if you use valgrind to Q/A your work, it doesn’t mean customers can’t find faults that valgrind didn’t witness.
Not only are there false negatives, but sometimes false positives too because it can make wrong assumptions. To be fair, valgrind does the best it can given the way it works after the fact, but it isn’t a panacea because it has to observe software side effects and not the source code at the root of the problem.
Well…greetings fellow coder! I’m sure you’re a qualified C coder but maybe you need to learn more about rust. I fully understand that many coders aren’t interested in change: “get off my lawn”. But even if you won’t admit it, the memory problems created by our kind programming in C are very real. And each generation continues to create software with serious, often latent, faults that lead to crashes & exploits.
All humans are fallible, but I actually won’t harp on that…. Let’s assume your code is perfect and it’s just other people’s code that’s broken…it doesn’t really matter. Even companies that have been trying to hire perfect candidates for decades still end up producing real software faults and vulnerabilities. This objective truth should be evident to all. Languages that aren’t memory safe naturally increase the risk of these kinds of faults ending up in software; faults that are effectively mitigated in memory safe languages.
I’m calling him a snob on the basis of reading the site for years, not his one small bit of snobbery and lack of independent thinking about Rust. You don’t seem to have experience enough to know what you are talking about or you’re being intentionally deceptive. The are a lot more tools to secure C code than just filters and preprocessors like RATS or Valgrind. Those are helpful, but I’m still talking past you. You completely ignored (or hid) and overlooked compiler flags and features which is what I mentioned in the first place, and went off on filters and preprocessors because it’s easier to attack there if you ignore compiler features.
What about stack protection and bounds checking flags like -fstack-protector-all, -fPIE, -fPIC, -D_FORTIFY_SOURCE=2, -ftrapv, -fstack-clash-protection, -fsanitize=safe-stack. You ignored or hid knowledge of the better static analysis tools like Clang’s ‘scan-build’ and things like -Wextra, -Wall, -Wpedantic, and talked only about Valgrind. You ignored CFI tools like -fsanitize=cfi, You ignored -fsanitize=undefined for UBsan. You ignored or hid the fact that some platforms like ARM support memory tagging with hardware support in both Clang and GCC. You ignored address santizers (asan) like -fsanitize=address.
In short, you seem to have no idea what you’re saying and are just parroting back journalist talking points. We also didn’t talk about Rust being significantly slower than C in many common benchmarks and specifically The Compiler Shootout. So, you’re ignoring the fact that “Just start your life over in Rust and it’ll all be great” doesn’t take into account the burden of lower performance. Cue the violins and the lecture about how performance doesn’t matter. I’ve heard it all before and it’s still not an eyes-wide-open comparison until you actually acknowledge the alternatives rather than just lecturing people who do it every day as if you know what you’re talking about. Until you can acknowledge reality instead of hiding it, we cannot have a serious conversation, just a pointless argument.
aliver,
You are using ad hominem attacks. That doesn’t refute anything I’m saying.
The onus is on you to be specific about what you are thinking otherwise those of us reading your post have to guess.
Anyway, you can enable flags to help detect/interfere with invalid memory access, but only after the fact. That is they try to mitigate/detect the symptoms of unsafe languages rather than the root cause. Nothing reaches the level of rustlang’s compile time memory safety verification capabilities, which can catch memory errors before they are triggered, even in multithreaded code, which is notoriously difficult for humans to consistently get right without race conditions.
That’s neither fair nor true. But you are entitled to your opinion and I know that there’s nothing I can say because you are already bent on justifying unsafe language regardless of the memory faults that keep coming out of them. I accept the fact that there are many in the industry who have a disregard for safe languages and remain adamant that C’s memory faults aren’t a big deal regardless of it’s track record. Nevertheless, as I mentioned earlier, I do think a generational shift is happening: new students are becoming more accustomed to safe programming languages meanwhile older generations who have a greater affinity for unsafe languages inevitably have to retire.
Rust is appropriate where safety is a paramount concern. That’s not always the case. In many cases performance is the biggest concern and Rust still has a performance penalty (yes, “but but but but, sometimes it’s faster” yeah, occasionally but not usually). Maybe there is a generational shift. We’ll see. I’m sure folks said the same of FORTRAN and COBOL, too, and they were at least partially correct. There is nothing “wrong” with Rust. drink the entire bottle of kool aid if you wish, but it’s a set of trade offs that not everyone is willing to make, especially not those of us who have no problems creating secure code with C and reap the benefit of it’s high performance and familiarity. It’s not as hard as you make it out to be.
aliver,
That’s where Rustlang shines though compared to other managed languages. Most perform checks at run time and even resort to garbage collection scanning the object hierarchy. However rustlang does not have that overhead and unlike C rust requires all assumptions about object lifetime, memory semantics and accessibility to be resolved at compile time.
And although I don’t think people should rely on it too much, rust does support unsafe code and I’d like to emphasize why this is better than C. In C, the entire code base becomes the equivalent of rust’s “unsafe” sections. Most code should not depend on unsafe sections but if unsafe code is needed for any reason rust’s ability to limit the scope of it is extremely beneficial for auditing! Consider a project with millions of lines of code, but a few hundred or thousand are designated as memory unsafe. This represents a thousandfold improvement on the effort to find potential unsafe memory vulnerabilities.
I still disagree with you that safe code is slower than unsafe code. All of the checks that rust performs are checks that C programmers MUST do as well (if the code is to be correct). The difference is that in C the programmer has to mentally keep track of all the object lifespans mentally whereas in rust the language requires the compiler to verify it. If humans never made mistakes in projects of ever increasing scopes, then rust’s safety checks would effectively be redundant with human’s. But in the decades we’ve been writing C software we know that mistakes will be made. So it makes a lot of sense for computers to verify our code correctness and not just assume correctness.
I agree that programmers are stubborn and don’t like to change. This is a big reason I consider it a generational change.
I don’t make correct code out to be hard. In any given specific case we should all understand what makes code incorrect….the problem is humans become fallable as projects scale up.