Hacker News new | ask | show | jobs
by lohnjemon 896 days ago
What kinds of memory safety bugs do you really care about in coreutils? Genuinely curious.

Given how mature and well defined the GNU Coreutils are, how small their scope is, how they are used, I really don't see the supposed security upside here.

There simply has to be a better reason to me, than "Rust good".

3 comments

Some CVEs have happened in the past [1]. None of them memory issues, but a couple that seem unlikely in idiomatic rust or are much easier to prevent in rust.

Specifically, integer overflow is much easier to correctly handle in rust, making bugs like CVE-2015-4042 less likely, and correct handling of multibyte strings is basically enforced by the standard library, making issues like CVE-2015-4041 very unlikely in a rust implementation

1: https://www.cvedetails.com/vulnerability-list/vendor_id-72/p...

So this one integer overflow in sort, a command which is never ran as root is an issue somehow, because it can cause a denial of service(it crashes)? Am I missing something here. Can I use this to exploit someone's machine?

I can search uutils/coreutils for "overflow" and get way more hits, I don't see how this is a rational thing to be afraid of within GNU Coreutils considering it's a collection of tools, that have been developed and maintained for decades and used by millions over that time period.

https://github.com/uutils/coreutils/issues/1420 https://github.com/uutils/coreutils/issues/886 https://github.com/uutils/coreutils/issues/5149

To be clear, I don't see any problems personally with any of these issues, they don't seem very exploitable to me.

However, I think that relying on Rust to be the bastion of safety merely because the name "Rust" is mentioned is nothing but a fallacy.

To me, logic bugs are the far more egregious category in something like coreutils. Me making the assumption, that something works the way it's documented, but doesn't can lead to horrible things down the road. Much more so, than any integer overflow crash could ever dream to.

But you still need to pay attention to use overflow checking versions of functions when doing arithmetics, because in release mode regular integers are not overflow-checked at runtime, unless you explicitly enable -C overflow-checks=true—whichin my opinion would be a good default for many non-performance-critical applications.

Arguably it's the "pay attention" part that causes the bug in the first place, so I don't think the performance-oriented default was a good pick.

The issue is mitigated a bit by the remaining runtime array bounds checks, but I must wonder if those checks could be removed by the optimizer when it believes e.g. a variable can never be below a certain value.

Apart from overflow checking in debug mode or with the right compile flag, rust also makes it a lot easier to do the right thing, e.g. 100u8.saturating_add(255) or even encoding it in the type system (`use std::num::Saturating; let mut x: Saturating<u8> = Saturating(128); x += 200; assert!(x == Saturating(255))`) (obviously you can also use Checking for explicit handling or Wrapping instead of Saturating). Meanwhile overflow handling in C/C++ is difficult, tedious and full of footguns caused by compiler optimizations.
It seems it's going to become easier to check them in C++26 with https://en.cppreference.com/w/cpp/numeric/add_sat and friends. Or if you want saturating integer types, you can find https://github.com/StefanHamminga/saturating (granted this does not seem maintained) or https://www.boost.org/doc/libs/master/libs/safe_numerics/doc... from boost for a checked integer type. https://github.com/mbeutel/slowmath gives you exception throwing checking.

I haven't tried that style in Rust—or in C++ for that matter—but is it truly much nicer than the options available for C++? Perhaps out-of-the-box experience is the winner there.

There are lints you can enable to enforce this, rather than just "pay attention".
Wasn't it just a couple of years ago that we had shell shock? According to Wikipedia that bug was introduced in 1989. Of course, that wasn't a memory safety issue (and it's probably important to reiterate that memory safety doesn't mean free of bugs and / or exploits). But it does demonstrate that issues can exist for a long time in mature code without anyone noticing.
> Wasn't it just a couple of years ago that we had shell shock?

Yes, but Bash (or any other shell) isn't part of coreutils.

https://en.wikipedia.org/wiki/List_of_GNU_Core_Utilities_com...

I think the upside is that these utils are not set in stone and never updated. Future maintainers will probably find it easier to work on a more modern codebase with more footgun protections. So, yes while the current utils is great, at some point the code will have to be modified and I would much rather modify clean Rust code than 30, 40, 50 year old super optimized C that no one truly understands anymore.