Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Simple Bash syntax error in Steam for Linux executed “rm -rf /*” (2015) (github.com/valvesoftware)
31 points by jakejarvis on April 10, 2019 | hide | past | favorite | 12 comments


My first thought on reading the headline was "what Linux still did that in 2015"? I thought I read somewhere years ago that Sun, BSD and GNU rm all had checks in them to spot the / or /* and refuse to run. According to this SE page[1] GNU even has an option to tell rm "no I really do want to blow away my whole root" by using "--no-preserve-root".

Apparently the "fix" only applies to the root user. The article is about a regular user who recursively lost everything he owned starting at /.

Ouch!

[1] https://unix.stackexchange.com/questions/19547/how-far-can-y...


GNU rm only catches "/". The Steam issue was for /* which is expanded by the shell.


That seemed crazy to me so I spun up a VM, took a snapshot and then ran rm -rf /* as root. Sure enough it started nuking everything it could, skipping over only a few things like most of what's in proc, etc...

Thanks, it's was interesting to see the difference!


The real problem here is that a multi-hundred-line script was written in bash. While bugs can happen in any language, this particular error was due to a bash-specific pitfall, and bash has many such pitfalls. Bash is really only suitable for interactive use, or for bootstrapping the install of another scripting language.


I think this goes too far. There are many robust scripts out there. If you use rm -rf, change into a hardcoded directory first and then remove another explicit directory.

Recursively removing something that starts with a shell variable is stupid.


>Line 468: rm -rf "$STEAMROOT/"*

Oh man, reading that line made me cringe.


Seriously, how do you use rm -rf anywhere in a script without copious if statements? It's quite easy to avoid this mistake.


TIL that this quick trick [1] also would have prevented this:

  ${STEAMROOT:?}
...where :? throws an error if the variable is unset or empty. (Still far too scary for my taste, though!)

[1] https://github.com/koalaman/shellcheck/wiki/SC2115


Or you just do

  set -euo pipefail
as the first thing in your bash script which you absolutely should do every single time.


Note that's bash not POSIX though right?


If you need an extra check in any API to do something really damaging, the problem is with the design of the API itself.

I generally just prefer not using Bash scripting, as it's very hard to compose functionality in it.


Or maybe just `set -o nounset`




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: