summaryrefslogtreecommitdiffstats
path: root/bin/rm
diff options
context:
space:
mode:
authorkevlo <kevlo@FreeBSD.org>2012-06-20 02:21:53 +0000
committerkevlo <kevlo@FreeBSD.org>2012-06-20 02:21:53 +0000
commit592e847dfeee3afbd0174cd2a749345b1d68a951 (patch)
tree6bbf4ac92d1bfee774d598f2e638ffb95b10493e /bin/rm
parent5c7e44656e584946db7a32059adb6ebc4ef211e2 (diff)
downloadFreeBSD-src-592e847dfeee3afbd0174cd2a749345b1d68a951.zip
FreeBSD-src-592e847dfeee3afbd0174cd2a749345b1d68a951.tar.gz
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
Diffstat (limited to 'bin/rm')
-rw-r--r--bin/rm/rm.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/bin/rm/rm.c b/bin/rm/rm.c
index 3c2ba61..1f81885 100644
--- a/bin/rm/rm.c
+++ b/bin/rm/rm.c
@@ -408,7 +408,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;
@@ -427,8 +427,15 @@ rm_overwrite(char *file, struct stat *sbp)
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);
OpenPOWER on IntegriCloud