93

I haven't tried this command on Ubuntu (for obvious reasons) so I am not sure if Ubuntu will allow its execution. But it's famous for deleting everything. Just out of curiosity, what happens when the kernel and /bin are deleted? How does rm maintain a run time stack? How does rm manage to communicate with the file system and complete deletion? How does it communicate with hardware?

12
  • 20
    rm -rf / doesn't delete anything without --no-preserve-root.
    – muru
    Apr 2, 2015 at 11:58
  • 53
    My very first experience with Linux was making a Ubuntu vm so that I could "rm -rf /" it. I recommend you try this. It's pretty quick to setup, it keeps your host safe and is very entertaining to watch the different parts of the OS crumble before your eyes. Very satisfying.
    – DJMcMayhem
    Apr 2, 2015 at 14:31
  • 23
    Reminds me of my favourite understated bug report: bugzilla.redhat.com/show_bug.cgi?id=1202858 "Expected results: Squid is restarted. Actual results: All files are deleted on the machine."
    – user12753
    Apr 2, 2015 at 16:01
  • 10
    You should read Unix Recovery Legend. As long as you are still logged into a shell, the system isn't completely dead! Apr 2, 2015 at 17:46
  • 2
    @gerrit I did. :)
    – muru
    Apr 2, 2015 at 18:06

6 Answers 6

88

It doesn't matter that /bin/rm is deleted. It's only being run once and by that point it's all loaded in memory, as is everything else required to keep sending deletes to the filesystem and disk.


Sidebar/Update: Per David Hoelzer's answer (and mentioned in the comments), the inode the hardlink /bin/rm used to point to would remain right up until rm finished (because Linux holds in an open state) but that fact is irrelevant; the state of the disk doesn't matter at all.

The binary is loaded into memory before it is run. Even if you could manually destroy the rm disk data, it wouldn't affect or stop the deletion from completing (assuming you don't otherwise make the disk unavailable).

No idea what an inode or hardlink are? This is the answer where I worked it out.


Anyway, this is also why you can delete the package for the current kernel without the computer imploding. As long as you install a different version, it'll be able to boot up.

Again, this works because rm is only called once. The following would fail after /bin/rm died because it calls it once for every filename:

find / -exec rm {} \;

That said, find / -exec rm -rf {} + and find / -print0 | xargs -0 rm -rf would also both likely fail because they both have argument limits, meaning they would only delete a number of files before being called again. At some point along the journey, /bin/rm could expire (and be released) before the rest of the files were deleted. It's not guaranteed though. If /bin/ were the last directory entered, these methods could work.

10
  • 7
    As @DavidHoelzer explains, unlinked files need not be already in memory to keep working. The kernel knows there's an open file handle, so it keeps the file data around to satisfy any requests (including page-ins) until the last handle is closed.
    – nobody
    Apr 2, 2015 at 23:57
  • 4
    @Desty, no, that wouldn't succeed, as long as /bin/rm isn't close enough to be the end to be in the very last batch; -exec ... {} + (the backslash escaping is unnecessary) still results in multiple executions; not one per file, but one per batch based on the number of arguments that can fit into ARG_MAX. Apr 3, 2015 at 18:25
  • 6
    @Oli, it's not about paging; reference counters are linked to the inode, not the directory entry, and an open file handle counts as a reference (same as a hard link does), preventing the inode from being deallocated. File size is not a factor at all, and this happens even if there's no swap space (thus, no paging) at all. Apr 3, 2015 at 18:25
  • 2
    @CharlesDuffy Regardless of whether you have swap space or not, paging will be used for all memory mapped files. That includes all executables and libraries. In fact lack of swap space can actually mean more paging going on for memory mapped files.
    – kasperd
    Apr 6, 2015 at 11:59
  • 2
    @CharlesDuffy Yes, the size is indeed irrelevant. Memory mapping a file doesn't cause any of the contents of the file to be loaded until accessed. And memory used to load the accessed parts of the file can be freed again if needed, after which it will be loaded from the file if accessed again. So the file does indeed have to stay on the file system as long as it is mapped, and this behave the same way for a one page file as it does for a file large enough to span the entire address space. (The details are a bit more complicated for copy-on-write mappings which are needed for dynamic linking.)
    – kasperd
    Apr 6, 2015 at 14:53
60

I haven't tried this command on Ubuntu (for obvious reasons) so I am not sure if Ubuntu will allow its execution.

I did. rm -rf / --no-preserve-root was running in a root session opened directly on the machine, while I was also connected through ssh from another machine, using the root account as well.

What happens is that you start to get a lot of messages like:

rm: cannot remove '/...': Operation not permitted

or:

rm: cannot remove '/...': Device or resource busy

enter image description here

Surprisingly, ssh connection remained opened until the end of the operation. It's only when I closed the connection and tried to reopen it that a error appeared:

Read from socket failed: Connection reset by peer

On the machine, four directories remain:

  • /dev. This is where device files are stored.
  • /proc—in-memory filesystem created by the kernel.
  • /run, a standardized file system location for daemons.
  • /sys. This allows you to get information about the system and its components.

This means that there is not much left, and not much to do there. You can't ls (although when using Tab, the names of directories and files are still displayed). You can cd in different directories, and also echo stuff, but commands such as cat are not available any longer.

There is no sudo either.

shutdown -h now and reboot disappeared as well, so your only option seems to turn the machine down manually. Logout (exit) doesn't work, even if it shows a nice "logout" text.

Once you try to reboot the machine, you're presented with a nice GRUB error 15, and then, nothing happens, at which point you may start thinking that your rm might have done something bad to your system.

enter image description here

You can do it too

No, wait, don't do it on your machine!

What you can do instead is to run a virtual machine. VMs have a benefit of making experimentation really easy. Since you are using Ubuntu, you may be interested by vmbuilder. This is a tool which allows you to deploy virtual machines in a matter of minutes (the official documentation claims that it can be done "in about a minute", but the actual time, even on fast hardware, is more about two-three minutes.

Once the deployment ends, you have an environment you can play with. If you end up destroying it, it doesn't matter: you deploy the machine again, and two minutes later you can continue.

If you use software such as VMWare, you may also be interested in snapshots (note that the free VMWare Player doesn't have this feature; you have to purchase VMware Workstation). Note that Hyper-V is free and supports snapshots (but you have to run Windows).

The benefit of snapshots is that you can take one in a matter of milliseconds. Rolling back to a snapshot takes longer, but is often a matter of seconds. This makes experimentation even easier and faster.

This experimentation is not limited to the operating system itself. You can do all sort of things involving software. Got a suspicious application? Test it in a VM—if it's a virus, it won't do any harm. Want to test an operation on a database, given that it might affect the environment? Test it in a VM.

What if you did that on a real, non-test machine?

Bad things happen. Note that rm protects you from yourself: rm -rf / won't work: you need to use --no-preserve-root. Still, what if you actually achieved, by mistake, to remove everything?

rm only unlinks files, but the data is still there, on your hard disk. This makes it possible to recover it later (which is why you shouldn't just throw away your hard disks with sensitive data when they are not working any longer).

This means that you just have to have a spare PC with a hard drive enclosure to actually recover nearly all the files. The important thing is to avoid writing anything to the hard disk to recover: the data you write will overwrite the unlinked files.

As noted by the article in 200_success's comment, if you act smart, you can get the machine back even without a spare PC. If you care just about data, I wouldn't bother—recovering it with a spare PC is much easier.

7
  • VirtualBox supports disk snapshots. Apr 2, 2015 at 18:47
  • 1
    Note that viruses are often designed to detect VMs, so I would not advise this virus detection process. A small question: those remaining four directories aren't "real" directories, right? They're not actually on the hard drive? What remains on the hard drive after running this command? Apr 2, 2015 at 23:32
  • 2
    @raptortech97 rm doesn't really erase stuff from the hard drive, it just "unlinks" (disassociates) the actual data on the disk from the filesystem tree, marking it free (so that it might get overwritten eventually through normal computer usage). So if you, say, rm -rf ~, not all is lost, as long as you act quickly (e.g. with extundelete). You can think of it as an even more unreliable version of the "deleted" folder in your mailbox, you can get stuff back if you don't wait too long, but eventually it will be purged.
    – Thomas
    Apr 3, 2015 at 7:05
  • @raptortech97 On the other hand, if for some reason you didn't use rm but shred, it's pretty much game over, though you'll probably have time to realize your mistake and abort since shredding takes longer.
    – Thomas
    Apr 3, 2015 at 7:07
  • 5
    The directories which are being kept are most likely mount points of some form or other. And the commands which continue to work are bash builtin commands, not separate binaries. So while ls is gone, for i in /*; do echo $i; done should work. And to replace cat you might use a command like while read i; do echo $i; done < /proc/self/maps.
    – MvG
    Apr 3, 2015 at 8:28
27

The reason is that the file naming layer (what you see with ls) is really just for your convenience. The file system driver and kernel care only what the inode is. When a file is referenced by name, it is immediately translated into the inode which contains all of the metadata including the permissions, the data blocks on the disk, the owner ID, the group ID and the link count.

The link count is what really matters here. When you delete a file on a UNIX system, the actual system call is an unlink. What's happening under the hood is that the link count (the number of file names in the file naming layer) pointing at that inode is decremented. The file system knows that a file is deleted when the link count reaches zero.

When a file is deleted by rm it will also edit the directory file (yes, it's just a file that contains the file name and the inode in addition to a few other bits that are not important for this answer). However, it is the unlinking that actually frees the disk resources.

This leads to some other interesting effects. First, it is possible to have a file open whose link count is zero. This happens when rm -rf / deletes the entry for /bin/rm. The file is open (there is a file handle to it) but the inode is marked deleted (link count = 0). The disk resources will not be released and reused until the file handle closes.

Another interesting effect is what happens when you have an inode with a link count greater than zero but nothing in the file naming layer that points to it. This is, in a sense, a very well hidden file :). To get access to it you would have to use something low level to reference it by inode number rather than by name (because there isn't one) or edit a directory entry to point at the inode using a hex editor.

A third interesting effect is what happens if you reduce the link count to zero but point a directory entry at the inode anyway. I'll leave that to you to experiment with if you'd like. Clearly, though, these last two both lead to the file system being in an inconsistent state.

4
  • Looking another way, the link count isn't zero, because opening a file adds a link within /proc.
    – OrangeDog
    Apr 3, 2015 at 9:10
  • @OrangeDog, this behavior still exists even if procfs is unmounted. Apr 3, 2015 at 18:28
  • 2
    @OrangeDog Charles Duffy is correct. The file handles in /proc do not modify the inodes, adjusting the link count. Apr 3, 2015 at 19:40
  • /proc and /sys are reflections of the current system (kernel) state. Only select actions to files and directories in there actually change the system state.
    – user
    Apr 7, 2015 at 7:22
19

Previous answers are good, but I want to clarify one detail:

rm isn't just a command. It is a program that is found in PATH.

Therefore what happens when you execute is following:

  • you call (as root) rm -rf /
  • instance of program rm is loaded in memory with arguments -rf and /
  • based on these arguments program rm starts its operations (going through everything in mounted / partition and recursively removing references to it [sorry for technicality ;)])
  • once it is finished, the instance of rm program is unloaded
  • at this point the only things in memory are the programs that were loaded there previously (e.g. bash if you have terminal open in Ubuntu, Desktop environment, kernel, drivers etc)
  • if you try to call any another command (which in case of Linux makes it a standalone program), it will fail because there is no such program found in PATH locations (and PATH locations do not exist anymore). However everything once loaded will still run

Just for the sake of understanding how it works try installing LAMP on ubuntu (in Virtualbox), some script and PHP opcode cache, then call this evil command. Surprisingly (if you are lucky enough and your opcode cache won't notice php file deletion) you still can access php scripts from outside via apache webserver!

PS: this evil command even ran as root wont delete everything, it cannot delete some kernel privileged processes from /proc and cannot delete some of stuff from /dev devices which appear on your system as as files. In fact, root is not as almighty as we think, kernel on the other hand is.

PPS: Also as a second thought you also will still have files that were locked by another process at the time of deletion attempt.

5
  • On Linux you certainly can remove device nodes when running as root. But yes, you can't delete anything from /proc as it's a read-only file system. Likewise for /sys. I believe you also can't delete mount points.
    – Brian
    Apr 2, 2015 at 21:47
  • @AlexKey I suggest editing to clarify what you mean by "non-kernel embedded command" (or to avoid that phrase altogether). It sounds like you're saying there are commands you can run through a shell that are implemented directly in the kernel so they always work no matter what. (Which is, as you likely know but many readers may not, not the case: when you run a command like cd, this calls the shell builtin by that name--that command is built into the shell, not the kernel.) Do you mean Alt+SysRq "commands"? Apr 3, 2015 at 0:12
  • @Brian does it depend on distro? I worked in variety of distros and as funny it sounds made this mistake multiple times. As I recalled after inspecting remains of / there still was something in /dev, but it could be things like cdrom or floppy... Apr 3, 2015 at 9:46
  • @EliahKagan As I tried to stay distro independent, so I used this term. It means that not on all systems cli command means external program. But thanks, for pointing that out, I will clarify the point. Apr 3, 2015 at 9:49
  • @AlexKey I believe you wouldn't be able to remove /dev/pts since it is a mount point. (And a read-only file system, too.)
    – Brian
    Apr 3, 2015 at 9:54
1

Once everything is wiped from the harddrives the kernel is still working but sort of stuck as there are no devices and programs, commands, etc. left.

The OS won't work anymore.

And it's true what Oli says, the command gets loaded/executed into memory and nothing will stop it unless you kill this process (of course, if the kill command is still present ^^).

3
  • 4
    Why would the kernel get stuck? The answer by MainMa suggests otherwise, and supports what I'd have expected.
    – MvG
    Apr 3, 2015 at 8:19
  • 4
    Programs run from memory, not the hard drive. The kernel wouldn't know anything is wrong until a reboot.
    – phyrfox
    Apr 5, 2015 at 12:16
  • Well maybe I need to change the words I used, the kernel is more or less "stuck" without devices, programs, etc. and if you are not in front of the root console you can't do bad stuff, heck even on that console you can't do bad stuff. But I will change my wording in my answer as it is misleading, I agree.
    – s1mmel
    Apr 9, 2015 at 7:09
0

Please be aware that if the system has selinux and selinux is in enforcing mode, and selinux's policies are set up properly; then nothing much will happen.

Selinux is mandatory access control, which means, among many thing, that the root user really has not much more power to destroy the system than any other user on the system.

Selinux is enforced in the kernel; you would have to compromise the kernel in order to get around it.

On a well designed system with good Selinux policies, root would not be able to do much on the system.

The later revisions of Android have Selinux enforcing just for this reason.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .