svn commit: r205423 - in head: lib/libc/sys sys/compat/linux sys/kern

Ed Schouten ed at FreeBSD.org
Sun Mar 21 20:43:24 UTC 2010


Author: ed
Date: Sun Mar 21 20:43:23 2010
New Revision: 205423
URL: http://svn.freebsd.org/changeset/base/205423

Log:
  Actually make O_DIRECTORY work.
  
  According to POSIX open() must return ENOTDIR when the path name does
  not refer to a path name. Change vn_open() to respect this flag. This
  also simplifies the Linuxolator a bit.

Modified:
  head/lib/libc/sys/open.2
  head/sys/compat/linux/linux_file.c
  head/sys/kern/vfs_syscalls.c
  head/sys/kern/vfs_vnops.c

Modified: head/lib/libc/sys/open.2
==============================================================================
--- head/lib/libc/sys/open.2	Sun Mar 21 18:18:58 2010	(r205422)
+++ head/lib/libc/sys/open.2	Sun Mar 21 20:43:23 2010	(r205423)
@@ -117,6 +117,7 @@ O_SYNC		synchronous writes
 O_NOFOLLOW	do not follow symlinks
 O_NOCTTY	don't assign controlling terminal
 O_TTY_INIT	restore default terminal attributes
+O_DIRECTORY	error if file is not a directory
 .Ed
 .Pp
 Opening a file with
@@ -222,6 +223,14 @@ The initial call to
 on a TTY will always restore default terminal attributes on
 .Fx .
 .Pp
+.Dv O_DIRECTORY
+may be used to ensure the resulting file descriptor refers to a
+directory.
+This flag can be used to prevent applications with elevated privileges
+from opening files which are even unsafe to open with
+.Dv O_RDONLY ,
+such as device nodes.
+.Pp
 If successful,
 .Fn open
 returns a non-negative integer, termed a file descriptor.
@@ -413,6 +422,9 @@ argument is not an absolute path and
 is neither
 .Dv AT_FDCWD
 nor a file descriptor associated with a directory.
+.It Bq Eq ENOTDIR
+.Dv O_DIRECTORY
+is specified and the file is not a directory.
 .El
 .Sh SEE ALSO
 .Xr chmod 2 ,

Modified: head/sys/compat/linux/linux_file.c
==============================================================================
--- head/sys/compat/linux/linux_file.c	Sun Mar 21 18:18:58 2010	(r205422)
+++ head/sys/compat/linux/linux_file.c	Sun Mar 21 20:43:23 2010	(r205423)
@@ -128,6 +128,8 @@ linux_common_open(struct thread *td, int
 	bsd_flags |= O_DIRECT;
     if (l_flags & LINUX_O_NOFOLLOW)
 	bsd_flags |= O_NOFOLLOW;
+    if (l_flags & LINUX_O_DIRECTORY)
+	bsd_flags |= O_DIRECTORY;
     /* XXX LINUX_O_NOATIME: unable to be easily implemented. */
 
     error = kern_openat(td, dirfd, path, UIO_SYSSPACE, bsd_flags, mode);
@@ -154,12 +156,6 @@ linux_common_open(struct thread *td, int
 			    PROC_UNLOCK(p);
 			    sx_sunlock(&proctree_lock);
 		    }
-		    if (l_flags & LINUX_O_DIRECTORY) {
-			    if (fp->f_type != DTYPE_VNODE ||
-				fp->f_vnode->v_type != VDIR) {
-				    error = ENOTDIR;
-			    }
-		    }
 		    fdrop(fp, td);
 		    /*
 		     * XXX as above, fdrop()/kern_close() pair is racy.

Modified: head/sys/kern/vfs_syscalls.c
==============================================================================
--- head/sys/kern/vfs_syscalls.c	Sun Mar 21 18:18:58 2010	(r205422)
+++ head/sys/kern/vfs_syscalls.c	Sun Mar 21 20:43:23 2010	(r205423)
@@ -4428,6 +4428,10 @@ fhopen(td, uap)
 		error = EOPNOTSUPP;
 		goto bad;
 	}
+	if (vp->v_type != VDIR && fmode & O_DIRECTORY) {
+		error = ENOTDIR;
+		goto bad;
+	}
 	accmode = 0;
 	if (fmode & (FWRITE | O_TRUNC)) {
 		if (vp->v_type == VDIR) {

Modified: head/sys/kern/vfs_vnops.c
==============================================================================
--- head/sys/kern/vfs_vnops.c	Sun Mar 21 18:18:58 2010	(r205422)
+++ head/sys/kern/vfs_vnops.c	Sun Mar 21 20:43:23 2010	(r205423)
@@ -200,6 +200,10 @@ restart:
 		error = EOPNOTSUPP;
 		goto bad;
 	}
+	if (vp->v_type != VDIR && fmode & O_DIRECTORY) {
+		error = ENOTDIR;
+		goto bad;
+	}
 	accmode = 0;
 	if (fmode & (FWRITE | O_TRUNC)) {
 		if (vp->v_type == VDIR) {


More information about the svn-src-head mailing list