aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/vfs_syscalls.c
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2020-09-22 22:22:29 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2020-09-22 22:22:29 +0000
commit861f039df1d72388af4564787b0b5f6e62344cbe (patch)
treec35152bcf865626c01eaf99aa862dc00bee6afbb /sys/kern/vfs_syscalls.c
parentc7de3d6f0b2234970b291b1e5914ecd17f492c2c (diff)
downloadsrc-861f039df1d72388af4564787b0b5f6e62344cbe.tar.gz
src-861f039df1d72388af4564787b0b5f6e62344cbe.zip
Add at2cnpflags()
the helper to convert AT_ flags for *at() syscalls to namei flags. Reviewed by: markj Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D25886
Notes
Notes: svn path=/head/; revision=366018
Diffstat (limited to 'sys/kern/vfs_syscalls.c')
-rw-r--r--sys/kern/vfs_syscalls.c69
1 files changed, 43 insertions, 26 deletions
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 769bfc3342d2..9eec74d4da22 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -112,6 +112,28 @@ static int kern_readlink_vp(struct vnode *vp, char *buf, enum uio_seg bufseg,
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;
+
+ MPASS((at_flags & (AT_SYMLINK_FOLLOW | AT_SYMLINK_NOFOLLOW)) !=
+ (AT_SYMLINK_FOLLOW | AT_SYMLINK_NOFOLLOW));
+
+ res = 0;
+ at_flags &= mask;
+ if ((at_flags & AT_BENEATH) != 0)
+ res |= BENEATH;
+ if ((at_flags & AT_SYMLINK_FOLLOW) != 0)
+ res |= FOLLOW;
+ /* NOFOLLOW is pseudo flag */
+ if ((mask & AT_SYMLINK_NOFOLLOW) != 0) {
+ res |= (at_flags & AT_SYMLINK_NOFOLLOW) != 0 ? NOFOLLOW :
+ FOLLOW;
+ }
+ return (res);
+}
+
int
kern_sync(struct thread *td)
{
@@ -1485,8 +1507,7 @@ sys_linkat(struct thread *td, struct linkat_args *uap)
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)));
}
int hardlink_check_uid = 0;
@@ -1851,7 +1872,7 @@ kern_funlinkat(struct thread *td, int dfd, const char *path, int fd,
restart:
bwillwrite();
NDINIT_ATRIGHTS(&nd, DELETE, LOCKPARENT | LOCKLEAF | AUDITVNODE1 |
- ((flag & AT_BENEATH) != 0 ? BENEATH : 0),
+ at2cnpflags(flag, AT_BENEATH),
pathseg, path, dfd, &cap_unlinkat_rights, td);
if ((error = namei(&nd)) != 0) {
if (error == EINVAL)
@@ -2075,7 +2096,7 @@ kern_accessat(struct thread *td, int fd, const char *path,
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),
pathseg, path, fd, &cap_fstat_rights, td);
if ((error = namei(&nd)) != 0)
goto out;
@@ -2369,10 +2390,9 @@ kern_statat(struct thread *td, int flag, int fd, const char *path,
if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_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_SYMLINK_NOFOLLOW) | LOCKSHARED | LOCKLEAF |
+ AUDITVNODE1, pathseg, path, fd, &cap_fstat_rights, td);
if ((error = namei(&nd)) != 0)
return (error);
@@ -2719,12 +2739,11 @@ kern_chflagsat(struct thread *td, int fd, const char *path,
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) | AUDITVNODE1, pathseg, path, fd,
&cap_fchflags_rights, td);
if ((error = namei(&nd)) != 0)
return (error);
@@ -2848,12 +2867,11 @@ kern_fchmodat(struct thread *td, int fd, const char *path,
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) | AUDITVNODE1, pathseg, path, fd,
&cap_fchmod_rights, td);
if ((error = namei(&nd)) != 0)
return (error);
@@ -2960,12 +2978,11 @@ kern_fchownat(struct thread *td, int fd, const char *path,
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) | AUDITVNODE1, pathseg, path, fd,
&cap_fchown_rights, td);
if ((error = namei(&nd)) != 0)
@@ -3322,8 +3339,8 @@ kern_utimensat(struct thread *td, int fd, const char *path,
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) | AUDITVNODE1,
pathseg, path, fd, &cap_futimes_rights, td);
if ((error = namei(&nd)) != 0)
return (error);
@@ -3818,7 +3835,7 @@ kern_frmdirat(struct thread *td, int dfd, const char *path, int fd,
restart:
bwillwrite();
NDINIT_ATRIGHTS(&nd, DELETE, LOCKPARENT | LOCKLEAF | AUDITVNODE1 |
- ((flag & AT_BENEATH) != 0 ? BENEATH : 0),
+ at2cnpflags(flag, AT_BENEATH),
pathseg, path, dfd, &cap_unlinkat_rights, td);
if ((error = namei(&nd)) != 0)
goto fdout;
@@ -4321,9 +4338,9 @@ kern_getfhat(struct thread *td, int flags, int fd, const char *path,
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) | LOCKLEAF | AUDITVNODE1,
+ pathseg, path, fd, td);
error = namei(&nd);
if (error != 0)
return (error);