3 ms·
The question is: Could such bugs be avoided in C using the right tools and strategies. And the answer is also often: yes. This is why a large component of the
by uecker 2y ago
The question is: Could such bugs be avoided in C using the right tools and strategies. And the answer is also often: yes.
This is why a large component of the argument for switching to other languages is usually that is impossible to avoid such bugs in C even for experts. But I think this argument, while having some small amount of truth to it, also is partially deceptive. One can not simply look at number of CVEs and conclude this, one needs to compare apples to apples and then I find the reality looks differently, e.g. if a simple mitigation for the bug in C could not be used for some reason, but this reason would also prevent the use of another language in the first place, then using this as argument is misleading.
- pornel 2y ago> Could such bugs be avoided in C using the right tools and strategies "right tools and strategies" is very open-ended, almost tautological — if you didn't catch the bug, then obviously you haven't used the right tools and the right strategies! In reality, the tools and strategies have flaws and limitations that turn such problem into "yes but actually no". Static analysis of C code has fundamental limits, so there are bugs it can't find, and there are non-trivial bugs that it can't find without also finding false positives. False positives make developers needlessly tweak code that was correct, and leads to fatigue that makes them downplay and ignore the reports. The more reliable tools require catching problems at run-time, but problems like double-free often happen only in rare code paths that are hard to test for, and fuzzers can't reach all code either.
- uecker 2y agoStatic analysis of arbitrary legacy code is limited. But I do not find it difficult to structure my code in a way that I can reasonable exclude most errors. The discussion of false positives in C is interesting. In some sense, 99% of what the Rust compiler would complain about would be considered false positives in C. So if you want to have safety in C, you can not approach this from this angle. But this relates to my point. If it is acceptable to structure the code in specific ways to make the Rust compiler happy, but you do not accept that you may have to write code in specific ways to avoid false positives in C, then you are already not comparing apples to apples.
- GTP 2y ago> If it is acceptable to structure the code in specific ways to make the Rust compiler happy I think this is a misleading way of presenting the issue. In Rust, there are class of bugs that no valid Rust code can have (unless maybe when using the "unsafe" keyword), while there is valid C code that has said bugs. And here's the difference: in Rust the compiler prevents some mistakes for you, while in C it is you that have to exercise discipline to make sure every single time you structure the code in such a way to make said bugs unlikely. From this, it follows that Rust code will have less (memory-related) bugs. It is not an apples to apples comparison because Rust is designed to be a memory safe fruit, while C isn't.
- uecker 2y agoThe point was that you can not reject warnings as part of a solution for C because "it annoys programmers because it has false positives" while accepting Rust's borrow checker as a solution.
- GTP 2y agoI think the general point of my comment still stands, as you and everyone else working on the project would need to be disciplined and only release binaries that were compiled with no warnings. And even using -Werror doesn't fully solve the problem in C, as not having warnings/errors is still not enough to get memory safety.
- uecker 2y agoI don't really disagree with you, but I was also making a slightly different point. If you need absolute memory safety, you can use Rust (without ever using unsafe) But you get 99% this way with C, a bit of discipline, and tooling and this also means maintaining a super clean code base with many warnings activated even though they cause false positives. My point is that these false positives are not a valid argument why this strategy does not work or is inferior. Your claim is that it is inferior because you only get 99% of safety and not 100%. But one can question whether you actually get 100% in Rust in practice in a project of relevant size and complexity, due to FFI and unsafe. One can also question whether 100% memory safety is all that important when there also many other issues to look out for, but this is a different argument.
- kpcyrd 2y agoThe blogpost claims they are already running "all the tools", can you please be more specific which one they are missing? Maybe the tool to avoid this kind of lifetime issue just happens to be rustc?
- uecker 2y agoRust is one tool which can be used to avoid life time issues. It is not the only tool. It also only works perfectly only when you exclusively limit yourself to using safe Rust and not use C libraries, unsafe Rust, or not directly use APIs that use integers (I assume in this example, Rust may have special safe wrappers, but in general the language also does not prevent this error). Resource management is something model checkers could verify in C. One could also design a safe API around it in C. Possibly GCC's analyzer could find such issues. In any case, the question is how much effort one wants to invest or not and what tradeoffs the solutions have. A small risk of missing such things may also be an entirely reasonable choice, even so Rust proponents irrationally claim otherwise. For example, curl uses C89 which is certainly not the best choice for safety. It is the best choice for portability to obscure platforms, but this requirement would also rule out Rust.
- kpcyrd 2y ago> It is not the only tool The burden of proof is on you. I asked which tool specifically would have detected CVE-2025-0665 and I don't mean to be mean, but your reply is essentially a very confident "I don't know but I'm sure somebody could build one", while also handwaving the security benefits of programming in Rust. When building a http client library, unsafe Rust and C FFI are not really a problem I'm having.
- uecker 2y agoI already mentioned model checkers one option. There are also other memory safe languages besides Rust. Whether an existing tool finds a bug in an existing C code is a different question though. I would have expected a double close to be found by GCC's analyzer, but I haven't tried for this particular bug (in simple cases it certainly find s it: https://godbolt.org/z/rzr9zT619 https://godbolt.org/z/rzr9zT619). In general, it these tools find bugs more easily in well written C code, but do not help much when code is convoluted. But not writing convoluted code is more important than the choice of programming language anyway.
- pjmlp 2y agoIt would help if since lint was created in 1979, the large majority of C developers actually used the right tools and strategies. In practice only when forced down MISRA like processes people seem to care, versus how relevant secure programming is seen in other programming language communities since 1960's. Secure programming was part of Burroughs and Multics design, so why is the answer from a systems language community designed a decade later, and after 40+ years since the Morris worm, "we don't use right tools and strategies over here"?
- uecker 2y agoI think this is probably the reason why Rust is attractive to companies. They can say, "use Rust and never use unsafe without sign-off from some senior programmer" and then can be relatively sure there is no buffer overflow. In C you would say, you need to follow these guidelines with tools X, Y, Z and then you can be relatively sure there is no buffer overflow. The problem is that this is a striking argument only when the only thing you care about are memory safety issues. As soon as you care about other forms of security / correctness, you need "guidelines with tools X, Y, Z" anyway. And when you have mixed code base, you also need this anyway.