For anyone unfamiliar how rust helps, the idea is this: first, you can identify common usage patterns and build safe wrappers around raw system operations.
The wrappers have no additional cost when compiled: A nested structure of Wrapper<OtherWrapper<OverSomePointer>> has a size of the flattened contained data, all the type info will be stripped away.
This part is the hardest, but the reward is that you can then use these wrappers without thinking about lower-level details. Of course, it is possible to do that in other languages, but rust type system can encode more information in types. That means more checks at compile time and less cautionary instructions are needed in the code comments.
I always hear arguments that "Rust still does not prevent X!". That's not the point. Rust type system simply can prevent more if used as intended.
Indeed. What I hate about C is a function that returns an integer, and go figure out the docs about what the value of this integer means. In Rust, an enum with "RequestSuccessul" usually means just that: a successful request. That means I have much less uncertainty about things and spend less time going through docs.
the seatbelt example isn't a 100% fit as seatbelt-opposers argued that seatbelts actually increase the risk of drowning, so they're not a security improvement but a trade-off.
of course, cases of drowning in an automobile where the passengers would have survived without a seatbelt are incredibly rare, while all other accidents where seatbelts help are comparably common.
Something can be more then useless yet still be less than worth it. Not saying rust isn't worth it in this case, just that the extremes are not the only two conditions.
Also, as mentioned in the patch's message, it's important to highlight that binder is a core component of Android. Its usage is so widespread that, to me, it kinda makes Android architecture very akin to a microkernel-based system.
Really unexpected, that the first kernel feature written in Rust is such a huge driver, I would've expected something much smaller first. The reasoning for the change is well laid out imo. I'm looking forward to this, especially since it looks like performance will be almost on par with the C version which will give Rust a good outlook.
It's surprising by importance but not by size, which is actually a sweet spot for evaluating a new systems language - a small dependency that everything uses.
I remember working with Binder in the context of Android/AIDL (IPC between apps). Wonder if Dianne Hackborn is still involved, she‘s notably absent in TFA. Her name was synonymous with Binder back then.
> Could I theoretically use it in my linux program just like any other IPC mechanism?
Yes, absolutely.
However, binder is implemented as a kernel module not enabled by default, so it depends on the build time configuration of your system's target kernel (eg., your distro's).
That given, it's important to note that the binder driver/module is just one piece of a greater framework and it's raw IPC features aren't as simple to use as SysV or POSIX's. For example, it requires a userspace process called context (or service) manager. Android has 3 different binder device instances and it builds a big framework on top of them wiring things like an interface definition language (AIDL), a set of libraries and SELinux permissions.
Does Rust prevent all mistakes with locking as the post seems to indicate? It prevents the most common issues of accessing variables without mutexes or something incorrectly by requiring them to be wrapped in RwLock or similar, but you can still get deadlocks can you not?
You can. There are definitely still footguns - some things are just not easy. But there are also fewer footguns, and the overall type system makes modelling problems in ways which are often simpler to reason about more achievable (trivial example - state machines are common, and easy to represent in relatively safe ways with exhaustively checked enums, matching, etc.)
Is rewriting something in Rust a guarantee of no bugs? Nope. But it does likely make it easier for the rewriters to reduce the number of bugs.
Also, since Rust provides and enforces the mechanisms to bypass huge swaths of bugs, like many locking errors, concurrency, exhaustive enum checking, etc., that frees up developers to spend their time debugging or reinforcing other areas where Rust can't make similar guarantees of correctness.
I recall reading somewhere that a lot of the ideas for Rust's safety system came from a Firefox analysis of bugs that had been reported and fixed, where something like 70% of bugs fell into a few broad categories (mostly memory safety, like use-after-free, buffer overruns, off-by-one, etc) which they could solve in a new language that could enforce correctness. The idea of being able to remove 70% of bugs, and to effectively guarantee that any bugs that do occur happen in those remaining 30% of areas, sounds like it could save a lot of developer time.
Rust does not protect against deadlocks, that is correct. It also doesn't fully prevent mistakes related to ref counting. But I don't get the impression that the post is claiming either of those things?
All mistakes is such an unachievable high bar, it’s almost a strawman argument. You can always imagine a programmer terrible enough that they will find every possible failure case.
However, Rust can prevent quite a lot of common mistakes. Getting rid of UAF, data races, and having deterministic destruction that unlocks locks is already a major quality improvement.
Rust can’t prevent deadlocks caused by wrong architecture, but of all concurrency issues deadlocks are the easiest to diagnose.
> You can always imagine a programmer terrible enough that they will find every possible failure case.
Uhh, no. That is an amazing programmer! Why? Because truly terrible programmers imagine a subset of every possible failure case and simply refuse to acknowledge other failure cases, especially the ones that are particularly common with particularly severe consequences.
The wrappers have no additional cost when compiled: A nested structure of Wrapper<OtherWrapper<OverSomePointer>> has a size of the flattened contained data, all the type info will be stripped away.
This part is the hardest, but the reward is that you can then use these wrappers without thinking about lower-level details. Of course, it is possible to do that in other languages, but rust type system can encode more information in types. That means more checks at compile time and less cautionary instructions are needed in the code comments.
I always hear arguments that "Rust still does not prevent X!". That's not the point. Rust type system simply can prevent more if used as intended.
That's just the Nirvana fallacy. Just because it's not perfect shouldn't prevent you from improving stasus quo.
Absurd example: "Seatbelts don't prevent impalements or drowning in car, ergo they are useless.
Dead Comment
[1]: https://cs.opensource.google/fuchsia/fuchsia/+/main:src/star...
https://en.wikipedia.org/wiki/OpenBinder
> the mechanisms provided by an operating system for processes to manage shared data
https://en.wikipedia.org/wiki/Inter-process_communication
"OpenBinder is the core technology that ex-Be engineers started at Be, Inc. as the “next generation BeOS”, finished implementing at PalmSource "
https://www.osnews.com/story/13674/introduction-to-openbinde...
They say 6,000 lines of code. That's not very much.
https://lpc.events/event/16/contributions/1180/attachments/1...
Could I theoretically use it in my linux program just like any other IPC mechanism?
Yes, absolutely.
However, binder is implemented as a kernel module not enabled by default, so it depends on the build time configuration of your system's target kernel (eg., your distro's).
That given, it's important to note that the binder driver/module is just one piece of a greater framework and it's raw IPC features aren't as simple to use as SysV or POSIX's. For example, it requires a userspace process called context (or service) manager. Android has 3 different binder device instances and it builds a big framework on top of them wiring things like an interface definition language (AIDL), a set of libraries and SELinux permissions.
Is rewriting something in Rust a guarantee of no bugs? Nope. But it does likely make it easier for the rewriters to reduce the number of bugs.
I recall reading somewhere that a lot of the ideas for Rust's safety system came from a Firefox analysis of bugs that had been reported and fixed, where something like 70% of bugs fell into a few broad categories (mostly memory safety, like use-after-free, buffer overruns, off-by-one, etc) which they could solve in a new language that could enforce correctness. The idea of being able to remove 70% of bugs, and to effectively guarantee that any bugs that do occur happen in those remaining 30% of areas, sounds like it could save a lot of developer time.
I'd argue that "It prevents mistakes with ref counting, locking, bounds checking..." implies "all" mistakes, but hey, maybe not...
However, Rust can prevent quite a lot of common mistakes. Getting rid of UAF, data races, and having deterministic destruction that unlocks locks is already a major quality improvement.
Rust can’t prevent deadlocks caused by wrong architecture, but of all concurrency issues deadlocks are the easiest to diagnose.
Uhh, no. That is an amazing programmer! Why? Because truly terrible programmers imagine a subset of every possible failure case and simply refuse to acknowledge other failure cases, especially the ones that are particularly common with particularly severe consequences.
However, there are schedulers that do guarantee deadlock free operation written in Rust, see RTIC for example.