Live data from Hacker News

Smart pointers for the kernel

lwn.net

71–80 of 120 posts

Re: Smart pointers for the kernel

#71
post #8

Earlier quoted context omitted.

Rust’s whole premise of guaranteed memory safety through compiletime checks has always been undermined when confronted with the reality that certain foundational operations must still be implemented using unsafe. Inevitably folks concede that lower level libraries will have these unsafe blocks and still expect higher level code to trust them, and at that point we’ve essentially recreated the core paradigm of C: trust…

I don't think you're giving Rust enough credit here. For those projects that don't use any unsafe, we can say -- absent compiler bugs or type system unsoundness -- that there will be no memory leaks or data races or undefined behavior. That's useful! Very useful! For projects that do need unsafe, that unsafe code can be cordoned off into a corner where it can be made as small as possible, and can be audited. The rest…

With C you can take proven algorithms from CLRS and translate them directly without boilerplate.

The same algorithms already become ugly/obfuscated in idiomatic C++.

Looking at the macro in the LWN article, the approach of Rust of using wrappers and boxes and complex macros to emulate features appears to go into the same direction as C++.

Still in 2024, gdb is far less useful for C++ than for C. C++ error messages are far less useful.

All of that matters for reliable software, crashes (which can occur anyway with unsafe) are just a tiny part of the equation.

Re: Smart pointers for the kernel

#72
post #64

Earlier quoted context omitted.

> If you limited wrong to "memory safe" Yes, because this is a discussion about the value of "unsafe", so we're only talking about the wrongs that are enabled by "unsafe". > and also ignore that unsafe parts violating invariants can make safe parts of Rust to be wrong. If I run a line of code that corrupts memory, and the program crashes 400 lines later, I don't say the spot where it crashes is wrong, I say the memor…

It does not invalidate an argument that you do not want to talk about it. Regarding the second point: yes, you can then blame the "unsafe" part but the issue is that the problem might not be so localized as the notion of "only auditing unsafe blocks is sufficient" implies. You may need to understand the subtle interaction of unsafe blocks with the rest of the program.

> the problem might not be so localized as the notion of "only auditing unsafe blocks is sufficient" implies

It depends on what you consider "problem" can mean. An unsafe function needs someone to write unsafe in order to call it, and it's on that calling code to make sure the conditions needed to call the unsafe function are met.

If that function itself is safe, but still let's you trigger the unsafe function unsafely? That function, which had to write 'unsafe', has a bug: either it's not upholding the preconditions of the unsafe function it's calling, or it _can't_ uphold the preconditions without their own callers also being in on it, in which case they themselves need to be an unsafe function (and consider whether their design is a good one).

In this way, you'll always find unsafe 'near' the bug.

Re: Smart pointers for the kernel

#73
post #58
post #23

Earlier quoted context omitted.

Also Rust is far from the only language that gives you escape-hatches out of the safety sandbox where you can make a mess if you're reckless. Java, Python, Go, C#... (heck, C# also has an `unsafe` keyword) but hardly anyone would argue those languages have the same safety issues that C has.

In C unsafe code is typically marked by surrounding it with {braces}.

Good one! ;-)

Re: Smart pointers for the kernel

#74
post #39
post #27

Earlier quoted context omitted.

The potential for undefined behavior is, I will agree, potentially fairly serious, especially depending on specific circumstances... (In most cases it should reliably hit an unmapped page and cause an exception, but there are exceptions on weird targets or with huge offsets.) But, you can pretty much entirely ignore it if you can just guarantee that the pointer isn't NULL in the first place, which not only prevents y…

> (In most cases it should reliably hit an unmapped page and cause an exception, but there are exceptions on weird targets or with huge offsets.) The kernel is one such exception.

Depends a lot on the system, but I don't think this is much of a problem with modern Linux systems. Looking on my machine, vm.mmap_min_addr is set to 65536, not to mention the mitigations modern CPUs have for preventing unintended access to user pages. Just as in userspace, a null dereference on a modern Linux system is almost guaranteed to hit a trap.

That said, a potentially bigger problem is what happens when handling it. Instead of a kernel panic, nowadays you get a kernel oops. That's definitely going to have weird side-effects that could have e.g. security implications. But honestly, this all goes back to the original problem: in a lot of cases, there just isn't really a more sensible thing to do anyways. Even if the null dereference itself is potentially scary, by the time you get to the point where it might happen, you've already missed the actual underlying problem, and there might not be anything reasonable you can do.

I will grant you though that there are definitely some exotic cases where null dereferences won't trap. But this wasn't the point, I glossed over it for a reason.

Re: Smart pointers for the kernel

#75
post #68
post #20

Earlier quoted context omitted.

It's not the same unwritten social contract: in Rust even the unsafe code has the same stricter type signatures as the safe code, so there is a formal way to judge which part of the program is at fault when the contract is broken. You might say the contract is now written. :-) In C, the type system does not express things like pointer validity, so you have to consider the system as a whole every time something goes w…

This got me intrigued. Is there a soundness proof for the Rust type system? The only language with such a proof that I am aware of is StandardML. Even OCaml is too complex for a soundness proof.

There was a paper a few years ago[0] was related to proving soundness. That could be what they meant.

[0] https://plv.mpi-sws.org/rustbelt/popl18/paper.pdf

Re: Smart pointers for the kernel

#76
post #66

Earlier quoted context omitted.

In practice this is a compiler bug, though, and is treated as such, and not a soundness hole in the abstract design of the type system. There has also not been a single case of this bug being triggered in the wild by accident.

I take this to mean e.g. the Oxide project has proven the Rust type system sound? There was a Git repository demontrating unsoundness issues in the compiler, but I seem to be unable to find it anymore :/. It seemed like there would be more than one underlying issue, but I can't really remember that.

You might be thinking of CVE-RS[0] which is exploiting bugs in the compiler.

[0] https://github.com/Speykious/cve-rs

Re: Smart pointers for the kernel

#77
post #66

Earlier quoted context omitted.

In practice this is a compiler bug, though, and is treated as such, and not a soundness hole in the abstract design of the type system. There has also not been a single case of this bug being triggered in the wild by accident.

I take this to mean e.g. the Oxide project has proven the Rust type system sound? There was a Git repository demontrating unsoundness issues in the compiler, but I seem to be unable to find it anymore :/. It seemed like there would be more than one underlying issue, but I can't really remember that.

I tried to look into it, and it does not seem like the type system is proven, yet, though the issue itself is closed: https://github.com/rust-lang/rust/issues/9883

Per https://blog.rust-lang.org/2023/01/20/types-announcement.htm... there is a roadmap for ensuring Rust type system soundness end of year 2027. I think it means the implementation.

Re: Smart pointers for the kernel

#78
post #76
post #66

Earlier quoted context omitted.

I take this to mean e.g. the Oxide project has proven the Rust type system sound? There was a Git repository demontrating unsoundness issues in the compiler, but I seem to be unable to find it anymore :/. It seemed like there would be more than one underlying issue, but I can't really remember that.

You might be thinking of CVE-RS[0] which is exploiting bugs in the compiler. [0] https://github.com/Speykious/cve-rs

You are quite likely correct. My search term included "unsound", and it missed this one.

But this time I've starred and cloned it!

I didn't quite see if this actually exploits multiple bugs or leverages just one, though.

Re: Smart pointers for the kernel

#79
post #61
post #27

Earlier quoted context omitted.

The potential for undefined behavior is, I will agree, potentially fairly serious, especially depending on specific circumstances... (In most cases it should reliably hit an unmapped page and cause an exception, but there are exceptions on weird targets or with huge offsets.) But, you can pretty much entirely ignore it if you can just guarantee that the pointer isn't NULL in the first place, which not only prevents y…

> In most cases it should reliably hit an unmapped page and cause an exception, but there are exceptions on weird targets or with huge offsets Perhaps the most important exception is when the optimizer assumed the pointer was non-null, so optimized it in a way that produces completely unexpected behavior when it is null. Also use-after-free and use of uninitialized pointers is more likely to point to incorrect, but m…

> Perhaps the most important exception is when the optimizer assumed the pointer was non-null, so optimized it in a way that produces completely unexpected behavior when it is null.

> Also use-after-free and use of uninitialized pointers is more likely to point to incorrect, but mapped, locations.

I stuck to a null pointer dereference because it's useful for demonstration since the side-effect of hitting one is usually not a huge deal, but actually it wouldn't matter if it were a huge deal or not. The point I'm trying to make, and maybe not making obvious enough, is that the null pointer dereference is just a symptom of the fact that other invariants are not being upheld; it's not just about preventing an unsafe operation, it's about preventing the kinds of incorrect code that lead to them. It's the same for a use-after-free. That's exactly why I am a fan of Rusts' borrow checker, you can statically eliminate the problem that causes use-after-frees.

It isn't really that hard to construct a memory safe programming language, but the "obvious" ways of doing it have trade-offs that are undesirable or infeasible for some use cases. Rather than make the operations "more safe" by ducktaping runtime checks, Rust just forces the code to be more correct by statically checking invariants.

Re: Smart pointers for the kernel

#80
post #74
post #39

Earlier quoted context omitted.

> (In most cases it should reliably hit an unmapped page and cause an exception, but there are exceptions on weird targets or with huge offsets.) The kernel is one such exception.

Depends a lot on the system, but I don't think this is much of a problem with modern Linux systems. Looking on my machine, vm.mmap_min_addr is set to 65536, not to mention the mitigations modern CPUs have for preventing unintended access to user pages. Just as in userspace, a null dereference on a modern Linux system is almost guaranteed to hit a trap. That said, a potentially bigger problem is what happens when hand…

See https://lwn.net/Articles/342330/
Post reply on HN