The sudo and su utilities mediate a critical privilege boundary on just about every open source operating system that powers the Internet. Unfortunately, these utilities have a long history of memory safety issues.
By rewriting sudo and su in Rust we can make sure they don’t suffer from any more memory safety vulnerabilities. We’re going to get it done.
Like I said – Rust is everywhere. Of course, these specific rewrites are not necessarily going to be picked up by the various Linux distributions, but the fact people are starting projects like this means it won’t be long before we’re going to see core UNIX utilities rewritten in Rust making their way to our machines.
People get excited about Rust too much.
Lots of security vulnerabilities are not about incorrect memory management/access but about logical errors which Rust does not alleviate.
Examples:
https://www.sudo.ws/security/advisories/sudoedit_any/
https://www.sudo.ws/security/advisories/minus_1_uid/
https://www.sudo.ws/security/advisories/tz/
And many others.
I am not sure what is being said here. Many sources have said that about 70% of security bugs in real-world software stem from memory safety mistakes. So, that leaves 30% which would be due to other things such as “logical errors which Rust does not alleviate”. All true.
What does that mean though? Is reducing the number of security issues by two-thirds a waste of time because a smaller number of bugs are still possible?
“People get excited about Rust too much”. Perhaps. Certainly I hope we land on something even better. I like that there are other attempts to address some of the same problems.
For me though, I am happy every time I see an effort like this. For a lot of software, I do not care if it gets written in Rust or something else. For these security critical or low-level and used by everything kinds of things though, Rust seems like a really good idea. The one I would love to see is, perhaps ironically, Relibc ( the C standard library ).
The way Microsoft has talked about Rust makes a lot of sense to me. They are not going to rewrite Windows in Rust but they are going to re-write parts of it–the parts either most susceptible to these kinds of problems or where such problems have the greatest impact. This su and sudo effort seems along those lines.
When you rewrite such a massive amount of code you’re bound to introduce a whole lot more new logical errors that there ever were in the first place.
Sudo is not a f-cking simple utility with 10KB of source code, it’s a mammoth code base which is a quagmire of code most people don’t even want to look at. 530 f-cking thousand lines of code.
If you’re OK with breaking the sudoers file format and writing your own sudo-rust-ed utility with its own file format, I’m all for it.
God, I’m trying to stay calm when I see this which a child could easily see from a mile but I can hardly restrain myself.
“it’s a mammoth code base which is a quagmire of code most people don’t even want to look at. 530 f-cking thousand lines of code.”
Thats one of the main-problems with writing secure code:
Most codebases are way too bloated.
smashIt,
Yeah, this type of bloat often accumulates over time and it becomes hard to get rid of. Linux definitely falls victim to such bloat, though to be fair this problem is not specific to linux. A lot of bloat was inherited from unix & posix. I wish we could reset a lot of bad and obsolete design decisions that create significant complexity today. Many of us would love to get rid of the bloat in favor of cleaner implementations that are easier to understand and written in safe languages. We’d be better off in the long run, but the trouble is it causes a lot of friction in the short term, which is where we always get hung up.
Artem S. Tashkinov,
I think tanishaj answered this well.
You are right that rust developers can still write valid code that does the wrong/buggy thing. However the good news is that, even when source code does contain a logic bug, rust will still execute the source code in good faith. The CPU will perfectly execute the logic as programed.
This is not the case with the memory corruption bugs that crop up in “unsafe” languages. When an invalid memory operation occurs under C/C++ (bad array bounds, use after free, faulty concurrency logic, etc), the result is “undefined” per the language. There could be a segfault, random or specific memory corruption, the call stack could get corrupted, etc. An immediate segfault is the best case scenario, but since “unsafe” languages have no mechanism to catch other memory access errors, the CPU just keeps chugging along executing instructions as is. but unfortunately none of the program logic is guarantied to be valid afterwards. The corruption means the software may start making logical decisions that are not even present in the source code. Obviously this is especially dangerous if hackers are able to exploit the corruption to take control of a process.
TLDR; Unlike C/C++, safe languages are well defined even when developers have logic bugs in the source. Not only does this make it much easier to debug and track down what’s going on, but it also prevents hackers from executing logic that isn’t in the source code.
So, in addition to tanishaj’s point about reducing the overall number of security issues, I think it’s worth consideration the classes of issues that are solved by eliminating C/C++ undefined memory behaviors. So IMHO the security benefits might be greater than the numbers suggest at face value.
In other words: If you want to code in “god mode” use C/C++, if you want the Disneyland wall gardens, use Rust.
Alfman, Rust is good, but you don’t need to bad mouth C/C++ to validate it. Don’t became the RMS of Rust. Remember that in the future Rust will be replaced too.
martini,
Actually no, that’s not a good conclusion. Rust can do all the same things C/C++ can, including generate unsafe code. However unlike C/C++ the use of unsafe code is explicit, which makes it significantly easier to audit than C/C++.
You can use “god mode” as a euphemism for the unsafe code that rust doesn’t generate by default, but ironically the primary use case for such unsafe code in rust is to integrate with C APIs. Believe it or not unsafe god mode code where inputs and lengths aren’t checked is bad practice even in C/C++! The difference is in rust correctness gets verified by the compiler, whereas in C/C++ it’s verified by the human developer and assumed to be correct.
Your portrayal is completely off the mark. I don’t say these things to bad mouth C/C++, but for better or worse these are the dominant languages responsible for nearly all system code including their software faults and vulnerabilities. It makes no sense whatsoever to disregard C/C++ in discussing what safe languages can bring to the table and frankly it really rubs me the wrong way that you would shun us and ask us to self-censor facts just because you don’t want to hear them. Kindly understand that I will be disregarding your advice and will continue to compare languages however I see fit. I make no apologies for this.
You seem to be assuming that I’d be thin skinned about this, but my position is pragmatic. If something else comes along, then I welcome it and encourage future discussions comparing the merits of all languages!
“[…] C/C++, but for better or worse these are the dominant languages responsible for nearly all system code including their software faults and vulnerabilities. It makes no sense whatsoever to disregard C/C++ in discussing what safe languages can bring to the table […]”
My thinking is a bit different I guess. C and/or C++ code is not good, bad, vulnerable, unsafe, etc., it’s just code. It becomes bad/etc. when the people who use them either don’t pay enough attention, or simply don’t have the skill to do so. I’ve seen my fair share of people coming from “safe” languages proclaiming themselves professional coders producing junk a$$ idiotic C/C++ code and doing full throated preaching about how C and C++ are bad, unsafe, whatever. Trying (again) to move “responsibility” from the coder to the compiler will (again) have the side effect of making those coders think they should not care about producing safe code.
Unfortunately I’m well aware that the number of people who have the skill and the will to produce safe code with whatever language they use is much much less than the number of people who proclaim themselves coding gods and produce landfills of junk. The latter drive the coding fashions waves. The good news is, that the good ones can adapt better and can ride the waves easier.
W.r.t. Rust: another language, another tool, it’s better to have more tools than less. Never complain about having too many possibilities. Learn to pick the right tools.
l3v1,
While I understand bad programmers can come into play, I don’t think we should be ignoring that even CS doctorates and industry veterans who are properly trained are also vulnerable to human error.. It’s not their fault, as software becomes larger, more bloated, more complex, etc. the likelihood of human error creeping in with no one being any wiser statistically increases. No organization or company is exempt from human error no matter their hiring practices. Real world projects typically have people coming and going on a regular basis. Even if an expert level senior developer signs off on the software, sheer scale and complexity will exceed their ability to consistently validate the code they are responsible for.
I’d like to circle back to what you said and look at it in terms of opportunity cost…
Even if humans could do manual code validation 100% correctly, which we can’t, what about the huge opportunity cost that comes from doing so?
As a thought experiment, we could have experts compute digits of pi manually using only human labor. Qualities like “good” and “bad” don’t have much meaning in the absence of context and automated alternatives. However I expect that you would agree that it makes little sense to have humans do the task when computers can automate it easier, faster, and more reliably than us. The automation is better in practically every way. Humans are much more expensive, significantly slower, and less efficient than computers that are extremely effective at consistently following rules and scaling them. So I have trouble understanding why, when it comes to programming languages, some developers become so defensive of old languages in the face of new languages automating code verification for large classes of memory and threading faults so that humans don’t have to. It almost seems like there’s an element of pride involved, insinuating that safe languages are primarily for untrained/inexperienced developers. IMHO this is a stigma the industry would do best to overcome. Why give memory validation chores to humans, even hypothetically perfect ones, when language automation can enable them to focus more deeply in other areas like logic bugs, features, and quality, etc?
So in summation experienced developer,s should be welcoming safe languages that offer automatic validation of memory faults. if not because the automation creates more reliable code, then because it enables human developers to become more efficient at their jobs.
Yes I agree.
Of all the things I hate about C and C++ fanboys, it’s exactly that feeling of superiority demonstrated in the quoted text. Here is a deal: If I told you you get to choose between coding in Rust, C, or C++, and for every memory-safety related error you will pay $10,000 to the corporation or organization you contribute the code to, would you still choose C or C++? I mean, you are coding in “god mode” and don’t need any of those “Disneyland walled gardens”, right? No? Then you are not coding in “god mode”, you just don’t care.
And don’t get me started about the idea that corporations and organizations should only recruit “god mode” programmers in a world where there is a huge demand for software. But I don’t have to get started, such programmers are vanishingly rare anyway, and certainly much rarer than your garden variety C and C++ fanboy.
So on one side you have this project called sudo. Written in C and developed and maintained for 40 years. All this done with some sparse funding. It enables people to have tight authority over their software stack. Something an average iPhone and to big extent Android user in this day and age doesn’t even comprehend. Anyway. All mayor companies use it extensively. Including AWS. And for sure it now makes much sense to rewrite sudo in Rust. And in a couple of years, when it’s done, then we have two large code bases to maintain. And when AWS pulls the plug on funding. It’s a given that some volunteer will do it for free. Maintain and improve the project. For the next couple of decades. Because it’s safe. I am a bit skeptical of that. But note that i don’t have a problem with it. It’s just the culture around it i find deserves a comment.
Geck,
So what though? This has no bearing on what’s best for the future. If we were all using your logic, we’d all still be using horse drawn carriages.
That’s disingenuous, you very much have a problem with those who view safe languages as progress. If you want to go be an Amish coder and stick to the old ways, then be my guest, do what feels right for you. I would whole heatedly defend that. But when you go judging others for the way they want to approach their projects, that’s just pretentious.
You are just a bit of a hipster in this regard. Future will sort itself out. In my opinion nobody will rewrite and maintain billions of C/C++ code in Rust. Hence we will still need to trust C/C++ in foreseeable future and consider it safe. If you like it or not. As for Rust projects. We will see in decades to come. On how successful and widespread they will become. Rust projects can for sure take sudo as a benchmark of authority in this regard. Still long way to go to match it.
Geck,
I’ve consistently said that legacy C/C++ code will stay around for a very long time. Once again I’ve caught you doubling down on this straw man. If this is your best argument against developers migrating parts of the codebase to rust, well it’s a bad argument. Nobody is saying change comes easy, but I’ve always believed it would be motivated by a generational shift, which I think we’re just starting to see evidence for. Stubborn people who are too attached to legacy technology will eventually get replaced by others who are more enthusiastic of modern languages. These generational transitions are slow, but am hopeful that safety will improve overall.
> nobody will rewrite and maintain billions of C/C++ code in Rust
Yet plenty of people *are* rewriting various C/C++/php/whatever tools in Rust/whatever, rather than maintaining old mature codebases. Sometimes it’s the right thing to do, and there are quite a few RIIR success stories now.
The fact that C/C++ will never fully die doesn’t mean we should keep all of it. Just as I am happy to leave the maintenance of old COBOL code to other people, I am looking forward to forgetting much of the C/C++-specific arcane knowledge I have acquired in the last 20 years.
> we will still need to trust C/C++ in foreseeable future and consider it safe
I don’t follow the logic here. The fact that I use/depend on something doesn’t mean that I fully trust it or can’t wish for something better.
If I wanted to play devils advocate I’d just write that C and C++ are for people incapable of writing ASM, playing God by proxy!
Rust is fine, whether it succeeds or fails shouldn’t be down to political preferences, it should be based on technical merits alone.
In any case, the evolution of C and C++ from origins is perhaps just as stark as the change from C or C++ to Rust, what is missing is time!
People tend to fall into two camps, those who oppose change regardless, and those who promote change regardless, it’s the eternal struggle.
“ People tend to fall into two camps, those who oppose change regardless, and those who promote change regardless”
This is the deepest wisdom in this comment section
cpcf,
I’m curious if you think I fall into one of those camps?
I’m probably over thinking it, but I’m not sure that change appeal is a primary driver or more of an arbitrary byproduct of something deeper. When I look at new operating systems (windows, linux, android, ios, etc) my reaction is often “meh”. I used to set windows to classic win2k themes because I feel that’s when microsoft was at their peak. Afterwards there was too much superficial eye candy and changes for changes sake, which doesn’t really interest me. So I’d be anti-change in this case. When I look at cars and appliances, I really prefer the older buttons over touchscreens. Again, anti-change. But when I compare unsafe legacy languages to safe modern ones, I think changing to safe languages has merit. Pro-change here.
Everyone can come up with their own examples for themselves. So I’m not sure if the desire for or aversion to change is fundamental. As a one dimensional concept, it’s feels too simplistic
While I agree it should be based on technical merits, I think that for most humans it can be hard to put merits above preferences. Once they have a preference in their head, they tend to commit to it and will view the world through filters that justify the validity of their preferences.
As an original C dev who fell in love with C++, believe me I was called all sorts of names by the C die hards. Its really interesting to see C & C++ diehards talking as if a real C dev would even share the same air as a C++ heathen.