Date: Wed, 27 Jun 2012 00:37:22 +0000 (UTC) From: Xin LI <delphij@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org Subject: svn commit: r237617 - stable/7/bin/rm Message-ID: <201206270037.q5R0bMCm071413@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: delphij Date: Wed Jun 27 00:37:22 2012 New Revision: 237617 URL: http://svn.freebsd.org/changeset/base/237617 Log: MFC r237339: Polish previous revision: if the fts_* routines have lstat()'ed the directory entry then use the struct stat from that instead of doing it again, and skip the rm_overwrite() call if fts_read() indicated that the entry couldn't be a regular file. Obtained from: OpenBSD MFC r237284 (kevlo): Fix potential symlink race condition in "rm -P" by adding a check that the file we have opened is the one we expected. Also open in non-blocking mode to avoid a potential hang with FIFOs. Obtained from: NetBSD via OpenBSD Modified: stable/7/bin/rm/rm.c Directory Properties: stable/7/bin/rm/ (props changed) Modified: stable/7/bin/rm/rm.c ============================================================================== --- stable/7/bin/rm/rm.c Wed Jun 27 00:34:06 2012 (r237616) +++ stable/7/bin/rm/rm.c Wed Jun 27 00:37:22 2012 (r237617) @@ -288,10 +288,16 @@ rm_tree(char **argv) if (fflag) continue; /* FALLTHROUGH */ - default: + + case FTS_F: + case FTS_NSOK: if (Pflag) - if (!rm_overwrite(p->fts_accpath, NULL)) + 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)) { if (rval == 0 && vflag) @@ -386,7 +392,7 @@ rm_file(char **argv) int rm_overwrite(char *file, struct stat *sbp) { - struct stat sb; + struct stat sb, sb2; struct statfs fsb; off_t len; int bsize, fd, wlen; @@ -405,8 +411,15 @@ rm_overwrite(char *file, struct stat *sb file, sbp->st_ino); return (0); } - if ((fd = open(file, O_WRONLY, 0)) == -1) + 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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201206270037.q5R0bMCm071413>