Date: Mon, 20 Oct 2003 17:43:50 -0700 (PDT) From: Robert Watson <rwatson@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 40049 for review Message-ID: <200310210043.h9L0ho5d009519@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=40049 Change 40049 by rwatson@rwatson_tislabs on 2003/10/20 17:43:36 Break System V IPC primitive MAC Framework pieces into their own files. mac_sysvipc_enforce is visible outside of the files because it is shared between them. Might want to make each type have its own local enforcement variable. Affected files ... .. //depot/projects/trustedbsd/mac/sys/conf/files#88 edit .. //depot/projects/trustedbsd/mac/sys/kern/kern_mac.c#415 edit .. //depot/projects/trustedbsd/mac/sys/security/mac/mac_internal.h#4 edit .. //depot/projects/trustedbsd/mac/sys/security/mac/mac_sysv_msg.c#2 edit .. //depot/projects/trustedbsd/mac/sys/security/mac/mac_sysv_sem.c#2 edit .. //depot/projects/trustedbsd/mac/sys/security/mac/mac_sysv_shm.c#2 edit Differences ... ==== //depot/projects/trustedbsd/mac/sys/conf/files#88 (text+ko) ==== @@ -1591,6 +1591,9 @@ security/mac/mac_pipe.c optional mac security/mac/mac_posix_sem.c optional mac security/mac/mac_system.c optional mac +security/mac/mac_sysv_msg.c optional mac +security/mac/mac_sysv_sem.c optional mac +security/mac/mac_sysv_shm.c optional mac security/mac_biba/mac_biba.c optional mac_biba security/mac_bsdextended/mac_bsdextended.c optional mac_bsdextended security/mac_ifoff/mac_ifoff.c optional mac_ifoff ==== //depot/projects/trustedbsd/mac/sys/kern/kern_mac.c#415 (text+ko) ==== @@ -68,10 +68,6 @@ #include <sys/pipe.h> #include <sys/socketvar.h> #include <sys/sysctl.h> -#include <sys/msg.h> -#include <sys/msg_msg.h> -#include <sys/sem.h> -#include <sys/shm.h> #include <vm/vm.h> #include <vm/pmap.h> @@ -160,11 +156,6 @@ &mac_enforce_socket, 0, "Enforce MAC policy on socket operations"); TUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket); -static int mac_enforce_sysv = 1; -SYSCTL_INT(_security_mac, OID_AUTO, enforce_sysv, CTLFLAG_RW, - &mac_enforce_sysv, 0, "Enforce MAC policy on System V IPC objects"); -TUNABLE_INT("security.mac.enforce_sysv", &mac_enforce_sysv); - static int mac_enforce_vm = 1; SYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW, &mac_enforce_vm, 0, "Enforce MAC policy on vm operations"); @@ -196,8 +187,7 @@ static unsigned int nmacmbufs, nmaccreds, nmacifnets, nmacbpfdescs, nmacsockets, nmacmounts, nmactemp, nmacvnodes, nmacdevfsdirents, - nmacipqs, nmacprocs, nmacipcmsgs, nmacipcmsqs, - nmacipcsemas, nmacipcshms; + nmacipqs, nmacprocs; SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mbufs, CTLFLAG_RD, &nmacmbufs, 0, "number of mbufs in use"); @@ -221,14 +211,6 @@ &nmacvnodes, 0, "number of vnodes in use"); SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, devfsdirents, CTLFLAG_RD, &nmacdevfsdirents, 0, "number of devfs dirents inuse"); -SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipc_msgs, CTLFLAG_RD, - &nmacipcmsgs, 0, "number of sysv ipc messages inuse"); -SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipc_msqs, CTLFLAG_RD, - &nmacipcmsqs, 0, "number of sysv ipc message queue identifiers inuse"); -SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipc_semas, CTLFLAG_RD, - &nmacipcsemas, 0, "number of sysv ipc semaphore identifiers inuse"); -SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipc_shms, CTLFLAG_RD, - &nmacipcshms, 0, "number of sysv ipc shm identifiers inuse"); #endif static int mac_policy_register(struct mac_policy_conf *mpc); @@ -701,42 +683,6 @@ mac_init_ifnet_label(&ifp->if_label); } -void -mac_init_ipc_msgmsg(struct msg *msgptr) -{ - - mac_init_label(&msgptr->label); - MAC_PERFORM(init_ipc_msgmsg_label, &msgptr->label); - MAC_DEBUG_COUNTER_INC(&nmacipcmsgs); -} - -void -mac_init_ipc_msgqueue(struct msqid_kernel *msqkptr) -{ - - mac_init_label(&msqkptr->label); - MAC_PERFORM(init_ipc_msgqueue_label, &msqkptr->label); - MAC_DEBUG_COUNTER_INC(&nmacipcmsqs); -} - -void -mac_init_ipc_sema(struct semid_kernel *semakptr) -{ - - mac_init_label(&semakptr->label); - MAC_PERFORM(init_ipc_sema_label, &semakptr->label); - MAC_DEBUG_COUNTER_INC(&nmacipcsemas); -} - -void -mac_init_ipc_shm(struct shmid_kernel *shmsegptr) -{ - - mac_init_label(&shmsegptr->label); - MAC_PERFORM(init_ipc_shm_label, &shmsegptr->label); - MAC_DEBUG_COUNTER_INC(&nmacipcshms); -} - int mac_init_ipq(struct ipq *ipq, int flag) { @@ -939,42 +885,6 @@ } void -mac_destroy_ipc_msgmsg(struct msg *msgptr) -{ - - MAC_PERFORM(destroy_ipc_msgmsg_label, &msgptr->label); - mac_destroy_label(&msgptr->label); - MAC_DEBUG_COUNTER_DEC(&nmacipcmsgs); -} - -void -mac_destroy_ipc_msgqueue(struct msqid_kernel *msqkptr) -{ - - MAC_PERFORM(destroy_ipc_msgqueue_label, &msqkptr->label); - mac_destroy_label(&msqkptr->label); - MAC_DEBUG_COUNTER_DEC(&nmacipcmsqs); -} - -void -mac_destroy_ipc_sema(struct semid_kernel *semakptr) -{ - - MAC_PERFORM(destroy_ipc_sema_label, &semakptr->label); - mac_destroy_label(&semakptr->label); - MAC_DEBUG_COUNTER_DEC(&nmacipcsemas); -} - -void -mac_destroy_ipc_shm(struct shmid_kernel *shmsegptr) -{ - - MAC_PERFORM(destroy_ipc_shm_label, &shmsegptr->label); - mac_destroy_label(&shmsegptr->label); - MAC_DEBUG_COUNTER_DEC(&nmacipcshms); -} - -void mac_destroy_ipq(struct ipq *ipq) { @@ -2108,36 +2018,6 @@ } void -mac_create_ipc_msgmsg(struct ucred *cred, struct msqid_kernel *msqkptr, - struct msg *msgptr) -{ - - MAC_PERFORM(create_ipc_msgmsg, cred, msqkptr, &msqkptr->label, - msgptr, &msgptr->label); -} - -void -mac_create_ipc_msgqueue(struct ucred *cred, struct msqid_kernel *msqkptr) -{ - - MAC_PERFORM(create_ipc_msgqueue, cred, msqkptr, &msqkptr->label); -} - -void -mac_create_ipc_sema(struct ucred *cred, struct semid_kernel *semakptr) -{ - - MAC_PERFORM(create_ipc_sema, cred, semakptr, &semakptr->label); -} - -void -mac_create_ipc_shm(struct ucred *cred, struct shmid_kernel *shmsegptr) -{ - - MAC_PERFORM(create_ipc_shm, cred, shmsegptr, &shmsegptr->label); -} - -void mac_create_socket(struct ucred *cred, struct socket *socket) { @@ -2374,34 +2254,6 @@ &mp->mnt_fslabel); } -void -mac_cleanup_ipc_msgmsg(struct msg *msgptr) -{ - - MAC_PERFORM(cleanup_ipc_msgmsg, &msgptr->label); -} - -void -mac_cleanup_ipc_msgqueue(struct msqid_kernel *msqkptr) -{ - - MAC_PERFORM(cleanup_ipc_msgqueue, &msqkptr->label); -} - -void -mac_cleanup_ipc_sema(struct semid_kernel *semakptr) -{ - - MAC_PERFORM(cleanup_ipc_sema, &semakptr->label); -} - -void -mac_cleanup_ipc_shm(struct shmid_kernel *shmsegptr) -{ - - MAC_PERFORM(cleanup_ipc_shm, &shmsegptr->label); -} - int mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet) { @@ -2459,209 +2311,6 @@ } int -mac_check_ipc_msgmsq(struct ucred *cred, struct msg *msgptr, - struct msqid_kernel *msqkptr) -{ - int error; - - if (!mac_enforce_sysv) - return (0); - - //XXX: Should we also pass &msqkptr->label ?? - MAC_CHECK(check_ipc_msgmsq, cred, msgptr, msqkptr); - - return(error); -} - -int -mac_check_ipc_msgrcv(struct ucred *cred, struct msg *msgptr) -{ - int error; - - if (!mac_enforce_sysv) - return (0); - - //XXX: Should we also pass &msqkptr->label ?? - MAC_CHECK(check_ipc_msgrcv, cred, msgptr); - - return(error); -} - -int -mac_check_ipc_msgrmid(struct ucred *cred, struct msg *msgptr) -{ - int error; - - if (!mac_enforce_sysv) - return (0); - - //XXX: Should we also pass &msqkptr->label ?? - MAC_CHECK(check_ipc_msgrmid, cred, msgptr); - - return(error); -} - -int -mac_check_ipc_msqget(struct ucred *cred, struct msqid_kernel *msqkptr) -{ - int error; - - if (!mac_enforce_sysv) - return (0); - - //XXX: Should we also pass &msqkptr->label ?? - MAC_CHECK(check_ipc_msqget, cred, msqkptr); - - return(error); -} - -int -mac_check_ipc_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr) -{ - int error; - - if (!mac_enforce_sysv) - return (0); - - //XXX: Should we also pass &msqkptr->label ?? - MAC_CHECK(check_ipc_msqsnd, cred, msqkptr); - - return(error); -} - -int -mac_check_ipc_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr) -{ - int error; - - if (!mac_enforce_sysv) - return (0); - - //XXX: Should we also pass &msqkptr->label ?? - MAC_CHECK(check_ipc_msqrcv, cred, msqkptr); - - return(error); -} - -int -mac_check_ipc_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr, - int cmd) -{ - int error; - - if (!mac_enforce_sysv) - return (0); - - //XXX: Should we also pass &msqkptr->label ?? - MAC_CHECK(check_ipc_msqctl, cred, msqkptr, cmd); - - return(error); -} - -int -mac_check_ipc_semctl(struct ucred *cred, struct semid_kernel *semakptr, - int cmd) -{ - int error; - - if (!mac_enforce_sysv) - return (0); - - //XXX: Should we also pass &semakptr->label ?? - MAC_CHECK(check_ipc_semctl, cred, semakptr, cmd); - - return(error); -} - -int -mac_check_ipc_semget(struct ucred *cred, struct semid_kernel *semakptr) -{ - int error; - - if (!mac_enforce_sysv) - return (0); - - //XXX: Should we also pass &semakptr->label ?? - MAC_CHECK(check_ipc_semget, cred, semakptr); - - return(error); -} - -int -mac_check_ipc_semop(struct ucred *cred, struct semid_kernel *semakptr, - size_t accesstype) -{ - int error; - - if (!mac_enforce_sysv) - return (0); - - //XXX: Should we also pass &semakptr->label ?? - MAC_CHECK(check_ipc_semop, cred, semakptr, accesstype); - - return(error); -} - -int -mac_check_ipc_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr, - int shmflg) -{ - int error; - - if (!mac_enforce_sysv) - return (0); - - //XXX: Should we also pass &shmsegptr->label ?? - MAC_CHECK(check_ipc_shmat, cred, shmsegptr, shmflg); - - return(error); -} - -int -mac_check_ipc_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr, - int cmd) -{ - int error; - - if (!mac_enforce_sysv) - return (0); - - //XXX: Should we also pass &shmsegptr->label ?? - MAC_CHECK(check_ipc_shmctl, cred, shmsegptr, cmd); - - return(error); -} - -int -mac_check_ipc_shmdt(struct ucred *cred, struct shmid_kernel *shmsegptr) -{ - int error; - - if (!mac_enforce_sysv) - return (0); - - //XXX: Should we also pass &shmsegptr->label ?? - MAC_CHECK(check_ipc_shmdt, cred, shmsegptr); - - return(error); -} - -int -mac_check_ipc_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr, - int shmflg) -{ - int error; - - if (!mac_enforce_sysv) - return (0); - - //XXX: Should we also pass &shmsegptr->label ?? - MAC_CHECK(check_ipc_shmget, cred, shmsegptr, shmflg); - - return(error); -} - -int mac_check_mount_stat(struct ucred *cred, struct mount *mount) { int error; ==== //depot/projects/trustedbsd/mac/sys/security/mac/mac_internal.h#4 (text+ko) ==== @@ -55,6 +55,8 @@ extern struct mac_policy_list_head mac_policy_list; extern struct mac_policy_list_head mac_static_policy_list; extern int mac_late; +extern int mac_enforce_sysv; + /* * MAC Framework global types and constants. */ ==== //depot/projects/trustedbsd/mac/sys/security/mac/mac_sysv_msg.c#2 (text+ko) ==== @@ -1,12 +1,7 @@ /*- - * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson - * Copyright (c) 2001 Ilmar S. Habibulin - * Copyright (c) 2001, 2002, 2003 Networks Associates Technology, Inc. + * Copyright (c) 2003 Networks Associates Technology, Inc. * All rights reserved. * - * 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"), @@ -34,673 +29,44 @@ * SUCH DAMAGE. */ -/* - * Framework for extensible kernel access control. Kernel and userland - * interface to the framework, policy registration and composition. - */ - #include <sys/cdefs.h> __FBSDID("$FreeBSD: src/sys/kern/kern_mac.c,v 1.99 2003/09/29 18:35:17 rwatson Exp $"); #include "opt_mac.h" -#include "opt_devfs.h" #include <sys/param.h> -#include <sys/condvar.h> -#include <sys/extattr.h> -#include <sys/imgact.h> #include <sys/kernel.h> #include <sys/lock.h> #include <sys/malloc.h> #include <sys/mutex.h> #include <sys/mac.h> -#include <sys/module.h> -#include <sys/proc.h> #include <sys/sbuf.h> #include <sys/systm.h> -#include <sys/sysproto.h> -#include <sys/sysent.h> #include <sys/vnode.h> #include <sys/mount.h> #include <sys/file.h> #include <sys/namei.h> -#include <sys/socket.h> -#include <sys/pipe.h> -#include <sys/socketvar.h> #include <sys/sysctl.h> #include <sys/msg.h> #include <sys/msg_msg.h> -#include <sys/sem.h> -#include <sys/shm.h> - -#include <vm/vm.h> -#include <vm/pmap.h> -#include <vm/vm_map.h> -#include <vm/vm_object.h> #include <sys/mac_policy.h> -#include <fs/devfs/devfs.h> - -#include <net/bpfdesc.h> -#include <net/if.h> -#include <net/if_var.h> - -#include <netinet/in.h> -#include <netinet/ip_var.h> - #include <security/mac/mac_internal.h> -#ifdef MAC - -/* - * Declare that the kernel provides MAC support, version 1. This permits - * modules to refuse to be loaded if the necessary support isn't present, - * even if it's pre-boot. - */ -MODULE_VERSION(kernel_mac_support, 1); - -SYSCTL_NODE(_security, OID_AUTO, mac, CTLFLAG_RW, 0, - "TrustedBSD MAC policy controls"); - -#if MAC_MAX_SLOTS > 32 -#error "MAC_MAX_SLOTS too large" -#endif - -static unsigned int mac_max_slots = MAC_MAX_SLOTS; -static unsigned int mac_slot_offsets_free = (1 << MAC_MAX_SLOTS) - 1; -SYSCTL_UINT(_security_mac, OID_AUTO, max_slots, CTLFLAG_RD, - &mac_max_slots, 0, ""); - -/* - * Has the kernel started generating labeled objects yet? All read/write - * access to this variable is serialized during the boot process. Following - * the end of serialization, we don't update this flag; no locking. - */ -int mac_late = 0; - -/* - * Warn about EA transactions only the first time they happen. - * Weak coherency, no locking. - */ -static int ea_warn_once = 0; - -/* - * Flag to indicate whether or not we should allocate label storage for - * new mbufs. Since most dynamic policies we currently work with don't - * rely on mbuf labeling, try to avoid paying the cost of mtag allocation - * unless specifically notified of interest. One result of this is - * that if a dynamically loaded policy requests mbuf labels, it must - * be able to deal with a NULL label being returned on any mbufs that - * were already in flight when the policy was loaded. Since the policy - * already has to deal with uninitialized labels, this probably won't - * be a problem. Note: currently no locking. Will this be a problem? - */ -#ifndef MAC_ALWAYS_LABEL_MBUF -static int mac_labelmbufs = 0; -#endif - -static int mac_enforce_fs = 1; -SYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW, - &mac_enforce_fs, 0, "Enforce MAC policy on file system objects"); -TUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs); - -static int mac_enforce_network = 1; -SYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW, - &mac_enforce_network, 0, "Enforce MAC policy on network packets"); -TUNABLE_INT("security.mac.enforce_network", &mac_enforce_network); - -static int mac_enforce_process = 1; -SYSCTL_INT(_security_mac, OID_AUTO, enforce_process, CTLFLAG_RW, - &mac_enforce_process, 0, "Enforce MAC policy on inter-process operations"); -TUNABLE_INT("security.mac.enforce_process", &mac_enforce_process); - -static int mac_enforce_socket = 1; -SYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW, - &mac_enforce_socket, 0, "Enforce MAC policy on socket operations"); -TUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket); - -static int mac_enforce_sysv = 1; +int mac_enforce_sysv = 1; SYSCTL_INT(_security_mac, OID_AUTO, enforce_sysv, CTLFLAG_RW, &mac_enforce_sysv, 0, "Enforce MAC policy on System V IPC objects"); TUNABLE_INT("security.mac.enforce_sysv", &mac_enforce_sysv); -static int mac_enforce_vm = 1; -SYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW, - &mac_enforce_vm, 0, "Enforce MAC policy on vm operations"); -TUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm); - -static int mac_mmap_revocation = 0; -SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW, - &mac_mmap_revocation, 0, "Revoke mmap access to files on subject " - "relabel"); - -static int mac_mmap_revocation_via_cow = 1; -SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation_via_cow, CTLFLAG_RW, - &mac_mmap_revocation_via_cow, 0, "Revoke mmap access to files via " - "copy-on-write semantics, or by removing all write access"); - #ifdef MAC_DEBUG -SYSCTL_NODE(_security_mac, OID_AUTO, debug, CTLFLAG_RW, 0, - "TrustedBSD MAC debug info"); - -static int mac_debug_label_fallback = 0; -SYSCTL_INT(_security_mac_debug, OID_AUTO, label_fallback, CTLFLAG_RW, - &mac_debug_label_fallback, 0, "Filesystems should fall back to fs label" - "when label is corrupted."); -TUNABLE_INT("security.mac.debug_label_fallback", - &mac_debug_label_fallback); - -SYSCTL_NODE(_security_mac_debug, OID_AUTO, counters, CTLFLAG_RW, 0, - "TrustedBSD MAC object counters"); - -static unsigned int nmacmbufs, nmaccreds, nmacifnets, nmacbpfdescs, - nmacsockets, nmacmounts, nmactemp, nmacvnodes, nmacdevfsdirents, - nmacipqs, nmacprocs, nmacipcmsgs, nmacipcmsqs, - nmacipcsemas, nmacipcshms; - -SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mbufs, CTLFLAG_RD, - &nmacmbufs, 0, "number of mbufs in use"); -SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, creds, CTLFLAG_RD, - &nmaccreds, 0, "number of ucreds in use"); -SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ifnets, CTLFLAG_RD, - &nmacifnets, 0, "number of ifnets in use"); -SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipqs, CTLFLAG_RD, - &nmacipqs, 0, "number of ipqs in use"); -SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, bpfdescs, CTLFLAG_RD, - &nmacbpfdescs, 0, "number of bpfdescs in use"); -SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, sockets, CTLFLAG_RD, - &nmacsockets, 0, "number of sockets in use"); -SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, procs, CTLFLAG_RD, - &nmacprocs, 0, "number of procs in use"); -SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mounts, CTLFLAG_RD, - &nmacmounts, 0, "number of mounts in use"); -SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, temp, CTLFLAG_RD, - &nmactemp, 0, "number of temporary labels in use"); -SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, vnodes, CTLFLAG_RD, - &nmacvnodes, 0, "number of vnodes in use"); -SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, devfsdirents, CTLFLAG_RD, - &nmacdevfsdirents, 0, "number of devfs dirents inuse"); +static unsigned int nmacipcmsgs, nmacipcmsqs; SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipc_msgs, CTLFLAG_RD, &nmacipcmsgs, 0, "number of sysv ipc messages inuse"); SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipc_msqs, CTLFLAG_RD, &nmacipcmsqs, 0, "number of sysv ipc message queue identifiers inuse"); -SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipc_semas, CTLFLAG_RD, - &nmacipcsemas, 0, "number of sysv ipc semaphore identifiers inuse"); -SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipc_shms, CTLFLAG_RD, - &nmacipcshms, 0, "number of sysv ipc shm identifiers inuse"); -#endif - -static int mac_policy_register(struct mac_policy_conf *mpc); -static int mac_policy_unregister(struct mac_policy_conf *mpc); - -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); - -static void mac_destroy_socket_label(struct label *label); - -static int mac_setlabel_vnode_extattr(struct ucred *cred, - struct vnode *vp, struct label *intlabel); - -MALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage"); - -/* - * mac_static_policy_list holds a list of policy modules that are not - * loaded while the system is "live", and cannot be unloaded. These - * policies can be invoked without holding the busy count. - * - * mac_policy_list stores the list of dynamic policies. A busy count is - * maintained for the list, stored in mac_policy_busy. The busy count - * is protected by mac_policy_mtx; the list may be modified only - * while the busy count is 0, requiring that the lock be held to - * prevent new references to the list from being acquired. For almost - * all operations, incrementing the busy count is sufficient to - * guarantee consistency, as the list cannot be modified while the - * busy count is elevated. For a few special operations involving a - * change to the list of active policies, the mtx itself must be held. - * A condition variable, mac_policy_cv, is used to signal potential - * exclusive consumers that they should try to acquire the lock if a - * first attempt at exclusive access fails. - */ -#ifndef MAC_STATIC -static struct mtx mac_policy_mtx; -static struct cv mac_policy_cv; -static int mac_policy_count; -#endif -struct mac_policy_list_head mac_policy_list; -struct mac_policy_list_head mac_static_policy_list; - -/* - * We manually invoke WITNESS_WARN() to allow Witness to generate - * warnings even if we don't end up ever triggering the wait at - * run-time. The consumer of the exclusive interface must not hold - * any locks (other than potentially Giant) since we may sleep for - * long (potentially indefinite) periods of time waiting for the - * framework to become quiescent so that a policy list change may - * be made. - */ -void -mac_policy_grab_exclusive(void) -{ - -#ifndef MAC_STATIC - WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, - "mac_policy_grab_exclusive() at %s:%d", __FILE__, __LINE__); - mtx_lock(&mac_policy_mtx); - while (mac_policy_count != 0) - cv_wait(&mac_policy_cv, &mac_policy_mtx); -#endif -} - -void -mac_policy_assert_exclusive(void) -{ - -#ifndef MAC_STATIC - mtx_assert(&mac_policy_mtx, MA_OWNED); - KASSERT(mac_policy_count == 0, - ("mac_policy_assert_exclusive(): not exclusive")); -#endif -} - -void -mac_policy_release_exclusive(void) -{ - -#ifndef MAC_STATIC - KASSERT(mac_policy_count == 0, - ("mac_policy_release_exclusive(): not exclusive")); - mtx_unlock(&mac_policy_mtx); - cv_signal(&mac_policy_cv); -#endif -} - -void -mac_policy_list_busy(void) -{ - -#ifndef MAC_STATIC - mtx_lock(&mac_policy_mtx); - mac_policy_count++; - mtx_unlock(&mac_policy_mtx); -#endif -} - -int -mac_policy_list_conditional_busy(void) -{ -#ifndef MAC_STATIC - int ret; - - mtx_lock(&mac_policy_mtx); - if (!LIST_EMPTY(&mac_policy_list)) { - mac_policy_count++; - ret = 1; - } else - ret = 0; - mtx_unlock(&mac_policy_mtx); - return (ret); -#else - return (0); -#endif -} - -void -mac_policy_list_unbusy(void) -{ - -#ifndef MAC_STATIC - mtx_lock(&mac_policy_mtx); - mac_policy_count--; - KASSERT(mac_policy_count >= 0, ("MAC_POLICY_LIST_LOCK")); - if (mac_policy_count == 0) - cv_signal(&mac_policy_cv); - mtx_unlock(&mac_policy_mtx); -#endif -} - -/* - * Initialize the MAC subsystem, including appropriate SMP locks. - */ -static void -mac_init(void) -{ - - LIST_INIT(&mac_static_policy_list); - LIST_INIT(&mac_policy_list); - -#ifndef MAC_STATIC - mtx_init(&mac_policy_mtx, "mac_policy_mtx", NULL, MTX_DEF); - cv_init(&mac_policy_cv, "mac_policy_cv"); -#endif -} - -/* - * For the purposes of modules that want to know if they were loaded - * "early", set the mac_late flag once we've processed modules either - * linked into the kernel, or loaded before the kernel startup. - */ -static void -mac_late_init(void) -{ - - mac_late = 1; -} - -/* - * After the policy list has changed, walk the list to update any global - * flags. Currently, we support only one flag, and it's conditionally - * defined; as a result, the entire function is conditional. Eventually, - * the #else case might also iterate across the policies. - */ -static void -mac_policy_updateflags(void) -{ -#ifndef MAC_ALWAYS_LABEL_MBUF - struct mac_policy_conf *tmpc; - int labelmbufs; - - mac_policy_assert_exclusive(); - - labelmbufs = 0; - LIST_FOREACH(tmpc, &mac_static_policy_list, mpc_list) { - if (tmpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_LABELMBUFS) - labelmbufs++; - } - LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) { - if (tmpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_LABELMBUFS) - labelmbufs++; - } - mac_labelmbufs = (labelmbufs != 0); -#endif -} - -/* - * Allow MAC policy modules to register during boot, etc. - */ -int -mac_policy_modevent(module_t mod, int type, void *data) -{ - struct mac_policy_conf *mpc; - int error; - - error = 0; - mpc = (struct mac_policy_conf *) data; - -#ifdef MAC_STATIC - if (mac_late) { - printf("mac_policy_modevent: MAC_STATIC and late\n"); - return (EBUSY); - } -#endif - - switch (type) { - case MOD_LOAD: - if (mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_NOTLATE && - mac_late) { - printf("mac_policy_modevent: can't load %s policy " - "after booting\n", mpc->mpc_name); - error = EBUSY; - break; - } - error = mac_policy_register(mpc); - break; - case MOD_UNLOAD: - /* Don't unregister the module if it was never registered. */ - if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) - != 0) - error = mac_policy_unregister(mpc); - else - error = 0; - break; - default: - break; - } - - return (error); -} - -static int -mac_policy_register(struct mac_policy_conf *mpc) -{ - struct mac_policy_conf *tmpc; - int error, slot, static_entry; - - error = 0; - - /* - * We don't technically need exclusive access while !mac_late, - * but hold it for assertion consistency. - */ - mac_policy_grab_exclusive(); - - /* - * If the module can potentially be unloaded, or we're loading - * late, we have to stick it in the non-static list and pay - * an extra performance overhead. Otherwise, we can pay a - * light locking cost and stick it in the static list. - */ - static_entry = (!mac_late && - !(mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK)); - - if (static_entry) { - LIST_FOREACH(tmpc, &mac_static_policy_list, mpc_list) { - if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) { - error = EEXIST; - goto out; - } - } - } else { - LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) { - if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) { - error = EEXIST; - goto out; - } - } - } - if (mpc->mpc_field_off != NULL) { - slot = ffs(mac_slot_offsets_free); - if (slot == 0) { - error = ENOMEM; - goto out; - } - slot--; - mac_slot_offsets_free &= ~(1 << slot); - *mpc->mpc_field_off = slot; - } - mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED; - - /* - * If we're loading a MAC module after the framework has - * initialized, it has to go into the dynamic list. If - * we're loading it before we've finished initializing, - * it can go into the static list with weaker locker - * requirements. - */ - if (static_entry) - LIST_INSERT_HEAD(&mac_static_policy_list, mpc, mpc_list); - else - LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list); - - /* Per-policy initialization. */ - if (mpc->mpc_ops->mpo_init != NULL) - (*(mpc->mpc_ops->mpo_init))(mpc); - mac_policy_updateflags(); - - printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname, - mpc->mpc_name); - -out: - mac_policy_release_exclusive(); - return (error); -} - -static int -mac_policy_unregister(struct mac_policy_conf *mpc) -{ - - /* - * If we fail the load, we may get a request to unload. Check - * to see if we did the run-time registration, and if not, - * silently succeed. - */ - mac_policy_grab_exclusive(); - if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) == 0) { - mac_policy_release_exclusive(); - return (0); >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200310210043.h9L0ho5d009519>