Live data from Hacker News

Bugs Rust won't catch

corrode.dev

201–210 of 395 posts

Re: Bugs Rust won't catch

#201
post #81

Earlier quoted context omitted.

Rewriting perfectly good code was a colossal mistake.

I do wonder whether people got down the article enough to see the list of bugs patched in GNU coreutils. That "perfectly good code" that it sounds like no one should question included "split --line-bytes has a user controlled heap buffer overflow".

Yes, perfectly good code can have bugs. This is ridiculous thinking to scrap a codebase because it's not bug-free, to replace it with one riddled with differences in behavior that break everything that uses it.

Re: Bugs Rust won't catch

#202
post #190

I find it interesting how people will criticise Rust for not preventing all bugs, when the alternative languages don't prevent those same bugs nor the bugs rust does catch . If you're comparing Rust to a perfect language that doesn't exist, you should probably also compare your alternative to that perfect language as well right? I'd be interested in a comparison with the amount of bugs and CVE's in GNU coreutils at t…

"The alternative languages" - in this case you're talking about C, 99% of the time. So let's talk about that. Well written C code, especially for the purpose of writing and continuing to maintain mature GNU coreutils, is not a big risk in terms of CVE. Between having an inexperienced Rust developer and an extremely experienced C developer (who's been through all the motions), I'd say the latter is likely the safer op…

100% it's the safer option.

The software with the best security track record of all time is written in C.

Re: Bugs Rust won't catch

#203

The root cause of some of the bugs seems to be the opaque nature of some of the Unix API. E.g. > The trap is that get_user_by_name ends up loading shared libraries from the new root filesystem to resolve the username. An attacker who can plant a file in the chroot gets to run code as uid 0. To me such a get_user_by_name function is like a booby trap, an accident that is waiting to happen. You need to have user data,…

> The root cause of some of the bugs seems to be the opaque nature of some of the Unix API. Some, maybe, but if you've decided to rewrite coreutils from scratch, understanding the POSIX APIs is literally your entire job. And in any case, their test for whether a path was pointing to the fs root was `file == Path::new("/")`. That's not an API problem, the problem is that whoever wrote that is uniquely unqualified to b…

> Some, maybe, but if you've decided to rewrite coreutils from scratch, understanding the POSIX APIs is literally your entire job.

Yes, it is. But still such traps in API just unacceptable. If you design API that requires obscure knowledge to do it right, and if you do it wrong you'll get privilege escalation, it is just... just... I have no words for it. It is beyond stupidity. You are just making sure that your system will get these privilege escalations, and not just once, but multiple times.

Re: Bugs Rust won't catch

#205

Earlier quoted context omitted.

If you want to support file I/O in the standard library, you have to choose _some_ API, and that either is limited to the features common to all platforms, or it covers all features, but call that cannot be supported return errors, or you pick a preferred platform and require all other platforms to try as hard as they can to mimic that. Almost all languages/standard libraries pick the latter, and many choose UNIX or…

You have to choose something, and I'm glad they didn't go with the idiotic Go approach ("every path is a valid UTF-8 string" or we just garble the path at the standard library level"). You can usually abstract away platform weirdness at the implementation level, but programming on non-Unix environments it's more like programming against cygwin. A standard library for files and paths that lacks things like ACLs and lo…

As far as I can tell from Microsoft's documentation, WinAPI access for ACLs was added in Windows 10, which Rust 1.0 predates. And std::fs attempts to provide both minimalist and cross-platform APIs, which in practice means (for better or worse) it's the lowest common denominator between Windows and Unix, with the objective being that higher-level libraries can leverage it as a building block. From the documentation for std::fs:

"This module contains basic methods to manipulate the contents of the local filesystem. All methods in this module represent cross-platform filesystem operations. Extra platform-specific functionality can be found in the extension traits of std::os::$platform."

Following its recommendation, if we look at std::os::windows::fs we see an extension trait for setting Windows-specific flags for WinAPI-specific flags, like dwDesiredAccess, dwShareMode, dwFlagsAndAttributes. I'm not a Windows dev but AFAICT we want an API to set lpSecurityAttributes. I don't see an option for that in std::os::windows::fs, likely complicated by the fact that it's a pointer, so acquiring a valid value for that parameter is more involved than just constructing a bitfield like for the aforementioned parameters. But if you think this should be simple, then please propose adding it to std::os::windows::fs; the Rust stdlib adds new APIs all the time in response to demand. (In the meantime, comprehensive Windows support is generally provided by the de-facto standard winapi crate, which provides access to the raw syscall).

Re: Bugs Rust won't catch

#206

> uutils now runs the upstream GNU coreutils test suite against itself in CI. That’s the right scale of defense for this class of bug. That's the minimum, it is absurd that they did not start from that!

I believe they did it all the time. Maybe it was not automated? But they boasted in news multiple times how many coreutils tests they are passing. I suspect that those tests are useless for security, they are more about compatibility or something like that.

Re: Bugs Rust won't catch

#207
post #140

Earlier quoted context omitted.

As other people have mentioned, the goal of uutils was not "let's reduce bugs in coreutils by rewriting it in Rust", it was "it's 2013 and here's a pre-1.0 language that looks neat and claims to be a credible replacement for C, let's test that hypothesis by porting coreutils, giving us an excuse to learn and play with a new language in the process". It seems worth emphasizing that its creation was neither ideological…

But are the current uutils developers the same as the 2013 developers? At least based on GitHub's graphs, that's not the case (it looks fairly bimodal to me), and so it wouldn't be unreasonable to treat the 2013-era project differently to the 2020-era project. So judging the 2020-era project for its current and ongoing failures does not seem unreasonable. Similarly, sudo-rs dropping "legacy" features leaves a bad tas…

doas and sudo-rs occupy different niches, specifically doas aims for extreme minimalism and deliberately sacrifices even more compatibility than sudo-rs, which represents a middle ground.

Re: Bugs Rust won't catch

#208

> This is the largest cluster of bugs in the audit. It’s also the reason cp, mv, and rm are still GNU in Ubuntu 26.04 LTS. :( This is what grinds my gears. Why all the hate against GNU? Honestly, this is why I don't learn Rust, and why I didn't bother to read the rest of the article.

Rust does not hate GNU, and I'm not sure why anyone would have that misconception. It would be like saying that C hates GNU because the BSDs aren't GNU. The fact that there is less GNU-licensed Rust software than MIT-licensed Rust software is attributable to the simple fact that, in general, GNU has been ceding ground to MIT for more than 20 years.

Re: Bugs Rust won't catch

#209
> Rust’s standard library makes this easy to get wrong. The ergonomic APIs you reach for first (fs::metadata, File::create, fs::remove_file, fs::set_permissions) all take a path and re-resolve it every time, rather than taking a file descriptor and operating relative to that. That’s fine for a normal program, but if you’re writing a privileged tool that needs to be secure against local attackers, you have to be careful.

It's not fine even for a normal program, because operations on a large number of files will end up an order of magnitude slower. No matter what language you write your utility in.

... reads the article to the end, marvels at all the problems resulting from not understanding how the OS works and missing 40 years of refinement ...

Is this in an Ubuntu LTS ?!?

Re: Bugs Rust won't catch

#210

Hi, I am one of the maintainers of GNU Coreutils. Thanks for the article, it covers some interesting topics. In the little Rust that I have used, I have felt that it is far too easy to write TOCTOU races using std::fs. I hope the standard library gets an API similar to openat eventually. I just want to mention that I disagree with the section titled "Rule: Resolve Paths Before Comparing Them". Generally, it is better…

I don't know if you're aware, but there is a demonstration of wget (a fellow "gnu utility", right?) being auto-translated to a memory-safe subset of C++ [1]. Because the translation essentially does a one-for-one substitution of potentially unsafe C elements with safe C++ counterparts that mirror the behavior, the translation should be much less susceptible to the introduction of new bugs and behaviors in the way a rewrite would be.

With a little cleaning-up of the original code, the code translation ends up being fully automatic and so can be used as a build step to produce (slightly slower) memory-safe executables from the original C source.

[1] https://duneroadrunner.github.io/scpp_articles/PoC_autotrans...

Post reply on HN