9 ms·
As one of the original creators of sudo (https://en.wikipedia.org/wiki/Sudo https://en.wikipedia.org/wiki/Sudo) I've witnessed it getting nearly totally rewritt
by coggs 3y ago
As one of the original creators of sudo (https://en.wikipedia.org/wiki/Sudo https://en.wikipedia.org/wiki/Sudo) I've witnessed it getting nearly totally rewritten and then incrementally bug-fixed over the last 43 years. It must take the prize for the UNIX command most highly-scrutinized for security flaws. Flaws which have been identified and fixed.
Thousands of developers and security experts have gone over it. So part of me wonders - how is it possible for a single dev team to totally reimplement it without unknowingly
introducing at least a bug or two? Is there something to this Rust language which magically eliminates all chances of any bug being introduced?
- narinxas 3y ago> Is there something to this Rust language which magically eliminates all chances of any bug being introduced? apperently, yes... and its the type system, but granted it's only 'memory safety' bugs... the kind of error that C languages are really suceptible to.
- noahjk 3y agoOn the surface, sudo seems fairly straightforward, so it’s interesting to hear how much work has gone into it! Do you have any interesting facts or anecdotes you’d care to share?
- nolok 3y agoThe key is in "on the surface". While the common usage of sudo is fairly straightforward, you me and most people use like 5% of it. The trick is in all the side shows.
- yesimahuman 3y agoMakes you wonder then why it does so much, if those rarely used features increase the surface area of possible exploits? This is just a question I’ve had about *nix utilities in general, since sudo is hardly the only tool with obscure flags and features
- yjftsjthsd-h 3y agoBecause the long tail of features is useful to someone. Mind, I like doas for this reason, but having the more feature rich option available makes sense.
- __turbobrew__ 3y agoThis is part of what the openbsd ‘doas’ was trying to solve. They drastically reduced the functionality to reduce the attack surface.
- coggs 3y agoHackaday interviewed me about the origin story - https://www.youtube.com/watch?v=LaAwl3HN5ds&ab_channel=HACKADAY https://www.youtube.com/watch?v=LaAwl3HN5ds&ab_channel=HACKA...
- ralgozino 3y agogreat story! also, TIL that I've been pronouncing `sudo` wrong, I was 100% sure that it was supposed to be like pseudo, but I guess that is a myth :) It's so great to be able to listen and learn from the people that invented these important building blocks themselves, I feel lucky. Thanks for sharing.
- folmar 3y ago> sudo seems fairly straightforward `su` is straightforward, `sudo` is a very powerful piece of software and the configuration has a lot of edge cases.
- SoftTalker 3y agoYes, have a read of the sudoers man page and marvel at the complexity of the configuration, and wonder about your chances of getting it right if you are not well-experienced. This is the config file with the infamous paragraph: The sudoers grammar will be described below in Extended Backus-Naur Form (EBNF). Don’t despair if you are unfamiliar with EBNF; it is fairly simple, and the definitions below are annotated. OpenBSD replaced sudo with their own "doas" command a few years ago; the doas.conf manual page is about 100 lines; sudoers is over 2,000.
- nolok 3y agoIn memory safety ? Yes, the language is much better at being safe by default. But it does nothing for logics bugs. The thing is, replacing from C (sudo or anything else), the number of exploit due to null pointer or buffer abuse or ... represent easily 50% of it.
- lionkor 3y agoIs that because theyre easy to find, or because theyre the worst?
- yakubin 3y agoThey’re easy to make.
- tialaramex 3y agoA lot of the most serious security vulnerabilities are memory safety because e.g. remote code execution is very often along the lines of "LOL, I smash buffer with machine code, it gets executed" and that's a memory safety problem. For sudo you have potential for some very serious logic bugs, where the program does exactly what the programmer wrote, but what they wrote was not what they intended. Rust's type safety makes it less vulnerable to these mistakes than some languages, but there is no magic. In C obviously a UID, a PID, a duration, an inode number, a file descriptor, a counter are all just integers. In Rust you could make all those distinct types (the "New type idiom"), and out of the box the Duration and the File Descriptor are in fact provided as distinct types. So, some improvement.
- Someone 3y ago> In C obviously a UID, a PID, a duration, an inode number, a file descriptor, a counter are all just integers. In Rust you could make all those distinct types For various kinds of IDs you can do that in C, too: struct UID { int value; }; A C compiler can pass these in registers to functions (https://wintermade.it/blog/posts/value-struct.html https://wintermade.it/blog/posts/value-struct.html). So, performance impact should be zero. It may be not as nice as other languages, but it isn’t bad, either. If you use C++, it can be made a bit nicer, and you could also have such structs that you can calculate with.
- jchw 3y agoAdvanced type systems and borrow checking/memory safe languages DO go a long way, but obviously, No. The best developers can do pulling a RiiR is try to follow best practices and learn from past mistakes. We've certainly come a long way in 43 years. Ditching C string handling eliminates a ton of bugs before you factor in the memory safety. Heck, you have to admit: someone setting out to make a secure sudo replacement could do a lot better nowadays even using just C. The OpenBSD project does a pretty good job demonstrating this imo. If you make a programming language that doesn't have many of the sharp edges OpenBSD code avoids, you could probably get yourself a head start, but clearly it also is going to take plenty of care and experience too, and a programming language can't really grant you that. I think it's at least worth humoring. It probably shouldn't be shipping as a default any time soon, though...
- alexvitkov 3y ago[flagged]
- lionkor 3y agoNo, but maybe it feels better to know memory bugs aren't there (but all others are, and worse than in sudo)
- stefs 3y ago> Is there something to this Rust language which magically eliminates all chances of any bug being introduced? no, altough it has features that prevent or reduce the probability of some types of bugs - one example of this being memory safety bugs. rust can't prevent logic bugs. the rust reimplementation probably has more bugs than the original, but a theoretically better chance to achieve fewer bugs in the long run. is rewriting mature linux infrastructure in rust a good idea? many people agree that no, it's probably not a good idea outside of special use cases.
- pohl 3y agoI think a better question might be whether it prevents categories of bugs that are more likely to be exploitable than, say, the logic errors that no language could ever prevent? Also, it sounds like your seasoned eyes would be valuable in reviewing this code.
- hoherd 3y agoRust aside, one thing to consider is that a reimplementation of an existing piece of software does offer the benefit of being able to test the old version and the new version side by side for consistent behavior. You could have an entire class of test cases that is just "do X with the old version, and then do X with the new version, and just make sure the result is the same." There is also the entire bug history of the old version that can be investigated during reimplementation. If the old version has specific tests for each resolved bug, those can also be run against the new version to ensure it has consistent behavior. In this case though, it's only a partial reimplementation: "Leaving out less commonly used features so as to reduce attack surface", which would complicate that approach.
- WesolyKubeczek 3y agoWhile I don't negate your experience and I genuinely anticipate that this project is going to rediscover some pain, there's something to be said about the fact that we don't have to replicate the life work of Newton, Leibniz, Maxwell, etc to really "get" classical physics. It fits now into the high school curriculum, and if you pass it, you can be fairly decent at it; with a little additional effort, you can get real freaking good at what took those people their whole freaking lifetimes. This is because we can stand on those giants' shoulders and have the benefit of hindsight and not have to also repeat each and every of their blunders, and have better technology and learning methodology to boot. So I presume if you yourself wanted to rewrite sudo from the first principles, you, with all your experience and knowledge already there, would spend a lot less time doing it, and it would be way cleaner and simpler. So while I'm not dunking on your effort and experience, I'm just pointing out that it's not impossible to take your experience and turn it into something better over a smaller timespan.
- tptacek 3y agoWhatever else happened in those 43 years, we had a widely-exploitable memory corruption vulnerability (Baron Samedit) as recently as 2021.
- ndr 3y agoAnd it looks like it was a buffer overflow: https://blog.qualys.com/vulnerabilities-threat-research/2021/01/26/cve-2021-3156-heap-based-buffer-overflow-in-sudo-baron-samedit https://blog.qualys.com/vulnerabilities-threat-research/2021... Would Rust prevent this?
- jvanderbot 3y agoYes buffer overflows are one of the explicitly addressed vulnerabilities of Rust's bounds checker, which is always on, if memory serves. I haven't touched Rust in a year.
- adastra22 3y agoYou can get around the bounds checker with unsafe code. But yes, by default an overflow should result in a panic and program termination.
- Filligree 3y agoYou can, but unsafe code is discouraged in general, even given a slight performance cost. For performance-insensitive, security-critical code, there really shouldn't be any such code in the entire program—and it would be easy to verify that with a presubmit.
- bunderbunder 3y agoIn an ideal world, no, there shouldn't. But `unsafe` is not just a performance hack; people do find things that they legitimately need to do that Rust can't statically verify. Probably the most trivial example is interacting with code that is not itself written in Rust. This does imply that some of the stronger claims about Rust's level of static safety guarantees that float around on the Internet can't really be true unless substantially everything you might want to do has a version that's been completely written in Rust. Whether you feel that means that achieving the desired level of safety implies you've still got to rely on some dynamic analysis tools just to be sure probably depends on how much safety you really want, and how much faith you're willing to place in the skills of the authors of the libraries you use. And even then, if we really want to go least common denominator, if you're running your program on Windows or a Unix or basically any other OS that isn't Redox, then you've got unsafe code executing every time Rust's own standard library needs to make a syscall to achieve something. Which I don't say by way of criticizing rust Rust. It's got to live in the same crappy world we all have to live in, and it's arguably doing a better job of de-crappifying it than any other systems programming language. I'm just trying to illustrate how an unqualified statement along the lines of "there shouldn't be any unsafe code in the entire program" is kind of a self-strawman, precisely because Rust has to live in said crappy world, and I think that it might be unsafe to lose sight of that fact.
- 0xbadcafebee 3y ago[flagged]
- steveklabnik 3y ago> Recently a Rust sudo replacement (maybe this one?) got a security audit. It is the same one. It's weird because, this article is from August. But the one you're referencing is from three days ago: https://ferrous-systems.com/blog/sudo-rs-audit/ https://ferrous-systems.com/blog/sudo-rs-audit/ > the severity was worse in the Rust version. I am unsure where you got this. It's the same vulnerability.
- db-interface 3y agoThe link you cite says it was worse in the Rust version: > During the audit, it came to light that the original sudo implementation was also affected by [CLN-001: relative path traversal vulnerability], although with a lower security severity due to their use of the openat function.
- jwilk 3y agoI don't see how openat() would help.
- steveklabnik 3y agoThank you. I literally re-read it to try and find this, and missed it somehow. Guess I need to drink even more coffee.
- scns 3y ago> Guess I need to drink even more coffee. Have you tried green tea? It contains a substance that offsets the sideeffects of caffeine a little. https://en.wikipedia.org/wiki/Theanine?wprov=sfla1 https://en.wikipedia.org/wiki/Theanine?wprov=sfla1 Disclaimer: Zero Caffeine for me either way. Makes my ADD way worse. Theanine was nice though. Okay i lied, i allow myself dark chocolate sometimes.
- khimaros 3y agoi wonder what fraction of these fixes came with automated texts to prevent regressions (and to aid new implementations from making the same mistakes).
- sgerenser 3y agoIt can eliminate many bugs, but it certainly wouldn’t eliminate all bugs. During implementation they realized they were not implementing sudo’s (undocumented) feature of failing to run if the sudoers file is world-writable: https://ferrous-systems.com/blog/testing-sudo-rs/ https://ferrous-systems.com/blog/testing-sudo-rs/. Of course they did find and fix the bug, but in general Rust isn’t going to protect you from bugs like this that are essentially logic errors.
- Calzifer 3y agoThat is documented. Since the mercurial web interface isn't very nice to use I picked a random version. sudo 1.8.6 from 2012 writes in the man page "The sudoers file must not be world-writable,". https://www.sudo.ws/repos/sudo/file/SUDO_1_8_6/doc/sudoers.man.in#l3270 https://www.sudo.ws/repos/sudo/file/SUDO_1_8_6/doc/sudoers.m... This is also a very common behaviour for security sensitive applications to check config file permissions. Another example I remember are ssh private keys. I might be to harsh but it is not so trustworthy they still made this error and still miss the documentation.
- jrmg 3y agoI’m not sure why people are downvoting you. I suspect they may be clicking the link and thinking ‘that’s not documentation it’s source code’, not realizing it actually _is_ documentation. The language it’s in is ‘mdoc’ - a markup format for man pages: https://man.freebsd.org/cgi/man.cgi?mdoc https://man.freebsd.org/cgi/man.cgi?mdoc It’s the source code for the man page, which is about as documentationey as you can get.
- deleted 3y ago[deleted]
- sgerenser 3y agoInteresting, the posting I linked to indicated this behavior wasn’t documented. It’s certainly not surprising and as you mentioned, it’s equivalent to openssh requiring specific permissions on private key files.
- 3y ago
- grayhatter 3y agoThank you for working to create one of the tools which is obviously on the list of the most valuable and beneficial to computer security. Perhaps only second to netfilter. And I'm really sorry so many people have decided they're going to imply something is wrong or broken with it for their own clout. Or because they've bought into the lie that no code written in C can be safe or correct. For what it's worth, I and all the engineers I willingly associate with (read: the ones who I respect) all have said the exact same thing. Switching to rust here, just 'cause, isn't going to meaningfully increase anyone's security. But what are you gonna do. Other than ask people to be honest? Annoying fanboys aside... again, *thank you*! The computer security world is meaningfully better because of your work, and that's something the RIIR fad will never be able to replace :)
- godelski 3y agoYou gotta start somewhere right? I mean its not like you got it right the first time. Don't everyone go switching over just yet, but people can't scrutinize something that doesn't exist.
- amai 3y ago> How is it possible for a single dev team to totally reimplement it without unknowingly introducing at least a bug or two This is possible if every bug fixed has an associated test. If they use this battery of tests to test their new implementation it should be as good as the original implementation.
- kristopolous 3y agoSo let's settle this. Does sudo rhyme with judo or voodoo?
- jjgreen 3y agosu(peruser) do, so soodoo
- kristopolous 3y agoLanguage isn't necessarily that logical. It can be whatever he says it is.
- jjgreen 3y agoLanguage will evolve as it will, the person who invents a word does not get to tell the world how it will be pronounced for the rest of time.
- kristopolous 3y agoCool I'll pronounce it ghoti then
- jjgreen 3y agoYour grandchildren may
- flexagoon 3y agoIt actually stands for "substitute user do" now
- slikrick 3y agohow do you pronounce gif
- rnijveld 3y agoI can only thank you for the work you've done in creating sudo, I think it's an invaluable tool in the general day to day use for so many people. As someone working on sudo-rs, our goal with creating it never was to invalidate any of the work previously done, and we are very much aware that our implementation will not be bug free, especially not at the start. For me personally, creating this Rust version allowed me to work on something that I would normally not be able to work on, given how I would not rate my confidence in writing relatively safe C code very high. If nothing else, at least we already found a few bugs in the original sudo because of this work. Despite the 43 years of bugfixing, such a piece of software is unlikely to ever be free of bugs, even if just for the changing surroundings. Other than that, having some alternatives can never hurt, as long as we keep cooperating and trying to learn from each others work (and from each others mistakes).
- alkonaut 3y agoI’m sure there is a logic bug or two in the new implementation. Whether you want to take the risk of new logic bugs for the benefit of removing several whole categories of bugs (both known and unknown!) is the question and tradeoff in each case like this. This too requires scrutiny, but I’d be a lot more comfortable running a Rust program with 2 years of scrutiny than any C program with 40.
- AndyKelley 3y agoBy making it simpler and not having a ton of rarely used features, and by using a programming language that makes it more difficult to write bugs.
- deleted 3y ago[deleted]
- larodi 3y agoOf course it's not. But hubris is possible and does not take years to master. And honestly statements like my overnight-rust-sudo is better than some poor peoples 40 years of work... well they don't really help Rust becoming more popular, but actually contribute to everything rust becoming even more irritating. Most rust tools are released with this pathos of "we fix what oldies couldn't get right with C". Not a great attitude to approach giants whose shoulders we're standing on indeed.
- sophacles 3y agoWho said anything about "overnight"? This project has been worked on for a year, implemented a test suite that found bugs in the original sudo, and have generally been respectful of the original work. I think you might be projecting something here, there's no evidence for for your assertions.
- knorker 3y ago> how is it possible for a single dev team to totally reimplement it without unknowingly introducing at least a bug or two? As someone with over three decades of C programming experience (so not as much as you), maintaining widely used stuff written in C for decades, that has recently switched from C and C++ as main languages for systems programming to Rust, I'd instead ask this: How is it possible, even given 43 years of working the problem, to create a program in C that does what it's supposed to, and only what it's supposed to? But also, one of the answers from the article is "Leaving out less commonly used features so as to reduce attack surface". Most security bugs in sudo are in features I don't use. Rust isn't just memory safe. It's also orders of magnitude harder to accidentally make other mistakes, such as race conditions.