Index: head/bin/rm/rm.1 =================================================================== --- head/bin/rm/rm.1 +++ head/bin/rm/rm.1 @@ -32,7 +32,7 @@ .\" @(#)rm.1 8.5 (Berkeley) 12/5/94 .\" $FreeBSD$ .\" -.Dd September 12, 2018 +.Dd November 10, 2018 .Dt RM 1 .Os .Sh NAME @@ -42,7 +42,7 @@ .Sh SYNOPSIS .Nm .Op Fl f | i -.Op Fl dIPRrvWx +.Op Fl dIRrvWx .Ar .Nm unlink .Op Fl - @@ -86,26 +86,9 @@ .Fl i yet provides almost the same level of protection against mistakes. .It Fl P -Overwrite regular files before deleting them. -Files are overwritten three times, first with the byte pattern 0xff, -then 0x00, and then 0xff again, before they are deleted. -Files with multiple links will not be overwritten nor deleted -and a warning will be issued. -If the -.Fl f -option is specified, files with multiple links will also be overwritten -and deleted. -No warning will be issued. -.Pp -Specifying this flag for a read only file will cause -.Nm -to generate an error message and exit. -The file will not be removed or overwritten. -.Pp -N.B.: The -.Fl P -flag is not considered a security feature -.Pq see Sx BUGS . +This flag has no effect. +It is kept only for backwards compatibility with +.Bx 4.4 Lite2 . .It Fl R Attempt to remove the file hierarchy rooted in each .Ar file @@ -192,12 +175,6 @@ .Pp .Dl "rm /home/user/-filename" .Dl "rm ./-filename" -.Pp -When -.Fl P -is specified with -.Fl f -the file will be overwritten and removed even if it has hard links. .Sh EXAMPLES Recursively remove all files contained within the .Pa foobar @@ -227,6 +204,12 @@ .Bx implementations prompted on the standard output, not the standard error output. +.Pp +The +.Fl P +option does not have any effect as of +.Fx 13 +and may be removed in the future. .Sh SEE ALSO .Xr chflags 1 , .Xr rmdir 1 , @@ -250,15 +233,3 @@ .Nm command appeared in .At v1 . -.Sh BUGS -The -.Fl P -option assumes that the underlying storage overwrites file blocks -when data is written to an existing offset. -Several factors including the file system and its backing store could defeat -this assumption. -This includes, but is not limited to file systems that use a -Copy-On-Write strategy (e.g. ZFS or UFS when snapshots are being used), Flash -media that are using a wear leveling algorithm, or when the backing datastore -does journaling, etc. -In addition, only regular files are overwritten, other types of files are not. Index: head/bin/rm/rm.c =================================================================== --- head/bin/rm/rm.c +++ head/bin/rm/rm.c @@ -61,7 +61,7 @@ #include #include -static int dflag, eval, fflag, iflag, Pflag, vflag, Wflag, stdin_ok; +static int dflag, eval, fflag, iflag, vflag, Wflag, stdin_ok; static int rflag, Iflag, xflag; static uid_t uid; static volatile sig_atomic_t info; @@ -71,7 +71,6 @@ static void checkdot(char **); static void checkslash(char **); static void rm_file(char **); -static int rm_overwrite(const char *, struct stat *); static void rm_tree(char **); static void siginfo(int __unused); static void usage(void); @@ -110,7 +109,7 @@ exit(eval); } - Pflag = rflag = xflag = 0; + rflag = xflag = 0; while ((ch = getopt(argc, argv, "dfiIPRrvWx")) != -1) switch(ch) { case 'd': @@ -128,7 +127,7 @@ Iflag = 1; break; case 'P': - Pflag = 1; + /* Compatibility no-op. */ break; case 'R': case 'r': /* Compatibility. */ @@ -313,12 +312,6 @@ case FTS_F: case FTS_NSOK: - if (Pflag) - if (!rm_overwrite(p->fts_accpath, p->fts_info == - FTS_NSOK ? NULL : p->fts_statp)) - continue; - /* FALLTHROUGH */ - default: rval = unlink(p->fts_accpath); if (rval == 0 || (fflag && errno == ENOENT)) { @@ -389,12 +382,8 @@ rval = undelete(f); else if (S_ISDIR(sb.st_mode)) rval = rmdir(f); - else { - if (Pflag) - if (!rm_overwrite(f, &sb)) - continue; + else rval = unlink(f); - } } if (rval && (!fflag || errno != ENOENT)) { warn("%s", f); @@ -409,85 +398,7 @@ } } -/* - * rm_overwrite -- - * Overwrite the file 3 times with varying bit patterns. - * - * XXX - * This is a cheap way to *really* delete files. Note that only regular - * files are deleted, directories (and therefore names) will remain. - * Also, this assumes a fixed-block file system (like FFS, or a V7 or a - * System V file system). In a logging or COW file system, you'll have to - * have kernel support. - */ static int -rm_overwrite(const char *file, struct stat *sbp) -{ - struct stat sb, sb2; - struct statfs fsb; - off_t len; - int bsize, fd, wlen; - char *buf = NULL; - - fd = -1; - if (sbp == NULL) { - if (lstat(file, &sb)) - goto err; - sbp = &sb; - } - if (!S_ISREG(sbp->st_mode)) - return (1); - if (sbp->st_nlink > 1 && !fflag) { - warnx("%s (inode %ju): not overwritten due to multiple links", - file, (uintmax_t)sbp->st_ino); - return (0); - } - if ((fd = open(file, O_WRONLY|O_NONBLOCK|O_NOFOLLOW, 0)) == -1) - goto err; - if (fstat(fd, &sb2)) - goto err; - if (sb2.st_dev != sbp->st_dev || sb2.st_ino != sbp->st_ino || - !S_ISREG(sb2.st_mode)) { - errno = EPERM; - goto err; - } - if (fstatfs(fd, &fsb) == -1) - goto err; - bsize = MAX(fsb.f_iosize, 1024); - if ((buf = malloc(bsize)) == NULL) - err(1, "%s: malloc", file); - -#define PASS(byte) { \ - memset(buf, byte, bsize); \ - for (len = sbp->st_size; len > 0; len -= wlen) { \ - wlen = len < bsize ? len : bsize; \ - if (write(fd, buf, wlen) != wlen) \ - goto err; \ - } \ -} - PASS(0xff); - if (fsync(fd) || lseek(fd, (off_t)0, SEEK_SET)) - goto err; - PASS(0x00); - if (fsync(fd) || lseek(fd, (off_t)0, SEEK_SET)) - goto err; - PASS(0xff); - if (!fsync(fd) && !close(fd)) { - free(buf); - return (1); - } - -err: eval = 1; - if (buf) - free(buf); - if (fd != -1) - close(fd); - warn("%s", file); - return (0); -} - - -static int check(const char *path, const char *name, struct stat *sp) { int ch, first; @@ -511,10 +422,6 @@ strmode(sp->st_mode, modep); if ((flagsp = fflagstostr(sp->st_flags)) == NULL) err(1, "fflagstostr"); - if (Pflag) - errx(1, - "%s: -P was specified, but file is not writable", - path); (void)fprintf(stderr, "override %s%s%s/%s %s%sfor %s? ", modep + 1, modep[10] == ' ' ? "" : " ", user_from_uid(sp->st_uid, 0),