Comment by crote
4 days ago
Its vulnerability overview page[0] also helpfully lists which were caused by the use of C. The fact that even an extremely-high-quality codebase like Curl is still encountering things like use-after-free issues is pretty damning for the people clamoring that it is perfectly possible for skilled programmers to write safe C.
If even Daniel Stenberg can't consistently write safe C code, I think we can assume that nobody can. Either you switch to a memory-safe language like Rust, or you adopt a high-cost runtime checker like Fil-C, or you'll have to live with a never-ending series of memory safety vulnerabilities.
I don't know, that just seems like a category error that breaks apart when you get closer to any individual project. Use-after-free is still possible in Rust with unsafe. Assuming nobody _can_ write memory safe C is a good assumption for things like security modelling, regardless of how unlikely those issues actually come up.
Securing code you/your org did not write and programming for yourself/your org are just fundamentally different jobs.
It is absolutely possible, but all of the data we currently have shows that reducing the amount of code that could possibly have the error has meaningful effects on the number of vulnerabilities. Mitigation may not be the same as elimination, but it is effective.
> Use-after-free is still possible in Rust with unsafe
Of course! But in practice all potential bugs are neatly wrapped in small and easy-to-audit "unsafe" blocks, rather than silently lurking all over your codebase.
You could indeed wrap your entire codebase into one giant unsafe statement and write it like C. But, as the actix-web discussion showed years ago, the Rust community very much prefers restricting unsafe to the absolute bare minimum possible. You wouldn't write, say, a mail server in mostly-unsafe Rust for the same reason that you wouldn't write it in mostly-inline-assembly: you gain nothing, and in return it'll probably blow up in your face sooner rather than later.
Rust has an escape hatch because we're all adults. The big difference is that its footgun has an explicit safety latch, so you have to deliberately opt in to blowing your own foot off.
Where is your extreme assessment coming from?
It isn't very extreme, in my opinion. I am only making one claim, and it's a rather modest one: Memory safety bugs aren't any different from other bugs.
The "you're holding it wrong" crowd has been claiming that memory safety bugs are a skill issue for ages now, and that the issue is overblown and can be solved by having programmers suck less.
Curl provides the counterexample to this. Its main developer seems to be quite skilled, as reiterated by the various AI audits it is a very solid codebase, yet it still suffers from memory safety vulnerabilities. If the "you're holding it wrong" crowd is right, we're faced with a contradiction. Is Curl secretly a poor-quality codebase which has managed to fool the community until now? Is Daniel Stenberg uniquely susceptible to writing memory safety bugs, negating his otherwise-seemingly-decent programming skills? Is he perhaps intentionally introducing memory safety bugs to make C look bad?
In other words: if memory safety bugs are indeed a different breed altogether and are completely avoidable if we try hard enough, why are they still hitting Curl?
I posit that they are not: if you are writing unsafe code, you will introduce memory safety bugs. You can avoid them altogether by switching to inherently-safe languages like Go or Kotlin, by catching them at compile time like Rust, or by catching them at runtime like Fil-C. Or you can ignore the problem altogether and keep writing C like we've been doing for decades, but that means you will keep shipping memory safety vulnerabilities - like we've been doing for decades.
> Memory safety bugs aren't any different from other bugs.
This is highly dependent on what kind of software you are writing.
On the one end, there's stuff like an image format parser in a browser -- a pure function from untrusted bytes to untrusted pixels. In a memory-safe language, it's pretty hard for such code to have vulnerabilities (other than DoS) in such code -- you'd have to explicitly go out of your way to do weird stuff (open unrelated files, start subprocesses, ...). Simple logic bugs can only lead the wrong pixels or panics. But when memory safety bugs are possible, remote code execution is common in such code. Memory-safe languages make a massive difference here!
On the other end, you have stuff like a javascript JIT compiler, which turns untrusted javascript into trusted machine code -- here pretty much any logic bug leading to "wrong output" can be turned into a remote code execution exploit. Memory safe languages are not very useful here.
I meant extreme as in "extremely-high-quality codebase", without which a single example of curl means little for your broader point.