summaryrefslogtreecommitdiff
path: root/bin/rm
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2012-06-18 00:33:48 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2012-06-18 00:33:48 +0000
commita7e024bf8cce2ccb754d7ecef9c9bebf4a8e7c5b (patch)
tree3c767f3c9ce5e9646cec713670d6cfe55d664b20 /bin/rm
parente3572ee10b9c76e407a985734e97e791fce50ba5 (diff)
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. Reported by Radoslaw A. Zarzynski. Fix adapted from NetBSD. OK guenther@
Diffstat (limited to 'bin/rm')
-rw-r--r--bin/rm/rm.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/bin/rm/rm.c b/bin/rm/rm.c
index 10a6404fb1e..5d6b46622a1 100644
--- a/bin/rm/rm.c
+++ b/bin/rm/rm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rm.c,v 1.23 2009/10/27 23:59:22 deraadt Exp $ */
+/* $OpenBSD: rm.c,v 1.24 2012/06/18 00:33:47 millert Exp $ */
/* $NetBSD: rm.c,v 1.19 1995/09/07 06:48:50 jtc Exp $ */
/*-
@@ -270,7 +270,7 @@ rm_file(char **argv)
int
rm_overwrite(char *file, struct stat *sbp)
{
- struct stat sb;
+ struct stat sb, sb2;
struct statfs fsb;
size_t bsize;
int fd;
@@ -289,8 +289,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, 1024U);