Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

There are lots of vulnerabilities in the C code, too. Should we remove C or do we accept that fact that no language is perfect since they are used by humans and continue to make improvements and use tools that help us along as time goes forward?

The cherry picking for this one Rust vulnerability to the ~150 C vulnerabilities is such a weird take that I can't help but think people have some weird hatred of Rust.





> Should we remove C or

Your post is curious, for the post I quoted basically argued for just that eventuality for all new code. Even as the new language introduces undefined behavior vulnerabilities.

The promises as stated previously, and the goal as stated by that lwn.net post now, are starkly different. And the poster did not even wait until the new language has proven its worth. And then a UB CVE comes by in the code in the new language.

What Linus wrote in the past:

https://www.phoronix.com/news/Torvalds-On-Rust-Maintainers

> So when you change the C interfaces, the Rust people will have to deal with the fallout, and will have to fix the Rust bindings. That's kind of the promise here: there's that "wall of protection" around C developers that don't want to deal with Rust issues in the promise that they don't have to deal with Rust.

That both you and that lwn.net poster writes these things, is extraordinarily weird and strange.


But this sounds like hubris and user error, then, and not a language discussion at all?

I do not think it is weird. Every C bug was taken as clear evidence that we need to abandon C and switch to Rust. So the fact that there are also such bugs in Rust is - while obvious - also important to highlight. So it is not weird hatred against Rust, but hatred against bullshit. And considering that most of the code is C, your 150 C vulnerabilities is a meaningless number, so you still continue with this nonsense.

One C bug was not taken as clear evidence that we need to abandon C and switch to Rust. Hundreds of thousands of very similar bugs, over decades, in common code patterns were. I’ve never understood how other C or C++ developers could seriously question whether Rust solves any safety problems at all. Maybe the tradeoffs aren’t worth it for a particular use case, but how could you find it unimaginable that even just enforced bounds checks would catch lots of bugs that (normal, non-verified) C would miss? Do you doubt that Python code corrupts memory a lot less because you saw a CPython CVE once?

What language do you think Graydon Hoare was spending most of this time writing while he started working of Rust as a side project? Hint: it sure wasn’t Java. Rust is not the product of some developer who has only used 2 scripting languages and had to read the definition of stack-smashing off of Wikipedia showing those C developers how to live in the future. It’s not old enough for many of the developers working on it to have only ever used Rust. It’s mostly C and C++ developers trying to build a new option for solving their same problems.


> It’s mostly C and C++ developers trying to build a new option for solving their same problems.

I've observed that a lot of the folks I used to meet at ruby conferences have moved to Rust. No idea what led to this, but maybe it's just folks that were generally curious about new programming languages that moved to ruby when it became better known and that the same interest led to adopting Rust.


I worked on a Ruby codebase that moved to Rust - I think that part is mostly cargo-culting cool things in the news to be perfectly honest. There’s type safety advantages, but if Ruby’s performance envelope was even conceivably acceptable for your use-case there are likely better options. I strongly suspect a lot of the friction between Rust and only-C/C++ developers is the product of a bunch of people coming at Rust from higher level languages parroting lines about safety, and then looking at you blankly if you ask how it handles nested pointer indirection.

But I don’t think that applies to the people actually driving the language forward, just those talking a big game on HN/Reddit.


Giving the size and age of the C ecosystem, the number of bugs is not really a valid argument. We will see an increasing numbers with Rust as Rust is increasingly used. I also do not question that Rust solves some problems. It just solves them rather badly and at high cost while bringing new problems.

I looked at firefox code a decade ago, it was a complete complex nightmare mix of different languages. I can see that this motivated starting something new, but it was not a clean C code base (and not even C).


What number of CVEs is Rust kernel code allowed to have before we have good evidence it’s a categorical failure? Do you turn off KASLR for your Linux machines because there exist CVEs it doesn’t protect against?

As long as the kernel will be developed, there will be CVEs - even with Rust. So at what point the number is so high that we should drop Rust and move to formal verification? And even then, there will be CVEs... This whole argument is nonsense.

But I also do not agree that memory safety is of much higher importance than other issues. Memory safety is highly critical if you have a monopolistic walled garden spyware ecosystem - such as Android. Not that I do not want memory safety, but the people I know who got hacked, did not get hacked because of memory safety issue, but because of weak passwords or unpatched software. And at least the later problems gets harder with Rust...


Your priorities do not match that of most kernel developers or most operators of network-connected Linux systems (even if we ignore Android). So I don’t think your problem is with Rust at all, you’ll need to fork Linux if you want the project to stop putting huge amounts of effort into memory safety (as it has for decades).

You are right, I do not have a problem with Rust as a language nor with the kernel improving memory safety. My issue is solely with exaggerated claims and aggressive marketing of Rust.

(And I am operating network-connected Linux devices since 30 years myself. Memory safety is not the known issue, at the moment I worry more about limited security updates due to Rust.)


The number of memory related bugs is absolutely a valid issue with C when the same bugs are impossible in Rust. The C memory model is a disaster when every computer is connected to the Internet.

You are saying the Rust bug in the kernel was impossible? How did it happen then? Come on guys.

> Every C bug was taken as clear evidence that we need to abandon C and switch to Rust.

I think more charitably it's every "simple" C bug that tends to provoke that reaction. Buffer overflows, use-after-frees, things for which mechanically-enforceable solutions have existed and been widespread for a while. I think more exotic bugs tend to produce more interesting discussions since the techniques for avoiding those bugs tend to be similarly exotic.

> So the fact that there are also such bugs in Rust

Similarly, I think you need to be careful about what exactly "such bugs" encompasses. This bug wasn't one of the above "simple" bugs IMHO, so I would guess an equivalent bug in C code would at least avoid the worst of the more strident calls you so dislike. Hard to say for sure, though, given our unfortunate lack of a time machine.


I agree with you that this is more nuanced and that I oversimplified this a bit in my comment.

Okay, fair that since the majority of the codebase is C and that 150 vulnerabilities is probably negligible in comparison since we're talking about ratios, but if we're to be THAT nuanced then we also need to consider that code has been iterated upon for decades, so, I think the point is moot.

The claim has never, ever, been that Rust is bug free. The objective was to help reduce bugs, which is an outcome I've seen first hand in projects I work on. You still seem to speak in aggro terms, so it still feels like an emotional response to Rust.


What features do you like the most in Rust? Are pattern matching and enums some of them?

Ah, credibility attacks. Nice.

Safe Rust eliminates some of the more common memory bugs in C. The bug under discussion was written in unsafe Rust—but even that doesn't obviate the huge advantages Rust has over C. Even unsafe Rust, for instance, has far fewer UB gotchas than C. And with Rust, you can isolate the tricky bits in 'unsafe' blocks and write higher-level logic in safe Rust, giving your code an extra layer of protection. C is 100% unsafe—"unsafe at any speed" as I like to say.

IMHO, "C is 100% unsafe" is a misleading way to look at it and the kind of exaggeration which I criticize. Also in C only specific language features are unsafe and not all code, and you can screen for these features and also isolate critical code in helper functions. Saying these features could appear everywhere is no difference from "unsafe" possibly appearing everywhere in Rust. I agree that "unsafe" is easier to find as a keyword, but I do not think this is a fundamental advantage, especially in projects where you have a lot of such "unsafe" blocks.

> Saying these features could appear everywhere is no difference from "unsafe" possibly appearing everywhere in Rust.

That's not true in practice: Unsafe code is clearly delineated and can be 100% correctly identified. In C, usage of dangerous features can occur at any point and is much harder to clearly separate.


First, if "unsafe" worked so well 100% time, why did we have this bug? (and many other) So this already obviously wrong statement.

Then yes, you can use dangerous features in C at any time, but obviously you can also use "unsafe" at any time. The only difference is that "unsafe" is clearer to recognize. But how much this is worth is unclear. First, if you do not invalidly reduce the discussion to only memory safety, you need to review all other code anyway! But even then, it is also not true that only the code marked with "unsafe" is relevant. This is major myth. The "unsafe" code can cause UB outside "unsafe" and logic bugs outside "unsafe" can cause bugs unsafe. This does not perfectly decouple if you Rust repeat this nonsense over and over again.

Don't get me wrong, I think the unsafe keyword is good idea. But the magical powers Rust fans attribute to it and the "SAFETY" comment they put next to it tells me they are a bit delusional.


> logic bugs outside "unsafe" can cause bugs unsafe.

This is the wrong understanding of Rust's unsafety encapsulation. For example, no logic bug outside of `unsafe` can cause undefined behavior of Rust std's `Vec` abstraction, which is using underlying unsafe to build.

The point that "because unsafe is used so the entire Rust program is also unsafe" is a real major myth. It's as absurd as saying "because Java runtime using unsafe underlying to build so Java is also unsafe".


Two questions:

Why was the fix to this unsafe memory safety bug [0] only changes to code outside of unsafe Rust blocks?[1][2]

Why does the Rustonomicon[3] say the following?

> This code is 100% Safe Rust but it is also completely unsound. Changing the capacity violates the invariants of Vec (that cap reflects the allocated space in the Vec). This is not something the rest of Vec can guard against. It has to trust the capacity field because there's no way to verify it.

> Because it relies on invariants of a struct field, this unsafe code does more than pollute a whole function: it pollutes a whole module. Generally, the only bullet-proof way to limit the scope of unsafe code is at the module boundary with privacy.

[0] https://social.kernel.org/notice/B1JLrtkxEBazCPQHDM

[1] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux...

[2] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux...

[3] https://doc.rust-lang.org/nomicon/working-with-unsafe.html


If a logic bug inside Vec and outside any unsafe blocks inside Vec happens, and that logic bug violates any invariants and requirements of the unsafe blocks, that can cause memory unsafety.

That would be the unsoundness of `Vec` itself, but if the abstraction of `Vec` is sound, there would be no way to use `Vec` outside of `unsafe` that can cause memory unsafety.

The point coming back to abstraction and responsibility, in Rust, you can build abstraction that is sound and guarantee memory safety from there. There can be soundness bug inside your abstraction, but it will be a massively smaller surface for auditing and expert required to write such abstraction. Also, when soundness bug appears, the responsibility is solely on the abstraction writer, not the user.

Whereas in C, without those safe abstraction, the surface of doing thing right to avoid memory safety issue is your entire codebase, and responsibility of "holding the knife correctly" is on the user.


> There can be soundness bug inside your abstraction, but it will be a massively smaller surface for auditing and expert required to write such abstraction.

If all of the Vec has to be "audited", or checked and reviewed, including all the code that is not inside unsafe blocks, how would the surface be any smaller?

> The point coming back to abstraction and responsibility, in Rust, you can build abstraction that is sound and guarantee memory safety from there.

Isn't it normal for programming languages to support building abstractions that can help with not only memory safety, but general correctness? C is a bit barebones, but lots of other programming languages, like C#, C++, Haskell and Scala support building abstractions that are harder to misuse.


All of `Vec` is much smaller than all of the place using Vec. IIRC, Vec is around 3k LoC. And for even low level code like Oxide & Android core, they are observed less than 4% of their code is inside or related to unsafe, that’s a massive improvement.

Yes, Rust is not new in term of allow building hard to misuse abstraction, it’s just allow abstraction over memory safety without relying on GC or runtime checks. Rust achieve this by adding capability to enforce shared XOR mutability with its borrowck which C++ couldn’t.


[flagged]


Wow, now no more discussion and an accuse of bot? I’m flattered.

Also you are doing tech, be specific, what is much shallower or hollow?


> in C only specific language features are unsafe and not all code

Using rust's definition of unsafe which is roughly "can cause undefined behaviour" then it seems to me isolating use of these features isn't possible. What is C without:

* Dereferencing pointers * Array access * Incrementing signed integers

You can do all of the above without invoking UB, but you can't separate the features in C that can cause UB from the ones that can't.


The first misunderstanding is that safety is a property of the language or not. Rust marketing convinced many people that this is so, but C can be safe or unsafe. Fil-C shows that even all of C can be memory safe (but at a substantial cost in performance). But even just with GCC and Clang, array access and signed integer can be made safe with a compiler flag, and a violation then traps and this is similar to a Rust panic. The cases which can not be dealt with easily are pointer arithmetic, unions, and free and concurrently related issues. And it is very well possible to isolate and review all of these. This will not find all bugs, but neither does this work perfectly for Rust "unsafe" as this bug (and many others) nicely illustrates.

I guess that means you're using the colloquial meaning of the word safety/unsafe rather than the rust definition. It's worth being explicit about that (or choosing a different word) in these discussions to prevent confusion.

For Rust safety (meaning no UB) most definitely is a property of the language. If a module does not contain unsafe and the modules it uses that do contain unsafe are implemented soundly then there is no UB.

In C UB is a part of the language.


No, in the comment you reply to, I am using safe/unsafe in the Rust sense. E.g. signed overflow changed to trap avoids the UB.

Also "If .. are implemented soundly" sounds harmless but simply means there is no safety guarantee (in contrast to Fil-C or formally verified C, for example). It relies on best-effort manual review. (but even without "unsafe" use anywhere, there are various issues in Rust's type system which would still allow UB but I agree that this is not that critical)

In C UB is part of the ISO language specification, but not necessarily part of a specific implementation of ISO C. If you argue that the ISO spec matters so much, I like to point out that Rust does not even have one, so from this perspective it is completely UB.


> Also "If .. are implemented soundly" sounds harmless but simply means there is no safety guarantee (in contrast to Fil-C or formally verified C, for example).

Don't those also depend on implementations being sound? Fil-C has its own unsafe implementation, formal verification tools have their trusted kernels, it's turtles all the way down.


The implementation itself being sound, yes. And yes, in Rust if you only use sound libraries (in combination), never use unsafe yourself and ignore the known defects in Rust, then it is also guaranteed to be safe. But in system programming, you usually have to use "unsafe" in your own code, and then there is no guarantee and you make sure the could has no UB yourself, just like in C.

Sure. My point is mostly that the problem is less that your safety guarantees rely on correct implementations (since that applies to all "safe" systems as long as we're running on unsafe hardware) and more that the trusted codebase tends to be quite a bit larger for (current?) Rust compared to Fil-C/formal verification tools. There are efforts to improve the situation there, but it'll take time.

Does make me wonder how easy porting Fil-C to Rust/Zig/etc. would be. IIRC most of the work is done via LLVM pass(es?) and changes to frontends were relatively minor, so it might be an interesting alternative to MIRI/ASan.


The safest computer is a rock.

The point is that when you start using rust in the real world to get real work done a lot of the promises that were made about safety have to be dropped because you need to boot your computer before the heat death of the universe. The result will be that we end up with something about as safe as C is currently - because CPUs are fundamentally unsafe and we need them to work somehow.

Rust is from the universe in which micro kernels weren't a dead end and we could avoid all the drivers being written in C.


> when you start using rust in the real world to get real work done a lot of the promises that were made about safety have to be dropped because you need to boot your computer before the heat death of the universe.

Safe rust isn't slow like Python, Go or Fil-C. It gets compiled to normal native code just like C and C++. It generally runs just as fast as C. At least, almost all the time. Arrays have runtime bounds checks. And ... thats about it.

> The result will be that we end up with something about as safe as C is currently - because CPUs are fundamentally unsafe and we need them to work somehow.

Nah. Most rust is safe rust. Even in the kernel, not much code actually interacts directly with raw hardware. The argument in favour of moving to rust isn't that it will remove 100% of memory safety bugs. Just that it'll hopefully remove most of them.


A million memory error bugs is used as a valid argument to stop using C and switch to rust where such bugs are impossible.



Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: