Re-implementing Sudo in Rust (when you want more than just a sandwich)
This blog is part of a series about sudo-rs:
- Re-implementing Sudo in Rust (when you want more than just a sandwich) by Marc. (You are here...)
- Testing sudo-rs and improving sudo along the way by Jorge.
- UPCOMING: A blog about the sudo-rs audit!
Why Sudo matters
If you have experience with maintaining a Linux machine, you will have come to terms with the sudo command. When you discover that a recently configured system is missing an important program, the following interaction will be familiar:
$ ddate bash: ddate: command not found $ apt install ddate (...) Permission denied (...), are you root? $ sudo apt install ddate (...) NEW packages will be installed: ddate (...) $ ddate Today is Pungenday, the 15th day of Discord in the YOLD 3189
Making changes to a system requires admin privileges, and sudo temporarily grants us those privileges. This is easier and safer than logging in as root. Nearly all operating systems heavily rely on sudo---Ubuntu even disables the root account by default.
More than just sandwiches
For most people sudo is in fact just this: the "make me a sandwich" command. A simple safety switch so that you can use your system without the fear of (the software you use) accidentally breaking things, while also allowing you to escape this safe environment when necessary.
However, sudo can do much, much more than this. You may have sudo privileges, but most of the background processes on your computer won't. Similarly, on systems shared by multiple users, most users will not be permitted to use sudo.
Furthermore, in an enterprise setting it can be configured to allow some groups of users to just execute a carefully selected set of commands or edit only certain files on behalf of the superuser. Or sudo can allow them to get more rights than normal, but not the full power of root. And sudo can keep a log of what users are doing. In short, it's much more configurable than most people think.
Why use Rust for this?
Like many iconic UNIX commands, sudo is written in C. It has had its fair share of bugs and advisories over the years. And since sudo is a program that has superuser status itself, exploits in it get bad fast.
Todd Miller---the maintainer of sudo---estimates that about one third of all vulnerabilities in sudo are caused by typical memory bugs that happen easily in C code. By using Rust, we can eliminate almost all of those by avoiding
Of course sudo also has had bugs in its business logic that are not memory-related. We think using Rust can help there too: in C, everything has to be expressed in low-level concepts (pointers, bytes, arrays), whereas the higher-level Rust language allows us to more clearly encode the "logic" of sudo.
Open source project
Just using Rust by itself is not a silver bullet. We also need many eyeballs. Therefore, this effort will be run as an open source project. We have joined hands with fellow Rust experts from Ferrous Systems GmbH, under the umbrella of the Prossimo project. Prossimo's aim is to create memory-safe foundations for the internet's critical infrastructure. Tweede golf has previously worked for them to create a safe replacement for the Network Time Protocol daemon.
Being an open source project means we can also freely consult the original sudo source code as a guide, and we continue to be in contact with Todd Miller for his advice on implementation details. If during this project we find any bugs in the original code, we will of course contribute back to him. We highly respect Todd's work and what he has achieved by maintaining sudo for all these years.
Of course our sudo already makes sandwiches (buritos, even)---but we are currently still adding features every week. We have the following technical goals for
- Be a drop-in replacement for all common modern use cases of sudo, but not legacy features that are no longer considered relevant today. We will be compatible with the existing
unsafecode only when absolutely needed, and fenced-in behind a safe interface. In particular, the
/etc/sudoersparser, policy checker, and environment setup will consist of purely safe code---free from memory bugs.
- Rely only on widely-used, well-maintained and well-known dependencies---and as little as possible---to avoid introducing bugs indirectly.
- Have the code audited for security: a
setuidprogram should not leak sensitive information to ordinary users.
- Test our sudo re-implementation against original sudo using a compliance testing framework.
If you want to know more about our testing strategy and how our compliance testing framework has already helped us find bugs and differences between our re-implementation and original sudo, read this blog by my colleague Jorge from Ferrous Systems!
What you can do?
You can follow the development of
sudo-rs on https://github.com/memorysafety/sudo-rs; give us a star if you support this project! The current state is an alpha version; you can play around with it but you should not use it in a production setting yet.
If you happen to be a system administrator who uses sudo for more than just "make me a sandwich": you can help in a more concrete way! Having examples of real-world uses of
/etc/sudoers helps us in deciding what features we need to focus on. Contact me (project lead) if you would like to supply us with some examples; we´d greatly appreciate it!
If you want to support this work, or other projects that make the internet more memory safe, you can find information about how to do that over on https://www.memorysafety.org/. Or check out Project Pendulum to support the maintainership of