svn commit: r366018 - head/sys/kern

Konstantin Belousov kib at FreeBSD.org
Tue Sep 22 22:22:30 UTC 2020


Author: kib
Date: Tue Sep 22 22:22:29 2020
New Revision: 366018
URL: https://svnweb.freebsd.org/changeset/base/366018

Log:
  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

Modified:
  head/sys/kern/vfs_syscalls.c

Modified: head/sys/kern/vfs_syscalls.c
==============================================================================
--- head/sys/kern/vfs_syscalls.c	Tue Sep 22 22:06:20 2020	(r366017)
+++ head/sys/kern/vfs_syscalls.c	Tue Sep 22 22:22:29 2020	(r366018)
@@ -112,6 +112,28 @@ static int kern_readlink_vp(struct vnode *vp, char *bu
 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 
 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 *p
 		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
 	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 *
     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 *p
     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 *p
     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 *
 
 	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 *
 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, con
 	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);


More information about the svn-src-head mailing list