Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 2 Oct 2004 12:06:35 +0300
From:      Giorgos Keramidas <keramida@freebsd.org>
To:        Michael Reifenberger <mike@reifenberger.com>
Cc:        freebsd-hackers@freebsd.org
Subject:   Re: Protection from the dreaded "rm -fr /"
Message-ID:  <20041002090635.GA71050@gothmog.gr>
In-Reply-To: <20041002085143.GA52519@gothmog.gr>
References:  <20041002081928.GA21439@gothmog.gr> <20041002102918.W22102@fw.reifenberger.com> <20041002085143.GA52519@gothmog.gr>

next in thread | previous in thread | raw e-mail | index | archive | help
On 2004-10-02 11:51, Giorgos Keramidas <keramida@freebsd.org> wrote:
> On 2004-10-02 10:34, Michael Reifenberger <mike@reifenberger.com> wrote:
> >
> > This does only help for the obvious case of '/' but not for the
> > './' and '../' or '../../' ... accidents.
>
> Hmm, indeed.  This can be fixed, but it might take a little thinking
> over about ways to implement it without adding too much overhead to the
> way rm(1) works now.

One way to do that is to use realpath(3), but I have to ask more
knowledgeable people about the comment immediately below my change:

%%%
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 09:00:41 -0000
@@ -157,6 +157,8 @@
 void
 rm_tree(char **argv)
 {
+	char *rpath;
+	char **argv_tmp;
 	FTS *fts;
 	FTSENT *p;
 	int needstat;
@@ -164,6 +166,20 @@
 	int rval;
 
 	/*
+	 * If one of the members of argv[] is the root directory abort the
+	 * entire operation.
+	 */
+	rpath = malloc(PATH_MAX * sizeof(char));
+	if (rpath == NULL)
+		err(1, "malloc");
+	for (argv_tmp = argv; *argv_tmp != NULL; argv_tmp++) {
+		if (realpath(*argv_tmp, rpath) == NULL)
+			err(1, "%s", *argv_tmp);
+		if (strcmp(rpath, "/") == 0)
+			errx(1, "recursive rm of / is not allowed");
+	}
+
+	/*
 	 * Remove a file hierarchy.  If forcing removal (-f), or interactive
 	 * (-i) or can't ask anyway (stdin_ok), don't stat the file.
 	 */
%%%

I'm a bit worried about the "don't stat the file" comment below.  The
realpath(3) library function *does* stat the file when trying to find
its real pathname ;-/



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20041002090635.GA71050>