Naar de Nederlandstalige versie
RustIEC newsletter (September 2024)
Welcome to the second newsletter for the RustIEC project. In this newsletter, we provide you with updates on the progress made by the RustIEC teams.
RustIEC demo at IMEC's Wireless Community event
Wednesday October 9, 2024, at IMEC - Leuven (12h - 19h) we will showcase RustIEC's results on secure embedded programming in Rust. We will demonstrate a wireless version of the pong game which we presented during our embedded workshop. The main topic of IMEC's Wireless Community even of October 9th is Secure over-the-air firmware updates of IoT devices, but the scope is broader.
Subscriptions via Wireless Community Workshop.
Rust Embedded Operating Systems and Frameworks
The VUB team submitted Overview of Rust Embedded Operating Systems and Frameworks to the MDPI Sensors journal, which was accepted for publication. The paper focuses on several Rust-based OSes and frameworks, including Tock, Hubris, RTIC and Embassy, It shows the potential of Rust offering a high-level language, without sacrificing low-level control or memory safety, making embedded systems more reliable and secure. Each OS brings something unique, from real-time capabilities to hardware abstraction, tailored to meet the challenges of modern embedded devices.
The first part of the paper covers the basics of the embedded Rust landscape, explaining how Rust can be used to write firmware for microcontrollers. It also explains the benefits of using asynchronous Rust for embedded systems, providing a more efficient and structured way to interact with peripherals. The most important parts of an embedded OS are also discussed, such as how tasks are scheduled, how processes communicate, how to interact with hardware, and finally how these OSes and frameworks handle networking.
The final part of the paper provides an evaluation of the interrupt and scheduling latency for each of the different OSes and frameworks. The results show that Rust-based OSes and frameworks can achieve low latencies, making them suitable for real-time applications. The memory requirements of each OS are also compared.
Crabstick: a chess engine in Rust
Thibaut and Ruben of the VUB team built a chess engine in Rust called Crabstick. This Friday-night hobby project is a work in progress, but it already plays a decent game of chess. You can play against Crabstick on Lichess.
The Lichess-integration is an interesting case study of how to integrate Rust with a web service: Crabstick is deployed as a Kubernetes service, and it can scale up to handle multiple games at once. Every game is handled by a separate worker deployment, which communicates with the main manager via a REST API. The worker deployment is implemented as an Actix actor, and exposes the games to Prometheus.
Figure 1: Crabstick statistics in Prometheus, showing the number of games played over time.
You can already have a look around the Crabstick source code. At a later time, we plan to make a comprehensive report on user space Rust tools and techniques.
Onwards Into the Breach
Over the duration of the RustIEC project Rust has been gaining more traction than ever. It is no longer only big companies like Google, Android, and Mozilla that are sharing their positive experiences with using Rust, governments are also getting involved. The White House now advises that new code ought not to be written in memory unsafe languages like C and C++, but instead should be developed in memory safe languages like Rust.
Translating C to Rust
Both academia and industry are making great strides in reducing the challenges of adopting Rust in systems level software. One domain that we have spent quite some time on during RustIEC, which is especially gaining interest, is automatic translation from C to Rust. The Translating All C to Rust(TRACTOR) program introduced by the Defense Advanced Research projects Agency (DARPA) is one indication of the growing interest. Hanliang Zhang et al., Jaemin Hong, Jaemin Hong et al., and Mehmet Emre et al. propose solutions based on program analysis while Momoko Shiraishi, Hasan Ferit Eniser, and Yoshiki Takashima propose solutions based on machine learning. Both angles have their pros and cons. While program analysis techniques aim to translate very specific code patterns, the code before and after transformation is very unlikely to have changed semantically. On the other hand, machine learning approaches are more holistic, and can cover whole code bases. However, they do come with a cost, and that is semantic equivalence. There is a significant probability that the code after the transformation will no longer compile, or the new program may exhibit completely different behavior. The future, therefore, will likely be a marriage between the two angles along with some extensive verification of the resulting program.
While TRACTOR is aiming for fully automated translations, either with program analysis or AI, or a combination of both, we have been looking into what tools we can provide until a reliable and usable fully automated translator is available. While we do believe that a fully automated translator is the future, there is no telling how long it will take before such a program can be trusted to operate on real infrastructure. In the meantime we propose a semi-automated tool that provides suggested translations in order of criticality to a developer who then decides whether those changes would be semantics preserving. While this means there is more manual labor necessary, this proposal also comes with more semantics preserving guarantees.
C and Rust Interoperability
While it remains impossible to translate whole codebases completely from C to memory safe Rust, using C and Rust together is a must. Thankfully Rust was designed with C interoperability in mind, so it is a mostly solved problem. The how of the matter is answered, however, whether we should do it in the first place wasn't asked during RustIEC. This question has popped up in recent literature. The concern explored by Michalis Papaevripides et al. and Samuel Mergendahl et al. is that unexploitable memory errors in hardened C code, that are passed to Rust code, could be used to exploit the memory safe Rust code. Since this attack was formulated Inyoung Bang et al., Peiming Liu et al., Hussain Almohri, Paul Kirth, and Elijah Rivera have proposed memory separation techniques such that the possibly corrupted C data can never corrupt Rust data. These protections still have some drawbacks, confused deputy attacks are not covered and, most importantly, the current tools are prototypes, so not industry ready.
Translation and Interoperability in the Real World
We used the Rust for Linux kernel as a case study to see how the introduction of Rust into a C code base is done in the real world. On the front of translating C to Rust, the maintainers of the Rust for Linux kernel chose to redesign when translating, instead of creating a one to one translation. More impactful than that were the large API and design changes throughout the duration of the RustIEC project, which we covered in the user group meeting on the 5th of June. However, the Rust for Linux kernel seems to be stabilizing and new Rust features are slowly but steadily being added to the mainline Linux kernel. One point of contention that seems to remain is how the Rust and C code should interface as there are few semantic definitions available for the C API. Therefore, on the front of C and Rust interoperability the main issue seems to be communication between the rather disjoint C and Rust maintainers and, at least for the time being, not security issues.
Questions or Suggestions?
If you have any questions or suggestions, feel free to reach out to us:
- General questions about the RustIEC project: An Braeken and Kris Steenhaut
- Technical questions about Web, Cloud and Async: Ruben De Smet
- Technical questions about Embedded Rust: Thibaut Vandervelden and Diana Deac
- Technical questions about Automatic translation and Linux kernel drivers: Stijn Volckaert and Alicia Andires