From e183f80e54905eb37052153422ea11250f357dfd Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Sun, 6 Oct 2002 02:46:26 +0000 Subject: [PATCH] Sync from MAC tree: break out the single mmap entry point into seperate entry points for each occasion: mac_check_vnode_mmap() Check at initial mapping mac_check_vnode_mprotect() Check at mapping protection change mac_check_vnode_mmap_downgrade() Determine if a mapping downgrade should take place following subject relabel. Implement mmap() and mprotect() entry points for labeled vnode policies. These entry points are currently not hooked up to the VM system in the base tree. These changes improve the consistency of the access control interface and offer more flexibility regarding limiting access to vnode mmaping. Obtained from: TrustedBSD Project Sponsored by: DARPA, Network Associates Laboratories --- sys/kern/kern_mac.c | 81 +++++++++++++++++++++++++------- sys/security/mac/mac_framework.c | 81 +++++++++++++++++++++++++------- sys/security/mac/mac_framework.h | 7 +-- sys/security/mac/mac_internal.h | 81 +++++++++++++++++++++++++------- sys/security/mac/mac_net.c | 81 +++++++++++++++++++++++++------- sys/security/mac/mac_pipe.c | 81 +++++++++++++++++++++++++------- sys/security/mac/mac_policy.h | 12 +++-- sys/security/mac/mac_process.c | 81 +++++++++++++++++++++++++------- sys/security/mac/mac_syscalls.c | 81 +++++++++++++++++++++++++------- sys/security/mac/mac_system.c | 81 +++++++++++++++++++++++++------- sys/security/mac/mac_vfs.c | 81 +++++++++++++++++++++++++------- sys/security/mac_biba/mac_biba.c | 54 ++++++++++++--------- sys/security/mac_mls/mac_mls.c | 54 ++++++++++++--------- sys/security/mac_none/mac_none.c | 24 +++++++++- sys/security/mac_stub/mac_stub.c | 24 +++++++++- sys/security/mac_test/mac_test.c | 24 +++++++++- sys/sys/mac.h | 7 +-- sys/sys/mac_policy.h | 12 +++-- 18 files changed, 723 insertions(+), 224 deletions(-) diff --git a/sys/kern/kern_mac.c b/sys/kern/kern_mac.c index 69b177208fdb..bed8a954102b 100644 --- a/sys/kern/kern_mac.c +++ b/sys/kern/kern_mac.c @@ -216,8 +216,8 @@ static int mac_policy_register(struct mac_policy_conf *mpc); static int mac_policy_unregister(struct mac_policy_conf *mpc); static int mac_stdcreatevnode_ea(struct vnode *vp); -static void mac_cred_mmapped_drop_perms(struct thread *td, - struct ucred *cred); +static void mac_check_vnode_mmap_downgrade(struct ucred *cred, + struct vnode *vp, int *prot); static void mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, struct vm_map *map); @@ -813,8 +813,16 @@ mac_policy_register(struct mac_policy_conf *mpc) mpc->mpc_ops->mpo_check_vnode_lookup = mpe->mpe_function; break; - case MAC_CHECK_VNODE_MMAP_PERMS: - mpc->mpc_ops->mpo_check_vnode_mmap_perms = + case MAC_CHECK_VNODE_MMAP: + mpc->mpc_ops->mpo_check_vnode_mmap = + mpe->mpe_function; + break; + case MAC_CHECK_VNODE_MMAP_DOWNGRADE: + mpc->mpc_ops->mpo_check_vnode_mmap_downgrade = + mpe->mpe_function; + break; + case MAC_CHECK_VNODE_MPROTECT: + mpc->mpc_ops->mpo_check_vnode_mprotect = mpe->mpe_function; break; case MAC_CHECK_VNODE_OPEN: @@ -1940,21 +1948,56 @@ mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, return (error); } -vm_prot_t -mac_check_vnode_mmap_prot(struct ucred *cred, struct vnode *vp, int newmapping) +int +mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot) { - vm_prot_t result = VM_PROT_ALL; + int error; - if (!mac_enforce_vm) - return (result); + ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap"); - /* - * This should be some sort of MAC_BITWISE, maybe :) - */ - ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_perms"); - MAC_BOOLEAN(check_vnode_mmap_perms, &, cred, vp, &vp->v_label, - newmapping); - return (result); + if (!mac_enforce_fs || !mac_enforce_vm) + return (0); + + error = vn_refreshlabel(vp, cred); + if (error) + return (error); + + MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot); + return (error); +} + +void +mac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot) +{ + int result = *prot; + + ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade"); + + if (!mac_enforce_fs || !mac_enforce_vm) + return; + + MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label, + &result); + + *prot = result; +} + +int +mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot) +{ + int error; + + ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect"); + + if (!mac_enforce_fs || !mac_enforce_vm) + return (0); + + error = vn_refreshlabel(vp, cred); + if (error) + return (error); + + MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot); + return (error); } int @@ -2337,7 +2380,8 @@ mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, struct vm_map *map) { struct vm_map_entry *vme; - vm_prot_t result, revokeperms; + int result; + vm_prot_t revokeperms; vm_object_t object; vm_ooffset_t offset; struct vnode *vp; @@ -2378,7 +2422,8 @@ mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, continue; vp = (struct vnode *)object->handle; vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); - result = mac_check_vnode_mmap_prot(cred, vp, 0); + result = vme->max_protection; + mac_check_vnode_mmap_downgrade(cred, vp, &result); VOP_UNLOCK(vp, 0, td); /* * Find out what maximum protection we may be allowing diff --git a/sys/security/mac/mac_framework.c b/sys/security/mac/mac_framework.c index 69b177208fdb..bed8a954102b 100644 --- a/sys/security/mac/mac_framework.c +++ b/sys/security/mac/mac_framework.c @@ -216,8 +216,8 @@ static int mac_policy_register(struct mac_policy_conf *mpc); static int mac_policy_unregister(struct mac_policy_conf *mpc); static int mac_stdcreatevnode_ea(struct vnode *vp); -static void mac_cred_mmapped_drop_perms(struct thread *td, - struct ucred *cred); +static void mac_check_vnode_mmap_downgrade(struct ucred *cred, + struct vnode *vp, int *prot); static void mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, struct vm_map *map); @@ -813,8 +813,16 @@ mac_policy_register(struct mac_policy_conf *mpc) mpc->mpc_ops->mpo_check_vnode_lookup = mpe->mpe_function; break; - case MAC_CHECK_VNODE_MMAP_PERMS: - mpc->mpc_ops->mpo_check_vnode_mmap_perms = + case MAC_CHECK_VNODE_MMAP: + mpc->mpc_ops->mpo_check_vnode_mmap = + mpe->mpe_function; + break; + case MAC_CHECK_VNODE_MMAP_DOWNGRADE: + mpc->mpc_ops->mpo_check_vnode_mmap_downgrade = + mpe->mpe_function; + break; + case MAC_CHECK_VNODE_MPROTECT: + mpc->mpc_ops->mpo_check_vnode_mprotect = mpe->mpe_function; break; case MAC_CHECK_VNODE_OPEN: @@ -1940,21 +1948,56 @@ mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, return (error); } -vm_prot_t -mac_check_vnode_mmap_prot(struct ucred *cred, struct vnode *vp, int newmapping) +int +mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot) { - vm_prot_t result = VM_PROT_ALL; + int error; - if (!mac_enforce_vm) - return (result); + ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap"); - /* - * This should be some sort of MAC_BITWISE, maybe :) - */ - ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_perms"); - MAC_BOOLEAN(check_vnode_mmap_perms, &, cred, vp, &vp->v_label, - newmapping); - return (result); + if (!mac_enforce_fs || !mac_enforce_vm) + return (0); + + error = vn_refreshlabel(vp, cred); + if (error) + return (error); + + MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot); + return (error); +} + +void +mac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot) +{ + int result = *prot; + + ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade"); + + if (!mac_enforce_fs || !mac_enforce_vm) + return; + + MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label, + &result); + + *prot = result; +} + +int +mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot) +{ + int error; + + ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect"); + + if (!mac_enforce_fs || !mac_enforce_vm) + return (0); + + error = vn_refreshlabel(vp, cred); + if (error) + return (error); + + MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot); + return (error); } int @@ -2337,7 +2380,8 @@ mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, struct vm_map *map) { struct vm_map_entry *vme; - vm_prot_t result, revokeperms; + int result; + vm_prot_t revokeperms; vm_object_t object; vm_ooffset_t offset; struct vnode *vp; @@ -2378,7 +2422,8 @@ mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, continue; vp = (struct vnode *)object->handle; vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); - result = mac_check_vnode_mmap_prot(cred, vp, 0); + result = vme->max_protection; + mac_check_vnode_mmap_downgrade(cred, vp, &result); VOP_UNLOCK(vp, 0, td); /* * Find out what maximum protection we may be allowing diff --git a/sys/security/mac/mac_framework.h b/sys/security/mac/mac_framework.h index fd8b7241b7c3..cd82ef5ffef3 100644 --- a/sys/security/mac/mac_framework.h +++ b/sys/security/mac/mac_framework.h @@ -339,9 +339,10 @@ int mac_check_vnode_link(struct ucred *cred, struct vnode *dvp, struct vnode *vp, struct componentname *cnp); int mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, struct componentname *cnp); -/* XXX This u_char should be vm_prot_t! */ -u_char mac_check_vnode_mmap_prot(struct ucred *cred, struct vnode *vp, - int newmapping); +int mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, + int prot); +int mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, + int prot); int mac_check_vnode_open(struct ucred *cred, struct vnode *vp, mode_t acc_mode); int mac_check_vnode_poll(struct ucred *active_cred, diff --git a/sys/security/mac/mac_internal.h b/sys/security/mac/mac_internal.h index 69b177208fdb..bed8a954102b 100644 --- a/sys/security/mac/mac_internal.h +++ b/sys/security/mac/mac_internal.h @@ -216,8 +216,8 @@ static int mac_policy_register(struct mac_policy_conf *mpc); static int mac_policy_unregister(struct mac_policy_conf *mpc); static int mac_stdcreatevnode_ea(struct vnode *vp); -static void mac_cred_mmapped_drop_perms(struct thread *td, - struct ucred *cred); +static void mac_check_vnode_mmap_downgrade(struct ucred *cred, + struct vnode *vp, int *prot); static void mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, struct vm_map *map); @@ -813,8 +813,16 @@ mac_policy_register(struct mac_policy_conf *mpc) mpc->mpc_ops->mpo_check_vnode_lookup = mpe->mpe_function; break; - case MAC_CHECK_VNODE_MMAP_PERMS: - mpc->mpc_ops->mpo_check_vnode_mmap_perms = + case MAC_CHECK_VNODE_MMAP: + mpc->mpc_ops->mpo_check_vnode_mmap = + mpe->mpe_function; + break; + case MAC_CHECK_VNODE_MMAP_DOWNGRADE: + mpc->mpc_ops->mpo_check_vnode_mmap_downgrade = + mpe->mpe_function; + break; + case MAC_CHECK_VNODE_MPROTECT: + mpc->mpc_ops->mpo_check_vnode_mprotect = mpe->mpe_function; break; case MAC_CHECK_VNODE_OPEN: @@ -1940,21 +1948,56 @@ mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, return (error); } -vm_prot_t -mac_check_vnode_mmap_prot(struct ucred *cred, struct vnode *vp, int newmapping) +int +mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot) { - vm_prot_t result = VM_PROT_ALL; + int error; - if (!mac_enforce_vm) - return (result); + ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap"); - /* - * This should be some sort of MAC_BITWISE, maybe :) - */ - ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_perms"); - MAC_BOOLEAN(check_vnode_mmap_perms, &, cred, vp, &vp->v_label, - newmapping); - return (result); + if (!mac_enforce_fs || !mac_enforce_vm) + return (0); + + error = vn_refreshlabel(vp, cred); + if (error) + return (error); + + MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot); + return (error); +} + +void +mac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot) +{ + int result = *prot; + + ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade"); + + if (!mac_enforce_fs || !mac_enforce_vm) + return; + + MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label, + &result); + + *prot = result; +} + +int +mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot) +{ + int error; + + ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect"); + + if (!mac_enforce_fs || !mac_enforce_vm) + return (0); + + error = vn_refreshlabel(vp, cred); + if (error) + return (error); + + MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot); + return (error); } int @@ -2337,7 +2380,8 @@ mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, struct vm_map *map) { struct vm_map_entry *vme; - vm_prot_t result, revokeperms; + int result; + vm_prot_t revokeperms; vm_object_t object; vm_ooffset_t offset; struct vnode *vp; @@ -2378,7 +2422,8 @@ mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, continue; vp = (struct vnode *)object->handle; vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); - result = mac_check_vnode_mmap_prot(cred, vp, 0); + result = vme->max_protection; + mac_check_vnode_mmap_downgrade(cred, vp, &result); VOP_UNLOCK(vp, 0, td); /* * Find out what maximum protection we may be allowing diff --git a/sys/security/mac/mac_net.c b/sys/security/mac/mac_net.c index 69b177208fdb..bed8a954102b 100644 --- a/sys/security/mac/mac_net.c +++ b/sys/security/mac/mac_net.c @@ -216,8 +216,8 @@ static int mac_policy_register(struct mac_policy_conf *mpc); static int mac_policy_unregister(struct mac_policy_conf *mpc); static int mac_stdcreatevnode_ea(struct vnode *vp); -static void mac_cred_mmapped_drop_perms(struct thread *td, - struct ucred *cred); +static void mac_check_vnode_mmap_downgrade(struct ucred *cred, + struct vnode *vp, int *prot); static void mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, struct vm_map *map); @@ -813,8 +813,16 @@ mac_policy_register(struct mac_policy_conf *mpc) mpc->mpc_ops->mpo_check_vnode_lookup = mpe->mpe_function; break; - case MAC_CHECK_VNODE_MMAP_PERMS: - mpc->mpc_ops->mpo_check_vnode_mmap_perms = + case MAC_CHECK_VNODE_MMAP: + mpc->mpc_ops->mpo_check_vnode_mmap = + mpe->mpe_function; + break; + case MAC_CHECK_VNODE_MMAP_DOWNGRADE: + mpc->mpc_ops->mpo_check_vnode_mmap_downgrade = + mpe->mpe_function; + break; + case MAC_CHECK_VNODE_MPROTECT: + mpc->mpc_ops->mpo_check_vnode_mprotect = mpe->mpe_function; break; case MAC_CHECK_VNODE_OPEN: @@ -1940,21 +1948,56 @@ mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, return (error); } -vm_prot_t -mac_check_vnode_mmap_prot(struct ucred *cred, struct vnode *vp, int newmapping) +int +mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot) { - vm_prot_t result = VM_PROT_ALL; + int error; - if (!mac_enforce_vm) - return (result); + ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap"); - /* - * This should be some sort of MAC_BITWISE, maybe :) - */ - ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_perms"); - MAC_BOOLEAN(check_vnode_mmap_perms, &, cred, vp, &vp->v_label, - newmapping); - return (result); + if (!mac_enforce_fs || !mac_enforce_vm) + return (0); + + error = vn_refreshlabel(vp, cred); + if (error) + return (error); + + MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot); + return (error); +} + +void +mac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot) +{ + int result = *prot; + + ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade"); + + if (!mac_enforce_fs || !mac_enforce_vm) + return; + + MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label, + &result); + + *prot = result; +} + +int +mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot) +{ + int error; + + ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect"); + + if (!mac_enforce_fs || !mac_enforce_vm) + return (0); + + error = vn_refreshlabel(vp, cred); + if (error) + return (error); + + MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot); + return (error); } int @@ -2337,7 +2380,8 @@ mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, struct vm_map *map) { struct vm_map_entry *vme; - vm_prot_t result, revokeperms; + int result; + vm_prot_t revokeperms; vm_object_t object; vm_ooffset_t offset; struct vnode *vp; @@ -2378,7 +2422,8 @@ mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, continue; vp = (struct vnode *)object->handle; vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); - result = mac_check_vnode_mmap_prot(cred, vp, 0); + result = vme->max_protection; + mac_check_vnode_mmap_downgrade(cred, vp, &result); VOP_UNLOCK(vp, 0, td); /* * Find out what maximum protection we may be allowing diff --git a/sys/security/mac/mac_pipe.c b/sys/security/mac/mac_pipe.c index 69b177208fdb..bed8a954102b 100644 --- a/sys/security/mac/mac_pipe.c +++ b/sys/security/mac/mac_pipe.c @@ -216,8 +216,8 @@ static int mac_policy_register(struct mac_policy_conf *mpc); static int mac_policy_unregister(struct mac_policy_conf *mpc); static int mac_stdcreatevnode_ea(struct vnode *vp); -static void mac_cred_mmapped_drop_perms(struct thread *td, - struct ucred *cred); +static void mac_check_vnode_mmap_downgrade(struct ucred *cred, + struct vnode *vp, int *prot); static void mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, struct vm_map *map); @@ -813,8 +813,16 @@ mac_policy_register(struct mac_policy_conf *mpc) mpc->mpc_ops->mpo_check_vnode_lookup = mpe->mpe_function; break; - case MAC_CHECK_VNODE_MMAP_PERMS: - mpc->mpc_ops->mpo_check_vnode_mmap_perms = + case MAC_CHECK_VNODE_MMAP: + mpc->mpc_ops->mpo_check_vnode_mmap = + mpe->mpe_function; + break; + case MAC_CHECK_VNODE_MMAP_DOWNGRADE: + mpc->mpc_ops->mpo_check_vnode_mmap_downgrade = + mpe->mpe_function; + break; + case MAC_CHECK_VNODE_MPROTECT: + mpc->mpc_ops->mpo_check_vnode_mprotect = mpe->mpe_function; break; case MAC_CHECK_VNODE_OPEN: @@ -1940,21 +1948,56 @@ mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, return (error); } -vm_prot_t -mac_check_vnode_mmap_prot(struct ucred *cred, struct vnode *vp, int newmapping) +int +mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot) { - vm_prot_t result = VM_PROT_ALL; + int error; - if (!mac_enforce_vm) - return (result); + ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap"); - /* - * This should be some sort of MAC_BITWISE, maybe :) - */ - ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_perms"); - MAC_BOOLEAN(check_vnode_mmap_perms, &, cred, vp, &vp->v_label, - newmapping); - return (result); + if (!mac_enforce_fs || !mac_enforce_vm) + return (0); + + error = vn_refreshlabel(vp, cred); + if (error) + return (error); + + MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot); + return (error); +} + +void +mac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot) +{ + int result = *prot; + + ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade"); + + if (!mac_enforce_fs || !mac_enforce_vm) + return; + + MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label, + &result); + + *prot = result; +} + +int +mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot) +{ + int error; + + ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect"); + + if (!mac_enforce_fs || !mac_enforce_vm) + return (0); + + error = vn_refreshlabel(vp, cred); + if (error) + return (error); + + MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot); + return (error); } int @@ -2337,7 +2380,8 @@ mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, struct vm_map *map) { struct vm_map_entry *vme; - vm_prot_t result, revokeperms; + int result; + vm_prot_t revokeperms; vm_object_t object; vm_ooffset_t offset; struct vnode *vp; @@ -2378,7 +2422,8 @@ mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, continue; vp = (struct vnode *)object->handle; vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); - result = mac_check_vnode_mmap_prot(cred, vp, 0); + result = vme->max_protection; + mac_check_vnode_mmap_downgrade(cred, vp, &result); VOP_UNLOCK(vp, 0, td); /* * Find out what maximum protection we may be allowing diff --git a/sys/security/mac/mac_policy.h b/sys/security/mac/mac_policy.h index 51a6d3713a81..5610e01dff11 100644 --- a/sys/security/mac/mac_policy.h +++ b/sys/security/mac/mac_policy.h @@ -303,8 +303,12 @@ struct mac_policy_ops { int (*mpo_check_vnode_lookup)(struct ucred *cred, struct vnode *dvp, struct label *dlabel, struct componentname *cnp); - vm_prot_t (*mpo_check_vnode_mmap_perms)(struct ucred *cred, - struct vnode *vp, struct label *label, int newmapping); + int (*mpo_check_vnode_mmap)(struct ucred *cred, struct vnode *vp, + struct label *label, int prot); + void (*mpo_check_vnode_mmap_downgrade)(struct ucred *cred, + struct vnode *vp, struct label *label, int *prot); + int (*mpo_check_vnode_mprotect)(struct ucred *cred, + struct vnode *vp, struct label *label, int prot); int (*mpo_check_vnode_open)(struct ucred *cred, struct vnode *vp, struct label *label, mode_t acc_mode); int (*mpo_check_vnode_poll)(struct ucred *active_cred, @@ -463,7 +467,9 @@ enum mac_op_constant { MAC_CHECK_VNODE_GETEXTATTR, MAC_CHECK_VNODE_LINK, MAC_CHECK_VNODE_LOOKUP, - MAC_CHECK_VNODE_MMAP_PERMS, + MAC_CHECK_VNODE_MMAP, + MAC_CHECK_VNODE_MMAP_DOWNGRADE, + MAC_CHECK_VNODE_MPROTECT, MAC_CHECK_VNODE_OPEN, MAC_CHECK_VNODE_POLL, MAC_CHECK_VNODE_READ, diff --git a/sys/security/mac/mac_process.c b/sys/security/mac/mac_process.c index 69b177208fdb..bed8a954102b 100644 --- a/sys/security/mac/mac_process.c +++ b/sys/security/mac/mac_process.c @@ -216,8 +216,8 @@ static int mac_policy_register(struct mac_policy_conf *mpc); static int mac_policy_unregister(struct mac_policy_conf *mpc); static int mac_stdcreatevnode_ea(struct vnode *vp); -static void mac_cred_mmapped_drop_perms(struct thread *td, - struct ucred *cred); +static void mac_check_vnode_mmap_downgrade(struct ucred *cred, + struct vnode *vp, int *prot); static void mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, struct vm_map *map); @@ -813,8 +813,16 @@ mac_policy_register(struct mac_policy_conf *mpc) mpc->mpc_ops->mpo_check_vnode_lookup = mpe->mpe_function; break; - case MAC_CHECK_VNODE_MMAP_PERMS: - mpc->mpc_ops->mpo_check_vnode_mmap_perms = + case MAC_CHECK_VNODE_MMAP: + mpc->mpc_ops->mpo_check_vnode_mmap = + mpe->mpe_function; + break; + case MAC_CHECK_VNODE_MMAP_DOWNGRADE: + mpc->mpc_ops->mpo_check_vnode_mmap_downgrade = + mpe->mpe_function; + break; + case MAC_CHECK_VNODE_MPROTECT: + mpc->mpc_ops->mpo_check_vnode_mprotect = mpe->mpe_function; break; case MAC_CHECK_VNODE_OPEN: @@ -1940,21 +1948,56 @@ mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, return (error); } -vm_prot_t -mac_check_vnode_mmap_prot(struct ucred *cred, struct vnode *vp, int newmapping) +int +mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot) { - vm_prot_t result = VM_PROT_ALL; + int error; - if (!mac_enforce_vm) - return (result); + ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap"); - /* - * This should be some sort of MAC_BITWISE, maybe :) - */ - ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_perms"); - MAC_BOOLEAN(check_vnode_mmap_perms, &, cred, vp, &vp->v_label, - newmapping); - return (result); + if (!mac_enforce_fs || !mac_enforce_vm) + return (0); + + error = vn_refreshlabel(vp, cred); + if (error) + return (error); + + MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot); + return (error); +} + +void +mac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot) +{ + int result = *prot; + + ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade"); + + if (!mac_enforce_fs || !mac_enforce_vm) + return; + + MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label, + &result); + + *prot = result; +} + +int +mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot) +{ + int error; + + ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect"); + + if (!mac_enforce_fs || !mac_enforce_vm) + return (0); + + error = vn_refreshlabel(vp, cred); + if (error) + return (error); + + MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot); + return (error); } int @@ -2337,7 +2380,8 @@ mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, struct vm_map *map) { struct vm_map_entry *vme; - vm_prot_t result, revokeperms; + int result; + vm_prot_t revokeperms; vm_object_t object; vm_ooffset_t offset; struct vnode *vp; @@ -2378,7 +2422,8 @@ mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, continue; vp = (struct vnode *)object->handle; vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); - result = mac_check_vnode_mmap_prot(cred, vp, 0); + result = vme->max_protection; + mac_check_vnode_mmap_downgrade(cred, vp, &result); VOP_UNLOCK(vp, 0, td); /* * Find out what maximum protection we may be allowing diff --git a/sys/security/mac/mac_syscalls.c b/sys/security/mac/mac_syscalls.c index 69b177208fdb..bed8a954102b 100644 --- a/sys/security/mac/mac_syscalls.c +++ b/sys/security/mac/mac_syscalls.c @@ -216,8 +216,8 @@ static int mac_policy_register(struct mac_policy_conf *mpc); static int mac_policy_unregister(struct mac_policy_conf *mpc); static int mac_stdcreatevnode_ea(struct vnode *vp); -static void mac_cred_mmapped_drop_perms(struct thread *td, - struct ucred *cred); +static void mac_check_vnode_mmap_downgrade(struct ucred *cred, + struct vnode *vp, int *prot); static void mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, struct vm_map *map); @@ -813,8 +813,16 @@ mac_policy_register(struct mac_policy_conf *mpc) mpc->mpc_ops->mpo_check_vnode_lookup = mpe->mpe_function; break; - case MAC_CHECK_VNODE_MMAP_PERMS: - mpc->mpc_ops->mpo_check_vnode_mmap_perms = + case MAC_CHECK_VNODE_MMAP: + mpc->mpc_ops->mpo_check_vnode_mmap = + mpe->mpe_function; + break; + case MAC_CHECK_VNODE_MMAP_DOWNGRADE: + mpc->mpc_ops->mpo_check_vnode_mmap_downgrade = + mpe->mpe_function; + break; + case MAC_CHECK_VNODE_MPROTECT: + mpc->mpc_ops->mpo_check_vnode_mprotect = mpe->mpe_function; break; case MAC_CHECK_VNODE_OPEN: @@ -1940,21 +1948,56 @@ mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, return (error); } -vm_prot_t -mac_check_vnode_mmap_prot(struct ucred *cred, struct vnode *vp, int newmapping) +int +mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot) { - vm_prot_t result = VM_PROT_ALL; + int error; - if (!mac_enforce_vm) - return (result); + ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap"); - /* - * This should be some sort of MAC_BITWISE, maybe :) - */ - ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_perms"); - MAC_BOOLEAN(check_vnode_mmap_perms, &, cred, vp, &vp->v_label, - newmapping); - return (result); + if (!mac_enforce_fs || !mac_enforce_vm) + return (0); + + error = vn_refreshlabel(vp, cred); + if (error) + return (error); + + MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot); + return (error); +} + +void +mac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot) +{ + int result = *prot; + + ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade"); + + if (!mac_enforce_fs || !mac_enforce_vm) + return; + + MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label, + &result); + + *prot = result; +} + +int +mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot) +{ + int error; + + ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect"); + + if (!mac_enforce_fs || !mac_enforce_vm) + return (0); + + error = vn_refreshlabel(vp, cred); + if (error) + return (error); + + MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot); + return (error); } int @@ -2337,7 +2380,8 @@ mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, struct vm_map *map) { struct vm_map_entry *vme; - vm_prot_t result, revokeperms; + int result; + vm_prot_t revokeperms; vm_object_t object; vm_ooffset_t offset; struct vnode *vp; @@ -2378,7 +2422,8 @@ mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, continue; vp = (struct vnode *)object->handle; vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); - result = mac_check_vnode_mmap_prot(cred, vp, 0); + result = vme->max_protection; + mac_check_vnode_mmap_downgrade(cred, vp, &result); VOP_UNLOCK(vp, 0, td); /* * Find out what maximum protection we may be allowing diff --git a/sys/security/mac/mac_system.c b/sys/security/mac/mac_system.c index 69b177208fdb..bed8a954102b 100644 --- a/sys/security/mac/mac_system.c +++ b/sys/security/mac/mac_system.c @@ -216,8 +216,8 @@ static int mac_policy_register(struct mac_policy_conf *mpc); static int mac_policy_unregister(struct mac_policy_conf *mpc); static int mac_stdcreatevnode_ea(struct vnode *vp); -static void mac_cred_mmapped_drop_perms(struct thread *td, - struct ucred *cred); +static void mac_check_vnode_mmap_downgrade(struct ucred *cred, + struct vnode *vp, int *prot); static void mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, struct vm_map *map); @@ -813,8 +813,16 @@ mac_policy_register(struct mac_policy_conf *mpc) mpc->mpc_ops->mpo_check_vnode_lookup = mpe->mpe_function; break; - case MAC_CHECK_VNODE_MMAP_PERMS: - mpc->mpc_ops->mpo_check_vnode_mmap_perms = + case MAC_CHECK_VNODE_MMAP: + mpc->mpc_ops->mpo_check_vnode_mmap = + mpe->mpe_function; + break; + case MAC_CHECK_VNODE_MMAP_DOWNGRADE: + mpc->mpc_ops->mpo_check_vnode_mmap_downgrade = + mpe->mpe_function; + break; + case MAC_CHECK_VNODE_MPROTECT: + mpc->mpc_ops->mpo_check_vnode_mprotect = mpe->mpe_function; break; case MAC_CHECK_VNODE_OPEN: @@ -1940,21 +1948,56 @@ mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, return (error); } -vm_prot_t -mac_check_vnode_mmap_prot(struct ucred *cred, struct vnode *vp, int newmapping) +int +mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot) { - vm_prot_t result = VM_PROT_ALL; + int error; - if (!mac_enforce_vm) - return (result); + ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap"); - /* - * This should be some sort of MAC_BITWISE, maybe :) - */ - ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_perms"); - MAC_BOOLEAN(check_vnode_mmap_perms, &, cred, vp, &vp->v_label, - newmapping); - return (result); + if (!mac_enforce_fs || !mac_enforce_vm) + return (0); + + error = vn_refreshlabel(vp, cred); + if (error) + return (error); + + MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot); + return (error); +} + +void +mac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot) +{ + int result = *prot; + + ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade"); + + if (!mac_enforce_fs || !mac_enforce_vm) + return; + + MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label, + &result); + + *prot = result; +} + +int +mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot) +{ + int error; + + ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect"); + + if (!mac_enforce_fs || !mac_enforce_vm) + return (0); + + error = vn_refreshlabel(vp, cred); + if (error) + return (error); + + MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot); + return (error); } int @@ -2337,7 +2380,8 @@ mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, struct vm_map *map) { struct vm_map_entry *vme; - vm_prot_t result, revokeperms; + int result; + vm_prot_t revokeperms; vm_object_t object; vm_ooffset_t offset; struct vnode *vp; @@ -2378,7 +2422,8 @@ mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, continue; vp = (struct vnode *)object->handle; vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); - result = mac_check_vnode_mmap_prot(cred, vp, 0); + result = vme->max_protection; + mac_check_vnode_mmap_downgrade(cred, vp, &result); VOP_UNLOCK(vp, 0, td); /* * Find out what maximum protection we may be allowing diff --git a/sys/security/mac/mac_vfs.c b/sys/security/mac/mac_vfs.c index 69b177208fdb..bed8a954102b 100644 --- a/sys/security/mac/mac_vfs.c +++ b/sys/security/mac/mac_vfs.c @@ -216,8 +216,8 @@ static int mac_policy_register(struct mac_policy_conf *mpc); static int mac_policy_unregister(struct mac_policy_conf *mpc); static int mac_stdcreatevnode_ea(struct vnode *vp); -static void mac_cred_mmapped_drop_perms(struct thread *td, - struct ucred *cred); +static void mac_check_vnode_mmap_downgrade(struct ucred *cred, + struct vnode *vp, int *prot); static void mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, struct vm_map *map); @@ -813,8 +813,16 @@ mac_policy_register(struct mac_policy_conf *mpc) mpc->mpc_ops->mpo_check_vnode_lookup = mpe->mpe_function; break; - case MAC_CHECK_VNODE_MMAP_PERMS: - mpc->mpc_ops->mpo_check_vnode_mmap_perms = + case MAC_CHECK_VNODE_MMAP: + mpc->mpc_ops->mpo_check_vnode_mmap = + mpe->mpe_function; + break; + case MAC_CHECK_VNODE_MMAP_DOWNGRADE: + mpc->mpc_ops->mpo_check_vnode_mmap_downgrade = + mpe->mpe_function; + break; + case MAC_CHECK_VNODE_MPROTECT: + mpc->mpc_ops->mpo_check_vnode_mprotect = mpe->mpe_function; break; case MAC_CHECK_VNODE_OPEN: @@ -1940,21 +1948,56 @@ mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, return (error); } -vm_prot_t -mac_check_vnode_mmap_prot(struct ucred *cred, struct vnode *vp, int newmapping) +int +mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot) { - vm_prot_t result = VM_PROT_ALL; + int error; - if (!mac_enforce_vm) - return (result); + ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap"); - /* - * This should be some sort of MAC_BITWISE, maybe :) - */ - ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_perms"); - MAC_BOOLEAN(check_vnode_mmap_perms, &, cred, vp, &vp->v_label, - newmapping); - return (result); + if (!mac_enforce_fs || !mac_enforce_vm) + return (0); + + error = vn_refreshlabel(vp, cred); + if (error) + return (error); + + MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot); + return (error); +} + +void +mac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot) +{ + int result = *prot; + + ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade"); + + if (!mac_enforce_fs || !mac_enforce_vm) + return; + + MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label, + &result); + + *prot = result; +} + +int +mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot) +{ + int error; + + ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect"); + + if (!mac_enforce_fs || !mac_enforce_vm) + return (0); + + error = vn_refreshlabel(vp, cred); + if (error) + return (error); + + MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot); + return (error); } int @@ -2337,7 +2380,8 @@ mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, struct vm_map *map) { struct vm_map_entry *vme; - vm_prot_t result, revokeperms; + int result; + vm_prot_t revokeperms; vm_object_t object; vm_ooffset_t offset; struct vnode *vp; @@ -2378,7 +2422,8 @@ mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, continue; vp = (struct vnode *)object->handle; vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); - result = mac_check_vnode_mmap_prot(cred, vp, 0); + result = vme->max_protection; + mac_check_vnode_mmap_downgrade(cred, vp, &result); VOP_UNLOCK(vp, 0, td); /* * Find out what maximum protection we may be allowing diff --git a/sys/security/mac_biba/mac_biba.c b/sys/security/mac_biba/mac_biba.c index b202cdb18f95..b947a1b7e1d9 100644 --- a/sys/security/mac_biba/mac_biba.c +++ b/sys/security/mac_biba/mac_biba.c @@ -1563,6 +1563,34 @@ mac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, return (0); } +static int +mac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp, + struct label *label, int prot) +{ + struct mac_biba *subj, *obj; + + /* + * Rely on the use of open()-time protections to handle + * non-revocation cases. + */ + if (!mac_biba_enabled || !mac_biba_revocation_enabled) + return (0); + + subj = SLOT(&cred->cr_label); + obj = SLOT(label); + + if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { + if (!mac_biba_dominate_single(obj, subj)) + return (EACCES); + } + if (prot & VM_PROT_WRITE) { + if (!mac_biba_dominate_single(subj, obj)) + return (EACCES); + } + + return (0); +} + static int mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp, struct label *vnodelabel, mode_t acc_mode) @@ -1909,26 +1937,6 @@ mac_biba_check_vnode_write(struct ucred *active_cred, return (0); } -static vm_prot_t -mac_biba_check_vnode_mmap_perms(struct ucred *cred, struct vnode *vp, - struct label *label, int newmapping) -{ - struct mac_biba *subj, *obj; - vm_prot_t prot = 0; - - if (!mac_biba_enabled || (!mac_biba_revocation_enabled && !newmapping)) - return (VM_PROT_ALL); - - subj = SLOT(&cred->cr_label); - obj = SLOT(label); - - if (mac_biba_dominate_single(obj, subj)) - prot |= VM_PROT_READ | VM_PROT_EXECUTE; - if (mac_biba_dominate_single(subj, obj)) - prot |= VM_PROT_WRITE; - return (prot); -} - static struct mac_policy_op_entry mac_biba_ops[] = { { MAC_DESTROY, @@ -2129,6 +2137,10 @@ static struct mac_policy_op_entry mac_biba_ops[] = (macop_t)mac_biba_check_vnode_link }, { MAC_CHECK_VNODE_LOOKUP, (macop_t)mac_biba_check_vnode_lookup }, + { MAC_CHECK_VNODE_MMAP, + (macop_t)mac_biba_check_vnode_mmap }, + { MAC_CHECK_VNODE_MPROTECT, + (macop_t)mac_biba_check_vnode_mmap }, { MAC_CHECK_VNODE_OPEN, (macop_t)mac_biba_check_vnode_open }, { MAC_CHECK_VNODE_POLL, @@ -2163,8 +2175,6 @@ static struct mac_policy_op_entry mac_biba_ops[] = (macop_t)mac_biba_check_vnode_stat }, { MAC_CHECK_VNODE_WRITE, (macop_t)mac_biba_check_vnode_write }, - { MAC_CHECK_VNODE_MMAP_PERMS, - (macop_t)mac_biba_check_vnode_mmap_perms }, { MAC_OP_LAST, NULL } }; diff --git a/sys/security/mac_mls/mac_mls.c b/sys/security/mac_mls/mac_mls.c index 0b1e2ef91f5f..7fb2c782f8c4 100644 --- a/sys/security/mac_mls/mac_mls.c +++ b/sys/security/mac_mls/mac_mls.c @@ -1524,6 +1524,34 @@ mac_mls_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, return (0); } +static int +mac_mls_check_vnode_mmap(struct ucred *cred, struct vnode *vp, + struct label *label, int prot) +{ + struct mac_mls *subj, *obj; + + /* + * Rely on the use of open()-time protections to handle + * non-revocation cases. + */ + if (!mac_mls_enabled || !mac_mls_revocation_enabled) + return (0); + + subj = SLOT(&cred->cr_label); + obj = SLOT(label); + + if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { + if (!mac_mls_dominate_single(subj, obj)) + return (EACCES); + } + if (prot & VM_PROT_WRITE) { + if (!mac_mls_dominate_single(obj, subj)) + return (EACCES); + } + + return (0); +} + static int mac_mls_check_vnode_open(struct ucred *cred, struct vnode *vp, struct label *vnodelabel, mode_t acc_mode) @@ -1871,26 +1899,6 @@ mac_mls_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, return (0); } -static vm_prot_t -mac_mls_check_vnode_mmap_perms(struct ucred *cred, struct vnode *vp, - struct label *label, int newmapping) -{ - struct mac_mls *subj, *obj; - vm_prot_t prot = 0; - - if (!mac_mls_enabled || (!mac_mls_revocation_enabled && !newmapping)) - return (VM_PROT_ALL); - - subj = SLOT(&cred->cr_label); - obj = SLOT(label); - - if (mac_mls_dominate_single(subj, obj)) - prot |= VM_PROT_READ | VM_PROT_EXECUTE; - if (mac_mls_dominate_single(obj, subj)) - prot |= VM_PROT_WRITE; - return (prot); -} - static struct mac_policy_op_entry mac_mls_ops[] = { { MAC_DESTROY, @@ -2091,6 +2099,10 @@ static struct mac_policy_op_entry mac_mls_ops[] = (macop_t)mac_mls_check_vnode_link }, { MAC_CHECK_VNODE_LOOKUP, (macop_t)mac_mls_check_vnode_lookup }, + { MAC_CHECK_VNODE_MMAP, + (macop_t)mac_mls_check_vnode_mmap }, + { MAC_CHECK_VNODE_MPROTECT, + (macop_t)mac_mls_check_vnode_mmap }, { MAC_CHECK_VNODE_OPEN, (macop_t)mac_mls_check_vnode_open }, { MAC_CHECK_VNODE_POLL, @@ -2125,8 +2137,6 @@ static struct mac_policy_op_entry mac_mls_ops[] = (macop_t)mac_mls_check_vnode_stat }, { MAC_CHECK_VNODE_WRITE, (macop_t)mac_mls_check_vnode_write }, - { MAC_CHECK_VNODE_MMAP_PERMS, - (macop_t)mac_mls_check_vnode_mmap_perms }, { MAC_OP_LAST, NULL } }; diff --git a/sys/security/mac_none/mac_none.c b/sys/security/mac_none/mac_none.c index 9bbc1cd7fa8b..6456bf7037d3 100644 --- a/sys/security/mac_none/mac_none.c +++ b/sys/security/mac_none/mac_none.c @@ -689,9 +689,25 @@ static int mac_none_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, struct label *dlabel, struct componentname *cnp) { - + return (0); -} +} + +static int +mac_none_check_vnode_mmap(struct ucred *cred, struct vnode *vp, + struct label *label, int prot) +{ + + return (0); +} + +static int +mac_none_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, + struct label *label, int prot) +{ + + return (0); +} static int mac_none_check_vnode_open(struct ucred *cred, struct vnode *vp, @@ -1041,6 +1057,10 @@ static struct mac_policy_op_entry mac_none_ops[] = (macop_t)mac_none_check_vnode_link }, { MAC_CHECK_VNODE_LOOKUP, (macop_t)mac_none_check_vnode_lookup }, + { MAC_CHECK_VNODE_MMAP, + (macop_t)mac_none_check_vnode_mmap }, + { MAC_CHECK_VNODE_MPROTECT, + (macop_t)mac_none_check_vnode_mprotect }, { MAC_CHECK_VNODE_OPEN, (macop_t)mac_none_check_vnode_open }, { MAC_CHECK_VNODE_POLL, diff --git a/sys/security/mac_stub/mac_stub.c b/sys/security/mac_stub/mac_stub.c index 9bbc1cd7fa8b..6456bf7037d3 100644 --- a/sys/security/mac_stub/mac_stub.c +++ b/sys/security/mac_stub/mac_stub.c @@ -689,9 +689,25 @@ static int mac_none_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, struct label *dlabel, struct componentname *cnp) { - + return (0); -} +} + +static int +mac_none_check_vnode_mmap(struct ucred *cred, struct vnode *vp, + struct label *label, int prot) +{ + + return (0); +} + +static int +mac_none_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, + struct label *label, int prot) +{ + + return (0); +} static int mac_none_check_vnode_open(struct ucred *cred, struct vnode *vp, @@ -1041,6 +1057,10 @@ static struct mac_policy_op_entry mac_none_ops[] = (macop_t)mac_none_check_vnode_link }, { MAC_CHECK_VNODE_LOOKUP, (macop_t)mac_none_check_vnode_lookup }, + { MAC_CHECK_VNODE_MMAP, + (macop_t)mac_none_check_vnode_mmap }, + { MAC_CHECK_VNODE_MPROTECT, + (macop_t)mac_none_check_vnode_mprotect }, { MAC_CHECK_VNODE_OPEN, (macop_t)mac_none_check_vnode_open }, { MAC_CHECK_VNODE_POLL, diff --git a/sys/security/mac_test/mac_test.c b/sys/security/mac_test/mac_test.c index c1caa44fc6c5..9b93071802cc 100644 --- a/sys/security/mac_test/mac_test.c +++ b/sys/security/mac_test/mac_test.c @@ -1067,9 +1067,25 @@ static int mac_test_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, struct label *dlabel, struct componentname *cnp) { - + return (0); -} +} + +static int +mac_test_check_vnode_mmap(struct ucred *cred, struct vnode *vp, + struct label *label, int prot) +{ + + return (0); +} + +static int +mac_test_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, + struct label *label, int prot) +{ + + return (0); +} static int mac_test_check_vnode_open(struct ucred *cred, struct vnode *vp, @@ -1417,6 +1433,10 @@ static struct mac_policy_op_entry mac_test_ops[] = (macop_t)mac_test_check_vnode_link }, { MAC_CHECK_VNODE_LOOKUP, (macop_t)mac_test_check_vnode_lookup }, + { MAC_CHECK_VNODE_MMAP, + (macop_t)mac_test_check_vnode_mmap }, + { MAC_CHECK_VNODE_MPROTECT, + (macop_t)mac_test_check_vnode_mprotect }, { MAC_CHECK_VNODE_OPEN, (macop_t)mac_test_check_vnode_open }, { MAC_CHECK_VNODE_POLL, diff --git a/sys/sys/mac.h b/sys/sys/mac.h index fd8b7241b7c3..cd82ef5ffef3 100644 --- a/sys/sys/mac.h +++ b/sys/sys/mac.h @@ -339,9 +339,10 @@ int mac_check_vnode_link(struct ucred *cred, struct vnode *dvp, struct vnode *vp, struct componentname *cnp); int mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, struct componentname *cnp); -/* XXX This u_char should be vm_prot_t! */ -u_char mac_check_vnode_mmap_prot(struct ucred *cred, struct vnode *vp, - int newmapping); +int mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, + int prot); +int mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, + int prot); int mac_check_vnode_open(struct ucred *cred, struct vnode *vp, mode_t acc_mode); int mac_check_vnode_poll(struct ucred *active_cred, diff --git a/sys/sys/mac_policy.h b/sys/sys/mac_policy.h index 51a6d3713a81..5610e01dff11 100644 --- a/sys/sys/mac_policy.h +++ b/sys/sys/mac_policy.h @@ -303,8 +303,12 @@ struct mac_policy_ops { int (*mpo_check_vnode_lookup)(struct ucred *cred, struct vnode *dvp, struct label *dlabel, struct componentname *cnp); - vm_prot_t (*mpo_check_vnode_mmap_perms)(struct ucred *cred, - struct vnode *vp, struct label *label, int newmapping); + int (*mpo_check_vnode_mmap)(struct ucred *cred, struct vnode *vp, + struct label *label, int prot); + void (*mpo_check_vnode_mmap_downgrade)(struct ucred *cred, + struct vnode *vp, struct label *label, int *prot); + int (*mpo_check_vnode_mprotect)(struct ucred *cred, + struct vnode *vp, struct label *label, int prot); int (*mpo_check_vnode_open)(struct ucred *cred, struct vnode *vp, struct label *label, mode_t acc_mode); int (*mpo_check_vnode_poll)(struct ucred *active_cred, @@ -463,7 +467,9 @@ enum mac_op_constant { MAC_CHECK_VNODE_GETEXTATTR, MAC_CHECK_VNODE_LINK, MAC_CHECK_VNODE_LOOKUP, - MAC_CHECK_VNODE_MMAP_PERMS, + MAC_CHECK_VNODE_MMAP, + MAC_CHECK_VNODE_MMAP_DOWNGRADE, + MAC_CHECK_VNODE_MPROTECT, MAC_CHECK_VNODE_OPEN, MAC_CHECK_VNODE_POLL, MAC_CHECK_VNODE_READ,