From 390b4d50c18f26c6be7c03daab07f2b4cc16ab45 Mon Sep 17 00:00:00 2001 From: csjp Date: Tue, 4 Oct 2005 14:32:58 +0000 Subject: Standard Giant push down operations for the Mandatory Access Control (MAC) framework. This makes Giant protection around MAC operations which inter- act with VFS conditional, based on the MPSAFE status of the file system. Affected the following syscalls: o __mac_get_fd o __mac_get_file o __mac_get_link o __mac_set_fd o __mac_set_file o __mac_set_link -Drop Giant all together in __mac_set_proc because the mac_cred_mmapped_drop_perms_recurse routine no longer requires it. -Move conditional Giant aquisitions to after label allocation routines. -Move the conditional release of Giant to before label de-allocation routines. Discussed with: rwatson --- sys/security/mac/mac_syscalls.c | 61 ++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 34 deletions(-) (limited to 'sys/security/mac/mac_syscalls.c') diff --git a/sys/security/mac/mac_syscalls.c b/sys/security/mac/mac_syscalls.c index 5bb70d1..fd28931 100644 --- a/sys/security/mac/mac_syscalls.c +++ b/sys/security/mac/mac_syscalls.c @@ -728,9 +728,7 @@ __mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) PROC_UNLOCK(p); if (mac_enforce_vm) { - mtx_lock(&Giant); mac_cred_mmapped_drop_perms(td, newcred); - mtx_unlock(&Giant); } crfree(newcred); /* Free revocation reference. */ @@ -755,7 +753,7 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) struct pipe *pipe; struct socket *so; short label_type; - int error; + int vfslocked, error; error = copyin(uap->mac_p, &mac, sizeof(mac)); if (error) @@ -783,11 +781,11 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) case DTYPE_VNODE: vp = fp->f_vnode; intlabel = mac_vnode_label_alloc(); - mtx_lock(&Giant); /* VFS */ + vfslocked = VFS_LOCK_GIANT(vp->v_mount); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); mac_copy_vnode_label(vp->v_label, intlabel); VOP_UNLOCK(vp, 0, td); - mtx_unlock(&Giant); /* VFS */ + VFS_UNLOCK_GIANT(vfslocked); error = mac_externalize_vnode_label(intlabel, elements, buffer, mac.m_buflen); mac_vnode_label_free(intlabel); @@ -840,7 +838,7 @@ __mac_get_file(struct thread *td, struct __mac_get_file_args *uap) struct nameidata nd; struct label *intlabel; struct mac mac; - int error; + int vfslocked, error; error = copyin(uap->mac_p, &mac, sizeof(mac)); if (error) @@ -858,27 +856,25 @@ __mac_get_file(struct thread *td, struct __mac_get_file_args *uap) } buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); - mtx_lock(&Giant); /* VFS */ - NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, - td); + NDINIT(&nd, LOOKUP, MPSAFE | LOCKLEAF | FOLLOW, UIO_USERSPACE, + uap->path_p, td); error = namei(&nd); if (error) goto out; intlabel = mac_vnode_label_alloc(); + vfslocked = NDHASGIANT(&nd); mac_copy_vnode_label(nd.ni_vp->v_label, intlabel); error = mac_externalize_vnode_label(intlabel, elements, buffer, mac.m_buflen); NDFREE(&nd, 0); + VFS_UNLOCK_GIANT(vfslocked); mac_vnode_label_free(intlabel); - if (error == 0) error = copyout(buffer, mac.m_string, strlen(buffer)+1); out: - mtx_unlock(&Giant); /* VFS */ - free(buffer, M_MACTEMP); free(elements, M_MACTEMP); @@ -895,7 +891,7 @@ __mac_get_link(struct thread *td, struct __mac_get_link_args *uap) struct nameidata nd; struct label *intlabel; struct mac mac; - int error; + int vfslocked, error; error = copyin(uap->mac_p, &mac, sizeof(mac)); if (error) @@ -913,26 +909,25 @@ __mac_get_link(struct thread *td, struct __mac_get_link_args *uap) } buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); - mtx_lock(&Giant); /* VFS */ - NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, - td); + NDINIT(&nd, LOOKUP, MPSAFE | LOCKLEAF | NOFOLLOW, UIO_USERSPACE, + uap->path_p, td); error = namei(&nd); if (error) goto out; intlabel = mac_vnode_label_alloc(); + vfslocked = NDHASGIANT(&nd); mac_copy_vnode_label(nd.ni_vp->v_label, intlabel); error = mac_externalize_vnode_label(intlabel, elements, buffer, mac.m_buflen); NDFREE(&nd, 0); + VFS_UNLOCK_GIANT(vfslocked); mac_vnode_label_free(intlabel); if (error == 0) error = copyout(buffer, mac.m_string, strlen(buffer)+1); out: - mtx_unlock(&Giant); /* VFS */ - free(buffer, M_MACTEMP); free(elements, M_MACTEMP); @@ -953,7 +948,7 @@ __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) struct vnode *vp; struct mac mac; char *buffer; - int error; + int error, vfslocked; error = copyin(uap->mac_p, &mac, sizeof(mac)); if (error) @@ -984,10 +979,10 @@ __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) break; } vp = fp->f_vnode; - mtx_lock(&Giant); /* VFS */ + vfslocked = VFS_LOCK_GIANT(vp->v_mount); error = vn_start_write(vp, &mp, V_WAIT | PCATCH); if (error != 0) { - mtx_unlock(&Giant); /* VFS */ + VFS_UNLOCK_GIANT(vfslocked); mac_vnode_label_free(intlabel); break; } @@ -995,7 +990,7 @@ __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) error = vn_setlabel(vp, intlabel, td->td_ucred); VOP_UNLOCK(vp, 0, td); vn_finished_write(mp); - mtx_unlock(&Giant); /* VFS */ + VFS_UNLOCK_GIANT(vfslocked); mac_vnode_label_free(intlabel); break; @@ -1045,7 +1040,7 @@ __mac_set_file(struct thread *td, struct __mac_set_file_args *uap) struct mount *mp; struct mac mac; char *buffer; - int error; + int vfslocked, error; error = copyin(uap->mac_p, &mac, sizeof(mac)); if (error) @@ -1068,11 +1063,10 @@ __mac_set_file(struct thread *td, struct __mac_set_file_args *uap) if (error) goto out; - mtx_lock(&Giant); /* VFS */ - - NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, - td); + NDINIT(&nd, LOOKUP, MPSAFE | LOCKLEAF | FOLLOW, UIO_USERSPACE, + uap->path_p, td); error = namei(&nd); + vfslocked = NDHASGIANT(&nd); if (error == 0) { error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); if (error == 0) @@ -1082,7 +1076,7 @@ __mac_set_file(struct thread *td, struct __mac_set_file_args *uap) } NDFREE(&nd, 0); - mtx_unlock(&Giant); /* VFS */ + VFS_UNLOCK_GIANT(vfslocked); out: mac_vnode_label_free(intlabel); return (error); @@ -1099,7 +1093,7 @@ __mac_set_link(struct thread *td, struct __mac_set_link_args *uap) struct mount *mp; struct mac mac; char *buffer; - int error; + int vfslocked, error; error = copyin(uap->mac_p, &mac, sizeof(mac)); if (error) @@ -1122,11 +1116,10 @@ __mac_set_link(struct thread *td, struct __mac_set_link_args *uap) if (error) goto out; - mtx_lock(&Giant); /* VFS */ - - NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, - td); + NDINIT(&nd, LOOKUP, MPSAFE | LOCKLEAF | NOFOLLOW, UIO_USERSPACE, + uap->path_p, td); error = namei(&nd); + vfslocked = NDHASGIANT(&nd); if (error == 0) { error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); if (error == 0) @@ -1136,7 +1129,7 @@ __mac_set_link(struct thread *td, struct __mac_set_link_args *uap) } NDFREE(&nd, 0); - mtx_unlock(&Giant); /* VFS */ + VFS_UNLOCK_GIANT(vfslocked); out: mac_vnode_label_free(intlabel); return (error); -- cgit v1.1