vfs: elide MAC-induced locking on rename if there are no relevant hoooks
This commit is contained in:
parent
fd8c6a48ab
commit
fad6dd772d
@ -3541,6 +3541,33 @@ sys_renameat(struct thread *td, struct renameat_args *uap)
|
||||
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 *old, int newfd,
|
||||
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 |
|
||||
|
@ -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_array[] = {
|
||||
.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
|
||||
|
@ -482,6 +482,10 @@ mac_vnode_check_poll(struct ucred *active_cred, struct ucred *file_cred,
|
||||
#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,
|
||||
|
Loading…
Reference in New Issue
Block a user