Comment by alkonaut

14 days ago

> What’s notable is that all of these bugs landed in a production Rust codebase, written by people who knew what they were doing

So does this mean that neither did the original utils have any test harness, the process of rewriting them didn't start by creating one either?

Sure there are many edge cases, but surely the OS and FS can just be abstracted away and you can verify that "rm .//" actually ends up doing what is expected (Such as not deleting the current directory)?

This doesn't seem like sloppy coding, nor a critique of the language, it's just the same old "Oh, this is systems programming, we don't do tests"?

Alternatively: if the original utils _did_ have tests, and there were this many holes in the tests, then maybe there is a massive lack in the original utils test suite?

> So does this mean that neither did the original utils have any test harness, the process of rewriting them didn't start by creating one either?

Yes.

> Sure there are many edge cases, but surely the OS and FS can just be abstracted away and you can verify that "rm .//" actually ends up doing what is expected (Such as not deleting the current directory)?

I think people have been trying that since before I was born and haven't yet been successful, so I am much less sure than you are.

For example: How do you decide how many `/` characters to try?

For a better one: Can you imagine if "rm" could simply decide to refuse to delete files containing "important" as first 9 bytes? How would you think of a test for something like that without knowing the letters in that order? What if the magic word wasn't in a dictionary?

> This doesn't seem like sloppy coding, nor a critique of the language, it's just the same old "Oh, this is systems programming, we don't do tests"?

I've never heard anyone say that except as a straw man.

I've heard people say tests don't do what people think they do.

> Sure there are many edge cases, but surely the OS and FS can just be abstracted away and you can verify that "rm .//" actually ends up doing what is expected ?

This is one reason why Windows disables symlinks by default, and it's not an abstraction but wholesale removal of a feature. Unixes can't do that without breaking decades of software that relies on their existence.

MacOS does something similar, for example the chroot() bug isn't an issue in practice because MacOS forbids chroot() by default (you need to disable system integrity protection).

The fundamental problem is caused by the POSIX APIs. They have sharp edges by their very nature. The "fix" is to remove them.

My understanding is the uutils development process involved extensive testing against the behaviour of the original utilities, including preserving bugs.

  • But we still have CVE's for trivial things? I mean just a medium sized test suite for "rm" alone should probably be many thousand test cases or so. And you'd think that deleting "." and "./" respectively would be among them? Hindsight is always 20/20 and for inputs involving text input you can never be entirely covered, but still....

  • If something as basic as "rm ./" is broken, the word "extensive" does not apply to whatever testing there was.