6 ms·
My concern is that while re-implementing sudo in rust would solve bugs due to memory safety and off by one errors, it is a complex piece of software where logic
by sc68cal 3y ago
My concern is that while re-implementing sudo in rust would solve bugs due to memory safety and off by one errors, it is a complex piece of software where logic errors can create serious security issues.
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-22809 https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-2280...
- throwawaaarrgh 3y ago[flagged]
- Rusky 3y agoThis isn't how people seriously approach memory safety. Memory safety is a critical starting point, because without it you can no longer trust the logic you wrote in your program to behave in any particular bounded way. Memory safety bugs undermine everything else.
- woodruffw 3y ago“Free-after-use” is not a vulnerability class; it’s “use-after-free.” And Rust’s borrow checker provides temporal memory safety; you could even say that it primarily exists to prevent temporal vulnerability classes like UAFs.
- jcranmer 3y agoRust protects against most memory safety vulnerabilities: use-after-free, out-of-bounds accesses, returning dangling pointers. Probably the memory safety vulnerability it's the least protective against is using uninitialized memory. And recall that memory safety vulnerabilities are the vast majority of software vulnerabilities--somewhere in the 70+% range. But Rust doesn't only touch memory safety, it also has some measure of protection for other vulnerabilities. It's somewhat stricter on integer overflow vulnerabilities. Newtypes can be used to provide protection against validation vulnerabilities (e.g., SQL injection). Send and Sync traits can provide some measure of protection against data races: it takes a little bit of effort to use an object on a different thread if it's not able to be used from multiple threads. You don't hear as much about these protection efforts because, quite frankly, memory safety is so important that it alone is sufficient to drive many decisions.
- IshKebab 3y agoFortunately Rust also has a very good type system and strict ownership system that greatly reduces the chance of logic bugs too. Imagine not using seatbelts because they don't help if someone shoots you in the face.
- steveklabnik 3y agoYou are not wrong, but logic errors are a pervasive concept that applies to all code bases. Logic errors in the existing codebase, as you've demonstrated, can also cause issues. The pro-Rust argument here would be "letting the compiler handle memory safety for you frees up your attention to focus on those logic errors even more." Time will tell!
- tptacek 3y agoThat's not really responsive to the concern. The issue is that we've already had decades of experience with the existing sudo codebase looking for logic vulnerabilities. And, in fact, that's what the overwhelming majority of sudo vulnerabilities are; they're not generally memory safety bugs. So rewriting in a new language to get rid of memory safety vulnerabilities is not, in fact, an obviously good tradeoff.
- steveklabnik 3y agoI don't directly disagree with what you're saying here either. All of these things need to be weighed against each other. I am not familiar with sudo's codebase, and so I can't speak to if I personally agree with Prossimo or you here. What I will say is that I certainly agree that memory safety on its own would be a weaker justification for the reasons you cite. But this analysis doesn't take into account the relative usefulness of various language features for preventing logic errors. For example, I find that enums really help catch edge cases that are easy to forget about, causing bugs. Tagged unions are obviously a thing in C codebases but aren't as easy to use nor integrated into the language in useful ways, like exhaustiveness checking. You're absolutely right that, at the moment, the sudo codebase is more well understood, but one could make the argument that C's various weaknesses in areas like the typesystem means that as this codebase matures, and becomes well known itself, logic errors become more tractable. One could also make an argument that a new codebase is a good idea, even disregarding the C vs Rust factors. For example, they're not going for "100% drop-in replacement for sudo," they're going for "a drop in replacement for common cases." Sudo has users who I assume would be upset at removing features they rely on, whereas this project has no userbase, and therefore, can do whatever they'd like. Removing a bunch of code can also help reduce logic errors, as it's impossible to have logic errors in code that doesn't exist, obviously. Of course, this article focuses on the memory safety aspects and not the others, maybe that's a marketing mis-step. Then again, what's important here is the engineering, not the marketing. So yeah. It's not obviously a slam dunk either way, it really depends on how one personally weighs all sorts of factors. As I said above, time will tell.
- hannob 3y ago> it is a complex piece of software That's the problem. It shouldn't be. I hope the sudo-rs variant does better.
- ape4 3y agoThey should just replace /etc/sudoers.d with a Domain Specific Language ;) /s
- yjftsjthsd-h 3y agoActually, there's a point: doas is already smaller and safer, so it would probably be easier to port to a new language as well as having less attack surface in the first place. Of course, it's still necessary to work with sudo as well because it genuinely supports a lot more features and some of them are even useful, but if you want the low hanging fruit...
- phkahler 3y ago>> it is a complex piece of software where logic errors can create serious security issues. I know many unix commands have a lot of capabilities I never use, sudo? Not much logic other than "run this as root if user has permission" is there? OTOH I never thought about how a cli app can escalate privilige without already having it....
- wongarsu 3y agoThe escalating privileges part is easy: the file /usr/bin/sudo is owned by root and has the setuid flag set, meaning it gets executed with the permissions of the file owner instead of those of the caller. The complexity has more to do with the fact that it has 28 command line flags, plus a fairly complex config file to configure who is allowed to do what, impersonating which user, and whether they need a password to do so. All of that dealing with security critical stuff like what exactly should carry over and what should be reset (all configurable ofc). su is very simple by comparison (and you can do `sudo -s` anyways to get the same result as calling su without parameters).
- rnijveld 3y agoI’m one of the people working on this. While I do think that the memory safety aspect is an important one, I think that one thing where we can win even more is that Rust has a type system that is much more robust than what C offers. If set up right, we can prevent lots of these kinds of bugs right from the start. We can also simplify things in lots of cases by removing unnecessary details no longer relevant in a modern implementation.