Don't allow "rm -rf /"
authordaniel <daniel@openbsd.org>
Sun, 11 Oct 2015 03:08:46 +0000 (03:08 +0000)
committerdaniel <daniel@openbsd.org>
Sun, 11 Oct 2015 03:08:46 +0000 (03:08 +0000)
Patch from Theo Buehler who was inspired by watching Bryan Cantrill
in BSD Now 103.

Minor tweak from me to turn the complained variables into flags instead
of counters.

"i think it's ok" tedu@
"this isn't 1980 anymore" deraadt@
ok millert@

bin/rm/rm.1
bin/rm/rm.c

index f69a597..a6a56c8 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: rm.1,v 1.37 2014/05/25 19:07:36 jmc Exp $
+.\"    $OpenBSD: rm.1,v 1.38 2015/10/11 03:08:46 daniel Exp $
 .\"    $NetBSD: rm.1,v 1.8 1995/07/25 19:37:30 jtc Exp $
 .\"
 .\" Copyright (c) 1990, 1993, 1994
@@ -33,7 +33,7 @@
 .\"
 .\"    @(#)rm.1        8.5 (Berkeley) 12/5/94
 .\"
-.Dd $Mdocdate: May 25 2014 $
+.Dd $Mdocdate: October 11 2015 $
 .Dt RM 1
 .Os
 .Sh NAME
@@ -102,6 +102,7 @@ The
 utility removes symbolic links, not the files referenced by the links.
 .Pp
 It is an error to attempt to remove the files
+.Dq / ,
 .Dq \&.
 or
 .Dq .. .
index 49ed97e..e5e339e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rm.c,v 1.32 2015/10/09 01:37:06 deraadt Exp $ */
+/*     $OpenBSD: rm.c,v 1.33 2015/10/11 03:08:46 daniel Exp $  */
 /*     $NetBSD: rm.c,v 1.19 1995/09/07 06:48:50 jtc Exp $      */
 
 /*-
@@ -54,7 +54,7 @@ extern char *__progname;
 int dflag, eval, fflag, iflag, Pflag, stdin_ok;
 
 int    check(char *, char *, struct stat *);
-void   checkdot(char **);
+void   checkdotorslash(char **);
 void   rm_file(char **);
 int    rm_overwrite(char *, struct stat *);
 int    pass(int, off_t, char *, size_t);
@@ -113,7 +113,7 @@ main(int argc, char *argv[])
        if (argc < 1 && fflag == 0)
                usage();
 
-       checkdot(argv);
+       checkdotorslash(argv);
 
        if (*argv) {
                stdin_ok = isatty(STDIN_FILENO);
@@ -391,12 +391,12 @@ check(char *path, char *name, struct stat *sp)
  */
 #define ISDOT(a)       ((a)[0] == '.' && (!(a)[1] || ((a)[1] == '.' && !(a)[2])))
 void
-checkdot(char **argv)
+checkdotorslash(char **argv)
 {
        char *p, **save, **t;
-       int complained;
+       int dotcomplained, slashcomplained;
 
-       complained = 0;
+       dotcomplained = slashcomplained = 0;
        for (t = argv; *t;) {
                /* strip trailing slashes */
                p = strrchr (*t, '\0');
@@ -410,14 +410,24 @@ checkdot(char **argv)
                        p = *t;
 
                if (ISDOT(p)) {
-                       if (!complained++)
+                       if (!dotcomplained) {
+                               dotcomplained = 1;
                                warnx("\".\" and \"..\" may not be removed");
-                       eval = 1;
-                       for (save = t; (t[0] = t[1]) != NULL; ++t)
-                               continue;
-                       t = save;
-               } else
+                       }
+               } else if (*p == '\0') {
+                       if (!slashcomplained) {
+                               slashcomplained = 1;
+                               warnx("\"/\" may not be removed");
+                       }
+               } else {
                        ++t;
+                       continue;
+               }
+
+               eval = 1;
+               for (save = t; (t[0] = t[1]) != NULL; ++t)
+                       continue;
+               t = save;
        }
 }