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.
This commit is contained in:
Ed Schouten 2010-03-21 20:43:23 +00:00
parent e67afc40da
commit 0fef797f4a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=205423
4 changed files with 22 additions and 6 deletions

View File

@ -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 ,

View File

@ -128,6 +128,8 @@ linux_common_open(struct thread *td, int dirfd, char *path, int l_flags, int mod
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 dirfd, char *path, int l_flags, int mod
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.

View File

@ -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) {

View File

@ -200,6 +200,10 @@ vn_open_cred(struct nameidata *ndp, int *flagp, int cmode, u_int vn_open_flags,
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) {