Author: mjg
Date: Wed Jul 29 17:05:31 2020
New Revision: 363668
URL: https://svnweb.freebsd.org/changeset/base/363668

Log:
  vfs: elide MAC-induced locking on rename if there are no relevant hoooks

Modified:
  head/sys/kern/vfs_syscalls.c
  head/sys/security/mac/mac_framework.c
  head/sys/security/mac/mac_framework.h

Modified: head/sys/kern/vfs_syscalls.c
==============================================================================
--- head/sys/kern/vfs_syscalls.c        Wed Jul 29 17:04:33 2020        
(r363667)
+++ head/sys/kern/vfs_syscalls.c        Wed Jul 29 17:05:31 2020        
(r363668)
@@ -3541,6 +3541,33 @@ sys_renameat(struct thread *td, struct renameat_args *
            UIO_USERSPACE));
 }
 
+#ifdef MAC
+static int
+kern_renameat_mac(struct thread *td, int oldfd, const char *old, int newfd,
+    const char *new, enum uio_seg pathseg, struct nameidata *fromnd)
+{
+       int error;
+
+       NDINIT_ATRIGHTS(fromnd, DELETE, LOCKPARENT | LOCKLEAF | SAVESTART |
+           AUDITVNODE1, pathseg, old, oldfd, &cap_renameat_source_rights, td);
+       if ((error = namei(fromnd)) != 0)
+               return (error);
+       error = mac_vnode_check_rename_from(td->td_ucred, fromnd->ni_dvp,
+           fromnd->ni_vp, &fromnd->ni_cnd);
+       VOP_UNLOCK(fromnd->ni_dvp);
+       if (fromnd->ni_dvp != fromnd->ni_vp)
+               VOP_UNLOCK(fromnd->ni_vp);
+       if (error != 0) {
+               NDFREE(fromnd, NDF_ONLY_PNBUF);
+               vrele(fromnd->ni_dvp);
+               vrele(fromnd->ni_vp);
+               if (fromnd->ni_startdir)
+                       vrele(fromnd->ni_startdir);
+       }
+       return (error);
+}
+#endif
+
 int
 kern_renameat(struct thread *td, int oldfd, const char *old, int newfd,
     const char *new, enum uio_seg pathseg)
@@ -3553,30 +3580,19 @@ kern_renameat(struct thread *td, int oldfd, const char
 again:
        bwillwrite();
 #ifdef MAC
-       NDINIT_ATRIGHTS(&fromnd, DELETE, LOCKPARENT | LOCKLEAF | SAVESTART |
-           AUDITVNODE1, pathseg, old, oldfd,
-           &cap_renameat_source_rights, td);
-       if ((error = namei(&fromnd)) != 0)
-               return (error);
-       error = mac_vnode_check_rename_from(td->td_ucred, fromnd.ni_dvp,
-           fromnd.ni_vp, &fromnd.ni_cnd);
-       VOP_UNLOCK(fromnd.ni_dvp);
-       if (fromnd.ni_dvp != fromnd.ni_vp)
-               VOP_UNLOCK(fromnd.ni_vp);
-       if (error != 0) {
-               NDFREE(&fromnd, NDF_ONLY_PNBUF);
-               vrele(fromnd.ni_dvp);
-               vrele(fromnd.ni_vp);
-               if (fromnd.ni_startdir)
-                       vrele(fromnd.ni_startdir);
-               return (error);
-       }
-#else
+       if (mac_vnode_check_rename_from_enabled()) {
+               error = kern_renameat_mac(td, oldfd, old, newfd, new, pathseg,
+                   &fromnd);
+               if (error != 0)
+                       return (error);
+       } else {
+#endif
        NDINIT_ATRIGHTS(&fromnd, DELETE, WANTPARENT | SAVESTART | AUDITVNODE1,
-           pathseg, old, oldfd,
-           &cap_renameat_source_rights, td);
+           pathseg, old, oldfd, &cap_renameat_source_rights, td);
        if ((error = namei(&fromnd)) != 0)
                return (error);
+#ifdef MAC
+       }
 #endif
        fvp = fromnd.ni_vp;
        NDINIT_ATRIGHTS(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE |

Modified: head/sys/security/mac/mac_framework.c
==============================================================================
--- head/sys/security/mac/mac_framework.c       Wed Jul 29 17:04:33 2020        
(r363667)
+++ head/sys/security/mac/mac_framework.c       Wed Jul 29 17:05:31 2020        
(r363668)
@@ -139,6 +139,7 @@ FPFLAG(vnode_check_read);
 FPFLAG(vnode_check_write);
 FPFLAG(vnode_check_mmap);
 FPFLAG_RARE(vnode_check_poll);
+FPFLAG_RARE(vnode_check_rename_from);
 
 #undef FPFLAG
 #undef FPFLAG_RARE
@@ -427,6 +428,8 @@ struct mac_policy_fastpath_elem mac_policy_fastpath_ar
                .flag = &mac_vnode_check_mmap_fp_flag },
        { .offset = FPO(vnode_check_poll),
                .flag = &mac_vnode_check_poll_fp_flag },
+       { .offset = FPO(vnode_check_rename_from),
+               .flag = &mac_vnode_check_rename_from_fp_flag },
 };
 
 static void

Modified: head/sys/security/mac/mac_framework.h
==============================================================================
--- head/sys/security/mac/mac_framework.h       Wed Jul 29 17:04:33 2020        
(r363667)
+++ head/sys/security/mac/mac_framework.h       Wed Jul 29 17:05:31 2020        
(r363668)
@@ -482,6 +482,10 @@ mac_vnode_check_poll(struct ucred *active_cred, struct
 #endif
 int    mac_vnode_check_readdir(struct ucred *cred, struct vnode *vp);
 int    mac_vnode_check_readlink(struct ucred *cred, struct vnode *vp);
+#define mac_vnode_check_rename_from_enabled() 
__predict_false(mac_vnode_check_rename_from_fp_flag)
+#ifdef MAC
+extern bool mac_vnode_check_rename_from_fp_flag;
+#endif
 int    mac_vnode_check_rename_from(struct ucred *cred, struct vnode *dvp,
            struct vnode *vp, struct componentname *cnp);
 int    mac_vnode_check_rename_to(struct ucred *cred, struct vnode *dvp,
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to