Page MenuHomeFreeBSD

D25886.id77052.diff
No OneTemporary

D25886.id77052.diff

Index: lib/libc/sys/access.2
===================================================================
--- lib/libc/sys/access.2
+++ lib/libc/sys/access.2
@@ -127,6 +127,13 @@
flag in the
.Xr open 2
manual page.
+.It Dv AT_RELATIVE_BENEATH
+Only walks paths below the topping directory.
+See the description of the
+.Dv O_RELATIVE_BENEATH
+flag in the
+.Xr open 2
+manual page.
.El
.Pp
Even if a process's real or effective user has appropriate privileges
Index: lib/libc/sys/chflags.2
===================================================================
--- lib/libc/sys/chflags.2
+++ lib/libc/sys/chflags.2
@@ -102,6 +102,13 @@
flag in the
.Xr open 2
manual page.
+.It Dv AT_RELATIVE_BENEATH
+Only walks paths below the topping directory.
+See the description of the
+.Dv O_RELATIVE_BENEATH
+flag in the
+.Xr open 2
+manual page.
.El
.Pp
If
Index: lib/libc/sys/chmod.2
===================================================================
--- lib/libc/sys/chmod.2
+++ lib/libc/sys/chmod.2
@@ -109,6 +109,13 @@
flag in the
.Xr open 2
manual page.
+.It Dv AT_RELATIVE_BENEATH
+Only walks paths below the topping directory.
+See the description of the
+.Dv O_RELATIVE_BENEATH
+flag in the
+.Xr open 2
+manual page.
.El
.Pp
If
Index: lib/libc/sys/chown.2
===================================================================
--- lib/libc/sys/chown.2
+++ lib/libc/sys/chown.2
@@ -126,6 +126,13 @@
flag in the
.Xr open 2
manual page.
+.It Dv AT_RELATIVE_BENEATH
+Only walks paths below the topping directory.
+See the description of the
+.Dv O_RELATIVE_BENEATH
+flag in the
+.Xr open 2
+manual page.
.El
.Pp
If
Index: lib/libc/sys/fhlink.2
===================================================================
--- lib/libc/sys/fhlink.2
+++ lib/libc/sys/fhlink.2
@@ -113,6 +113,13 @@
flag in the
.Xr open 2
manual page.
+.It Dv AT_RELATIVE_BENEATH
+Only walks paths below the topping directory.
+See the description of the
+.Dv O_RELATIVE_BENEATH
+flag in the
+.Xr open 2
+manual page.
.El
.Pp
If
Index: lib/libc/sys/getfh.2
===================================================================
--- lib/libc/sys/getfh.2
+++ lib/libc/sys/getfh.2
@@ -112,6 +112,13 @@
flag in the
.Xr open 2
manual page.
+.It Dv AT_RELATIVE_BENEATH
+Only walks paths below the topping directory.
+See the description of the
+.Dv O_RELATIVE_BENEATH
+flag in the
+.Xr open 2
+manual page.
.El
.Pp
If
Index: lib/libc/sys/link.2
===================================================================
--- lib/libc/sys/link.2
+++ lib/libc/sys/link.2
@@ -122,6 +122,13 @@
flag in the
.Xr open 2
manual page.
+.It Dv AT_RELATIVE_BENEATH
+Only walks paths below the topping directory.
+See the description of the
+.Dv O_RELATIVE_BENEATH
+flag in the
+.Xr open 2
+manual page.
.El
.Pp
If
Index: lib/libc/sys/open.2
===================================================================
--- lib/libc/sys/open.2
+++ lib/libc/sys/open.2
@@ -117,6 +117,12 @@
a directory passed by the
.Fa fd
argument is used as the topping point for the resolution.
+When
+.Dv O_BENEATH
+is specified with a relative path, the
+.Fa fd
+argument is used both as the starting point, and as the topping point
+for the resolution.
See the definition of the
.Dv O_BENEATH
flag below.
@@ -183,7 +189,8 @@
O_DIRECTORY error if file is not a directory
O_CLOEXEC set FD_CLOEXEC upon open
O_VERIFY verify the contents of the file
-O_BENEATH require path to be strictly relative to topping directory
+O_BENEATH require resolved path to be strictly relative to topping directory
+O_RELATIVE_BENEATH require walked path to be strictly relative to topping directory
.Ed
.Pp
Opening a file with
@@ -311,8 +318,8 @@
.Dv O_BENEATH
returns
.Er ENOTCAPABLE
-if the specified relative path, after resolving all symlinks and ".."
-references, does not reside in the directory hierarchy of
+if the specified path, after resolving all symlinks and ".."
+references, does not end up with tail residing in the directory hierarchy of
children beneath the topping directory.
Topping directory is the process current directory if relative
.Fa path
@@ -322,11 +329,20 @@
.Fa fd
argument when using
.Fn openat .
-If the specified path is absolute,
.Dv O_BENEATH
allows arbitrary prefix that ends up at the topping directory,
after which all further resolved components must be under it.
.Pp
+.Dv O_RELATIVE_BENEATH
+returns
+.Er ENOTCAPABLE
+if any intermediate component of the specified relative path does not
+reside in the directory hierarchy beneath the topping directory.
+Comparing to
+.Dv O_BENEATH,
+absolute paths or even the temporal escape from beneath of the topping
+directory is not allowed.
+.Pp
When
.Fa fd
is opened with
@@ -540,6 +556,12 @@
.Dv O_EXEC
or
.Dv O_SEARCH .
+.It Bq Er EINVAL
+The
+.Dv O_RELATIVE_BENEATH
+flag is specified and
+.Dv path
+is absolute.
.It Bq Er EBADF
The
.Fa path
@@ -582,6 +604,12 @@
or the relative
.Fa path
escapes it.
+.It Bq Er ENOTCAPABLE
+The
+.Dv O_RELATIVE_BENEATH
+flag was provided, and the relative
+.Fa path
+escapes topping directory.
.El
.Sh SEE ALSO
.Xr chmod 2 ,
Index: lib/libc/sys/stat.2
===================================================================
--- lib/libc/sys/stat.2
+++ lib/libc/sys/stat.2
@@ -120,6 +120,13 @@
flag in the
.Xr open 2
manual page.
+.It Dv AT_RELATIVE_BENEATH
+Only walks paths below the topping directory.
+See the description of the
+.Dv O_RELATIVE_BENEATH
+flag in the
+.Xr open 2
+manual page.
.El
.Pp
If
Index: lib/libc/sys/unlink.2
===================================================================
--- lib/libc/sys/unlink.2
+++ lib/libc/sys/unlink.2
@@ -100,6 +100,13 @@
flag in the
.Xr open 2
manual page.
+.It Dv AT_RELATIVE_BENEATH
+Only walks paths below the topping directory.
+See the description of the
+.Dv O_RELATIVE_BENEATH
+flag in the
+.Xr open 2
+manual page.
.El
.Pp
If
Index: lib/libc/sys/utimensat.2
===================================================================
--- lib/libc/sys/utimensat.2
+++ lib/libc/sys/utimensat.2
@@ -154,6 +154,13 @@
flag in the
.Xr open 2
manual page.
+.It Dv AT_RELATIVE_BENEATH
+Only walks paths below the topping directory.
+See the description of the
+.Dv O_RELATIVE_BENEATH
+flag in the
+.Xr open 2
+manual page.
.El
.Sh RETURN VALUES
.Rv -std
Index: sys/kern/vfs_lookup.c
===================================================================
--- sys/kern/vfs_lookup.c
+++ sys/kern/vfs_lookup.c
@@ -178,11 +178,13 @@
nameicap_tracker_add(struct nameidata *ndp, struct vnode *dp)
{
struct nameicap_tracker *nt;
+ struct componentname *cnp;
if ((ndp->ni_lcf & NI_LCF_CAP_DOTDOT) == 0 || dp->v_type != VDIR)
return;
- if ((ndp->ni_lcf & (NI_LCF_BENEATH_ABS | NI_LCF_BENEATH_LATCHED)) ==
- NI_LCF_BENEATH_ABS) {
+ cnp = &ndp->ni_cnd;
+ if ((cnp->cn_flags & BENEATH) != 0 &&
+ (ndp->ni_lcf & NI_LCF_BENEATH_LATCHED) == 0) {
MPASS((ndp->ni_lcf & NI_LCF_LATCH) != 0);
if (dp != ndp->ni_beneath_latch)
return;
@@ -215,7 +217,11 @@
/*
* For dotdot lookups in capability mode, only allow the component
* lookup to succeed if the resulting directory was already traversed
- * during the operation. Also fail dotdot lookups for non-local
+ * during the operation. This catches situations where already
+ * traversed directory is moved to different parent, and then we walk
+ * over it with dotdots.
+ *
+ * Also allow to force failure of dotdot lookups for non-local
* filesystems, where external agents might assist local lookups to
* escape the compartment.
*/
@@ -234,14 +240,15 @@
return (ENOTCAPABLE);
TAILQ_FOREACH_REVERSE(nt, &ndp->ni_cap_tracker, nameicap_tracker_head,
nm_link) {
+ if ((ndp->ni_lcf & NI_LCF_LATCH) != 0 &&
+ ndp->ni_beneath_latch == nt->dp) {
+ ndp->ni_lcf &= ~NI_LCF_BENEATH_LATCHED;
+ nameicap_cleanup(ndp, false);
+ return (0);
+ }
if (dp == nt->dp)
return (0);
}
- if ((ndp->ni_lcf & NI_LCF_BENEATH_ABS) != 0) {
- ndp->ni_lcf &= ~NI_LCF_BENEATH_LATCHED;
- nameicap_cleanup(ndp, false);
- return (0);
- }
return (ENOTCAPABLE);
}
@@ -318,6 +325,7 @@
*/
if (IN_CAPABILITY_MODE(td) && (cnp->cn_flags & NOCAPCHECK) == 0) {
ndp->ni_lcf |= NI_LCF_STRICTRELATIVE;
+ ndp->ni_resflags |= NIRES_STRICTREL;
if (ndp->ni_dirfd == AT_FDCWD) {
#ifdef KTRACE
if (KTRPOINT(td, KTR_CAPFAIL))
@@ -396,6 +404,7 @@
ndp->ni_filecaps.fc_fcntls != CAP_FCNTL_ALL ||
ndp->ni_filecaps.fc_nioctls != -1) {
ndp->ni_lcf |= NI_LCF_STRICTRELATIVE;
+ ndp->ni_resflags |= NIRES_STRICTREL;
}
#endif
}
@@ -419,6 +428,16 @@
if (error == 0)
ndp->ni_lcf |= NI_LCF_LATCH;
}
+ if (error == 0 && (cnp->cn_flags & RBENEATH) != 0) {
+ if (cnp->cn_pnbuf[0] == '/' ||
+ (ndp->ni_lcf & NI_LCF_BENEATH_ABS) != 0) {
+ error = EINVAL;
+ } else if ((ndp->ni_lcf & NI_LCF_STRICTRELATIVE) == 0) {
+ ndp->ni_lcf |= NI_LCF_STRICTRELATIVE |
+ NI_LCF_CAP_DOTDOT;
+ }
+ }
+
/*
* If we are auditing the kernel pathname, save the user pathname.
*/
@@ -586,8 +605,8 @@
namei_cleanup_cnp(cnp);
} else
cnp->cn_flags |= HASBUF;
- if ((ndp->ni_lcf & (NI_LCF_BENEATH_ABS |
- NI_LCF_BENEATH_LATCHED)) == NI_LCF_BENEATH_ABS) {
+ if ((ndp->ni_lcf & (NI_LCF_LATCH |
+ NI_LCF_BENEATH_LATCHED)) == NI_LCF_LATCH) {
NDFREE(ndp, 0);
error = ENOTCAPABLE;
}
Index: sys/kern/vfs_syscalls.c
===================================================================
--- sys/kern/vfs_syscalls.c
+++ sys/kern/vfs_syscalls.c
@@ -112,6 +112,26 @@
static int kern_linkat_vp(struct thread *td, struct vnode *vp, int fd,
const char *path, enum uio_seg segflag);
+static uint64_t
+at2cnpflags(u_int at_flags, u_int mask)
+{
+ u_int64_t res;
+
+ res = 0;
+ at_flags &= mask;
+ if ((at_flags & AT_BENEATH) != 0)
+ res |= BENEATH;
+ if ((at_flags & AT_RESOLVE_BENEATH) != 0)
+ res |= RBENEATH;
+ /* FOLLOW is pseudo flag */
+ if ((at_flags & AT_SYMLINK_NOFOLLOW) != 0)
+ res |= NOFOLLOW;
+ if ((mask & AT_SYMLINK_FOLLOW) != 0 &&
+ (at_flags & AT_SYMLINK_FOLLOW) == 0)
+ res |= NOFOLLOW;
+ return (res);
+}
+
int
kern_sync(struct thread *td)
{
@@ -1136,7 +1156,7 @@
* understand exactly what would happen, and we don't think
* that it ever should.
*/
- if ((nd.ni_lcf & NI_LCF_STRICTRELATIVE) == 0 &&
+ if ((nd.ni_resflags & NIRES_STRICTREL) == 0 &&
(error == ENODEV || error == ENXIO) &&
td->td_dupfd >= 0) {
error = dupfdopen(td, fdp, td->td_dupfd, flags, error,
@@ -1183,7 +1203,7 @@
struct filecaps *fcaps;
#ifdef CAPABILITIES
- if ((nd.ni_lcf & NI_LCF_STRICTRELATIVE) != 0)
+ if ((nd.ni_resflags & NIRES_STRICTREL) != 0)
fcaps = &nd.ni_filecaps;
else
#endif
@@ -1484,12 +1504,13 @@
int flag;
flag = uap->flag;
- if ((flag & ~(AT_SYMLINK_FOLLOW | AT_BENEATH)) != 0)
+ if ((flag & ~(AT_SYMLINK_FOLLOW | AT_BENEATH |
+ AT_RESOLVE_BENEATH)) != 0)
return (EINVAL);
return (kern_linkat(td, uap->fd1, uap->fd2, uap->path1, uap->path2,
- UIO_USERSPACE, ((flag & AT_SYMLINK_FOLLOW) != 0 ? FOLLOW :
- NOFOLLOW) | ((flag & AT_BENEATH) != 0 ? BENEATH : 0)));
+ UIO_USERSPACE, at2cnpflags(flag, AT_SYMLINK_FOLLOW | AT_BENEATH |
+ AT_RESOLVE_BENEATH)));
}
int hardlink_check_uid = 0;
@@ -1854,7 +1875,7 @@
restart:
bwillwrite();
NDINIT_ATRIGHTS(&nd, DELETE, LOCKPARENT | LOCKLEAF | AUDITVNODE1 |
- ((flag & AT_BENEATH) != 0 ? BENEATH : 0),
+ at2cnpflags(flag, AT_BENEATH | AT_RESOLVE_BENEATH),
pathseg, path, dfd, &cap_unlinkat_rights, td);
if ((error = namei(&nd)) != 0) {
if (error == EINVAL)
@@ -2057,7 +2078,7 @@
struct nameidata nd;
int error;
- if ((flag & ~(AT_EACCESS | AT_BENEATH)) != 0)
+ if ((flag & ~(AT_EACCESS | AT_BENEATH | AT_RESOLVE_BENEATH)) != 0)
return (EINVAL);
if (amode != F_OK && (amode & ~(R_OK | W_OK | X_OK)) != 0)
return (EINVAL);
@@ -2078,7 +2099,7 @@
usecred = cred;
AUDIT_ARG_VALUE(amode);
NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF |
- AUDITVNODE1 | ((flag & AT_BENEATH) != 0 ? BENEATH : 0),
+ AUDITVNODE1 | at2cnpflags(flag, AT_BENEATH | AT_RESOLVE_BENEATH),
pathseg, path, fd, &cap_fstat_rights, td);
if ((error = namei(&nd)) != 0)
goto out;
@@ -2369,13 +2390,13 @@
struct nameidata nd;
int error;
- if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_BENEATH)) != 0)
+ if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_BENEATH |
+ AT_RESOLVE_BENEATH)) != 0)
return (EINVAL);
- NDINIT_ATRIGHTS(&nd, LOOKUP, ((flag & AT_SYMLINK_NOFOLLOW) != 0 ?
- NOFOLLOW : FOLLOW) | ((flag & AT_BENEATH) != 0 ? BENEATH : 0) |
- LOCKSHARED | LOCKLEAF | AUDITVNODE1, pathseg, path, fd,
- &cap_fstat_rights, td);
+ NDINIT_ATRIGHTS(&nd, LOOKUP, at2cnpflags(flag, AT_BENEATH |
+ AT_RESOLVE_BENEATH | AT_SYMLINK_NOFOLLOW) | LOCKSHARED | LOCKLEAF |
+ AUDITVNODE1, pathseg, path, fd, &cap_fstat_rights, td);
if ((error = namei(&nd)) != 0)
return (error);
@@ -2693,7 +2714,8 @@
sys_chflagsat(struct thread *td, struct chflagsat_args *uap)
{
- if ((uap->atflag & ~(AT_SYMLINK_NOFOLLOW | AT_BENEATH)) != 0)
+ if ((uap->atflag & ~(AT_SYMLINK_NOFOLLOW | AT_BENEATH |
+ AT_RESOLVE_BENEATH)) != 0)
return (EINVAL);
return (kern_chflagsat(td, uap->fd, uap->path, UIO_USERSPACE,
@@ -2722,12 +2744,11 @@
enum uio_seg pathseg, u_long flags, int atflag)
{
struct nameidata nd;
- int error, follow;
+ int error;
AUDIT_ARG_FFLAGS(flags);
- follow = (atflag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW;
- follow |= (atflag & AT_BENEATH) != 0 ? BENEATH : 0;
- NDINIT_ATRIGHTS(&nd, LOOKUP, follow | AUDITVNODE1, pathseg, path, fd,
+ NDINIT_ATRIGHTS(&nd, LOOKUP, at2cnpflags(atflag, AT_SYMLINK_NOFOLLOW |
+ AT_BENEATH | AT_RESOLVE_BENEATH) | AUDITVNODE1, pathseg, path, fd,
&cap_fchflags_rights, td);
if ((error = namei(&nd)) != 0)
return (error);
@@ -2822,7 +2843,8 @@
sys_fchmodat(struct thread *td, struct fchmodat_args *uap)
{
- if ((uap->flag & ~(AT_SYMLINK_NOFOLLOW | AT_BENEATH)) != 0)
+ if ((uap->flag & ~(AT_SYMLINK_NOFOLLOW | AT_BENEATH |
+ AT_RESOLVE_BENEATH)) != 0)
return (EINVAL);
return (kern_fchmodat(td, uap->fd, uap->path, UIO_USERSPACE,
@@ -2851,12 +2873,11 @@
enum uio_seg pathseg, mode_t mode, int flag)
{
struct nameidata nd;
- int error, follow;
+ int error;
AUDIT_ARG_MODE(mode);
- follow = (flag & AT_SYMLINK_NOFOLLOW) != 0 ? NOFOLLOW : FOLLOW;
- follow |= (flag & AT_BENEATH) != 0 ? BENEATH : 0;
- NDINIT_ATRIGHTS(&nd, LOOKUP, follow | AUDITVNODE1, pathseg, path, fd,
+ NDINIT_ATRIGHTS(&nd, LOOKUP, at2cnpflags(flag, AT_SYMLINK_NOFOLLOW |
+ AT_BENEATH | AT_RESOLVE_BENEATH) | AUDITVNODE1, pathseg, path, fd,
&cap_fchmod_rights, td);
if ((error = namei(&nd)) != 0)
return (error);
@@ -2951,7 +2972,8 @@
sys_fchownat(struct thread *td, struct fchownat_args *uap)
{
- if ((uap->flag & ~(AT_SYMLINK_NOFOLLOW | AT_BENEATH)) != 0)
+ if ((uap->flag & ~(AT_SYMLINK_NOFOLLOW | AT_BENEATH |
+ AT_RESOLVE_BENEATH)) != 0)
return (EINVAL);
return (kern_fchownat(td, uap->fd, uap->path, UIO_USERSPACE, uap->uid,
@@ -2963,12 +2985,11 @@
enum uio_seg pathseg, int uid, int gid, int flag)
{
struct nameidata nd;
- int error, follow;
+ int error;
AUDIT_ARG_OWNER(uid, gid);
- follow = (flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW;
- follow |= (flag & AT_BENEATH) != 0 ? BENEATH : 0;
- NDINIT_ATRIGHTS(&nd, LOOKUP, follow | AUDITVNODE1, pathseg, path, fd,
+ NDINIT_ATRIGHTS(&nd, LOOKUP, at2cnpflags(flag, AT_SYMLINK_NOFOLLOW |
+ AT_BENEATH | AT_RESOLVE_BENEATH) | AUDITVNODE1, pathseg, path, fd,
&cap_fchown_rights, td);
if ((error = namei(&nd)) != 0)
@@ -3320,13 +3341,14 @@
struct timespec ts[2];
int error, flags;
- if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_BENEATH)) != 0)
+ if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_BENEATH |
+ AT_RESOLVE_BENEATH)) != 0)
return (EINVAL);
if ((error = getutimens(tptr, tptrseg, ts, &flags)) != 0)
return (error);
- NDINIT_ATRIGHTS(&nd, LOOKUP, ((flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW :
- FOLLOW) | ((flag & AT_BENEATH) != 0 ? BENEATH : 0) | AUDITVNODE1,
+ NDINIT_ATRIGHTS(&nd, LOOKUP, at2cnpflags(flag, AT_SYMLINK_NOFOLLOW |
+ AT_BENEATH | AT_RESOLVE_BENEATH) | AUDITVNODE1,
pathseg, path, fd, &cap_futimes_rights, td);
if ((error = namei(&nd)) != 0)
return (error);
@@ -3821,7 +3843,7 @@
restart:
bwillwrite();
NDINIT_ATRIGHTS(&nd, DELETE, LOCKPARENT | LOCKLEAF | AUDITVNODE1 |
- ((flag & AT_BENEATH) != 0 ? BENEATH : 0),
+ at2cnpflags(flag, AT_BENEATH | AT_RESOLVE_BENEATH),
pathseg, path, dfd, &cap_unlinkat_rights, td);
if ((error = namei(&nd)) != 0)
goto fdout;
@@ -4307,7 +4329,8 @@
sys_getfhat(struct thread *td, struct getfhat_args *uap)
{
- if ((uap->flags & ~(AT_SYMLINK_NOFOLLOW | AT_BENEATH)) != 0)
+ if ((uap->flags & ~(AT_SYMLINK_NOFOLLOW | AT_BENEATH |
+ AT_RESOLVE_BENEATH)) != 0)
return (EINVAL);
return (kern_getfhat(td, uap->flags, uap->fd, uap->path, UIO_USERSPACE,
uap->fhp));
@@ -4325,9 +4348,9 @@
error = priv_check(td, PRIV_VFS_GETFH);
if (error != 0)
return (error);
- NDINIT_AT(&nd, LOOKUP, ((flags & AT_SYMLINK_NOFOLLOW) != 0 ? NOFOLLOW :
- FOLLOW) | ((flags & AT_BENEATH) != 0 ? BENEATH : 0) | LOCKLEAF |
- AUDITVNODE1, pathseg, path, fd, td);
+ NDINIT_AT(&nd, LOOKUP, at2cnpflags(flags, AT_SYMLINK_NOFOLLOW |
+ AT_BENEATH | AT_RESOLVE_BENEATH) | LOCKLEAF | AUDITVNODE1,
+ pathseg, path, fd, td);
error = namei(&nd);
if (error != 0)
return (error);
Index: sys/kern/vfs_vnops.c
===================================================================
--- sys/kern/vfs_vnops.c
+++ sys/kern/vfs_vnops.c
@@ -192,6 +192,23 @@
return (vn_open_cred(ndp, flagp, cmode, 0, td->td_ucred, fp));
}
+static uint64_t
+open2nameif(int fmode, u_int vn_open_flags)
+{
+ uint64_t res;
+
+ res = ISOPEN | LOCKLEAF;
+ if ((fmode & O_BENEATH) != 0)
+ res |= BENEATH;
+ if ((fmode & O_RESOLVE_BENEATH) != 0)
+ res |= RBENEATH;
+ if ((vn_open_flags & VN_OPEN_NOAUDIT) == 0)
+ res |= AUDITVNODE1;
+ if ((vn_open_flags & VN_OPEN_NOCAPCHECK) != 0)
+ res |= NOCAPCHECK;
+ return (res);
+}
+
/*
* Common code for vnode open operations via a name lookup.
* Lookup the vnode and invoke VOP_CREATE if needed.
@@ -218,19 +235,14 @@
return (EINVAL);
else if ((fmode & (O_CREAT | O_DIRECTORY)) == O_CREAT) {
ndp->ni_cnd.cn_nameiop = CREATE;
+ ndp->ni_cnd.cn_flags = open2nameif(fmode, vn_open_flags);
/*
* Set NOCACHE to avoid flushing the cache when
* rolling in many files at once.
*/
- ndp->ni_cnd.cn_flags = ISOPEN | LOCKPARENT | LOCKLEAF | NOCACHE;
+ ndp->ni_cnd.cn_flags |= LOCKPARENT | NOCACHE;
if ((fmode & O_EXCL) == 0 && (fmode & O_NOFOLLOW) == 0)
ndp->ni_cnd.cn_flags |= FOLLOW;
- if ((fmode & O_BENEATH) != 0)
- ndp->ni_cnd.cn_flags |= BENEATH;
- if (!(vn_open_flags & VN_OPEN_NOAUDIT))
- ndp->ni_cnd.cn_flags |= AUDITVNODE1;
- if (vn_open_flags & VN_OPEN_NOCAPCHECK)
- ndp->ni_cnd.cn_flags |= NOCAPCHECK;
if ((vn_open_flags & VN_OPEN_INVFS) == 0)
bwillwrite();
if ((error = namei(ndp)) != 0)
@@ -285,16 +297,11 @@
}
} else {
ndp->ni_cnd.cn_nameiop = LOOKUP;
- ndp->ni_cnd.cn_flags = ISOPEN |
- ((fmode & O_NOFOLLOW) ? NOFOLLOW : FOLLOW) | LOCKLEAF;
- if (!(fmode & FWRITE))
+ ndp->ni_cnd.cn_flags = open2nameif(fmode, vn_open_flags);
+ ndp->ni_cnd.cn_flags |= (fmode & O_NOFOLLOW) != 0 ? NOFOLLOW :
+ FOLLOW;
+ if ((fmode & FWRITE) == 0)
ndp->ni_cnd.cn_flags |= LOCKSHARED;
- if ((fmode & O_BENEATH) != 0)
- ndp->ni_cnd.cn_flags |= BENEATH;
- if (!(vn_open_flags & VN_OPEN_NOAUDIT))
- ndp->ni_cnd.cn_flags |= AUDITVNODE1;
- if (vn_open_flags & VN_OPEN_NOCAPCHECK)
- ndp->ni_cnd.cn_flags |= NOCAPCHECK;
if ((error = namei(ndp)) != 0)
return (error);
vp = ndp->ni_vp;
Index: sys/sys/fcntl.h
===================================================================
--- sys/sys/fcntl.h
+++ sys/sys/fcntl.h
@@ -136,6 +136,9 @@
#if __BSD_VISIBLE
#define O_VERIFY 0x00200000 /* open only after verification */
#define O_BENEATH 0x00400000 /* Fail if not under cwd */
+#define O_RESOLVE_BENEATH 0x00800000 /* As O_BENEATH, but do not allow
+ resolve to walk out of cwd even to
+ return back */
#endif
/*
@@ -215,6 +218,9 @@
#define AT_SYMLINK_FOLLOW 0x0400 /* Follow symbolic link */
#define AT_REMOVEDIR 0x0800 /* Remove directory instead of file */
#define AT_BENEATH 0x1000 /* Fail if not under dirfd */
+#define AT_RESOLVE_BENEATH 0x2000 /* As AT_BENEATH, but do not allow
+ resolve to walk out of dirfd even
+ to return back */
#endif
/*
Index: sys/sys/namei.h
===================================================================
--- sys/sys/namei.h
+++ sys/sys/namei.h
@@ -133,7 +133,8 @@
#define BENEATH 0x0080 /* No escape from the start dir */
#define LOCKSHARED 0x0100 /* Shared lock leaf */
#define NOFOLLOW 0x0000 /* do not follow symbolic links (pseudo) */
-#define MODMASK 0x01fc /* mask of operational modifiers */
+#define RBENEATH 0x100000000ULL /* XXX */
+#define MODMASK 0xf000001fcULL /* mask of operational modifiers */
/*
* Namei parameter descriptors.
*
@@ -183,6 +184,7 @@
* Namei results flags
*/
#define NIRES_ABS 0x00000001 /* Path was absolute */
+#define NIRES_STRICTREL 0x00000002 /* Restricted lookup result */
/*
* Flags in ni_lcf, valid for the duration of the namei call.

File Metadata

Mime Type
text/plain
Expires
Fri, Oct 18, 6:34 PM (9 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14253863
Default Alt Text
D25886.id77052.diff (20 KB)

Event Timeline