Protection from the dreaded "rm -fr /"

Giorgos Keramidas keramida at FreeBSD.org
Sat Oct 2 01:19:37 PDT 2004


John Beck, who works for Sun, has posted an entry in his blog yesterday
about "rm -fr /" protection, which I liked a lot:
http://blogs.sun.com/roller/page/jbeck/20041001#rm_rf_protection

His idea was remarkably simple, so I went ahead and wrote this patch for
rm(1) of FreeBSD:

%%%
Index: rm.c
===================================================================
RCS file: /home/ncvs/src/bin/rm/rm.c,v
retrieving revision 1.47
diff -u -r1.47 rm.c
--- rm.c	6 Apr 2004 20:06:50 -0000	1.47
+++ rm.c	2 Oct 2004 08:06:21 -0000
@@ -157,6 +157,7 @@
 void
 rm_tree(char **argv)
 {
+	char **argv_tmp;
 	FTS *fts;
 	FTSENT *p;
 	int needstat;
@@ -164,6 +165,17 @@
 	int rval;
 
 	/*
+	 * If one of the members of argv[] is the root directory abort the
+	 * entire operation.
+	 */
+	argv_tmp = argv;
+	while (*argv_tmp != NULL) {
+		if (strcmp(*argv_tmp, "/") == 0)
+			errx(1, "rm of / is not allowed");
+		argv_tmp++;
+	}
+
+	/*
 	 * Remove a file hierarchy.  If forcing removal (-f), or interactive
 	 * (-i) or can't ask anyway (stdin_ok), don't stat the file.
 	 */
%%%

To test it, I used a minimal chroot with /bin, /lib and /libexec copied
over from my real / partition:

    # mkdir -p /tmp/chroot/bin ; cp -Rp /lib /libexec /tmp/chroot
    # cp /bin/sh /bin/ls /tmp/chroot/bin
    # cp /a/freebsd/src/bin/rm/rm /tmp/chroot/bin
    # env PS1='chroot# ' chroot /tmp/chroot /bin/sh
    chroot# rm -fr /
    rm: recursive rm of / is not allowed
    chroot# exit
    #

It seems to work nicely here.  I'm not sure if the overhead of
traversing argv[] twice is a bug price to pay for the protection this
adds, but if a lot of people like it I'll commit it when I get the
approval of src-committers :-)

- Giorgos



More information about the freebsd-hackers mailing list