From 9e5c57050e599664a9e15aa2e9f6e98ba04541e7 Mon Sep 17 00:00:00 2001 From: daniel Date: Sun, 11 Oct 2015 03:08:46 +0000 Subject: [PATCH] Don't allow "rm -rf /" 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 | 5 +++-- bin/rm/rm.c | 34 ++++++++++++++++++++++------------ 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/bin/rm/rm.1 b/bin/rm/rm.1 index f69a597ca56..a6a56c825bc 100644 --- a/bin/rm/rm.1 +++ b/bin/rm/rm.1 @@ -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 .. . diff --git a/bin/rm/rm.c b/bin/rm/rm.c index 49ed97e2345..e5e339e9dab 100644 --- a/bin/rm/rm.c +++ b/bin/rm/rm.c @@ -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; } } -- 2.20.1