Memory safety CVEs differ between Rust and C/C++ (kobzol.github.io)

53 points by nicoburns 3 hours ago

42 comments:

by john_strinlai 9 minutes ago

>Because sometimes I see people online who compare the number of CVEs in Rust and C/C++ software, [...]

a rule of thumb i follow is that the second someone starts comparing or talking about the number of CVEs, i just ignore whatever they say next. its hard to think of a more useless metric than "number of CVEs", especially now.

by fweimer 16 minutes ago

I'm not convinced this is true. Otherwise, it does not bode well for Rust code because any type safety glitch will be considered a vulnerability. This would be really challenging for Rust developers because it goes beyond unsafe Rust code. You can easily have unexpected panics because your types do not enforce invariants as you expect. If a library has such a bug, is this a denial-of-service vulnerability in the library? Rather than dealing in absolutes, I would say that it's impossible to tell in isolation. If applications do not misuse the library in ways that triggers the panic, probably not, and treating this as a vulnerability just results in pointless noise.

Determining the impact of library bugs can be really hard. For example, some functionality might be so broken that it's simply impossible to use correctly, so a buffer overflow on top does not make a difference. Or a buffer overflow vulnerability triggers consistently during system boot, so that you never get to the login prompt. These can hardly be considered vulnerabilities. On the other hand, we have clear buffer management bugs, where we must expect that there is application code out there which specifies tight buffer bounds and requires that the library stays within that buffer. (Rust should help here, at least out-of-bounds accesses should turn into panics.) But most bugs are unfortunately somewhere in the middle. Tools like Debian Code Search can provide some evidence. But in the end, it's more subjective than I'd like it to be.

On the extreme end, we have compiler soundness bugs. I'm a bit of worried that I'm hitting any of those when I'm tweaking the types until the compiler no longer complains. Beyond the basics, I really don't have a grasp of Rust's type system rules. But I suspect they very difficult to hit by accident, and even if I do, the code must be miscompiled in meaningful, but difficult-to-notice way. All that seems rather unlikely, which is why these bugs aren't treated as vulnerabilities.

I really think we need some corrective factor (such as potential implication impact) when determining whether toolchain bugs are vulnerabilities.

by afdbcreid 2 minutes ago

You said

> I'm not convinced this is true.

But it is. It is true that Rust libraries could take this position of "any API misuse causing vulnerability is a CVE" more to the extreme, currently it is applied to memory safety but it could be applied to panics as well. However it is still true that pretty much all Rust libraries treat API misuses that cause UB as a CVE, and pretty much no C/C++ library does that, and that inflates the number of Rust CVEs.

> On the extreme end, we have compiler soundness bugs. I'm a bit of worried that I'm hitting any of those when I'm tweaking the types until the compiler no longer complains. Beyond the basics, I really don't have a grasp of Rust's type system rules. But I suspect they very difficult to hit by accident, and even if I do, the code must be miscompiled in meaningful, but difficult-to-notice way. All that seems rather unlikely, which is why these bugs aren't treated as vulnerabilities.

Rest assured that you are much more likely to hit a miscompilation in your compiler's backend, and that it is much harder to detect.

by dralley 2 minutes ago

>Otherwise, it does not bode well for Rust code because any type safety glitch will be considered a vulnerability.

I mean, this is basically true. And it goes beyond type safety - there have been CVEs filed against the Rust stdlib for TOCTOU problems of a kind that the C++ stdlib is absolutely replete with (often the exact same ones in the exact same places, to the extent that comparable APIs exist) which ended up being fixed quickly in Rust and largely ignored in C++.

On balance it's not such a bad thing, though it for sure does create headaches for those who need to categorize CVEs by impact. Creating a culture that wants to fix soundness issues rather than mark them as WONTFIX with a line of documentation is a core principle of Rust.

by cesaref an hour ago

Is it only me that would have expected curl_getenv() to have an assert that it's argument isn't NULL?

I know this doesn't stop runtime problems in release builds, but i'd have thought this sort of simple precondition check would help users find problems in their library useage.

It's not going to stop you passing a non-terminated string, or other such invalid input though, which is I guess more the point, that it's totally possible in C to produce good looking but actually invalid arguments that can't be spotted at runtime without UB (out of bounds access etc).

Edit: Actually thinking about this more, I guess the problem is that you are likely linking against a release library implementation, so it's not possible to add a precondition without introducing a runtime overhead, which is probably more likely what we are talking about with this case.

by hathawsh 41 minutes ago

If I were doing a code review, I would probably accept the code either with or without the assertion. The context of curl_getenv() makes it clear that null is not acceptable. If the author of curl_getenv() had evidence that callers are frequently breaking the contract by passing null, then perhaps the assertion would help shed some light on violators. Otherwise, I would expect everyone to play by the rules, making the assertion unnecessary.

by jurschreuder an hour ago

Just want to remind everyone that only 1% of vulnerabilities are memory related in the average Joe's code.

And only 20% of memory related bugs are use-after-free which the borrow checker fighting is for.

And 100% of the use-after-free exploits were to gain admin rights on an already hacked Windows (all windows) computer.

So for the vast majority of people the borrow checker adds nothing.

The vast majority of memory safety bugs (extreme pro level, super hard to exploit, only worth it in massively adopted evil outer world facing software) can be fixed by using C++26 with array bounds checking and forced initialisation.

These last two things that Rust forces catch 70-80% of the memory problems the borrow checker only 20-30% only use-after-free.

Most problems by far for normal developers are supply chain attacks, exposing api keys, remote code execution, wrong input validation, wrong auth-flow.

You're reading the CVEs of sudo and ssh and think your code will be hacked like that.

PHP is memory safe and still many people hack wordpress plugins.

by khuey an hour ago

> Just want to remind everyone that only 1% of vulnerabilities are memory related in the average Joe's code.

Unless your point is merely that average Joes write such terrible code that you don't even need memory safety issues to exploit their software, [citation needed]

Google says memory safety issues are 75% of exploited zero days. (https://security.googleblog.com/2024/10/safer-with-google-ad...)

by afdbcreid an hour ago

My understanding is that they claim that the average Joe writes code in a garbage-collected memory-safe language.

Which is... true? but irrelevant. Such applications are not suggested to be ported to Rust. Of course, some people still do that, because they like Rust; but that's their personal choice.

by kalaksi an hour ago

And at least in Chromium project, half of those memory safety issues are use-after-free: https://www.chromium.org/Home/chromium-security/memory-safet...

by bbippin an hour ago

The point is that memory issues are a smallish number of issue compared to the larger ecosystem of vulnerabilities, and choosing to port everything to Rust is like over-optimizing. Well, that’s my 2 cents.

For a language as ugly as Rust, my thought is that people should actually be using Ada, and have a mathematically provable correctness angle; not just a replacement for C/C++ with memory safety.

by khuey an hour ago

> The point is that memory issues are a smallish number of issue compared to the larger ecosystem of vulnerabilities

If memory safety issues are 75% of exploited zero days it sounds to me like they're the biggest issue in the ecosystem by far.

by chilljinx an hour ago

I do not believe that I agree, and I am not sure about all of your numbers.

The borrow checker does add something, but it definitely costs something as well in multiple ways, also in terms of how it is done in Rust and at a programming language design perspective.

It would be very funny if you were batting for Rust, and just having a laugh at others here.

by jeffbee an hour ago

Hrmm. I don't think there exists a set of compiler flags that will just make an existing C++ (or, worse, a mixed C and C++) project safe to the extent that you suggested. The STL hardening flags don't help for ordinary arrays that aren't accessed via smart pointers, and they don't help code that uses a pointer+offset style of access. As for UAF, nothing in C++ comprehensively prevents you from accessing an invalid stored reference even if you have cranked up the hardening mode to DEBUG. Rust, on the other hand, affirmatively prevents that.

by slopinthebag an hour ago

Any sources for these numbers?

by lawn an hour ago

90℅ of all statistics is made up.

by chilljinx an hour ago

Unsafe is not necessary to trigger UB in case no_std is used. Nor if one of the soundness holes in the Rust programming language itself is encountered. Nor if there is UB in one of the libraries used as a dependency by the library you are using. Nor if there is UB in the Rust standard library. Which has happened many times, since the Rust standard library is full of unsafe.

Rust also requires libraries to be safe regarding unsafe, no matter what kind of insane input that is given to the library and that would otherwise potentially be security issues. Which is too difficult for many library authors.

And unsafe in Rust is so difficult that many library authors throw their hands up, use Miri, and hope for the best. Even though Miri, all respect to it, has bugs, probability-based testing and other limitations and issues.

UB in both user library and standard library:

https://materialize.com/blog/rust-concurrency-bug-unbounded-...

by sunshowers an hour ago

If you are interested in a more nuanced take on what makes unsafe Rust both valuable and difficult, check out my blog post on the Oxide blog: https://oxide.computer/blog/iddqd-unsafe

I directly tackle the concerns you mentioned, and as a followup I'm actually working on formally verifying the library as well (I've had some success and will publish an update regarding this).

by reallyinchaos an hour ago

You should be careful that the Rust cultists don't sacrifice you in a ritual in the dark of night in some cave, while chanting "CRustlhu" over and over.

J/K, but seriously, some members of the Rust community might not be happy about your writings.

by sunshowers 41 minutes ago

I'm a huge fan of Rust! I like to think my writing makes the Rust community better more than it annoys people :)

by reallyinchaos 36 minutes ago

Still, be careful, it didn't exactly engender a lot of responses, only got 1 comment here:

https://old.reddit.com/r/rust/comments/1tuvxej/iddqd_or_the_...

Marketing of Rust is held very, very dear to some of the people in the community.

by kllrnohj an hour ago

> Nor if one of the soundness holes in the Rust programming language itself is encountered.

imo one of those soundness holes is caused directly from trying to prevent UB - integer overflows. It is inconsistent in Rust what happens in that scenario depending on compiler flags, which basically just makes it UB for any given piece of code. And, unfortunately, default release mode behavior is unsafe.

by afdbcreid an hour ago

You seem to have been misinformed. Rust panics on overflow in debug mode (or always if you toggle a compiler flag), and has a guaranteed wrap-around in release mode. In no case there is UB.

by Groxx 33 minutes ago
by chilljinx an hour ago

Which definition of UB are you using regarding that? Behavior changing based on configuration does not seem like UB, at least if none of the configurations allow for UB.

by Groxx an hour ago

I'm caught somewhere between interpreting this as "C is all we need. git gud" and "rust hurt me and I'm still mad" and I'm struggling to see any other option. It's an unfocused rant that seems keyed off "rust" and little else.

In broad strokes it's correct, this stuff happens and it's hard to be correct all the time. But are you trying to make a point? Or just ranting?

Also that linked issue was considered a CVE and is fixed (as the article says). Which, as far as I am able to infer intent from your comment, seems to oppose your comment's complaint.

by chilljinx an hour ago

Are you breaking the rules of the site?

by afdbcreid an hour ago

> Unsafe is not necessary to trigger UB in case no_std is used

I have no idea what are you talking about, no_std is just completely irrelevant here.

> Nor if one of the soundness holes in the Rust programming language itself is encountered

Have you actually examined those soundness holes? It is basically impossible to hit them without writing code which is meant to hit them.

And this is also noted in a footnote.

> Nor if there is UB in one of the libraries used as a dependency by the library you are using

If we treat a Rust program globally, this is kinda true. A more true statement will be that UB cannot happen without unsafe code somewhere, including in dependencies (and the original statement can be interpreted as saying that).

But the true power of unsafe is that it's local. If you've reviewed a library and its unsafe is sound, you can ignore it for the rest of the calculation. And of course, the more people review a library the more likely it is that it is sound.

> Which has happened many times, since the Rust standard library is full of unsafe

And here again the post's point stands: many CVEs in std are artificial, you can't exploit them without writing a program that is meant to be exploited. Such thing will never be a CVE in C/C++'s std.

> Rust also requires libraries to be safe regarding unsafe, no matter what kind of insane input that is given to the library and that would otherwise potentially be security issues. Which is too difficult for many library authors.

That is true, that is in fact the post's point: that if they fail this, a CVE will be filled, even if exploitation is just not possible realistically.

But there is a very simple solution for library authors: don't write unsafe code! You don't need to, the vast majority of times. And if you do not have the knowledge (which indeed is more complicated than in C/C++) how to not have an unsound API, then you just should not write unsafe code.

by chilljinx an hour ago

> no_std

Is 100% relevant.

Did you use ChatGPT to generate your comment?

by rumblefrog an hour ago

Little hostile with the refutal

by pitaj an hour ago

Explain how it is relevant

by afdbcreid an hour ago

What? Absolutely not. May you explain why no_std is relevant?

by slopinthebag an hour ago

> The fix for this bug is included in Rust 1.87.0

Am I missing something?

by shevy-java an hour ago

C and C++ are kind of losing out to Rust right now.

Take ladybird (last month blog; not that ladybird stands for all projects out there, of course; it is just an example):

https://ladybird.org/newsletter/2026-05-31/

"The HTML parser is now written in Rust" "The Rust parser is also about 10% faster than the C++ version it replaced,"

I am not saying this is a systematic analysis by far, but Rust is pushing into domains where C and C++ dominated in the past. And that seems to be a real push. To me it looks as if both C and C++ are standing to lose some ground in the next few years, directly to Rust. Perhaps even via snowball effect.

by ghosty141 an hour ago

> but Rust is pushing into domains where C and C++ dominated in the past.

I think it's also a big sign that the linux kernel adopted rust and not c++. (only for small parts but still)

by tialaramex 8 minutes ago

A not inconsiderable part of why is that Rust for Linux did the work.

When C++ people say they think there should be C++ in Linux, their proposal usually begins by proposing that it "should" be possible to just compile Linux as C++ software. This doesn't work because C isn't just "C++ but old", and they rapidly lose interest.

Which of course also feeds into Linus' semi-fair claim that not allowing C++ keeps out the low effort wannabes who would plague such a project. This makes C++ developers very angry, but part of the reason why is that it's true, C++ does attract these people.

The Rust for Linux people wrote a lot of code, a lot of documentation, they did Q&As, they worked very hard to actually deliver the idea to the kernel community, it's a totally different approach, it's a lot more work but some people thought it was worth the work.

by 360MustangScope an hour ago

I agree about Rust gaining ground but using the argument that it got 10% faster due to Rust is not really that useful.

If they rewrote it in C++ again, they would have most likely got the same result because they got a chance to fix a design that might not have been most optimal.

by cogman10 20 minutes ago

I think the difference in languages that allows for faster performance is that Rust does a good job of surfacing expensive operations and it makes defensive programming less of a requirement.

by reallyinchaos an hour ago

C++'s module system, introduced in large part by Gabriel Dos Reis, was not a success, and many was critical of it even when he first proposed it. Rust does miles better on that general topic. Perhaps Gabriel was trash at doing good designs, or perhaps he made a mess on purpose.

C++ also does not have pattern matching, which is wildly popular in Rust.

Ladybird in the past used Swift apart from C++, but abandoned it. Swift has some peculiar issues, some of which might not be fixed over time. Ladybird's LLM-based conversion to Rust is interesting. I don't know much much unsafe the converted code has.

by vouwfietsman 35 minutes ago

Knowing little about cpp modules and nothing about Gabriel Dos Reis, I expect a more design-by-committee type explanation for the result: the module system was probably a victim of having to be backwards compatible, abi stable, idiomatic, zero cost abstraction, be compatible with all weird cpp features, not hurt compile time, etc etc etc

I don't think its fair to attribute it to lack of skills or bad intent, unless there's some proof to any of it.

by reallyinchaos 34 minutes ago

Nice try, Gabriel.

by FpUser 32 minutes ago

>"are kind of losing out to Rust right now"

On publicity side / propaganda / some specific areas you might have a point. Practically amount of C++ code being in active development (I wat to stress this particular point) dwarfs that of Rust despite all that high profile pressure.

Personally I consider languages as just a tool and do not get hung up when client prefers this or that and I have developed all kinds of software in many languages.

Personally I consider Rust very restrictive and poor expression-wise comparatively to C++.

Data from: Hacker News, provided by Hacker News (unofficial) API