2893 lines
68 KiB
C
2893 lines
68 KiB
C
![]() |
/*
|
||
|
* Copyright (c) 2007-2016 Apple Inc. All rights reserved.
|
||
|
*
|
||
|
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
|
||
|
*
|
||
|
* This file contains Original Code and/or Modifications of Original Code
|
||
|
* as defined in and that are subject to the Apple Public Source License
|
||
|
* Version 2.0 (the 'License'). You may not use this file except in
|
||
|
* compliance with the License. The rights granted to you under the License
|
||
|
* may not be used to create, or enable the creation or redistribution of,
|
||
|
* unlawful or unlicensed copies of an Apple operating system, or to
|
||
|
* circumvent, violate, or enable the circumvention or violation of, any
|
||
|
* terms of an Apple operating system software license agreement.
|
||
|
*
|
||
|
* Please obtain a copy of the License at
|
||
|
* http://www.opensource.apple.com/apsl/ and read it before using this file.
|
||
|
*
|
||
|
* The Original Code and all software distributed under the License are
|
||
|
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||
|
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||
|
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||
|
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||
|
* Please see the License for the specific language governing rights and
|
||
|
* limitations under the License.
|
||
|
*
|
||
|
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
|
||
|
*/
|
||
|
/*-
|
||
|
* Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
|
||
|
* Copyright (c) 2001 Ilmar S. Habibulin
|
||
|
* Copyright (c) 2001, 2002, 2003, 2004 Networks Associates Technology, Inc.
|
||
|
* Copyright (c) 2005 SPARTA, Inc.
|
||
|
*
|
||
|
* This software was developed by Robert Watson and Ilmar Habibulin for the
|
||
|
* TrustedBSD Project.
|
||
|
*
|
||
|
* This software was developed for the FreeBSD Project in part by Network
|
||
|
* Associates Laboratories, the Security Research Division of Network
|
||
|
* Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
|
||
|
* as part of the DARPA CHATS research program.
|
||
|
*
|
||
|
* Redistribution and use in source and binary forms, with or without
|
||
|
* modification, are permitted provided that the following conditions
|
||
|
* are met:
|
||
|
* 1. Redistributions of source code must retain the above copyright
|
||
|
* notice, this list of conditions and the following disclaimer.
|
||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||
|
* notice, this list of conditions and the following disclaimer in the
|
||
|
* documentation and/or other materials provided with the distribution.
|
||
|
*
|
||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||
|
* SUCH DAMAGE.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#include <kern/kalloc.h>
|
||
|
#include <libkern/OSAtomic.h>
|
||
|
|
||
|
#include <sys/param.h>
|
||
|
#include <sys/systm.h>
|
||
|
#include <sys/kernel.h>
|
||
|
#include <sys/proc.h>
|
||
|
#include <sys/kauth.h>
|
||
|
|
||
|
#include <sys/file_internal.h>
|
||
|
#include <sys/imgact.h>
|
||
|
#include <sys/namei.h>
|
||
|
#include <sys/mount_internal.h>
|
||
|
#include <sys/pipe.h>
|
||
|
#include <sys/posix_sem.h>
|
||
|
#include <sys/posix_shm.h>
|
||
|
#include <sys/reason.h>
|
||
|
#include <sys/uio_internal.h>
|
||
|
#include <sys/vnode_internal.h>
|
||
|
#include <sys/kdebug.h>
|
||
|
|
||
|
|
||
|
#include <miscfs/devfs/devfsdefs.h>
|
||
|
#include <miscfs/devfs/fdesc.h>
|
||
|
|
||
|
#include <security/mac_internal.h>
|
||
|
|
||
|
/* convert {R,W,X}_OK values to V{READ,WRITE,EXEC} */
|
||
|
#define ACCESS_MODE_TO_VNODE_MASK(m) (m << 6)
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Optional tracing of policy operations. Define VFS_TRACE_POLICY_OPS to trace the operations.
|
||
|
*
|
||
|
* Along with DBG_FSYSTEM and DBG_VFS, dcode in the macros below is used to construct
|
||
|
* KDBG_EVENTID(DBG_FSYSTEM, DBG_VFS, dcode) global event id, see bsd/sys/kdebug.h.
|
||
|
* Note that dcode is multiplied by 4 and ORed as part of the construction. See bsd/kern/trace_codes
|
||
|
* for list of system-wide {global event id, name} pairs. Currently DBG_VFS event ids are in range
|
||
|
* [0x3130000, 0x3130188].
|
||
|
*/
|
||
|
|
||
|
//#define VFS_TRACE_POLICY_OPS
|
||
|
|
||
|
#ifdef VFS_TRACE_POLICY_OPS
|
||
|
#define DBG_VFS_CODE(dcode) FSDBG_CODE(DBG_VFS, dcode)
|
||
|
#define VFS_KERNEL_DEBUG_START0(dcode) KERNEL_DEBUG_CONSTANT(DBG_VFS_CODE(dcode) | DBG_FUNC_START, 0, 0, 0, 0, 0)
|
||
|
#define VFS_KERNEL_DEBUG_END0(dcode) KERNEL_DEBUG_CONSTANT(DBG_VFS_CODE(dcode) | DBG_FUNC_END, 0, 0, 0, 0, 0)
|
||
|
#define VFS_KERNEL_DEBUG_START1(dcode, darg) KERNEL_DEBUG_CONSTANT(DBG_VFS_CODE(dcode) | DBG_FUNC_START, darg, 0, 0, 0, 0)
|
||
|
#define VFS_KERNEL_DEBUG_END1(dcode, darg) KERNEL_DEBUG_CONSTANT(DBG_VFS_CODE(dcode) | DBG_FUNC_END, darg, 0, 0, 0, 0)
|
||
|
#else
|
||
|
#define VFS_KERNEL_DEBUG_START0(dcode) do {} while (0)
|
||
|
#define VFS_KERNEL_DEBUG_END0(dcode) do {} while (0)
|
||
|
#define VFS_KERNEL_DEBUG_START1(dcode, darg) do {} while (0)
|
||
|
#define VFS_KERNEL_DEBUG_END1(dcode, darg) do {} while (0)
|
||
|
#endif
|
||
|
|
||
|
void
|
||
|
mac_devfs_label_init(struct devnode *de)
|
||
|
{
|
||
|
mac_labelzone_alloc_owned(&de->dn_label, MAC_WAITOK, ^(struct label *label) {
|
||
|
VFS_KERNEL_DEBUG_START0(0);
|
||
|
MAC_PERFORM(devfs_label_init, label);
|
||
|
VFS_KERNEL_DEBUG_END0(0);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
struct label *
|
||
|
mac_devfs_label(struct devnode *de)
|
||
|
{
|
||
|
return mac_label_verify(&de->dn_label);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
mac_devfs_label_destroy(struct devnode *de)
|
||
|
{
|
||
|
mac_labelzone_free_owned(&de->dn_label, ^(struct label *label) {
|
||
|
VFS_KERNEL_DEBUG_START1(3, label);
|
||
|
MAC_PERFORM(devfs_label_destroy, label);
|
||
|
VFS_KERNEL_DEBUG_END1(3, label);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
void
|
||
|
mac_mount_label_init(struct mount *mp)
|
||
|
{
|
||
|
mac_labelzone_alloc_owned(&mp->mnt_mntlabel, MAC_WAITOK, ^(struct label *label) {
|
||
|
VFS_KERNEL_DEBUG_START0(1);
|
||
|
MAC_PERFORM(mount_label_init, label);
|
||
|
VFS_KERNEL_DEBUG_END0(1);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
struct label *
|
||
|
mac_mount_label(struct mount *mp)
|
||
|
{
|
||
|
return mac_label_verify(&mp->mnt_mntlabel);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
mac_mount_label_destroy(struct mount *mp)
|
||
|
{
|
||
|
mac_labelzone_free_owned(&mp->mnt_mntlabel, ^(struct label *label) {
|
||
|
VFS_KERNEL_DEBUG_START1(4, label);
|
||
|
MAC_PERFORM(mount_label_destroy, label);
|
||
|
VFS_KERNEL_DEBUG_END1(4, label);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
struct label *
|
||
|
mac_vnode_label_alloc(vnode_t vp)
|
||
|
{
|
||
|
return mac_labelzone_alloc_for_owner(vp ? &vp->v_label : NULL, MAC_WAITOK, ^(struct label *label) {
|
||
|
VFS_KERNEL_DEBUG_START0(2);
|
||
|
MAC_PERFORM(vnode_label_init, label);
|
||
|
VFS_KERNEL_DEBUG_END0(2);
|
||
|
OSIncrementAtomic(&mac_vnode_label_count);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
void
|
||
|
mac_vnode_label_init(vnode_t vp)
|
||
|
{
|
||
|
struct label *label;
|
||
|
|
||
|
label = mac_vnode_label_alloc(vp);
|
||
|
vp->v_label = label;
|
||
|
}
|
||
|
|
||
|
struct label *
|
||
|
mac_vnode_label(vnode_t vp)
|
||
|
{
|
||
|
return mac_label_verify(&vp->v_label);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
mac_vnode_label_cleanup(struct label *label)
|
||
|
{
|
||
|
VFS_KERNEL_DEBUG_START1(5, label);
|
||
|
MAC_PERFORM(vnode_label_destroy, label);
|
||
|
VFS_KERNEL_DEBUG_END1(5, label);
|
||
|
OSDecrementAtomic(&mac_vnode_label_count);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
mac_vnode_label_free(struct label *label)
|
||
|
{
|
||
|
if (label != NULL) {
|
||
|
mac_vnode_label_cleanup(label);
|
||
|
mac_labelzone_free(label);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void
|
||
|
mac_vnode_label_destroy(struct vnode *vp)
|
||
|
{
|
||
|
mac_labelzone_free_owned(&vp->v_label, ^(struct label *label) {
|
||
|
mac_vnode_label_cleanup(label);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_label_init_needed(vnode_t vp)
|
||
|
{
|
||
|
#if CONFIG_MACF_LAZY_VNODE_LABELS
|
||
|
(void)vp;
|
||
|
return false;
|
||
|
#else
|
||
|
return mac_label_vnodes != 0 && mac_vnode_label(vp) == NULL;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
struct label *
|
||
|
mac_vnode_label_allocate(vnode_t vp)
|
||
|
{
|
||
|
if (mac_vnode_label_init_needed(vp)) {
|
||
|
mac_vnode_label_init(vp);
|
||
|
}
|
||
|
return mac_vnode_label(vp);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* vnode labels are allocated at the same time as vnodes, but vnodes are never
|
||
|
* freed. Instead, we want to remove any sensitive information before putting
|
||
|
* them on the free list for reuse.
|
||
|
*/
|
||
|
void
|
||
|
mac_vnode_label_recycle(vnode_t vp)
|
||
|
{
|
||
|
struct label *v_label = mac_vnode_label(vp);
|
||
|
|
||
|
MAC_PERFORM(vnode_label_recycle, v_label);
|
||
|
#if CONFIG_MACF_LAZY_VNODE_LABELS
|
||
|
if (v_label) {
|
||
|
mac_vnode_label_destroy(vp);
|
||
|
vp->v_lflag &= ~VL_LABELED;
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void
|
||
|
mac_vnode_label_copy(struct label *src, struct label *dest)
|
||
|
{
|
||
|
VFS_KERNEL_DEBUG_START1(6, src);
|
||
|
if (src == NULL) {
|
||
|
MAC_PERFORM(vnode_label_init, dest);
|
||
|
} else {
|
||
|
MAC_PERFORM(vnode_label_copy, src, dest);
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_END1(6, src);
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_label_externalize_audit(struct vnode *vp, struct mac *mac)
|
||
|
{
|
||
|
int error;
|
||
|
|
||
|
/* It is assumed that any necessary vnode locking is done on entry */
|
||
|
error = MAC_EXTERNALIZE_AUDIT(vnode, mac_vnode_label(vp),
|
||
|
mac->m_string, mac->m_buflen);
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_label_externalize(struct label *label, char *elements,
|
||
|
char *outbuf, size_t outbuflen, int flags __unused)
|
||
|
{
|
||
|
int error;
|
||
|
|
||
|
error = MAC_EXTERNALIZE(vnode, label, elements, outbuf, outbuflen);
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_label_internalize(struct label *label, char *string)
|
||
|
{
|
||
|
int error;
|
||
|
|
||
|
error = MAC_INTERNALIZE(vnode, label, string);
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_mount_label_internalize(struct label *label, char *string)
|
||
|
{
|
||
|
int error;
|
||
|
|
||
|
error = MAC_INTERNALIZE(mount, label, string);
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_mount_label_externalize(struct label *label, char *elements,
|
||
|
char *outbuf, size_t outbuflen)
|
||
|
{
|
||
|
int error;
|
||
|
|
||
|
error = MAC_EXTERNALIZE(mount, label, elements, outbuf, outbuflen);
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
mac_devfs_label_copy(struct label *src, struct label *dest)
|
||
|
{
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_device_enforce) {
|
||
|
return;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
VFS_KERNEL_DEBUG_START1(7, src);
|
||
|
MAC_PERFORM(devfs_label_copy, src, dest);
|
||
|
VFS_KERNEL_DEBUG_END1(7, src);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
mac_devfs_label_update(struct mount *mp, struct devnode *de,
|
||
|
struct vnode *vp)
|
||
|
{
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_device_enforce) {
|
||
|
return;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
VFS_KERNEL_DEBUG_START1(8, vp);
|
||
|
MAC_PERFORM(devfs_label_update, mp, de, mac_devfs_label(de), vp,
|
||
|
mac_vnode_label(vp));
|
||
|
VFS_KERNEL_DEBUG_END1(8, vp);
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_label_associate(struct mount *mp, struct vnode *vp, vfs_context_t ctx)
|
||
|
{
|
||
|
struct devnode *dnp;
|
||
|
struct fdescnode *fnp;
|
||
|
int error = 0;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return error;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/* XXX: should not inspect v_tag in kernel! */
|
||
|
switch (vp->v_tag) {
|
||
|
case VT_DEVFS:
|
||
|
dnp = VTODN(vp);
|
||
|
mac_vnode_label_associate_devfs(mp, dnp, vp);
|
||
|
break;
|
||
|
case VT_FDESC:
|
||
|
fnp = VTOFDESC(vp);
|
||
|
error = mac_vnode_label_associate_fdesc(mp, fnp, vp, ctx);
|
||
|
break;
|
||
|
default:
|
||
|
error = mac_vnode_label_associate_extattr(mp, vp);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
mac_vnode_label_associate_devfs(struct mount *mp, struct devnode *de,
|
||
|
struct vnode *vp)
|
||
|
{
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_device_enforce) {
|
||
|
return;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
VFS_KERNEL_DEBUG_START1(9, vp);
|
||
|
MAC_PERFORM(vnode_label_associate_devfs,
|
||
|
mp, mp ? mac_mount_label(mp) : NULL,
|
||
|
de, mac_devfs_label(de),
|
||
|
vp, mac_vnode_label(vp));
|
||
|
VFS_KERNEL_DEBUG_END1(9, vp);
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_label_associate_extattr(struct mount *mp, struct vnode *vp)
|
||
|
{
|
||
|
int error;
|
||
|
|
||
|
VFS_KERNEL_DEBUG_START1(10, vp);
|
||
|
MAC_CHECK(vnode_label_associate_extattr, mp, mac_mount_label(mp), vp,
|
||
|
mac_vnode_label(vp));
|
||
|
VFS_KERNEL_DEBUG_END1(10, vp);
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
mac_vnode_label_associate_singlelabel(struct mount *mp, struct vnode *vp)
|
||
|
{
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return;
|
||
|
}
|
||
|
#endif
|
||
|
if (!mac_label_vnodes) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
VFS_KERNEL_DEBUG_START1(11, vp);
|
||
|
MAC_PERFORM(vnode_label_associate_singlelabel, mp,
|
||
|
mp ? mac_mount_label(mp) : NULL, vp, mac_vnode_label(vp));
|
||
|
VFS_KERNEL_DEBUG_END1(11, vp);
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_notify_create(vfs_context_t ctx, struct mount *mp,
|
||
|
struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(12, vp);
|
||
|
MAC_CHECK(vnode_notify_create, cred, mp, mac_mount_label(mp),
|
||
|
dvp, mac_vnode_label(dvp), vp, mac_vnode_label(vp), cnp);
|
||
|
VFS_KERNEL_DEBUG_END1(12, vp);
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
mac_vnode_notify_rename(vfs_context_t ctx, struct vnode *fvp,
|
||
|
struct vnode *fdvp, struct componentname *fcnp, struct vnode *tvp,
|
||
|
struct vnode *tdvp, struct componentname *tcnp, bool swap)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
VFS_KERNEL_DEBUG_START1(13, fvp);
|
||
|
MAC_POLICY_ITERATE({
|
||
|
/* BEGIN IGNORE CODESTYLE */
|
||
|
if (swap) {
|
||
|
if (mpc->mpc_ops->mpo_vnode_notify_swap != NULL) {
|
||
|
MAC_PERFORM_CALL(vnode_notify_swap, mpc);
|
||
|
mpc->mpc_ops->mpo_vnode_notify_swap(cred, fvp, mac_vnode_label(fvp),
|
||
|
tvp, mac_vnode_label(tvp));
|
||
|
MAC_PERFORM_RSLT(vnode_notify_swap, mpc);
|
||
|
} else if (mpc->mpc_ops->mpo_vnode_notify_rename != NULL) {
|
||
|
MAC_PERFORM_CALL(vnode_notify_swap_rename, mpc);
|
||
|
/* Call notify_rename twice, one for each member of the swap. */
|
||
|
mpc->mpc_ops->mpo_vnode_notify_rename(cred, fvp, mac_vnode_label(fvp),
|
||
|
tdvp, mac_vnode_label(tdvp), tcnp);
|
||
|
mpc->mpc_ops->mpo_vnode_notify_rename(cred, tvp, mac_vnode_label(tvp),
|
||
|
fdvp, mac_vnode_label(fdvp), fcnp);
|
||
|
MAC_PERFORM_RSLT(vnode_notify_swap_rename, mpc);
|
||
|
}
|
||
|
} else if (mpc->mpc_ops->mpo_vnode_notify_rename != NULL) {
|
||
|
MAC_PERFORM_CALL(vnode_notify_rename, mpc);
|
||
|
mpc->mpc_ops->mpo_vnode_notify_rename(cred, fvp, mac_vnode_label(fvp),
|
||
|
tdvp, mac_vnode_label(tdvp), tcnp);
|
||
|
MAC_PERFORM_RSLT(vnode_notify_rename, mpc);
|
||
|
}
|
||
|
/* END IGNORE CODESTYLE */
|
||
|
});
|
||
|
VFS_KERNEL_DEBUG_END1(13, fvp);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
mac_vnode_notify_open(vfs_context_t ctx, struct vnode *vp, int acc_flags)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(14, vp);
|
||
|
MAC_PERFORM(vnode_notify_open, cred, vp, mac_vnode_label(vp), acc_flags);
|
||
|
VFS_KERNEL_DEBUG_END1(14, vp);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
mac_vnode_notify_link(vfs_context_t ctx, struct vnode *vp,
|
||
|
struct vnode *dvp, struct componentname *cnp)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(15, vp);
|
||
|
MAC_PERFORM(vnode_notify_link, cred, dvp, mac_vnode_label(dvp), vp, mac_vnode_label(vp), cnp);
|
||
|
VFS_KERNEL_DEBUG_END1(15, vp);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
mac_vnode_notify_deleteextattr(vfs_context_t ctx, struct vnode *vp, const char *name)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(16, vp);
|
||
|
MAC_PERFORM(vnode_notify_deleteextattr, cred, vp, mac_vnode_label(vp), name);
|
||
|
VFS_KERNEL_DEBUG_END1(16, vp);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
mac_vnode_notify_setacl(vfs_context_t ctx, struct vnode *vp, struct kauth_acl *acl)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(17, vp);
|
||
|
MAC_PERFORM(vnode_notify_setacl, cred, vp, mac_vnode_label(vp), acl);
|
||
|
VFS_KERNEL_DEBUG_END1(17, vp);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
mac_vnode_notify_setattrlist(vfs_context_t ctx, struct vnode *vp, struct attrlist *alist)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(18, vp);
|
||
|
MAC_PERFORM(vnode_notify_setattrlist, cred, vp, mac_vnode_label(vp), alist);
|
||
|
VFS_KERNEL_DEBUG_END1(18, vp);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
mac_vnode_notify_setextattr(vfs_context_t ctx, struct vnode *vp, const char *name, struct uio *uio)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(19, vp);
|
||
|
MAC_PERFORM(vnode_notify_setextattr, cred, vp, mac_vnode_label(vp), name, uio);
|
||
|
VFS_KERNEL_DEBUG_END1(19, vp);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
mac_vnode_notify_setflags(vfs_context_t ctx, struct vnode *vp, u_long flags)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(20, vp);
|
||
|
MAC_PERFORM(vnode_notify_setflags, cred, vp, mac_vnode_label(vp), flags);
|
||
|
VFS_KERNEL_DEBUG_END1(20, vp);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
mac_vnode_notify_setmode(vfs_context_t ctx, struct vnode *vp, mode_t mode)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(21, vp);
|
||
|
MAC_PERFORM(vnode_notify_setmode, cred, vp, mac_vnode_label(vp), mode);
|
||
|
VFS_KERNEL_DEBUG_END1(21, vp);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
mac_vnode_notify_setowner(vfs_context_t ctx, struct vnode *vp, uid_t uid, gid_t gid)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(22, vp);
|
||
|
MAC_PERFORM(vnode_notify_setowner, cred, vp, mac_vnode_label(vp), uid, gid);
|
||
|
VFS_KERNEL_DEBUG_END1(22, vp);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
mac_vnode_notify_setutimes(vfs_context_t ctx, struct vnode *vp, struct timespec atime, struct timespec mtime)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(23, vp);
|
||
|
MAC_PERFORM(vnode_notify_setutimes, cred, vp, mac_vnode_label(vp), atime, mtime);
|
||
|
VFS_KERNEL_DEBUG_END1(23, vp);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
mac_vnode_notify_truncate(vfs_context_t ctx, kauth_cred_t file_cred, struct vnode *vp)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(24, vp);
|
||
|
MAC_PERFORM(vnode_notify_truncate, cred, file_cred, vp, mac_vnode_label(vp));
|
||
|
VFS_KERNEL_DEBUG_END1(24, vp);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Extended attribute 'name' was updated via
|
||
|
* vn_setxattr() or vn_removexattr(). Allow the
|
||
|
* policy to update the vnode label.
|
||
|
*/
|
||
|
void
|
||
|
mac_vnode_label_update_extattr(struct mount *mp, struct vnode *vp,
|
||
|
const char *name)
|
||
|
{
|
||
|
int error = 0;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return;
|
||
|
}
|
||
|
#endif
|
||
|
if (!mac_label_vnodes) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
VFS_KERNEL_DEBUG_START1(25, vp);
|
||
|
MAC_PERFORM(vnode_label_update_extattr, mp, mac_mount_label(mp), vp,
|
||
|
mac_vnode_label(vp), name);
|
||
|
VFS_KERNEL_DEBUG_END1(25, vp);
|
||
|
if (error == 0) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
vnode_lock(vp);
|
||
|
vnode_relabel(vp);
|
||
|
vnode_unlock(vp);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
static int
|
||
|
mac_vnode_label_store(vfs_context_t ctx, struct vnode *vp,
|
||
|
struct label *intlabel)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
if (!mac_label_vnodes) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(26, vp);
|
||
|
MAC_CHECK(vnode_label_store, cred, vp, mac_vnode_label(vp), intlabel);
|
||
|
VFS_KERNEL_DEBUG_END1(26, vp);
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
mac_cred_label_update_execve(vfs_context_t ctx, kauth_cred_t new, struct vnode *vp, off_t offset,
|
||
|
struct vnode *scriptvp, struct label *scriptvnodelabel, struct label *execl, u_int *csflags,
|
||
|
void *macextensions, int *disjoint, int *labelupdateerror)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
*disjoint = 0;
|
||
|
int error;
|
||
|
posix_cred_t pcred = posix_cred_get(new);
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_proc_enforce || !mac_vnode_enforce) {
|
||
|
return;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/* mark the new cred to indicate "matching" includes the label */
|
||
|
pcred->cr_flags |= CRF_MAC_ENFORCE;
|
||
|
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
|
||
|
/*
|
||
|
* NB: Cannot use MAC_CHECK macro because we need a sequence point after
|
||
|
* calling exec_spawnattr_getmacpolicyinfo() and before passing the
|
||
|
* spawnattrlen as an argument to the hook.
|
||
|
*/
|
||
|
VFS_KERNEL_DEBUG_START1(27, vp);
|
||
|
{
|
||
|
struct mac_policy_conf *mpc;
|
||
|
u_int i;
|
||
|
|
||
|
error = 0;
|
||
|
for (i = 0; i < mac_policy_list.staticmax; i++) {
|
||
|
mpc = mac_policy_list.entries[i].mpc;
|
||
|
if (mpc == NULL) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
mpo_cred_label_update_execve_t *hook = mpc->mpc_ops->mpo_cred_label_update_execve;
|
||
|
if (hook == NULL) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
size_t spawnattrlen = 0;
|
||
|
void *spawnattr = exec_spawnattr_getmacpolicyinfo(macextensions, mpc->mpc_name, &spawnattrlen);
|
||
|
|
||
|
error = mac_error_select(hook(cred, new, vfs_context_proc(ctx), vp, offset, scriptvp,
|
||
|
mac_vnode_label(vp), scriptvnodelabel, execl, csflags, spawnattr, spawnattrlen, disjoint),
|
||
|
error);
|
||
|
}
|
||
|
if (mac_policy_list_conditional_busy() != 0) {
|
||
|
for (; i <= mac_policy_list.maxindex; i++) {
|
||
|
mpc = mac_policy_list.entries[i].mpc;
|
||
|
if (mpc == NULL) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
mpo_cred_label_update_execve_t *hook = mpc->mpc_ops->mpo_cred_label_update_execve;
|
||
|
if (hook == NULL) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
size_t spawnattrlen = 0;
|
||
|
void *spawnattr = exec_spawnattr_getmacpolicyinfo(macextensions, mpc->mpc_name, &spawnattrlen);
|
||
|
|
||
|
error = mac_error_select(hook(cred, new, vfs_context_proc(ctx), vp, offset, scriptvp,
|
||
|
mac_vnode_label(vp), scriptvnodelabel, execl, csflags, spawnattr, spawnattrlen, disjoint),
|
||
|
error);
|
||
|
}
|
||
|
mac_policy_list_unbusy();
|
||
|
}
|
||
|
}
|
||
|
*labelupdateerror = error;
|
||
|
VFS_KERNEL_DEBUG_END1(27, vp);
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_cred_check_label_update_execve(vfs_context_t ctx, struct vnode *vp, off_t offset,
|
||
|
struct vnode *scriptvp, struct label *scriptvnodelabel, struct label *execlabel,
|
||
|
struct proc *p, void *macextensions)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int result = 0;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_proc_enforce || !mac_vnode_enforce) {
|
||
|
return result;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
|
||
|
VFS_KERNEL_DEBUG_START1(28, vp);
|
||
|
/*
|
||
|
* NB: Cannot use MAC_BOOLEAN macro because we need a sequence point after
|
||
|
* calling exec_spawnattr_getmacpolicyinfo() and before passing the
|
||
|
* spawnattrlen as an argument to the hook.
|
||
|
*/
|
||
|
{
|
||
|
struct mac_policy_conf *mpc;
|
||
|
u_int i;
|
||
|
|
||
|
for (i = 0; i < mac_policy_list.staticmax; i++) {
|
||
|
mpc = mac_policy_list.entries[i].mpc;
|
||
|
if (mpc == NULL) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
mpo_cred_check_label_update_execve_t *hook = mpc->mpc_ops->mpo_cred_check_label_update_execve;
|
||
|
if (hook == NULL) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
size_t spawnattrlen = 0;
|
||
|
void *spawnattr = exec_spawnattr_getmacpolicyinfo(macextensions, mpc->mpc_name, &spawnattrlen);
|
||
|
|
||
|
result = result || hook(cred, vp, offset, scriptvp, mac_vnode_label(vp), scriptvnodelabel, execlabel, p, spawnattr, spawnattrlen);
|
||
|
}
|
||
|
if (mac_policy_list_conditional_busy() != 0) {
|
||
|
for (; i <= mac_policy_list.maxindex; i++) {
|
||
|
mpc = mac_policy_list.entries[i].mpc;
|
||
|
if (mpc == NULL) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
mpo_cred_check_label_update_execve_t *hook = mpc->mpc_ops->mpo_cred_check_label_update_execve;
|
||
|
if (hook == NULL) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
size_t spawnattrlen = 0;
|
||
|
void *spawnattr = exec_spawnattr_getmacpolicyinfo(macextensions, mpc->mpc_name, &spawnattrlen);
|
||
|
|
||
|
result = result || hook(cred, vp, offset, scriptvp, mac_vnode_label(vp), scriptvnodelabel, execlabel, p, spawnattr, spawnattrlen);
|
||
|
}
|
||
|
mac_policy_list_unbusy();
|
||
|
}
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_END1(28, vp);
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_access(vfs_context_t ctx, struct vnode *vp,
|
||
|
int acc_mode)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
int mask;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
/* Convert {R,W,X}_OK values to V{READ,WRITE,EXEC} for entry points */
|
||
|
mask = ACCESS_MODE_TO_VNODE_MASK(acc_mode);
|
||
|
VFS_KERNEL_DEBUG_START1(29, vp);
|
||
|
MAC_CHECK(vnode_check_access, cred, vp, mac_vnode_label(vp), mask);
|
||
|
VFS_KERNEL_DEBUG_END1(29, vp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_chdir(vfs_context_t ctx, struct vnode *dvp)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(30, dvp);
|
||
|
MAC_CHECK(vnode_check_chdir, cred, dvp, mac_vnode_label(dvp));
|
||
|
VFS_KERNEL_DEBUG_END1(30, dvp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_chroot(vfs_context_t ctx, struct vnode *dvp,
|
||
|
struct componentname *cnp)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(31, dvp);
|
||
|
MAC_CHECK(vnode_check_chroot, cred, dvp, mac_vnode_label(dvp), cnp);
|
||
|
VFS_KERNEL_DEBUG_END1(31, dvp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_clone(vfs_context_t ctx, struct vnode *dvp,
|
||
|
struct vnode *vp, struct componentname *cnp)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(32, dvp);
|
||
|
MAC_CHECK(vnode_check_clone, cred, dvp, mac_vnode_label(dvp), vp,
|
||
|
mac_vnode_label(vp), cnp);
|
||
|
VFS_KERNEL_DEBUG_END1(32, dvp);
|
||
|
return error;
|
||
|
}
|
||
|
int
|
||
|
mac_vnode_check_create(vfs_context_t ctx, struct vnode *dvp,
|
||
|
struct componentname *cnp, struct vnode_attr *vap)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(33, dvp);
|
||
|
MAC_CHECK(vnode_check_create, cred, dvp, mac_vnode_label(dvp), cnp, vap);
|
||
|
VFS_KERNEL_DEBUG_END1(33, dvp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_unlink(vfs_context_t ctx, struct vnode *dvp, struct vnode *vp,
|
||
|
struct componentname *cnp)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(34, dvp);
|
||
|
MAC_CHECK(vnode_check_unlink, cred, dvp, mac_vnode_label(dvp), vp,
|
||
|
mac_vnode_label(vp), cnp);
|
||
|
VFS_KERNEL_DEBUG_END1(34, dvp);
|
||
|
return error;
|
||
|
}
|
||
|
#if 0
|
||
|
int
|
||
|
mac_vnode_check_deleteacl(vfs_context_t ctx, struct vnode *vp,
|
||
|
acl_type_t type)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(35, dvp);
|
||
|
MAC_CHECK(vnode_check_deleteacl, cred, vp, mac_vnode_label(vp), type);
|
||
|
VFS_KERNEL_DEBUG_END1(35, dvp);
|
||
|
return error;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_deleteextattr(vfs_context_t ctx, struct vnode *vp,
|
||
|
const char *name)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(36, vp);
|
||
|
MAC_CHECK(vnode_check_deleteextattr, cred, vp, mac_vnode_label(vp), name);
|
||
|
VFS_KERNEL_DEBUG_END1(36, vp);
|
||
|
return error;
|
||
|
}
|
||
|
int
|
||
|
mac_vnode_check_exchangedata(vfs_context_t ctx,
|
||
|
struct vnode *v1, struct vnode *v2)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(37, v1);
|
||
|
MAC_CHECK(vnode_check_exchangedata, cred, v1, mac_vnode_label(v1),
|
||
|
v2, mac_vnode_label(v2));
|
||
|
VFS_KERNEL_DEBUG_END1(37, v1);
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
#if 0
|
||
|
int
|
||
|
mac_vnode_check_getacl(vfs_context_t ctx, struct vnode *vp, acl_type_t type)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(38, vp);
|
||
|
MAC_CHECK(vnode_check_getacl, cred, vp, mac_vnode_label(vp), type);
|
||
|
VFS_KERNEL_DEBUG_END1(38, vp);
|
||
|
return error;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_getattr(vfs_context_t ctx, struct ucred *file_cred,
|
||
|
struct vnode *vp, struct vnode_attr *va)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(39, vp);
|
||
|
MAC_CHECK(vnode_check_getattr, cred, file_cred, vp, mac_vnode_label(vp), va);
|
||
|
VFS_KERNEL_DEBUG_END1(39, vp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_getattrlist(vfs_context_t ctx, struct vnode *vp,
|
||
|
struct attrlist *alist, uint64_t options)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(40, vp);
|
||
|
MAC_CHECK(vnode_check_getattrlist, cred, vp, mac_vnode_label(vp), alist, options);
|
||
|
VFS_KERNEL_DEBUG_END1(40, vp);
|
||
|
|
||
|
/* Falsify results instead of returning error? */
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_exec(vfs_context_t ctx, struct vnode *vp,
|
||
|
struct image_params *imgp)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error = 0;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_proc_enforce || !mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
|
||
|
/*
|
||
|
* NB: Cannot use MAC_CHECK macro because we need a sequence point after
|
||
|
* calling exec_spawnattr_getmacpolicyinfo() and before passing the
|
||
|
* spawnattrlen as an argument to the hook.
|
||
|
*/
|
||
|
VFS_KERNEL_DEBUG_START1(41, vp);
|
||
|
{
|
||
|
struct mac_policy_conf *mpc;
|
||
|
u_int i;
|
||
|
|
||
|
for (i = 0; i < mac_policy_list.staticmax; i++) {
|
||
|
mpc = mac_policy_list.entries[i].mpc;
|
||
|
if (mpc == NULL) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
mpo_vnode_check_exec_t *hook = mpc->mpc_ops->mpo_vnode_check_exec;
|
||
|
if (hook == NULL) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
size_t spawnattrlen = 0;
|
||
|
void *spawnattr = exec_spawnattr_getmacpolicyinfo(&imgp->ip_px_smpx, mpc->mpc_name, &spawnattrlen);
|
||
|
|
||
|
error = mac_error_select(
|
||
|
hook(cred,
|
||
|
vp, imgp->ip_scriptvp, mac_vnode_label(vp), imgp->ip_scriptlabelp,
|
||
|
imgp->ip_execlabelp, &imgp->ip_ndp->ni_cnd, &imgp->ip_csflags,
|
||
|
spawnattr, spawnattrlen), error);
|
||
|
}
|
||
|
if (mac_policy_list_conditional_busy() != 0) {
|
||
|
for (; i <= mac_policy_list.maxindex; i++) {
|
||
|
mpc = mac_policy_list.entries[i].mpc;
|
||
|
if (mpc == NULL) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
mpo_vnode_check_exec_t *hook = mpc->mpc_ops->mpo_vnode_check_exec;
|
||
|
if (hook == NULL) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
size_t spawnattrlen = 0;
|
||
|
void *spawnattr = exec_spawnattr_getmacpolicyinfo(&imgp->ip_px_smpx, mpc->mpc_name, &spawnattrlen);
|
||
|
|
||
|
error = mac_error_select(
|
||
|
hook(cred,
|
||
|
vp, imgp->ip_scriptvp, mac_vnode_label(vp), imgp->ip_scriptlabelp,
|
||
|
imgp->ip_execlabelp, &imgp->ip_ndp->ni_cnd, &imgp->ip_csflags,
|
||
|
spawnattr, spawnattrlen), error);
|
||
|
}
|
||
|
mac_policy_list_unbusy();
|
||
|
}
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_END1(41, vp);
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_fsgetpath(vfs_context_t ctx, struct vnode *vp)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(42, vp);
|
||
|
MAC_CHECK(vnode_check_fsgetpath, cred, vp, mac_vnode_label(vp));
|
||
|
VFS_KERNEL_DEBUG_END1(42, vp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_signature(struct vnode *vp, struct cs_blob *cs_blob,
|
||
|
struct image_params *imgp,
|
||
|
unsigned int *cs_flags, unsigned int *signer_type,
|
||
|
int flags, unsigned int platform)
|
||
|
{
|
||
|
int error;
|
||
|
char *fatal_failure_desc = NULL;
|
||
|
size_t fatal_failure_desc_len = 0;
|
||
|
|
||
|
char *vn_path = NULL;
|
||
|
vm_size_t vn_pathlen = MAXPATHLEN;
|
||
|
cpu_type_t cpu_type = (imgp == NULL) ? CPU_TYPE_ANY : imgp->ip_origcputype;
|
||
|
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_proc_enforce || !mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
VFS_KERNEL_DEBUG_START1(43, vp);
|
||
|
MAC_CHECK(vnode_check_signature, vp, mac_vnode_label(vp), cpu_type, cs_blob,
|
||
|
cs_flags, signer_type, flags, platform, &fatal_failure_desc, &fatal_failure_desc_len);
|
||
|
VFS_KERNEL_DEBUG_END1(43, vp);
|
||
|
|
||
|
if (fatal_failure_desc_len) {
|
||
|
// A fatal code signature validation failure occured, formulate a crash
|
||
|
// reason.
|
||
|
|
||
|
char const *path = NULL;
|
||
|
|
||
|
vn_path = zalloc(ZV_NAMEI);
|
||
|
if (vn_getpath(vp, vn_path, (int*)&vn_pathlen) == 0) {
|
||
|
path = vn_path;
|
||
|
} else {
|
||
|
path = "(get vnode path failed)";
|
||
|
}
|
||
|
|
||
|
if (error == 0) {
|
||
|
panic("mac_vnode_check_signature: MAC hook returned no error, "
|
||
|
"but status is claimed to be fatal? "
|
||
|
"path: '%s', fatal_failure_desc_len: %ld, fatal_failure_desc:\n%s\n",
|
||
|
path, fatal_failure_desc_len, fatal_failure_desc);
|
||
|
}
|
||
|
|
||
|
printf("mac_vnode_check_signature: %s: code signature validation failed fatally: %s",
|
||
|
path, fatal_failure_desc);
|
||
|
|
||
|
if (imgp == NULL) {
|
||
|
goto out;
|
||
|
}
|
||
|
|
||
|
os_reason_t reason = os_reason_create(OS_REASON_CODESIGNING,
|
||
|
CODESIGNING_EXIT_REASON_TASKGATED_INVALID_SIG);
|
||
|
|
||
|
if (reason == OS_REASON_NULL) {
|
||
|
printf("mac_vnode_check_signature: %s: failure to allocate exit reason for validation failure: %s\n",
|
||
|
path, fatal_failure_desc);
|
||
|
goto out;
|
||
|
}
|
||
|
|
||
|
imgp->ip_cs_error = reason;
|
||
|
reason->osr_flags = (OS_REASON_FLAG_GENERATE_CRASH_REPORT |
|
||
|
OS_REASON_FLAG_CONSISTENT_FAILURE);
|
||
|
|
||
|
if (fatal_failure_desc == NULL) {
|
||
|
// This may happen if allocation for the buffer failed.
|
||
|
printf("mac_vnode_check_signature: %s: fatal failure is missing its description.\n", path);
|
||
|
} else {
|
||
|
mach_vm_address_t data_addr = 0;
|
||
|
|
||
|
int reason_error = 0;
|
||
|
int kcdata_error = 0;
|
||
|
|
||
|
if ((reason_error = os_reason_alloc_buffer_noblock(reason, kcdata_estimate_required_buffer_size
|
||
|
(1, (uint32_t)fatal_failure_desc_len))) == 0 &&
|
||
|
(kcdata_error = kcdata_get_memory_addr(&reason->osr_kcd_descriptor,
|
||
|
EXIT_REASON_USER_DESC, (uint32_t)fatal_failure_desc_len,
|
||
|
&data_addr)) == KERN_SUCCESS) {
|
||
|
kern_return_t mc_error = kcdata_memcpy(&reason->osr_kcd_descriptor, (mach_vm_address_t)data_addr,
|
||
|
fatal_failure_desc, (uint32_t)fatal_failure_desc_len);
|
||
|
|
||
|
if (mc_error != KERN_SUCCESS) {
|
||
|
printf("mac_vnode_check_signature: %s: failed to copy reason string "
|
||
|
"(kcdata_memcpy error: %d, length: %ld)\n",
|
||
|
path, mc_error, fatal_failure_desc_len);
|
||
|
}
|
||
|
} else {
|
||
|
printf("mac_vnode_check_signature: %s: failed to allocate space for reason string "
|
||
|
"(os_reason_alloc_buffer error: %d, kcdata error: %d, length: %ld)\n",
|
||
|
path, reason_error, kcdata_error, fatal_failure_desc_len);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
out:
|
||
|
if (vn_path) {
|
||
|
zfree(ZV_NAMEI, vn_path);
|
||
|
}
|
||
|
|
||
|
if (fatal_failure_desc_len > 0 && fatal_failure_desc != NULL) {
|
||
|
/* KERN_AMFI_SUPPORTS_DATA_ALLOC >= 2 */
|
||
|
kfree_data(fatal_failure_desc, fatal_failure_desc_len);
|
||
|
}
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_supplemental_signature(struct vnode *vp,
|
||
|
struct cs_blob *cs_blob, struct vnode *linked_vp,
|
||
|
struct cs_blob *linked_cs_blob, unsigned int *signer_type)
|
||
|
{
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_proc_enforce || !mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
VFS_KERNEL_DEBUG_START1(93, vp);
|
||
|
MAC_CHECK(vnode_check_supplemental_signature, vp, mac_vnode_label(vp), cs_blob, linked_vp, linked_cs_blob,
|
||
|
signer_type);
|
||
|
VFS_KERNEL_DEBUG_END1(93, vp);
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
#if 0
|
||
|
int
|
||
|
mac_vnode_check_getacl(vfs_context_t ctx, struct vnode *vp, acl_type_t type)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(44, vp);
|
||
|
MAC_CHECK(vnode_check_getacl, cred, vp, mac_vnode_label(vp), type);
|
||
|
VFS_KERNEL_DEBUG_END1(44, vp);
|
||
|
return error;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_getextattr(vfs_context_t ctx, struct vnode *vp,
|
||
|
const char *name, struct uio *uio)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(45, vp);
|
||
|
MAC_CHECK(vnode_check_getextattr, cred, vp, mac_vnode_label(vp),
|
||
|
name, uio);
|
||
|
VFS_KERNEL_DEBUG_END1(45, vp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_ioctl(vfs_context_t ctx, struct vnode *vp, u_long cmd)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(46, vp);
|
||
|
MAC_CHECK(vnode_check_ioctl, cred, vp, mac_vnode_label(vp), cmd);
|
||
|
VFS_KERNEL_DEBUG_END1(46, vp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_kqfilter(vfs_context_t ctx, kauth_cred_t file_cred,
|
||
|
struct knote *kn, struct vnode *vp)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(47, vp);
|
||
|
MAC_CHECK(vnode_check_kqfilter, cred, file_cred, kn, vp,
|
||
|
mac_vnode_label(vp));
|
||
|
VFS_KERNEL_DEBUG_END1(47, vp);
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_link(vfs_context_t ctx, struct vnode *dvp,
|
||
|
struct vnode *vp, struct componentname *cnp)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(48, vp);
|
||
|
MAC_CHECK(vnode_check_link, cred, dvp, mac_vnode_label(dvp), vp,
|
||
|
mac_vnode_label(vp), cnp);
|
||
|
VFS_KERNEL_DEBUG_END1(48, vp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_listextattr(vfs_context_t ctx, struct vnode *vp)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(49, vp);
|
||
|
MAC_CHECK(vnode_check_listextattr, cred, vp, mac_vnode_label(vp));
|
||
|
VFS_KERNEL_DEBUG_END1(49, vp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_lookup_preflight(vfs_context_t ctx, struct vnode *dvp,
|
||
|
const char *path, size_t pathlen)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(50, dvp);
|
||
|
MAC_CHECK(vnode_check_lookup_preflight, cred, dvp, mac_vnode_label(dvp), path, pathlen);
|
||
|
VFS_KERNEL_DEBUG_END1(50, dvp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_lookup(vfs_context_t ctx, struct vnode *dvp,
|
||
|
struct componentname *cnp)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(51, dvp);
|
||
|
MAC_CHECK(vnode_check_lookup, cred, dvp, mac_vnode_label(dvp), cnp);
|
||
|
VFS_KERNEL_DEBUG_END1(51, dvp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_open(vfs_context_t ctx, struct vnode *vp, int acc_mode)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(52, vp);
|
||
|
MAC_CHECK(vnode_check_open, cred, vp, mac_vnode_label(vp), acc_mode);
|
||
|
VFS_KERNEL_DEBUG_END1(52, vp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_read(vfs_context_t ctx, struct ucred *file_cred,
|
||
|
struct vnode *vp)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(53, vp);
|
||
|
MAC_CHECK(vnode_check_read, cred, file_cred, vp,
|
||
|
mac_vnode_label(vp));
|
||
|
VFS_KERNEL_DEBUG_END1(53, vp);
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_readdir(vfs_context_t ctx, struct vnode *dvp)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(54, dvp);
|
||
|
MAC_CHECK(vnode_check_readdir, cred, dvp, mac_vnode_label(dvp));
|
||
|
VFS_KERNEL_DEBUG_END1(54, dvp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_readlink(vfs_context_t ctx, struct vnode *vp)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(55, vp);
|
||
|
MAC_CHECK(vnode_check_readlink, cred, vp, mac_vnode_label(vp));
|
||
|
VFS_KERNEL_DEBUG_END1(55, vp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_label_update(vfs_context_t ctx, struct vnode *vp,
|
||
|
struct label *newlabel)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(56, vp);
|
||
|
MAC_CHECK(vnode_check_label_update, cred, vp, mac_vnode_label(vp), newlabel);
|
||
|
VFS_KERNEL_DEBUG_END1(56, vp);
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_rename(vfs_context_t ctx, struct vnode *dvp,
|
||
|
struct vnode *vp, struct componentname *cnp, struct vnode *tdvp,
|
||
|
struct vnode *tvp, struct componentname *tcnp)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
VFS_KERNEL_DEBUG_START1(57, vp);
|
||
|
MAC_CHECK(vnode_check_rename_from, cred, dvp, mac_vnode_label(dvp), vp,
|
||
|
mac_vnode_label(vp), cnp);
|
||
|
if (error) {
|
||
|
VFS_KERNEL_DEBUG_END1(57, vp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
MAC_CHECK(vnode_check_rename_to, cred, tdvp, mac_vnode_label(tdvp), tvp,
|
||
|
tvp != NULL ? mac_vnode_label(tvp) : NULL, dvp == tdvp, tcnp);
|
||
|
if (error) {
|
||
|
VFS_KERNEL_DEBUG_END1(57, vp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
MAC_CHECK(vnode_check_rename, cred, dvp, mac_vnode_label(dvp), vp,
|
||
|
mac_vnode_label(vp), cnp, tdvp, mac_vnode_label(tdvp), tvp,
|
||
|
tvp != NULL ? mac_vnode_label(tvp) : NULL, tcnp);
|
||
|
VFS_KERNEL_DEBUG_END1(57, vp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_revoke(vfs_context_t ctx, struct vnode *vp)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(58, vp);
|
||
|
MAC_CHECK(vnode_check_revoke, cred, vp, mac_vnode_label(vp));
|
||
|
VFS_KERNEL_DEBUG_END1(58, vp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_searchfs(vfs_context_t ctx, struct vnode *vp, struct attrlist *returnattrs,
|
||
|
struct attrlist *searchattrs)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(59, vp);
|
||
|
MAC_CHECK(vnode_check_searchfs, cred, vp, mac_vnode_label(vp), returnattrs, searchattrs);
|
||
|
VFS_KERNEL_DEBUG_END1(59, vp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_select(vfs_context_t ctx, struct vnode *vp, int which)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(60, vp);
|
||
|
MAC_CHECK(vnode_check_select, cred, vp, mac_vnode_label(vp), which);
|
||
|
VFS_KERNEL_DEBUG_END1(60, vp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_setacl(vfs_context_t ctx, struct vnode *vp,
|
||
|
struct kauth_acl *acl)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(61, vp);
|
||
|
MAC_CHECK(vnode_check_setacl, cred, vp, mac_vnode_label(vp), acl);
|
||
|
VFS_KERNEL_DEBUG_END1(61, vp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_setattrlist(vfs_context_t ctx, struct vnode *vp,
|
||
|
struct attrlist *alist)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(62, vp);
|
||
|
MAC_CHECK(vnode_check_setattrlist, cred, vp, mac_vnode_label(vp), alist);
|
||
|
VFS_KERNEL_DEBUG_END1(62, vp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_setextattr(vfs_context_t ctx, struct vnode *vp,
|
||
|
const char *name, struct uio *uio)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(63, vp);
|
||
|
MAC_CHECK(vnode_check_setextattr, cred, vp, mac_vnode_label(vp),
|
||
|
name, uio);
|
||
|
VFS_KERNEL_DEBUG_END1(63, vp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_setflags(vfs_context_t ctx, struct vnode *vp, u_long flags)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(64, vp);
|
||
|
MAC_CHECK(vnode_check_setflags, cred, vp, mac_vnode_label(vp), flags);
|
||
|
VFS_KERNEL_DEBUG_END1(64, vp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_setmode(vfs_context_t ctx, struct vnode *vp, mode_t mode)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(65, vp);
|
||
|
MAC_CHECK(vnode_check_setmode, cred, vp, mac_vnode_label(vp), mode);
|
||
|
VFS_KERNEL_DEBUG_END1(65, vp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_setowner(vfs_context_t ctx, struct vnode *vp, uid_t uid,
|
||
|
gid_t gid)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(66, vp);
|
||
|
MAC_CHECK(vnode_check_setowner, cred, vp, mac_vnode_label(vp), uid, gid);
|
||
|
VFS_KERNEL_DEBUG_END1(66, vp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_setutimes(vfs_context_t ctx, struct vnode *vp,
|
||
|
struct timespec atime, struct timespec mtime)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(67, vp);
|
||
|
MAC_CHECK(vnode_check_setutimes, cred, vp, mac_vnode_label(vp), atime,
|
||
|
mtime);
|
||
|
VFS_KERNEL_DEBUG_END1(67, vp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_stat(vfs_context_t ctx, struct ucred *file_cred,
|
||
|
struct vnode *vp)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(68, vp);
|
||
|
MAC_CHECK(vnode_check_stat, cred, file_cred, vp,
|
||
|
mac_vnode_label(vp));
|
||
|
VFS_KERNEL_DEBUG_END1(68, vp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_trigger_resolve(vfs_context_t ctx, struct vnode *dvp,
|
||
|
struct componentname *cnp)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(69, dvp);
|
||
|
MAC_CHECK(vnode_check_trigger_resolve, cred, dvp, mac_vnode_label(dvp), cnp);
|
||
|
VFS_KERNEL_DEBUG_END1(69, dvp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_truncate(vfs_context_t ctx, struct ucred *file_cred,
|
||
|
struct vnode *vp)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(70, vp);
|
||
|
MAC_CHECK(vnode_check_truncate, cred, file_cred, vp,
|
||
|
mac_vnode_label(vp));
|
||
|
VFS_KERNEL_DEBUG_END1(70, vp);
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_write(vfs_context_t ctx, struct ucred *file_cred,
|
||
|
struct vnode *vp)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(71, vp);
|
||
|
MAC_CHECK(vnode_check_write, cred, file_cred, vp, mac_vnode_label(vp));
|
||
|
VFS_KERNEL_DEBUG_END1(71, vp);
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_uipc_bind(vfs_context_t ctx, struct vnode *dvp,
|
||
|
struct componentname *cnp, struct vnode_attr *vap)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(72, dvp);
|
||
|
MAC_CHECK(vnode_check_uipc_bind, cred, dvp, mac_vnode_label(dvp), cnp, vap);
|
||
|
VFS_KERNEL_DEBUG_END1(72, dvp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_uipc_connect(vfs_context_t ctx, struct vnode *vp, struct socket *so)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(73, vp);
|
||
|
MAC_CHECK(vnode_check_uipc_connect, cred, vp, mac_vnode_label(vp), (socket_t) so);
|
||
|
VFS_KERNEL_DEBUG_END1(73, vp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
mac_vnode_label_update(vfs_context_t ctx, struct vnode *vp, struct label *newlabel)
|
||
|
{
|
||
|
kauth_cred_t cred = vfs_context_ucred(ctx);
|
||
|
struct label *tmpl = NULL;
|
||
|
|
||
|
if (mac_vnode_label(vp) == NULL) {
|
||
|
tmpl = mac_vnode_label_alloc(vp);
|
||
|
}
|
||
|
|
||
|
vnode_lock(vp);
|
||
|
|
||
|
/*
|
||
|
* Recheck under lock. We allocate labels for vnodes lazily, so
|
||
|
* somebody else might have already got here first.
|
||
|
*/
|
||
|
if (mac_vnode_label(vp) == NULL) {
|
||
|
vp->v_label = tmpl;
|
||
|
tmpl = NULL;
|
||
|
}
|
||
|
|
||
|
VFS_KERNEL_DEBUG_START1(74, vp);
|
||
|
MAC_PERFORM(vnode_label_update, cred, vp, mac_vnode_label(vp), newlabel);
|
||
|
VFS_KERNEL_DEBUG_END1(74, vp);
|
||
|
vnode_unlock(vp);
|
||
|
|
||
|
if (tmpl != NULL) {
|
||
|
mac_vnode_label_free(tmpl);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_find_sigs(struct proc *p, struct vnode *vp, off_t offset)
|
||
|
{
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_proc_enforce || !mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
VFS_KERNEL_DEBUG_START1(75, vp);
|
||
|
MAC_CHECK(vnode_find_sigs, p, vp, offset, mac_vnode_label(vp));
|
||
|
VFS_KERNEL_DEBUG_END1(75, vp);
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
mac_mount_label_associate(vfs_context_t ctx, struct mount *mp)
|
||
|
{
|
||
|
kauth_cred_t cred = vfs_context_ucred(ctx);
|
||
|
|
||
|
/* XXX: eventually this logic may be handled by the policy? */
|
||
|
|
||
|
/* We desire MULTILABEL for the root filesystem. */
|
||
|
if ((mp->mnt_flag & MNT_ROOTFS) &&
|
||
|
(strcmp(mp->mnt_vfsstat.f_fstypename, "hfs") == 0)) {
|
||
|
mp->mnt_flag |= MNT_MULTILABEL;
|
||
|
}
|
||
|
|
||
|
/* MULTILABEL on DEVFS. */
|
||
|
if (strcmp(mp->mnt_vfsstat.f_fstypename, "devfs") == 0) {
|
||
|
mp->mnt_flag |= MNT_MULTILABEL;
|
||
|
}
|
||
|
|
||
|
/* MULTILABEL on FDESC pseudo-filesystem. */
|
||
|
if (strcmp(mp->mnt_vfsstat.f_fstypename, "fdesc") == 0) {
|
||
|
mp->mnt_flag |= MNT_MULTILABEL;
|
||
|
}
|
||
|
|
||
|
/* MULTILABEL on all NFS filesystems. */
|
||
|
if (strcmp(mp->mnt_vfsstat.f_fstypename, "nfs") == 0) {
|
||
|
mp->mnt_flag |= MNT_MULTILABEL;
|
||
|
}
|
||
|
|
||
|
/* MULTILABEL on all AFP filesystems. */
|
||
|
if (strcmp(mp->mnt_vfsstat.f_fstypename, "afpfs") == 0) {
|
||
|
mp->mnt_flag |= MNT_MULTILABEL;
|
||
|
}
|
||
|
|
||
|
if (mp->mnt_vtable != NULL) {
|
||
|
/* Any filesystem that supports native XATTRs. */
|
||
|
if ((mp->mnt_vtable->vfc_vfsflags & VFC_VFSNATIVEXATTR)) {
|
||
|
mp->mnt_flag |= MNT_MULTILABEL;
|
||
|
}
|
||
|
|
||
|
/* Filesystem does not support multilabel. */
|
||
|
if ((mp->mnt_vtable->vfc_vfsflags & VFC_VFSNOMACLABEL) &&
|
||
|
(mp->mnt_flag & MNT_MULTILABEL)) {
|
||
|
mp->mnt_flag &= ~MNT_MULTILABEL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
VFS_KERNEL_DEBUG_START1(76, mp);
|
||
|
MAC_PERFORM(mount_label_associate, cred, mp, mac_mount_label(mp));
|
||
|
VFS_KERNEL_DEBUG_END1(76, mp);
|
||
|
#if DEBUG
|
||
|
printf("MAC Framework enabling %s support: %s -> %s (%s)\n",
|
||
|
mp->mnt_flag & MNT_MULTILABEL ? "multilabel" : "singlelabel",
|
||
|
mp->mnt_vfsstat.f_mntfromname,
|
||
|
mp->mnt_vfsstat.f_mntonname,
|
||
|
mp->mnt_vfsstat.f_fstypename);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_mount_check_mount(vfs_context_t ctx, struct vnode *vp,
|
||
|
struct componentname *cnp, const char *vfc_name)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(77, vp);
|
||
|
MAC_CHECK(mount_check_mount, cred, vp, mac_vnode_label(vp), cnp, vfc_name);
|
||
|
VFS_KERNEL_DEBUG_END1(77, vp);
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_mount_check_mount_late(vfs_context_t ctx, struct mount *mp)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(78, mp);
|
||
|
MAC_CHECK(mount_check_mount_late, cred, mp);
|
||
|
VFS_KERNEL_DEBUG_END1(78, mp);
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_mount_check_snapshot_create(vfs_context_t ctx, struct mount *mp,
|
||
|
const char *name)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(79, mp);
|
||
|
MAC_CHECK(mount_check_snapshot_create, cred, mp, name);
|
||
|
VFS_KERNEL_DEBUG_END1(79, mp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_mount_check_snapshot_delete(vfs_context_t ctx, struct mount *mp,
|
||
|
const char *name)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(80, mp);
|
||
|
MAC_CHECK(mount_check_snapshot_delete, cred, mp, name);
|
||
|
VFS_KERNEL_DEBUG_END1(80, mp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_mount_check_snapshot_mount(vfs_context_t ctx, struct vnode *rvp, struct vnode *vp, struct componentname *cnp,
|
||
|
const char *name, const char *vfc_name)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(92, vp);
|
||
|
MAC_CHECK(mount_check_snapshot_mount, cred, rvp, vp, cnp, name, vfc_name);
|
||
|
VFS_KERNEL_DEBUG_END1(92, vp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_mount_check_snapshot_revert(vfs_context_t ctx, struct mount *mp,
|
||
|
const char *name)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(81, mp);
|
||
|
MAC_CHECK(mount_check_snapshot_revert, cred, mp, name);
|
||
|
VFS_KERNEL_DEBUG_END1(81, mp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_mount_check_remount(vfs_context_t ctx, struct mount *mp)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(82, mp);
|
||
|
MAC_CHECK(mount_check_remount, cred, mp, mac_mount_label(mp));
|
||
|
VFS_KERNEL_DEBUG_END1(82, mp);
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_mount_check_umount(vfs_context_t ctx, struct mount *mp)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(83, mp);
|
||
|
MAC_CHECK(mount_check_umount, cred, mp, mac_mount_label(mp));
|
||
|
VFS_KERNEL_DEBUG_END1(83, mp);
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_mount_check_getattr(vfs_context_t ctx, struct mount *mp,
|
||
|
struct vfs_attr *vfa)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(84, mp);
|
||
|
MAC_CHECK(mount_check_getattr, cred, mp, mac_mount_label(mp), vfa);
|
||
|
VFS_KERNEL_DEBUG_END1(84, mp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_mount_check_setattr(vfs_context_t ctx, struct mount *mp,
|
||
|
struct vfs_attr *vfa)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(85, mp);
|
||
|
MAC_CHECK(mount_check_setattr, cred, mp, mac_mount_label(mp), vfa);
|
||
|
VFS_KERNEL_DEBUG_END1(85, mp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_mount_check_stat(vfs_context_t ctx, struct mount *mount)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(86, mount);
|
||
|
MAC_CHECK(mount_check_stat, cred, mount, mac_mount_label(mount));
|
||
|
VFS_KERNEL_DEBUG_END1(86, mount);
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_mount_check_label_update(vfs_context_t ctx, struct mount *mount)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(87, mount);
|
||
|
MAC_CHECK(mount_check_label_update, cred, mount, mac_mount_label(mount));
|
||
|
VFS_KERNEL_DEBUG_END1(87, mount);
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_mount_check_fsctl(vfs_context_t ctx, struct mount *mp, u_long cmd)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(88, mp);
|
||
|
MAC_CHECK(mount_check_fsctl, cred, mp, mac_mount_label(mp), cmd);
|
||
|
VFS_KERNEL_DEBUG_END1(88, mp);
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
mac_devfs_label_associate_device(dev_t dev, struct devnode *de,
|
||
|
const char *fullpath)
|
||
|
{
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_device_enforce) {
|
||
|
return;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
VFS_KERNEL_DEBUG_START1(89, de);
|
||
|
MAC_PERFORM(devfs_label_associate_device, dev, de, mac_devfs_label(de),
|
||
|
fullpath);
|
||
|
VFS_KERNEL_DEBUG_END1(89, de);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
mac_devfs_label_associate_directory(const char *dirname, int dirnamelen,
|
||
|
struct devnode *de, const char *fullpath)
|
||
|
{
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_device_enforce) {
|
||
|
return;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
VFS_KERNEL_DEBUG_START1(90, de);
|
||
|
MAC_PERFORM(devfs_label_associate_directory, dirname, dirnamelen, de,
|
||
|
mac_devfs_label(de), fullpath);
|
||
|
VFS_KERNEL_DEBUG_END1(90, de);
|
||
|
}
|
||
|
|
||
|
int
|
||
|
vn_setlabel(struct vnode *vp, struct label *intlabel, vfs_context_t context)
|
||
|
{
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
if (!mac_label_vnodes) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
if (vp->v_mount == NULL) {
|
||
|
printf("vn_setlabel: null v_mount\n");
|
||
|
if (vp->v_type != VNON) {
|
||
|
printf("vn_setlabel: null v_mount with non-VNON\n");
|
||
|
}
|
||
|
return EBADF;
|
||
|
}
|
||
|
|
||
|
if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
|
||
|
return ENOTSUP;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Multi-phase commit. First check the policies to confirm the
|
||
|
* change is OK. Then commit via the filesystem. Finally,
|
||
|
* update the actual vnode label. Question: maybe the filesystem
|
||
|
* should update the vnode at the end as part of VNOP_SETLABEL()?
|
||
|
*/
|
||
|
error = mac_vnode_check_label_update(context, vp, intlabel);
|
||
|
if (error) {
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
error = VNOP_SETLABEL(vp, intlabel, context);
|
||
|
if (error == ENOTSUP) {
|
||
|
error = mac_vnode_label_store(context, vp,
|
||
|
intlabel);
|
||
|
if (error) {
|
||
|
printf("%s: mac_vnode_label_store failed %d\n",
|
||
|
__func__, error);
|
||
|
return error;
|
||
|
}
|
||
|
mac_vnode_label_update(context, vp, intlabel);
|
||
|
} else if (error) {
|
||
|
printf("vn_setlabel: vop setlabel failed %d\n", error);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_label_associate_fdesc(struct mount *mp, struct fdescnode *fnp,
|
||
|
struct vnode *vp, vfs_context_t ctx)
|
||
|
{
|
||
|
struct fileproc *fp;
|
||
|
#if CONFIG_MACF_SOCKET_SUBSET
|
||
|
struct socket *so;
|
||
|
#endif
|
||
|
struct pipe *cpipe;
|
||
|
struct vnode *fvp;
|
||
|
struct proc *p;
|
||
|
int error;
|
||
|
|
||
|
error = 0;
|
||
|
|
||
|
VFS_KERNEL_DEBUG_START1(91, vp);
|
||
|
/*
|
||
|
* If no backing file, let the policy choose which label to use.
|
||
|
*/
|
||
|
if (fnp->fd_fd == -1) {
|
||
|
MAC_PERFORM(vnode_label_associate_file, vfs_context_ucred(ctx),
|
||
|
mp, mac_mount_label(mp), NULL, NULL, vp, mac_vnode_label(vp));
|
||
|
VFS_KERNEL_DEBUG_END1(91, vp);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
p = vfs_context_proc(ctx);
|
||
|
error = fp_lookup(p, fnp->fd_fd, &fp, 0);
|
||
|
if (error) {
|
||
|
VFS_KERNEL_DEBUG_END1(91, vp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
if (fp->fp_glob == NULL) {
|
||
|
error = EBADF;
|
||
|
goto out;
|
||
|
}
|
||
|
|
||
|
switch (FILEGLOB_DTYPE(fp->fp_glob)) {
|
||
|
case DTYPE_VNODE:
|
||
|
fvp = (struct vnode *)fp_get_data(fp);
|
||
|
if ((error = vnode_getwithref(fvp))) {
|
||
|
goto out;
|
||
|
}
|
||
|
if (mac_vnode_label(fvp) != NULL) {
|
||
|
if (mac_label_vnodes != 0 && mac_vnode_label(vp) == NULL) {
|
||
|
mac_vnode_label_init(vp); /* init dst label */
|
||
|
}
|
||
|
MAC_PERFORM(vnode_label_copy, mac_vnode_label(fvp), mac_vnode_label(vp));
|
||
|
}
|
||
|
(void)vnode_put(fvp);
|
||
|
break;
|
||
|
#if CONFIG_MACF_SOCKET_SUBSET
|
||
|
case DTYPE_SOCKET:
|
||
|
so = (struct socket *)fp_get_data(fp);
|
||
|
socket_lock(so, 1);
|
||
|
MAC_PERFORM(vnode_label_associate_socket,
|
||
|
vfs_context_ucred(ctx), (socket_t)so, NULL,
|
||
|
vp, mac_vnode_label(vp));
|
||
|
socket_unlock(so, 1);
|
||
|
break;
|
||
|
#endif
|
||
|
case DTYPE_PSXSHM:
|
||
|
pshm_label_associate(fp, vp, ctx);
|
||
|
break;
|
||
|
case DTYPE_PSXSEM:
|
||
|
psem_label_associate(fp, vp, ctx);
|
||
|
break;
|
||
|
case DTYPE_PIPE:
|
||
|
cpipe = (struct pipe *)fp_get_data(fp);
|
||
|
/* kern/sys_pipe.c:pipe_select() suggests this test. */
|
||
|
if (cpipe == (struct pipe *)-1) {
|
||
|
error = EINVAL;
|
||
|
goto out;
|
||
|
}
|
||
|
PIPE_LOCK(cpipe);
|
||
|
MAC_PERFORM(vnode_label_associate_pipe, vfs_context_ucred(ctx),
|
||
|
cpipe, mac_pipe_label(cpipe), vp, mac_vnode_label(vp));
|
||
|
PIPE_UNLOCK(cpipe);
|
||
|
break;
|
||
|
case DTYPE_KQUEUE:
|
||
|
case DTYPE_FSEVENTS:
|
||
|
case DTYPE_ATALK:
|
||
|
case DTYPE_NETPOLICY:
|
||
|
case DTYPE_CHANNEL:
|
||
|
case DTYPE_NEXUS:
|
||
|
default:
|
||
|
MAC_PERFORM(vnode_label_associate_file, vfs_context_ucred(ctx),
|
||
|
mp, mac_mount_label(mp), fp->fp_glob, NULL,
|
||
|
vp, mac_vnode_label(vp));
|
||
|
break;
|
||
|
}
|
||
|
out:
|
||
|
VFS_KERNEL_DEBUG_END1(91, vp);
|
||
|
fp_drop(p, fnp->fd_fd, fp, 0);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
intptr_t
|
||
|
mac_vnode_label_get(struct vnode *vp, int slot, intptr_t sentinel)
|
||
|
{
|
||
|
struct label *l;
|
||
|
|
||
|
KASSERT(vp != NULL, ("mac_vnode_label_get: NULL vnode"));
|
||
|
l = mac_vnode_label(vp);
|
||
|
if (l != NULL) {
|
||
|
return mac_label_get(l, slot);
|
||
|
} else {
|
||
|
return sentinel;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void
|
||
|
mac_vnode_label_set(struct vnode *vp, int slot, intptr_t v)
|
||
|
{
|
||
|
struct label *l;
|
||
|
KASSERT(vp != NULL, ("mac_vnode_label_set: NULL vnode"));
|
||
|
l = mac_vnode_label(vp);
|
||
|
if (l == NULL) {
|
||
|
mac_vnode_label_init(vp);
|
||
|
l = mac_vnode_label(vp);
|
||
|
}
|
||
|
mac_label_set(l, slot, v);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
mac_vnode_notify_reclaim(struct vnode *vp)
|
||
|
{
|
||
|
VFS_KERNEL_DEBUG_START1(94, vp);
|
||
|
MAC_PERFORM(vnode_notify_reclaim, vp);
|
||
|
VFS_KERNEL_DEBUG_END1(94, vp);
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_mount_check_quotactl(vfs_context_t ctx, struct mount *mp, int cmd, int id)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(95, mp);
|
||
|
MAC_CHECK(mount_check_quotactl, cred, mp, cmd, id);
|
||
|
VFS_KERNEL_DEBUG_END1(95, mp);
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_getattrlistbulk(vfs_context_t ctx, struct vnode *vp, struct attrlist *alist, uint64_t options)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(96, mp);
|
||
|
MAC_CHECK(vnode_check_getattrlistbulk, cred, vp, alist, options);
|
||
|
VFS_KERNEL_DEBUG_END1(96, mp);
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
mac_vnode_check_copyfile(vfs_context_t ctx, struct vnode *dvp,
|
||
|
struct vnode *tvp, struct vnode *fvp, struct componentname *cnp,
|
||
|
mode_t mode, int flags)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
int error;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return 0;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(97, dvp);
|
||
|
MAC_CHECK(vnode_check_copyfile, cred, dvp, mac_vnode_label(dvp),
|
||
|
tvp, tvp ? mac_vnode_label(tvp) : NULL, fvp, mac_vnode_label(fvp), cnp, mode, flags);
|
||
|
VFS_KERNEL_DEBUG_END1(97, dvp);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
mac_vnode_notify_unlink(vfs_context_t ctx, struct vnode *dvp, struct vnode *vp,
|
||
|
struct componentname *cnp)
|
||
|
{
|
||
|
kauth_cred_t cred;
|
||
|
|
||
|
#if SECURITY_MAC_CHECK_ENFORCE
|
||
|
/* 21167099 - only check if we allow write */
|
||
|
if (!mac_vnode_enforce) {
|
||
|
return;
|
||
|
}
|
||
|
#endif
|
||
|
cred = vfs_context_ucred(ctx);
|
||
|
if (!mac_cred_check_enforce(cred)) {
|
||
|
return;
|
||
|
}
|
||
|
VFS_KERNEL_DEBUG_START1(98, vp);
|
||
|
MAC_PERFORM(vnode_notify_unlink, cred, dvp, mac_vnode_label(dvp), vp,
|
||
|
mac_vnode_label(vp), cnp);
|
||
|
VFS_KERNEL_DEBUG_END1(98, vp);
|
||
|
}
|