8 ms·
So 6 out of 174 CVEs could have been avoided this way. ... but how many more of the unavoided logic errors will be created by using a language which is far more
by nullc 3y ago
So 6 out of 174 CVEs could have been avoided this way. ... but how many more of the unavoided logic errors will be created by using a language which is far more complicated, less clear, and readable/reviewable to far fewer people?
That said, It's a great sign for that the tests that it was was comprehensive enough to find bugs in the original sudo. But a set of tests isn't really complete until it finds a compiler bug too. :)
- iknowstuff 3y agoRust is far more readable and reviewable than C code. As attested by 1000 Googlers.
- c_crank 3y agoI wouldn't trust Googlers as a measure of any sort of quality, given their love of Go. C code relying on tons of macros will be harder to read then C code that delegates preprocessing to another language. Rust code that leans heavily into the ML features and unwrap.parent.unwrap.parent.unwap... will be a lot more unpleasant than Rust code written to just get the bit shifting job done. I imagine it really depends on the code base.
- jeffbee 3y agoYou might be overestimating the popularity of Go within Google. That said, a tool like sudo should be written almost entirely in a very high-level language that is easy to use and review. C, C++, or even Rust should be reserved for places where the system interface requires it, if there are any such points of interface.
- c_crank 3y agoA job for Common Lisp!
- Chabsff 3y agoOn the flip side, languages like C,C++ and Rust have the major benefit of having next to no runtime component to it, allowing trace-driven fuzz testing to achieve a much higher level of confidence in its test coverage. For a tool like sudo, this can matter a lot.
- nullc 3y agoI think this is really important and it's a big part of what makes it unrealistic to write critical software in Python or Java: It's too slow to get extremely deep testing, even with fancy tricks like snapshotting the execution state to avoid startup costs. But, that said, Rust code compiled in debug mode which required to get integer overflow detection is slow enough that it severely degrades the ability to use fuzz testing on many codebases, FWIW. I believe the reason is that debug mode always disables numerous optimizations that are required to make rust performant at all because of all the boilerplate emitted by earlier stages of compilation. AFAIK there isn't a way to get the equivalent of GCC's "-fsanitize=undefined" (or -ftrapv) for checking for unexpected overflows at a performance cost similar to "-fsanitize=undefined" performance cost on C code. It's still a much better situation than python or java, I think-- but an area that could use improvement which won't be improved if rust is above criticism.
- steveklabnik 3y agoYou can pretty trivially turn on overflow checks yet compile with all of the other release options as normal. It's one line in cargo.toml or one flag to rustc.
- nullc 3y agoWhat is the one line? (I shall benchmark!)
- steveklabnik 3y agoiirc it's `-C overflow-checks=y` to rustc or [profile.release] overflow-checks = false in cargo.toml. I would probably use the flags with RUSTFLAGS to make sure that it goes to all dependencies and not just the crate you're building, if what you're building has dependencies.
- thwd 3y agoHuh? Go has its tradeoffs, some people don't like it and that's fine. But nobody can deny that it is by far one of the most 'readable and reviewable' (the argument in question) mainstream languages.
- c_crank 3y agoThe praise of Go didn't end with it being just readable, but also 'brutally pragmatic' and all that. If Googlers think that Rust code is just as readable as Go, even though Rust obviously makes tradeoffs against readability for other features, I would be tempted to mark that as Googlers just having a culture about being overeager to think the tools they are using are the best.
- earthling8118 3y agoWhy can't I deny that it is readable and reviewable? I don't think it is, basically at all. It gets evangelized as if it is but I have yet to see a compelling argument that can convince me. I've had the displeasure of having to dive into some codebases and I specifically hate it for that reason.
- thwd 3y agoWell, I can't speak for you, of course. I also haven't seen that code you reviewed. And I won't try to evangelize you. I'd say, in a nutshell, that Go is readable and reviewable because its grammar consists of the C-style basis that most every imperative language has, and not much more. It's the lack of features that makes it very 'WYSIWYG'.
- xxs 3y agoI think java is way more readable (and safe) than C - we should all switch to. Proof by authority w/o any background is not useful
- cryptonector 3y agoSolaris had a bit of Java in it, and it was a terrible fit on account of how slow the JVM startup was and how large its memory footprint. Now that was almost 20 years ago and by now there's ways to optimize the JVM for short-lived processes, but it's still a pain and it's still a huge installation just for a small program like `sudo`. No, something like `sudo` needs to be natively compiled, or if bytecompiled then to a tiny VM -- tiny in every way: tiny opcode set, tiny bytecode interpreter, tiny install size.
- shrimp_emoji 3y agoYou're not wrong, yet I'd sooner kill myself.
- tredre3 3y agoI think getting a fresh perspective from fresh developers is still a net positive, some of the CVEs are truly embarrassing for such a critical piece of code. That being said I skimmed the list of CVE and yeah Rust wouldn't have prevented anything. The rust evangelism is exhausting.
- j16sdiz 3y agogetting fresh perspective, or repeating the same mistake. Many logic error were discovered in real life use cases over many years
- nullc 3y agoIt's finally my turn to link this often linked essay: https://www.joelonsoftware.com/2000/04/06/things-you-should-never-do-part-i/ https://www.joelonsoftware.com/2000/04/06/things-you-should-... I don't believe I've ever seen it shared in the context of rewrite-in-rust, but I think the views it expresses also have some value in this context.
- 0cf8612b2e1e 3y agoOn the other hand, part of the goal is to strip out accumulated feature creep. Sudo apparently has a lot of functionality which I never knew existed, all of which could lead to future bugs. There are quite a few Unix tools which I think could use a similar refresh if not frozen in time thanks to POSIX.
- nullc 3y agoNo doubt 80% of the users only use 20% of the features... but do they use the same 20%? :) I think sudo is often the wrong tool for what people are using it for today-- it's a tool to delegate on a multi-user system. But today people are most often applying it on a single(-ish) user system to raise or lower their permissions. Ironically, most of the vulnerabilities that sudo has had aren't really of consequence in that modern single user usage: If the attacker can run code as the user, then they'll be able to take over any privilege raising process the user uses even if the 'sudo' tool were flawless. Once you leave that use case the greater feature set of sudo (including, perhaps some of those crusty features you mention) has more applicability. The thing to always keep in mind is that the programs cruft is substantially the body of its embedded knowledge. Some of that knowledge might be mistaken or outdated. If you really knew what parts were what-- you could just remove them. If the rewrite isn't sure it can remove it and just replicates, it may not have understood the function's purpose enough to replicate it faithfully and could even introduce security problems (or cause users to introduce them by forcing them to bodge around configuration statements that no longer work).
- jmmv 3y agoThe expressive type system and the borrow checker /also/ allow you to avoid many of the logic bugs that you’d have otherwise.
- nullc 3y agoIn the case of memory safety, we can say that absent compiler bugs, use of unsafe (including by dependencies), or callouts to other languages that rust defiantly eliminates essentially all memory safety bugs. We can't make the same strong statement about the type system preventing other bugs. The type system in rust requires a LOT more boiler plate code an extra typing, some of which can introduce bugs. I am not aware of any study that would support the claim that rust reduces the defect rate overall and I'm somewhat doubtful of claims that it does because of the absurd regularity that rust software immediately panics on me when I attempt to use it (and, the amount of firfox crashes I've experienced which of late are almost entirely rust code panicking under the hood). It's also possible that what I'm seeing are all defects that would have existed otherwise made slightly more visible, if so -- it's a good thing. But we shouldn't let the fact that we can take for granted that rust avoids memory safety bugs by construction from meaning that its other properties which MAY reduce defects over all actually do. Hopefully it does. But writing software entails a lot of cost and risk to undertake for a hope and plenty of things that have been intended to make things better actually made them worse.
- jmmv 3y agoI know it's hard to make a strong argument about this, and also to gather data on it. But there is https://opensource.googleblog.com/2023/06/rust-fact-vs-fiction-5-insights-from-googles-rust-journey-2022.html https://opensource.googleblog.com/2023/06/rust-fact-vs-ficti... , section "Rumor 5: Rust code is high quality – Confirmed!", which touches upon this. That said, personal experience has shown me that modeling data using types (instead of abusing, say, string-to-string dicts as is common in Python, or passing "untyped" strings around for things that /are/ strings but that have higher meaning, like file system paths) is very beneficial to program correctness. Obviously this is doable in many languages, but Rust helps enforce this due to the lack of implicit promotions and general adoption of these idioms in standard/common libraries. As one specific example, I originally wrote sandboxfs (a FUSE file system) in Go and then rewrote it in Rust -- part because I hit performance issues, and part because I wanted to learn Rust. Trying to reproduce the original structure of the code in Rust was not doable, and having to adapt it to Rust highlighted various logic and concurrency bugs that existed in the Go version but that silently went unnoticed.
- teaearlgraycold 3y agoI think your complaints about Rust would depend on the quality of the code. You can go wild, or you can keep things simple.
- berkes 3y ago> using a language which is far more complicated, less clear, and readable/reviewable to far fewer people? By that reasoning we should rewrite all these tools in JavaScript or Ruby, Python or some such. Clearer (than C), more readable and readable/reviewable to far more people. Edit: to be clear: I think that would be an extremely dumb idea.
- nullc 3y agoAll of JS, Ruby, and Python are vastly more complicated languages than C. They do have a shallower learning curve. It's unclear to me what degree they have a bigger review audience: there are an awful lot of write-only JS programmers! :)
- lelanthran 3y ago> By that reasoning we should rewrite all these tools in JavaScript or Ruby, Python or some such. Clearer (than C), more readable and readable/reviewable to far more people. > Edit: to be clear: I think that would be an extremely dumb idea. I dunno if it really is that dumb. Why can't sudo be rewritten in Go? The performance difference is not likely to be noticed and there's no runtime platform dependence (as with Python, et al). And, with managed memory, you'll have even fewer memory-safety bugs than with Rust. What exactly makes Rust a better fit for sudo than Go, bearing in mind that Go is a whole lot safer than Rust.
- paddim8 3y agoHow is Go a lot safer than rust?
- lelanthran 3y agoAny GC language is a lot safer than Rust. Seriously, anytime you have to manage memory yourself it's going to include the danger that you mismanage it. Rust does not prevent all types of memory mismanagement. What's more, the burden is on the programmer to manage memory; all the Rust compiler tells you is where there are potential (not actual) memory errors. The programmer still has to fix them, and even with that there are still a number of memory errors that will get through. Compare to a GC - allocate an object and then forget about it. No problems at all.
- arp242 3y agosudo doesn't have 174 CVEs. People always link to a simple mitre keyword search, and many just mention sudo in passing; you don't have to look far: the two first items on that list are not about sudo at all. The last time I looked at this[1] I found the most serious problems were logic issues, and not memory issues (although there are some of those a well). [1]: https://news.ycombinator.com/item?id=35756093 https://news.ycombinator.com/item?id=35756093
- entriesfull 3y ago> but how many more of the unavoided logic errors will be created by using a language which is far more complicated, less clear, and readable/reviewable to far fewer people? Can we stop pushing this false narrative about Rust being sooooo overly complicated? The real reason this narrative is pushed is because lazy developers don't want to take the time to learn a language that forces them to think. Yes I said it. Most of these developers want to go on autopilot just copying/pasting code from others and not even think about security in the slightest. Rust is actually really shallow in what you have to learn to write safe code. For me, languages like JavaScript, python, and C++ are the real complicated languages. Which is why I haven't "learned" (is that even possible) them.
- nullc 3y agoRust is a dramatically more complex language than C (what sudo is written in!). If you force the comparison with C++ then your position has more merit, however, I think there is still an argument that the subset of C++ that you must deal with in a given codebase can be (and often is) simpler than the portion of rust you must deal with in any rust codebase. I'm not particularly confident of this position, however, and it's tangential to the point that rust is unambiguously more complex than the language used by sudo. Aside, there is an enormous amount of thoughtless copy and paste in rust, just as there is in other language. Rust also comes with a culture of extremely promiscuous dependency use, it's not uncommon to build a rust program and watch the compilation download and build two different SSL libraries! -- even a program that you have no interest in using with HTTPS/SSL at all. Maybe in spite of the bad dependency culture rust actually will mean an advance in software quality in practice. But I think we simply don't have evidence of that (yet), and it's overly hopeful to assume that this will be the outcome simply because it was the intent of the creators of rust. The fact that any criticism or concern gets mobbed an that there is so much mindless advocacy from people that haven't even considered issues like the trusted-computing-base problem doesn't speak well for the prospects that rusts' own problems that limit its benefit will be addressed.
- entriesfull 3y agoWhich is why I didn't mention C along with those other languages that are spaghetti. C is simple, clean, and won't get in your way. That last part is why most serious bugs occur. Unless the language is built from the ground up to prevent the bugs from compiling then you will always have vulnerabilities. I know that C is a beautiful language and Rust is ugly but at some point we have to realize that humans are error prone and will always produce buggy C code. As for Rust dependency issues, here's a very simple article for beginners: https://marketsplash.com/tutorials/rust/rust-dependencies/ https://marketsplash.com/tutorials/rust/rust-dependencies/ There's also the cargo tree command to find duplicate dependencies: cargo tree --duplicates By far more better than the dependency hell that is Node.js :D