Page MenuHomeFreeBSD

D25886.id75213.diff
No OneTemporary

D25886.id75213.diff

Index: sys/kern/vfs_lookup.c
===================================================================
--- sys/kern/vfs_lookup.c
+++ sys/kern/vfs_lookup.c
@@ -415,6 +415,15 @@
if (error == 0)
ndp->ni_lcf |= NI_LCF_LATCH;
}
+ if ((cnp->cn_flags & RBENEATH) != 0) {
+ if ((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.
*/
@@ -1366,9 +1375,9 @@
}
void
-NDINIT_ALL(struct nameidata *ndp, u_long op, u_long flags, enum uio_seg segflg,
- const char *namep, int dirfd, struct vnode *startdir, cap_rights_t *rightsp,
- struct thread *td)
+NDINIT_ALL(struct nameidata *ndp, u_long op, u_int64_t flags,
+ enum uio_seg segflg, const char *namep, int dirfd, struct vnode *startdir,
+ cap_rights_t *rightsp, struct thread *td)
{
ndp->ni_cnd.cn_nameiop = op;
Index: sys/kern/vfs_syscalls.c
===================================================================
--- sys/kern/vfs_syscalls.c
+++ sys/kern/vfs_syscalls.c
@@ -114,6 +114,26 @@
static int kern_linkat_vp(struct thread *td, struct vnode *vp, int fd,
const char *path, enum uio_seg segflag);
+static u_int64_t
+at2cnpf(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_RBENEATH) != 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)
{
@@ -1486,12 +1506,12 @@
int flag;
flag = uap->flag;
- if ((flag & ~(AT_SYMLINK_FOLLOW | AT_BENEATH)) != 0)
+ if ((flag & ~(AT_SYMLINK_FOLLOW | AT_BENEATH | AT_RBENEATH)) != 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, at2cnpf(flag, AT_SYMLINK_FOLLOW | AT_BENEATH |
+ AT_RBENEATH)));
}
int hardlink_check_uid = 0;
@@ -1856,7 +1876,7 @@
restart:
bwillwrite();
NDINIT_ATRIGHTS(&nd, DELETE, LOCKPARENT | LOCKLEAF | AUDITVNODE1 |
- ((flag & AT_BENEATH) != 0 ? BENEATH : 0),
+ at2cnpf(flag, AT_BENEATH | AT_RBENEATH),
pathseg, path, dfd, &cap_unlinkat_rights, td);
if ((error = namei(&nd)) != 0) {
if (error == EINVAL)
@@ -2059,7 +2079,7 @@
struct nameidata nd;
int error;
- if ((flag & ~(AT_EACCESS | AT_BENEATH)) != 0)
+ if ((flag & ~(AT_EACCESS | AT_BENEATH | AT_RBENEATH)) != 0)
return (EINVAL);
if (amode != F_OK && (amode & ~(R_OK | W_OK | X_OK)) != 0)
return (EINVAL);
@@ -2080,7 +2100,7 @@
usecred = cred;
AUDIT_ARG_VALUE(amode);
NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF |
- AUDITVNODE1 | ((flag & AT_BENEATH) != 0 ? BENEATH : 0),
+ AUDITVNODE1 | at2cnpf(flag, AT_BENEATH | AT_RBENEATH),
pathseg, path, fd, &cap_fstat_rights, td);
if ((error = namei(&nd)) != 0)
goto out;
@@ -2371,13 +2391,12 @@
struct nameidata nd;
int error;
- if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_BENEATH)) != 0)
+ if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_BENEATH | AT_RBENEATH)) != 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, at2cnpf(flag, AT_BENEATH | AT_RBENEATH |
+ AT_SYMLINK_NOFOLLOW) | LOCKSHARED | LOCKLEAF | AUDITVNODE1,
+ pathseg, path, fd, &cap_fstat_rights, td);
if ((error = namei(&nd)) != 0)
return (error);
@@ -2698,7 +2717,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_RBENEATH)) != 0)
return (EINVAL);
return (kern_chflagsat(td, uap->fd, uap->path, UIO_USERSPACE,
@@ -2727,12 +2747,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, at2cnpf(atflag, AT_SYMLINK_NOFOLLOW |
+ AT_BENEATH | AT_RBENEATH) | AUDITVNODE1, pathseg, path, fd,
&cap_fchflags_rights, td);
if ((error = namei(&nd)) != 0)
return (error);
@@ -2827,7 +2846,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_RBENEATH)) != 0)
return (EINVAL);
return (kern_fchmodat(td, uap->fd, uap->path, UIO_USERSPACE,
@@ -2856,12 +2876,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, at2cnpf(flag, AT_SYMLINK_NOFOLLOW |
+ AT_BENEATH | AT_RBENEATH) | AUDITVNODE1, pathseg, path, fd,
&cap_fchmod_rights, td);
if ((error = namei(&nd)) != 0)
return (error);
@@ -2956,7 +2975,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_RBENEATH)) != 0)
return (EINVAL);
return (kern_fchownat(td, uap->fd, uap->path, UIO_USERSPACE, uap->uid,
@@ -2968,12 +2988,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, at2cnpf(flag, AT_SYMLINK_NOFOLLOW |
+ AT_BENEATH | AT_RBENEATH) | AUDITVNODE1, pathseg, path, fd,
&cap_fchown_rights, td);
if ((error = namei(&nd)) != 0)
@@ -3325,13 +3344,13 @@
struct timespec ts[2];
int error, flags;
- if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_BENEATH)) != 0)
+ if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_BENEATH | AT_RBENEATH)) != 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, at2cnpf(flag, AT_SYMLINK_NOFOLLOW |
+ AT_BENEATH | AT_RBENEATH) | AUDITVNODE1,
pathseg, path, fd, &cap_futimes_rights, td);
if ((error = namei(&nd)) != 0)
return (error);
@@ -3826,7 +3845,7 @@
restart:
bwillwrite();
NDINIT_ATRIGHTS(&nd, DELETE, LOCKPARENT | LOCKLEAF | AUDITVNODE1 |
- ((flag & AT_BENEATH) != 0 ? BENEATH : 0),
+ at2cnpf(flag, AT_BENEATH | AT_RBENEATH),
pathseg, path, dfd, &cap_unlinkat_rights, td);
if ((error = namei(&nd)) != 0)
goto fdout;
@@ -4312,7 +4331,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_RBENEATH)) != 0)
return (EINVAL);
return (kern_getfhat(td, uap->flags, uap->fd, uap->path, UIO_USERSPACE,
uap->fhp));
@@ -4330,9 +4350,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, at2cnpf(flags, AT_SYMLINK_NOFOLLOW |
+ AT_BENEATH | AT_RBENEATH) | 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
@@ -223,6 +223,8 @@
ndp->ni_cnd.cn_flags |= FOLLOW;
if ((fmode & O_BENEATH) != 0)
ndp->ni_cnd.cn_flags |= BENEATH;
+ if ((fmode & O_RBENEATH) != 0)
+ ndp->ni_cnd.cn_flags |= RBENEATH;
if (!(vn_open_flags & VN_OPEN_NOAUDIT))
ndp->ni_cnd.cn_flags |= AUDITVNODE1;
if (vn_open_flags & VN_OPEN_NOCAPCHECK)
@@ -287,6 +289,8 @@
ndp->ni_cnd.cn_flags |= LOCKSHARED;
if ((fmode & O_BENEATH) != 0)
ndp->ni_cnd.cn_flags |= BENEATH;
+ if ((fmode & O_RBENEATH) != 0)
+ ndp->ni_cnd.cn_flags |= RBENEATH;
if (!(vn_open_flags & VN_OPEN_NOAUDIT))
ndp->ni_cnd.cn_flags |= AUDITVNODE1;
if (vn_open_flags & VN_OPEN_NOCAPCHECK)
Index: sys/sys/fcntl.h
===================================================================
--- sys/sys/fcntl.h
+++ sys/sys/fcntl.h
@@ -136,6 +136,7 @@
#if __BSD_VISIBLE
#define O_VERIFY 0x00200000 /* open only after verification */
#define O_BENEATH 0x00400000 /* Fail if not under cwd */
+#define O_RBENEATH 0x00800000 /* XXX */
#endif
/*
@@ -215,6 +216,7 @@
#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_RBENEATH 0x2000 /* XXX */
#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.
*
@@ -196,7 +197,7 @@
#define NDINIT_ATVP(ndp, op, flags, segflg, namep, vp, td) \
NDINIT_ALL(ndp, op, flags, segflg, namep, AT_FDCWD, vp, 0, td)
-void NDINIT_ALL(struct nameidata *ndp, u_long op, u_long flags,
+void NDINIT_ALL(struct nameidata *ndp, u_long op, u_int64_t flags,
enum uio_seg segflg, const char *namep, int dirfd, struct vnode *startdir,
cap_rights_t *rightsp, struct thread *td);

File Metadata

Mime Type
text/plain
Expires
Fri, Oct 18, 6:35 PM (9 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14253870
Default Alt Text
D25886.id75213.diff (10 KB)

Event Timeline