Rust in the FreeBSD kernel

I am following the Linux Rust experiment with much interest.
The most curious thing for me is where and how they will harness the (comparative to C) great power of Rust.
But so far I see only simple and trivial kernel drivers being done in Rust.
Apropos serious operating system use of Rust, have you seen the work of the Google Android (a Linux fork) team?

About three years ago Google decided to analyze the CVE for Android bugs, and pick a hot spot (modules in the codebase where the most defects were found over the past several years) to refactor into Rust. That experiment was successful enough that they kept going.

Apparently the team had almost no Rust experience when they started.

Newly reported exploitable defects in Android began falling immediately, and have continued falling, steadily.

Rust in Android: Move fast and fix things.
 
Aren't device drivers inherently not suitable for safe programming? Every time you write into device memory it is unsafe.
There's at least some theoretical advantage to implementing a device driver in memory safe languages due to the exploitability of the non-DMA parts of the driver.

Every other member of this forum knows more about this than do I, but a quick glance at the CVE for FreeBSD shows some candidate examples (one would need to look at the code commit history of the patch to see for certain.) Consider CVE-2025-0373 Buffer overflow in some filesystems via NFS including tarfs and ext2fs as one possible example.
 
I don't think hatred is what drives most people and even organizations. There are valid technical reasons to use FreeBSD that are not related to the licenses.

Most of the push for Rust+MIT is ideological, though. They do hate the FSF because of Richard Stallman.
Apple, rather famously, spent about 20 years and invested a few billion dollars to expunge the GPL from macOS. This was one of several motivations behind LLVM/Clang.
 
This is the 39c3 talk about FreeBSD jails. We discussed the general conclusions in a different thread, but I want to add it here because it mentions Rust in the FreeBSD kernel as one recommendation. They found 50 or so bugs mostly related to jails isolation and a majority of those wouldn't have happened in Rust.


47 min 40 sec ia the recommendations is Rust.

54:50 is a followup question - would you turn on integer overflow checking?
Color me skeptical
 
Here is a paper on using LLMs to help with memory safety in C:

 
Here is a paper on using LLMs to help with memory safety in C:

April arrived rather late in the year.
 
April arrived rather late in the year.

I don't see it as that hopeless.

I see it as something you let loose on your existing code, which you already engineered to have no memory errors you are aware of. The LLM gives additional suggestions. Outside an occasional misleading comment that could confuse you into relexing your perfectly fine own code I see this as a useful additional eye on the same code.
 
Benny Siegert, a well known NetBSD developer, gives some reasons why in his opinion Rust will never make it into the NetBSD kernel:

First of all: I’m not so sure that Rust in the kernel would have been chosen to cater to a younger developer audience. It’s probably more on merits such as memory-safety. Rust has a number of fans who are power users. I would be interested to learn why you think this is an odd decision.

NetBSD already has taken a much odder decision in the same space, by adding Lua into the kernel! This was also much discussed at the time. I have not used it, but apparently Lua is useful for rapid development and prototyping of kernel drivers.

Note that in general, NetBSD is more conservative in its technical decisions than FreeBSD or Linux. Rust in the core of NetBSD is probably a non-starter for multiple reasons:

  • There are many architectures that NetBSD supports where Rust is not available. This is probably the most important argument against Rust.
  • Today, even getting a Rust compiler running in the first place is hard.Keeping Rust working (in pkgsrc) is quite a bit of work, resting on the shoulders of a few developers.
  • In general, the bootstrap relies on a binary package of the previous version. This is unacceptable for an otherwise source-only, self-contained distribution like the NetBSD sources.
  • For Rust to be used in base or in the kernel, the compiler would also have to be part of the base system. This means adding a lot of code and maintenance. It would not be impossible though – we already have LLVM (a major dependency) in base. But again, the binary bootstrap kits are a significant hurdle.
  • Finally, the release cycles of Rust are not compatible with the NetBSD ones. We support the last two major releases. Today, that’s NetBSD 9 and 10. NetBSD 9.0 was released in 2020. Rust 1.41 was the current version back then. If Rust 1.41 had been part of NetBSD 9, it would be useless for anything except compiling NetBSD itself – Rust 1.41 is so old that basically no modern code would compile with it. Not great.
 
Rust does not eliminate memory-related bugs in a kernel context; it merely shifts where and how they occur. The moment Rust code interacts with existing C kernel infrastructure through FFI, shared data structures, or unsafe blocks the language’s safety guarantees basicly disappear altogether.
 
Rust will never make it into the NetBSD kernel:

There are many architectures that NetBSD supports where Rust is not available. This is probably the most important argument against Rust.
Supporting a billion architectures (for example, VAX, last made in the 80s) is NetBSD's thing, so this is predictable. FreeBSD on the other hand is dropping driver support for FireWire (last made in 2000s)
 
Rust does not eliminate memory-related bugs in a kernel context; it merely shifts where and how they occur. The moment Rust code interacts with existing C kernel infrastructure through FFI, shared data structures, or unsafe blocks the language’s safety guarantees basicly disappear altogether.
Indeed. The problem is that the viral hordes don't see that. This complex and unsafe work is hidden in the depths of all the dependencies that these guys just flippantly pull in from crates.io.
 
Indeed. The problem is that the viral hordes don't see that. This complex and unsafe work is hidden in the depths of all the dependencies that these guys just flippantly pull in from crates.io.

Don’t even get me started on crates.io. In my opinion, it’s a prime target for supply-chain attacks along with nodejs and python packages. People often respond with “but the code is open, you can inspect it,” but the xz-utils incident is a perfect reminder of why that argument falls apart. A backdoor was introduced by a trusted maintainer and went unnoticed.

Finding vulnerabilities in real-world code is hard, especially when you don’t already know what you’re looking for. Simply having access to the source does not mean it’s being meaningfully reviewed.

Thats one of the top reasons I use FreeBSD over Linux, you don't know who's doing what to the Linux userland!!
 
Kernel contexts are often tied tightly with hardware specific things, and some (maybe most of) hardwares are mutually "memory unsafe" by sharing buffers, by memory mapped I/Os, ...
Rust should drop supports for mutually memory-unsafe operations like "volatile" and let them implemented with non-memory-safe languages.
The only unsafe part should be limited with the interface definitions.

This way, anything cannot re-implemented to Rust can be easily considered as "mutually memory unsafe".

This should be applicable with all other "stating memory-safe" languages.
 
Kernel contexts are often tied tightly with hardware specific things, and some (maybe most of) hardwares are mutually "memory unsafe" by sharing buffers, by memory mapped I/Os, ...
Rust should drop supports for mutually memory-unsafe operations like "volatile" and let them implemented with non-memory-safe languages.
The only unsafe part should be limited with the interface definitions.

This way, anything cannot re-implemented to Rust can be easily considered as "mutually memory unsafe".

This should be applicable with all other "stating memory-safe" languages.

The problem is that in a kernel, the unsafe boundary isn’t small or well defined. Hardware, DMA, MMIO, shared buffers, and existing C subsystems all continuously violate the assumptions Rust relies on for memory safety.

If the foundation you’re building on is already memory-unsafe, wrapping parts of it in a memory safe language doesn’t meaningfully improve correctness it just moves the unsafety around and obscures it behind interfaces. Unless the entire system is designed around memory safety from the ground up, you end up with a false sense of security while still relying on large amounts of unsafe code underneath.
 
Unless the entire system is designed around memory safety from the ground up, you end up with a false sense of security while still relying on large amounts of unsafe code underneath.
This should include the designs of hardwares. Not OS and/or firmwares alone. Mutual memory safety is so difficult.
 
Given things like rowhammer, not even the hardware is too sure what memory it is to touch and which not.
We can make stuff hard and harder, but 100% is off the menu.
 
The only high level language I have seen that does allow direct interop with C, is basically C++ and Obj-C. Actually one of Stroustrups key design decisions or C++ to be successful was because he understood that interop with C was so important. I imagine that had this not been the case, the language would have failed to receive adoption by the industry.
Zig does as well. To me it's much more interesting than Rust for that reason. It provides a modern ergonomic dev experience; has mechanisms to make memory safety more accessible without enforcing it like Rust; and integrates well with C (including being able to compile C).

Its main shortcoming for committing to a major project is that the language is too unstable - every new release requires rewriting some aspect of your code. But for utilities that call C libraries, I think it's by far the most interesting of this recent generation of languages.
 
Given things like rowhammer, not even the hardware is too sure what memory it is to touch and which not.
We can make stuff hard and harder, but 100% is off the menu.
Fortunately, 100% isn't typically necessary, it just has to be good enough that the work to exploit it isn't profitable in most cases. And that can be accomplished using a series of different measures from hardening systems, to not paying ransoms to improving the banking system so that money is harder to transfer without being properly followed.

Where memory safe languages make the most sense are VMs, jails and the like.
 
Given things like rowhammer,
My laptop's unlocked BIOS has a setting under Memory to "Actively prevent Rowhammer"; I disable it :p

I'm not too impressed with software trying to do stuff hardware does at lower-level; my hardware lets me disable safety, but apps want to force it on no-disable on some higher-level ideology like the dev knows better. I know my security requirements and how to balance performance :cool:
 
Excuse me the late entry, but
I really hope Rust does not make it into the kernel. Not because of Rust itself and not because I am gatekeeping or just old.

I do not want Rust in the kernel because I do not want zealotry infiltrating the system I hold so dear. I do not want civil discussion and careful thought to be driven out by force, browbeating, and strong arm tactics. This is the exact behaviour that seems so prevalent in people campaigning for Rust.

Rust's advocates seem to both simultaneously understand the value of working code and woefully undervalue it.

I'm certain they recognise the value given the many attempts to get established projects to rewrite in Rust rather than starting their own from scratch. The value of an established project's name is clear. The momentum of its community even more so. It is not so clear that they see the value of the code beyond a base from which to capture the former two. Incremental conversion, though not ideal, is simply a necessary step and the cost of the real value. The utility of having one's foot in the door certainly could hardly have escaped notice either.

On the other hand, it is also clear is how advocates underestimate and downplay the costs of rewriting. Unintentional incompatibility (as cracauer@ has pointed out), regressions from previously fixed bugs, and introducing new bugs are serious risks that must be acknowledged. The chance to revisit past design decisions will undoubtedly lead to "second system syndrome" unless one is very disciplined. Such things are rarely mentioned in rewrite discussions. Nothing in Rust's memory safety cannot help with any of these.

Whether the tenor of rewrite discussions is due to lack of experience, lack of concern, or intentional duplicity, I cannot say.
What I can say is that I find it very disagreeable working with such people that demand so vehemently that others listen while their own ears are so tightly shut.

I don't know if the designers of Rust, themselves, are pushing as hard as the advocates are for its use in kernel space. I suspect not, at least for the time being, given their seeming lack of a response to the grave technical issues leveled against such use. I suspect that they're more concerned with developing languages than entering into the fray. I can't fault them for that.
 
....young people aren't into low levels and C and classic language ecosystems, ....
Not an argument for or against, but just an interesting data point. In the 1970s, General Motors wrote an operating system for the Control Data Corporation Star-100 computer. It was called the GM Multiple Console Time Sharing System. (https://en.wikipedia.org/wiki/Multiple_Console_Time_Sharing_System). (Why was GM writing operating systems? IIRC, they were looking for better graphics support.)

MCTS was written in Malus, which was a stripped-down dialect of PL/I. The application language, a fuller dialect of PL/I was called Apple. (I have been told that Malus is Latin for Apple. Google translate thinks that Malum is Latin for Apple, and Malus is Latin for bad.)

Here is where this all ties into the current discussion. There was no assembler. Malus had an inline instruction, which could stick a hardware instruction into the middle of the Malus code. (I never worked with Malus, I just read internal reports when I worked for GM, so I don't know how it hooked into the Malus code.) They said that 10% of the kernel was inline instructions, while 1% of the userland was.

So these guys (and a few women) who were in the 30s or 40s, were also not into low levels. (They weren't into C, because they were apparently influenced by MULTICS, which was PL/I based.)

Now one could argue about whether or not this was a good approach. In the past, there have been both COBOL and FORTRAN compilers that allowed inline assembly language. Besides not being portable (which was less of an issue back in the day), when you language abstracts you away from the underlying machine code, then you suddenly are working at the machine code level, it is a context shift that encourages errors. It is similar to the problem commercial pilots have when they are just chilling while the autopilot flies the plane, then the autopilot fails, and suddenly they have to fly it manually, but first the have to establish their attitude and location if they haven't been playing close attention.
 
Back
Top