Rust in the 6.2 kernel
lwn.net
lwn.net
Me too, I agree.
The vast majority of people spouting opinions on Rust don't even write systems software, and have never even compiled a kernel driver. Linux, systemd, grub are all written in C and continue to have fewer flaws than trivial userland applications that allow for privilege escelation. The kernel core is incredibly high quality C, and time would be better spent working on the actual kernel security model. Dennis Ritchie himself wrote a paper about the deficiencies of the Unix security model which was designed for a trusting and shared computing environment.
But of course updating the API surface isn't as sexy as writing in a new cool programming language.
Cargo culting this notion that Rust is good because it is a security silver bullet is both ignorant AND dangerous because it moves the focal point away from the areas that actually need work to make Linux more secure. It's also completely asinine to assume that poorly written Rust will have fewer flaws than expertly written C that has been vetted for literally decades.
Iterative improvement has ALWAYS been the answer over throw everything away and start fresh. C tooling has gotten better over the decades, the C standard has evolved, and people will continue to successfully write secure and performant applications in C.
Edit:
Also are you upset that people still use hammers in 2022? I guess if we aren't throwing away all of our tools instead of improving on their design we aren't really seeing any *Progress*
No one is advocating for writing the kernel in “poorly-written Rust”. This whole post is one giant, obvious straw man.
When replacing battle-tested code with newly-written code, you're going to encounter new bugs. Guaranteed.
If you don't have the tests you just listed another reason why using a language with better safety guarantees that will not let broken things compile is a good idea.
The way I see it even battle tested old code can become a liability, if it's surrounding and dependencies change.
I think the only thing I can say wrt poorly/expertly written is I haven't met very many people capable of writing top-quality Rust (most are "I've used it for a side project or two"), whereas my professional network is filled with C experts.
I expect this is due to the types of jobs I work, but the point stands: if we were to try to replace C with Rust we would likely get at most "journeyman" quality.
I have done this. I don't anymore, but my entry into the software world was exploitation of C code and I was particularly interested in the Linux kernel. I'm not really an expert on it, but I've certainly worked with many. Here's an example of some of the work my company has done, which I was not the main driver for but was involved [0]. You'll note the zero days and n days in the Linux kernel. I really don't think compiling a kernel driver is very hard, uncommon, or relevant experience here.
We also attacked Firecracker, a Rust project, and I'd say I'm quite experienced in the language.
> Linux, systemd, grub are all written in C and continue to have fewer flaws
If by "Linux" you mean the Linux kernel, absolutely not, and I can't imagine anyone informed would say that. Linux has tons of bugs all the time.
> The kernel core is incredibly high quality C, and time would be better spent working on the actual kernel security model
A few things:
1. This isn't a zero sum game. Some people are working on making existing kernel code safer, some people are working on Rust, some people are working on new approaches to access control.
2. If an attacker can exploit the kernel your security model doesn't matter, they'll bypass the thing enforcing it.
3. Rewriting the entire kernel's privilege concept is a sort of hilarious ask since it's completely counterproductive (there are tons of powerful access mechanisms in the kernel already) and would be extremely costly.
> It's also completely asinine to assume that poorly written Rust will have fewer flaws than expertly written C that has been vetted for literally decades.
lol sorry, this just really gets me. The Linux kernel is not expertly written C, nor is it being vetted for decades. That's just... so wrong. The kernel codebase is riddled with flaws that are often exploitable. You're just... so so wrong on this.
Further, auditing Rust code for memory safety errors is trivial compared to C. As we showed in our post on Firecracker we could basically just "grep forunsafe" and then manually trace the code from that point.
> Iterative improvement has ALWAYS been the answer over throw everything away and start fresh.
No one is throwing anything away, you obviously are very confused about what Rust in the kernel means.
> and people will continue to successfully write secure and performant applications in C.
At first glance, this is a hilarious statement, but it ultimately makes me sad that developers are so ignorant about computer security that they'd feel ok saying something so obviously wrong to anyone who knows wtf they're talking about.
> Also are you upset that people still use hammers in 2022? I guess if we aren't throwing away all of our tools instead of improving on their design we aren't really seeing any Progress
Terrible analogy.
What it does, however, is assure that an unsafe-free program will not contain any of a certain class of bugs, including invalid memory accesses or data races.
At the same time, it is an objective fact that a huge proportion of serious exploits and vulnerabilities are caused by exactly this kinds of bugs, no matter how much people like you go "just write correct code bro". Formal verification is the way forward and Rust is an excellent first step.
As a bonus, even if you wrapped your whole program in `unsafe`, Rust is a miles better systems programming language than C, in terms of features (imho of course).
Obviously you have never experienced or oversaw what goes in the linux kernel mailing list.
Yes, for the average user Linux is rock solid, but behind the curtains lies the countless sweats of kernel contribuitors fighting the bugs, regressions, memory leaks and crashes.
This is like saying "Uhh mountains are unsafe, I don't get why they put up a handrail at that crowded vantage point over there".
Whether a tool/safety mesure is appropriate is always is about context. I have literally met zero people who work on security or safety critical (e.g. embedded, networking, ...) C code who do not welcome the guarantees Rust brings. It is a complete no-brainer. The ones that complain are the I am a genius who never makes mistakes"-crowd. So precisely the people you should never* let anywhere near anything safety critical.
I write C and I delved into Rust and I can tell you that I trust a vomitted out piece of Rust I wrote more than a piece of C I carefully vetted — and there are rational resons for that. The things that can go wrong at any given point in a C code are more, the ways they can go undetected are more and so on.
Anybody who claims otherwise has not put in the legwork themselves.
Rust is incredibly rigid and stringent by default and if something compiles you can be sure that it now just needs it's logic tested (which is a joy to do in that language).
Though, as you mention, if required I will gladly write it if the situation warrants such a tool. Any suggestions for idiomatic testing?
An it definitely did have its fair share of dangerous issues [1] which would likely not happen if a safer language were used to write it.
1: https://www.cvedetails.com/vulnerability-list.php?vendor_id=...
Have you seen the hammers available in 2022? Not shitty $10 at the DIY store hammers, the kind professionals use? They're making hammers out of Titanium. They're engineering the hammers to produce the best trade offs between striking force and rebound, to deliver a tool that's more effective but hurts less to use for a full day's work.
People have continued to fail to write secure and performant applications in C at an unacceptable rate.
Even Modula-2, released in 1978, has safety features that are yet to be part of C23, about 40 years later.
Rust as a language feels unusually high level for something running in kernelspace, although it never really sacrifices any control. But I wonder how far we can reasonably go in making kernelspace feel like userspace, by importing more of the language's 'vocabulary types', and maybe a few of the best utility crates for comfort.
But besides people having fun out of tree, the kernel has plenty of fundamental complexity that can't very well be reduced. That tends to be the good complexity, the meat of it. What I would like to see is things that aren't essential complexity becoming nicer.
Simple cultural things like better error messages when the tooling fails, or documentation becoming more common rather than the exception. None of this is guaranteed to magically happen just because there's a bit of infrastructure where Make can call rustc. But here's to hoping =)
Take filesystem code for example. It can sound like a conceptually simple and well trodden topic, but if you try writing one there's a pretty large design space and tons of interesting problems to try to solve. And then because of concurrency and the need for performance, there can be very intricate locking to the point it can be challenging to hold the whole model in your head all at once (you can have truncates, writes, mmap, all sorts of very different operations in flight in parallel that interract in funny ways).
Or memory models. Reading memory-barriers.txt is a lesson in humility, I believe you can count on your fingers and toes the number of people in this world who can truly claim intimate familiarity with all the corner-cases and details implied by the model in that little text file =)
But take practically any big subsystem of the kernel, and there tends to be plenty of interesting domain-specific problems and challenges.
But some stuff doesn't _have_ to be hard. Like OP said, there's no inherent reason for error messages and failures to be cryptic or documentation to be sparse. The system could be more transparent or modular, easier to debug/analyze, etc.
I think there's an example in GCC vs Clang here, but I'm not qualified to comment.
Wasn't this a thing that would not happen at all? at least that is what I remember from previous discussions. Another question would be how do you avoid an explosion of crates with different versions for each module.
Rust's String (the mutable owned string type from alloc) implements AddAssign meaning you can write fname += ".txt" and that works, but Rust for Linux doesn't allow that. This is just a really obvious example, there are many other differences
If this is out of tree, AFAIK you can use these all you want. Whether or not you _should_ is obviously a different matter.
In Rust the alloc library's Vec has a function Vec::push(&mut self, value: T)
https://doc.rust-lang.org/std/vec/struct.Vec.html#method.pus...
In Rust for Linux their custom alloc library does not have that function offering instead Vec::try_push(&mut self, value: T) -> Result<(), TryReserveError>
https://rust-for-linux.github.io/docs/alloc/vec/struct.Vec.h...
edit to clarify: the reason it won't help (much) is because most of the things it would help with have already been optimized via features like CoW pages, the VDSO, sendfile, etc.
You can use things like XDP to get a lot of performance back but 0 context switches/ 0 copies is always going to be faster.
It feels like it sacrifices control wrt when you allocate and free-memory.
I understand it's deterministic in rust, but it's not explicitly controllable - or at least I've seen it be.
In userspace it is rare enough that a Rust panic is considered acceptable behavior, but this is not the case for the kernel.
But, it is controllable for sure
To add something concrete, you can manually free memory as well based on some dynamic property if you wish.
I don't think pace is slow. I am actually surprised how fast it is going. Code review is a good practice, and I think Rust patches are being reviewed nearly as fast as possible.
Just to be clear, I agree--"relative" is the key word!
It is slow if you're currently using Rust to develop a driver.
I thought they liked C for its simplicity.
Why would they adopt the modern version of C++? (a language they, or at least Linus, look down upon)
Shouldn't they wait for a language with Rust's safety guarantees but with a more minimal feature set?
The kernel internally makes no promises about ABI even in C, why would that change for Rust?
For userspace, Rust doesn't export anything new to userspace. The kernel APIs remain as they were, and Linus has the same view as ever about whether it's OK to break userspace.
There might be two different definitions of “ABI” in this thread.
The kernel indeed makes no promises regarding e.g. the order in which structure members are declared or the stability of that order from version to version.
It probably can be said, though, to promise (through its interaction with the C compiler) that if you take a structure declaration as it appears in the source code, then in a normally-compiled kernel that structure will be laid out in a manner that’s predictable and most probably even described in a human-readable document. Those rules usually have not changed for decades (even if I sometimes wish they were different).
As far as I know, unless you ask for that specifically, the Rust compiler does not promise any of that, the only documentation for what it will do by default is the source code, and it is free to change the rules from version to version with no notice.
What would be even better, IMHO, would be to bring full software fault isolation (SFI) into the kernel and move to a model where many kernel services are implemented as Wasm modules.
I am surprised Linus agreed to this given that he doesn’t like C++ and usually errs on the side of clear over clever, and we have yet to see tangible benefits of using Rust.
My take however is that C++ is inherently a complex language due to deliberately not sacrificing backwards-compatability of the syntax and semantics, which has been creating a mess as the language has evolved: there are many, many things to define semantically in order to "fit" a new piece in this old already-elaborate puzzle that is the C++ standard.
You cannot say the same thing about Rust.
Please correct me if you see things differently.
At least not yet. My fear is it's _very_ easy to fall in to the same trap as C++ has, and become a big mess. Scott Meyers have a very nice talk here: https://www.youtube.com/watch?v=KAWA1DuvCnQ about all these traps and pifalls that we have to deal with in C++.
That said, I'm starting a bit with rust and enjoy it so a lot, especially the tooling alone is worth it - and if I never have to write another line of C++, I would be very happy (ofc the real world argues I have a lot of C++ code that will need maintenance).
Some devs thrive on that, but most people can’t and shouldn’t have to. And you can see that contrary to what some in the Rust community are saying, there’s a push to use Rust for web. Bonkers.
But there’s too much overlap with C++ and not enough projects. IMO Rust has proven that it can survive, but by far hasn’t reached enough popularity to justify a switch and keeping two complex yet similar languages in ones head is unwise. So I’d rather focus on Go and Python which actually bring something complementary to the table.
When you boil code down to its bare essentials it is moving stuff from one part of memory with a possible transform to another. C does that exceedingly well and gets out of the way. However, the heavy price we pay for that is low type/bounds checking. Pretty much all other languages have tried to get the 'get out the way of part' but with type checking. Rust has taken the approach of you ask for memory and it is tracked at compile time. Not a bad idea. But it seems to trip some people up. Especially if you do not 'get' the idea of object/memory ownership. Which is something you have to do manually in C/C++. C++ has started to put wrappers around all this junk which helps.
And the rust ORM libraries are catching up with other languages so there is no additional advantage from picking a gc collected language.
and we have yet to see tangible benefits of using Rust
Is that the royal we? Have you actually (successfully) tried writing something in it? I am surprised Linus agreed to this given that he doesn’t like C++
Maybe Linus has lost the plot after decades of careful stewardship. Or maybe it is an opportune moment for a closer second look. Who knows.Sometimes that is what I try to do when my expectations are subverted if I care enough about the subject.
Right on point that kernel style C is its own unique world, with a steep learning curve, so lets add Rust with its own steep learning curve. Rust readability isn't any better than kernel C, guess I'm missing the 10,000 hours of reading Rust.
./KISS
Rust is relatively easy to read I think. The borrow checker is what gets all the hate, but that is an issue for writing, not reading. If anything, things like pattern matching make otherwise long if chains easier to read IMO
> we have yet to see tangible benefits of using Rust
Rust eradicates whole classes of errors in safe code, and unsafe code is more safe than the equivalent C or C++. The only theoretical way to not have a tangible reduction in errors would be to believe that a C programmer is good enough to never commit the error classes Rust eradicates, and believe Rust usage would increase the number of logic errors. This seems incredibly unlikely to me.
The whole point of `unsafe` is to define a clear boundary across which invariants must be upheld. In this case, it's those given here: https://doc.rust-lang.org/std/primitive.pointer.html#method....
What's the use case for wanting to convert an invalid pointer to a `&mut` and then not use it?
If I'm missing something, perhaps you could show me some code that highlights the problem (on, say, rust playground).
I've put together a playground at https://play.rust-lang.org/?version=stable&mode=debug&editio.... "Object graph" architectures are common in C++ and sometimes necessary in Rust when building GUI applications or emulators. Rust's pointer aliasing rules invalidate otherwise-correct code, placing roadblocks in the way of writing correct code. And there's so much creation of &mut (which invalidates aliasing pointers for the duration of the &mut, and invalidates sibling &mut and all pointers constructed from them), that's so implicit I don't know what's legal and what's not by auditing code. (Box<T> used to also invalidate aliasing pointers, but this may be changed. The current plan for enabling self-reference is Pin<&mut T>, but the exact semantics for how and when putting a &mut T in a wrapper struct makes it not invalidate self-reference and incoming pointers, is still not specified.)
I've heard statements that addr_of_mut! is an interim API, and the situation may be improved with &raw and unsafe-deref syntax (https://faultlore.com/blah/fix-rust-pointers/). But I expect a production systems language to be an improvement upon C/C++'s usability in their strongest domains out of the box (much like how Send/Sync as marker types not creating UB beyond C++ makes threading more tractable, and enums are superior to std::variant). Instead today's Rust pointer rules redefines swathes of C and C++'s use cases and design patterns as undefined behavior, and the alternative approaches are ugly to express in safe code (Cell/RefCell), and easy to get wrong and tricky and ugly to get right in unsafe code (see my playground), with the promise that they were trying to make programming easier and are trying to create a suitable replacement someday down the line (7 years and counting after Rust 1.0).
It reminds me of C++'s long-running object lifetime saga (https://en.cppreference.com/w/cpp/language/lifetime, https://www.reddit.com/r/cpp_questions/comments/dfglt2), but I've never had to deal with this mess directly, unlike Rust object graphs.
I'm actually pretty sanguine about the general case of invalidating C/C++ patterns. It doesn't surprise me that some new computer science is going to be necessary to help deal with the edge cases exposed by mainstreaming a new paradigm.
As an example, ghost cells are an interesting solution to address some of these kinds of problems https://crates.io/crates/ghost-cell
It feels to me that the question comes down to whether changing paradigms is worth it. I have found overwhelmingly that it has been and with my hard won battle scars, I'll stay here.
Separately, I've been loosely following gcc-rs's development, which has uncovered some surprising hidden complexity in rustc's operation leaking into the Rust language's behavior. For example, for loops "requires Iterators that will need generics and traits to be implemented first" (https://thephilbert.io/2021/02/15/gcc-rust-weekly-status-rep...) and these abstractions likely don't get optimized away in debug builds, and resolving method calls can take dozens of steps evaluating Deref and adding and removing & and &mut (https://thephilbert.io/2022/01/31/gcc-rust-weekly-status-rep...). I think that bidirectional type inference (one time extracting a lambda from a method argument to a variable broke argument inference), complex method call resolution algorithms, and defining the semantics of code (not just validity as with borrow checking) through complex trait resolver algorithms now being reimplemented in Prolog (Chalk and possibly datafrog), collectively do Rust a disservice in fulfilling the role of a transparent, explicit, well-specified language.
For now I'm just waiting for the language I'm hoping for (whether or not it's a language you want to use). My fear is that the inertia and resources of C and C++ on one end, and Rust and pcwalton calling Zig with general-case memory management a "massive step backwards for the industry" on the other end, have drained away available resources from a language (Zig, Nim?, Hare?, etc.) which uses abstraction and higher-order functions sparingly in places where they resolve problems without causing harm, rather than making them the most viable option in the language by crippling alternatives.
I write C++, Kotlin and Go code day to day, and I respectfully disagree. the syntax is incredibly terse. Most rust code I've encountered sprinkles macros with functions, which have slightly different semantics (note this is not an indictment of C or C++'s macros, far from it), and the combination of macros, pattern matching and unwrap lead to code like [0], which frankly I find incredibly difficult to work with.
> Rust eradicates whole classes of errors in safe code, and unsafe code is more safe than the equivalent C or C++.
Completely agree here, and nopt only does it do that it does so _without sacrificing performance_ in many cases.
[0] https://github.com/mozilla/sccache/blob/main/src/compiler/gc...
need_explicit_dep_target = true;
if let DepArgumentRequirePath::NotNeeded = need_explicit_dep_argument_path {
need_explicit_dep_argument_path = DepArgumentRequirePath::Missing;
}
I am currently trying to translate "simple" Rust code to C but I am having difficulties.https://github.com/RustCrypto/formats/blob/master/base32ct/s...
Where is `threshold` and `offset` coming from? How come running `cargo test` in directory `base32ct` actually tests nothing (I get 0 everywhere) despite there being some test code? Messed up `Cargo.toml` file? sighs
Lots of mysteries in Rust, at least for me.
let my_option = Some("test");
if let Some(my_str) = my_option {
println!("I matched this string: {my_str}");
}And none of the existing DRM drivers are likely to be rewritten in Rust.
In the medium term, maybe some in-kernel dependencies might end up getting rewritten in Rust, or maybe some brand-new architecture may have a greenfield development in Rust.
I'm going to speculate that FreeBSD on commodity graphics hardware is safe enough for a few years, but that longer term Rust compatibility might have to be added to the Linux KPI.
I wonder how they're planning on tackling the graphics driver.
Maybe they'll be adding Rust support to that KPI layer sooner that I guessed.
Tell that to Asahi Lina: https://twitter.com/LinaAsahi/status/1577667445719912450
Isn't that already the case? Rust now is very different from Rust in the early days and is also exponentially more unintuitive. Maybe that's fine, I don't know, but I'm personally very much struggling with its quirks.
Rust pre 1.0 kinda doesn't count.
The whole point of 1.0 is that there is a guarantee that there will be no more dramatic changes to the language.
> exponentially more unintuitive
Almost nothing about any programming language is really intuitive.
You mean that C uses paradigms that are intuitive to you due to your experience with it or similar languages.
Rust uses different paradigms that are more immediately intuitive to people with experience in functional languages. And the borrow checker. Which is probably immediately intuitive to nobody, but worth it.
As a long-time C and C++ programmer, I have to disagree. C and C++ have been great and so much software has been written using them, but the time has come to move on.
The majority of software security bugs are due to the lack of controls in C and C++. This is not an opinion or an anecdote, it is a fact:
https://www.zdnet.com/article/microsoft-70-percent-of-all-se...
https://www.zdnet.com/article/chrome-70-of-all-security-bugs...
https://media.defense.gov/2022/Nov/10/2003112742/-1/-1/0/CSI...
Operating systems need to be secure. Operating system kernels even more so.
The Linux kernel could move to Rust or Ada or Nim or something else, but keeping it in C is an invitation for continued security problems:
https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=%22linux+ke...
Time will tell, but Rust support for use in Linux kernel development is increasing.
If it solves problems and is easier to use, it will gain traction and see wider adoption.
std::string_view make_view(const std::string& in)
{
return in;
}
Is an absolute minefield, as is: std::vector<int> vec = {1, 2};
std::span<int> sp = vec;
vec.push-back(3);
These are using safe, modern C++ techniques that are designed to help catch errors, but are still absolutely lethal.Basically all the ways that ranges::view can go wrong and even trigger UB.
Finally, the address sanitizer helps you with that, however I wonder how many actually do use sanitizers?
Overall, I agree that something could have been done to prevent temporary objects at all. From my newbie point over view, it seems the standard API has the tendency to be lower level rather than ergonomic: it's up to you to know how to use it (and fuck up with it). Quite sad, because that kind of makes the language more difficult to use than it should be. I don't have enough knowledge, and I wonder if making the constructor on (const std::string&&) private/deleted would have been enough to prevent it?
The second case I guess the principle is similar. Not sure if the sanitizer finds the error there, but still scary.
In a short, C++ approach is to give any object a "blank state" which it must turn into after the value was moved from it. It is an attempt to track state "value was moved out" dynamically. Rust tracks it statically by treating a variable whose value was moved out as uninitialized variable and ensuring that are no accesses to uninitialized variables.
It's a different approach, and definitely less efficient than compile-time checking, but if your program is not too complex I think it's OK. Especially if you use such sanitizers at the unit test level.
I don't have enough experience to say if it actually works in general though, because as usual everything on paper is always working.
I use C++ to write general backend servers / web apps among the other things. Not a single one ever deployed without passing sanitizer tests.
Not that my code would ever look like the examples above. I personally consider modern C++ safe enough for decent level programmer.
Of course I can not guarantee safety buy my servers run non stop servicing tens of thousands of client for months between updates without any hick-ups.
I looked at Rust to see if it can offer me any practical advantage vs modern C++ for what I do and so far did not see anything convincing enough.
EDIT: Just to know: clang sanitizers or anything else?
I understand that this is rather unique position but this is what I wanted, worked for and had managed to achieve. I mostly design and create products from start to finish for my clients. Been on my own for 20+ years already.
BTW. I doubt that Rust or any language for that matter can be a cure from shitty programmers. Some help sure but they'll manage to fuck things up regardless on a different level.
I am quite happy no longer to do code review of such deliveries.
Hence why I only use C++ on personal projects.
This is the problem with naked pointers in the first case. We've had I don't know how many years of experience to tell us that relying on programmers to not make mistakes is a terrible idea. If documenting requirements fixed these issues we would still just be able to write C.
The problem with sanitizers is they're an opt-in addition, and like static analysis tools they have a tendency to be have some false positives, which causes people to distrust then and say "but I'd never make that mistake". Compiling with asan enabled would cause our CI build times to double, as we'd need to build with and without (and we have 4 configurations over 3 platforms. My previous project had 3 configurations over 9 platforms).
It seems that the primary security argument is that N-1 types of issues is better than N. I would argue that the formula is really N - 1 + X, and that we're all focused on the very positive "-1" aspect, but what's the value of X? In other words, what are we trading off by using Rust instead of C in the kernel? Why trade a language which we know the pitfalls of (N) for a language that's potentially adding X pitfalls, and if you're going to argue that Rust has no pitfalls, then to me that's just the kool-aid talking. Realistically, in a new language, you don't know if X is 0, and adding unknown unknowns are precisely the one thing you do not want in a critical piece of software like a kernel.
Furthermore, if OSes need to be secure, and system kernels need to be even more secure, which we all agree on, then all you're doing by advocating against using a stable language with known pitfalls like C is you're lowering the knowledge bar ("hey look I can write kernel code now because I won't introduce memory issues!"), thereby increasing the pool of people who will make logical mistakes out of lack of knowledge, which you will not eliminate with static analysis.
C is not ideal, but it's a practical way to gate the entry to critical software, because
1. C, the language, has a handful of pitfalls, while the software written in any language has orders of magnitude more avenues to exploit it (e.g. access permissions, communication protocols, environmental assumptions, etc).
2. Most of what's difficult in C stems from the realities of dealing with computer architectures. If you can't be bothered to learn the ins and outs of C, you're not fit to write portable low level machine code in a kernel just yet. Just because we can be reasonably sure you won't introduce a memory problem is not sufficient guarantee that you won't do stupid things in the kernel that will cause security problems in a different way.
In the end, I hope I'm wrong about Rust and X is 0, but it seems to me that there's a much better way to ensure we get to an N-1 situation without an X: introduce the borrow checker in C.
Why throw the baby with the bath water? The software industry is very aware by now of the pitfalls of rewriting a project instead of making incremental changes. Bring the memory safety to C. You get 50 years of stability and well documented issues, while still removing a whole class of bugs. Now that would be an absolute win.
I don't think it's fair to blame the issues that code written in C can have on incompetence.
Is it? Rewrites only succeed if the original people rewrite the original code, because code is just a serialization of someone's thoughts. That's why it's the people who are the most important assets in a project, not the code. When the original people leave, projects typically fail.
Rust is not being written by the same people who made GCC. It's a different group of people who are trying to do better than C. I wish them best of luck, but to say that they're "building on top of 50 years of experience" is implying that the software they generate is as good as software that has been battle tested for decades on numerous architectures.
> I don't think it's fair to blame the issues that code written in C can have on incompetence.
It's not a blaming game. Code written in C has issues because C has issues, but are you then saying that Rust has no issues? Will never have any issues? What's the bar here?
Rust eliminates an entire class of issues that constitute 70% of C bugs (and largely the most critical bugs at that) by design. Nobody's saying Rust has no issues and never will, but they are saying that this is an objective improvement.
Ok, so we agree that Rust must have some issues, some of them undiscovered yet. What suggests that Rust won't introduce issues that will be larger than the 70% of issues that it solves with C? Because to me, it just sounds like we can't know so we're being hopeful that we don't run into that situation.
Rust was released 12 years ago.
For a given value of "issues," that's an accurate portrayal. Statically verified memory safety at the language level is a central part of Rust's mission statement. This is an essential difference from C in how it approaches that problem space. Rust might "have issues" in the sense that compiler bugs are exposed by particular edge cases, or that dealing with certain problems is needlessly difficult or verbose, but reducing everything to "issues" to portray it as equivalent to C is absurd. You might as well say they both have "syntax" and conclude that all code written in Rust is still written in C.
If professional chefs would constantly maim themself and each other despite extensive occupancy safety training, knives have no place in the hands of a responsible professional.
Using C is the SE equivalent of taping down one button of the two-hand control device of a die cutter.
If, what ever the happens there, is not up to your standard of professionalism, maybe your standard is unrealistic?
Now you're measuring how many people drowned, and you're saying "let's enforce that everyone use a flotation device, and there will be fewer deaths".
Sure, but there will also be fewer actual swimmers.
To make this more concrete, you can't look at something in aggregate and say "well, we are having this one type of issue, let's just throw everything away and start over".
Yes we must do something, I just don't think that Rust is the best answer. Maybe have an actual safety training. The language is hard. Write a compiler for it, study the spec, simplify the spec, upgrade the language, etc.
This is mincing words and a bad-faith argument. I consider this discussion pointless and will not continue.
If working on the Linux kernel is the training then you're measuring incidents that occur _during training_.
The whole point of training is to practice and make mistakes _before_ the actual work. Once they're considered experts, you can measure the knife cuts in their work.
It does not misrepresent what you said, and failure to see that means you did not actually understand it
> Your argument is fatally flawed due to the reason i stated
This is then false as well, and my argument stands.
> this discussion was and remains over
It's good to agree
Oh yes, I do. I do know what i mean and I can see that your quote of it was either extremely unintelligent, something you can by definition not see, or intentionally miss representing and therefore bad faith and therefore something you by definition lie about.
I'm heavily leaning to bad faith, because you never make any attempts to refute arguments anywhere in the whole thread.
So, of course, I'm obviously correct on on this one, so it's good thing either of us wasted any time talking on the substance.
Some of the first software I ever wrote was C and then C++. I’ve since worked on Billion+ line Java code bases. I’ve also worked professionally in python, ruby, Type/JavaScript.
When I picked up Rust 15 years into writing software, it taught me to write better code.
Let me repeat that: even after extensive training and professional use of other languages, rustc the compiler taught me to write better code.
If you’re looking for a “we should train people better to not make mistakes” you want people to learn software development from rustc. That training is very transferable back to C and C++ and even Java. Could this automated “teacher” be better? Sure. Could it be less strict? In certain cases sure. Is it the best training program we have? This best I’ve ever seen.
I highly recommend you at least try it! :)
This is patently untrue. What do malloc and free have to do with computer architecture? Most of C's difficulty is deficiency of the language unrelated to its low level nature.
proof or gtfo.
> What do malloc and free have to do with computer architecture?
You're talking about a library at this point, but ultimately the root cause for allocating memory is because memory is limited, unlike, say CPU time. We do not allocate CPU time explicitly, even though there could be a CPU architecture that could support that, and C would run on it.
> Most of C's difficulty is deficiency of the language unrelated to its low level nature
Do you think that comparing signed and unsigned integers is also unrelated to CPU architectures?
Sure, and we have driving licenses to make sure people know how to handle a car, but you won't find a race driver who doesn't use seatbelts. Because even the best humans are still human. Arguing against safety measures because you think you're too skilled to make mistakes is also something to be avoided.
We agree though that adding memory safety to C would be the equivalent of racecars with seatbelts.
Well it's been 6 years since Rust 1.0 was released. And it's had extensive adoption over that time period, including in projects used in vast numbers of devices and services. Firefox runs on Rust, Dropbox runs on Rust, AWS and Cloudflare are both using Rust for core services. Android is shipping Rust. Microsoft is looking at adopting it in Windows. What would count as a long time for you?
Lol you do realise this is a dunk on C right? 40 years of experience and we have seen all kinds of stupid shit written by very smart people. Just imagine if the kernel wasn’t written in C and someone wants to introduce C instead.
If you want robust and well known, pick ada/spark. That language and it's culture is all about security and has been for decades. It also doesn't have quite the performance of c and rust.
And about the sharp knife... I have worked embedded c++ for decades now, some safety critical where we inspected the assembly generated and verified 100% code and branch coverage, on the assembly. I have made one memory safety error that escaped test in those years. That has been found yet...
I'm not in the kernel culture so I don't know. But it doesn't seem like it values things like static analysis, unit test coverage, san builds etc. It seems from the outside they are simply relying on their knife skills instead of measuring the quality of their work. Microsoft and Google both say over 70% of their exploits have come from memory safety errors. So it isnt M-1 + x. It is M0.3 + X. And rust isn't super new, so we have some ideas about X from early production use in firefox and dropbox. And we have an idea about how many knife users never cut themselves given even just the recent history like beacown.
It is time to start the incremental change.
Aw, yes, the C makes genius programmers meme. I think we've seen very little evidence this is the case. C may be useful to know. Learning C well, because it is difficult, may be useful. These things are speculative, but let's grant them. Unfortunately for you, the proof of the pudding is in the eating? The fact that lots of C code has lots of problems should be an indication that, not only is C not working to solve many modern problems, but that, if C gives us geniuses, we aren't seeing the results.
> introduce the borrow checker in C
You: Just glue on some wings and see if it flies...
Me: That's not how this works! That's not how any of this works!
> Aw, yes, the C makes genius programmers meme
Not claiming that. I'm only claiming that to be effective at C you must understand computer architecture well. You did set up a strawman here.
> if C makes gives us geniuses, we aren't seeing the results
Perfect strawman execution.
> Just glue on some wings and see if it flies...
Right, because the only way to fix problems is to rewrite? Typical inexperienced programmer attitude.
You still have this problem: We have lots and lots of buggy C code in critical software.
If your claim is to be effective at C you must understand computer architecture well, but unfortunately few are effective at C, because few really understand computer architecture well, and unfortunately we have lots of buggy C code as a result, I'm not sure where you are after that?
Is it possible C hasn't worked as the gate you say it has worked as?
> to be effective at C you must understand computer architecture well.
So long as we are here, I would also quibble with this claim. Knowing loads about C, or more specifically how to prevent C memory safety issues, is perhaps not the best indication one knows anything about network security or cryptography. In fact, we know the reverse is the case. There are plenty of OpenSSL devs who are domain experts in cryptography, who have not proven themselves well adapted to deal with C memory safety issues. Something like Rust sounds perfect for such a use case?
> Right, because the only way to fix problems is to rewrite? Typical inexperienced programmer attitude.
What do you think writing a borrow checker for C would entail?! Do I think it would be a tremendous effort, with little gained? Oh yeah. Do I think we should just use Rust for new software? Yep, because why wait for this C borrow checker? I just don't get it. I think saying "Just use Rust" makes me sensible. "Let's build a borrow checker for C!" is tilting at windmills.
Anyway, in terms of bug severity that 70% is also way worse than the other 30%.
The rest of your post is all just silly "people should code better" and isn't worth responding to.
I don't disagree, but this is objectively just hope. The only reason N*7 is huge is because C's adoption. There is nothing to suggest that Rust's N*(bad issue %) is smaller than Cs if it had the same adoption as C. It's fanbase is just trying to increase its presence at the expense of C, to then be able to say "see, we did it, we replaced C and we're better off!", but today, it's equally likely that the outcome is going to be "well, we didn't know about <insert issue here> at the time".
Great! So we agree that no person should have any business writing C. It's proven time and time again that even the best of the best C developers can't write safe C code.
This is fine for many use cases, but not for the Linux Kernel IMO.
correct
> unstable
incorrect
> There are lots of features you need the nightly compiler for
inaccurate
There are lots of features that are currently nightly-only. you may or may not need these depending on what you are doing. In particular kernel development does require quite a few nightly-only features, but there is no reason to think that all of these won't make it into stable rust in due course.
> and there are large breaking changes with every edition every few years
totally incorrect
...but then you go on to agree?
And yes, presumably at some stage there will be a migration of the kernel from nightly to stable. There may be breaking changes. This will be a one time thing, and, (based on the current difference between nightly and stable and rate of change) not much more of a hurdle than changing C editions or gcc versions.
See my other comment.
Features land in all editions unless they specifically would be backwards incompatible otherwise.
Yes, you can stay on an old edition forever and not experience any of the breaking changes. But there are features that the kernel needs that rust does not support yet, such as a fallible allocation API. These features will trickle in over the next few years. In order to use them, all of the kernel's rust code will have to jump versions and deal with the breaking changes.
https://lwn.net/Articles/885941/
https://lwn.net/Articles/855095/
This happens rarely and is not considered especially burdensome. Currently it is believed that Rust editions would be handled similarly and be no more burdensome.
Linux was written from day 1 in "ANSI C", which is C89 (Edit - it was actually C89 with GNU extensions. Thanks for the corrections). Only now, after 30 years of development, are they considering moving to C99, which is itself over 20 years old.
This is laughably untrue. If it were so, ClangBuiltLinux project would have been trivial, but it was anything but. Linux was written from day 1 in GCC C, and it still is.
Actually, Linux was written from day 1 in the GCC dialect of C (that is, "gnu89"), using GCC extensions without worry. Compiling the kernel with clang only became possible after clang implemented nearly all GCC extensions the kernel used.
> upgrading to a new edition of C OR version of gcc
the latter absolutely does happen every few years. Maybe I shouldn't have lumped the C thing in with it, but whatever.
The list of backwards incompatibilities in the 2021 edition was pretty small.
I don't think that there will be a need to migrate language versions all that often, and, based on what I've seen of how Rust handles backwards compatibility, I don't think it will be an especially big leap.
Will changes to interfaces in nightly be handled similarly to how internal kernel API changes are handled? - i.e. if your code is in-tree then the mantainers of the Rust integration will update your code to ensure compatibility with the new nightly interface.
It's done that once, in 30 years.
New language features may require a new edition, though the vast majority of them don't - here's the list of all the changes in Edition 2021 (a new one is released every 3 years): https://blog.rust-lang.org/2021/10/21/Rust-1.56.0.html
My understanding is that it might not be entirely settled yet, and is still being discussed. That could explain why there isn't much solid documentation written yet
Have you actually tried Rust or are you just copying talking points?
When people talk about big Rust binaries they often forget to strip debug information. Doing it can easily shed half of the binary size. And there are other relatively well known ways of reducing binary size (such as strategically using dynamic dispatch instead of monomorphization, using abort for panics, compiling with opt-level=z/s, etc.).
$ ldd `which rustc`
linux-vdso.so.1
librustc_driver-1ca4abb0311ec689.so => /lib64/librustc_driver-1ca4abb0311ec689.so
libstd-f1d4d1a0beb2c43e.so => /lib64/libstd-f1d4d1a0beb2c43e.so
libc.so.6 => /lib64/libc.so.6
[...]While you may be talking about larger boards, the fact that Rust code can fit into even smaller ones means Rust isn't the issue here.
Regarding multiple rust binaries each bundling a copy of stdlib and inflating the space, this approach would only link the bits of the stdlib each binary uses, but still it’s not ideal. Three approaches I can think of are:
1. Use a file system that compresses its contents like btrfs or zfs or their embedded variant. It should reduce the redundancies.
2. Go the busybox way, as you said. This requires work but it’s definitely doable.
3. Link stdlib dynamically. There is a way, I believe. Rust maintains a “stable” ABI as long as you use the same rustc version if I’m not mistaken.
4. This is ridiculous, so I don’t even count this as a way, but what if you just stored the .a static libs and did the linking on demand into a temporary file that would then be executed?
I personally have never encountered 50MiB optimized stripped and LT optimized rust binaries, only ‘materialized’ which was like 138MiB but it contained debug symbols, no LTO and is quite a large database application.
https://android.googlesource.com/platform//system/bt/+/83498...
1. Rust will become the main language for new projects
2. There will still be an enormous amount of C that will be maintained for many decades and the majority of "lines of (systems) code" will be C rather than Rust for decades
As long as there is just one Rust compiler (Or are there two? How about the ABI of the second?),it doesn't matter much. But one day it will.
Nope. They've thought that through.
(In fact, cargo is only used to build test helpers. https://github.com/Rust-for-Linux/linux/blob/rust/Documentat...)
I wonder what that's supposed to mean?
Hm... I could screenshot a single character and say: "I chose this character because if it's removed, the no one can log into twitter, and the whole system stops working.
Or maybe I'd show a line of code that initiates advertiser charges, and say: "without this line of code we'd just be giving away as space, and we would lose most our revenue!
But actually, I'd probably try to find a fiendishly complex snarl of logic (yeah, I sometimes do those, on my bad days) to befuddle the poor fella with.