17bc82500SRobert Watson /*- 26bd11732SRobert Watson * Copyright (c) 2002, 2003 Networks Associates Technology, Inc. 37bc82500SRobert Watson * All rights reserved. 47bc82500SRobert Watson * 56201265bSRobert Watson * This software was developed for the FreeBSD Project in part by Network 66201265bSRobert Watson * Associates Laboratories, the Security Research Division of Network 76201265bSRobert Watson * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), 86201265bSRobert Watson * as part of the DARPA CHATS research program. 97bc82500SRobert Watson * 107bc82500SRobert Watson * Redistribution and use in source and binary forms, with or without 117bc82500SRobert Watson * modification, are permitted provided that the following conditions 127bc82500SRobert Watson * are met: 137bc82500SRobert Watson * 1. Redistributions of source code must retain the above copyright 147bc82500SRobert Watson * notice, this list of conditions and the following disclaimer. 157bc82500SRobert Watson * 2. Redistributions in binary form must reproduce the above copyright 167bc82500SRobert Watson * notice, this list of conditions and the following disclaimer in the 177bc82500SRobert Watson * documentation and/or other materials provided with the distribution. 187bc82500SRobert Watson * 197bc82500SRobert Watson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 207bc82500SRobert Watson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 217bc82500SRobert Watson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 227bc82500SRobert Watson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 237bc82500SRobert Watson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 247bc82500SRobert Watson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 257bc82500SRobert Watson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 267bc82500SRobert Watson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 277bc82500SRobert Watson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 287bc82500SRobert Watson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 297bc82500SRobert Watson * SUCH DAMAGE. 307bc82500SRobert Watson */ 31677b542eSDavid E. O'Brien 32677b542eSDavid E. O'Brien #include <sys/cdefs.h> 33677b542eSDavid E. O'Brien __FBSDID("$FreeBSD$"); 34677b542eSDavid E. O'Brien 357bc82500SRobert Watson #include "opt_mac.h" 36f9d0d524SRobert Watson 377bc82500SRobert Watson #include <sys/param.h> 3895fab37eSRobert Watson #include <sys/kernel.h> 3995fab37eSRobert Watson #include <sys/lock.h> 40b656366bSBruce Evans #include <sys/malloc.h> 4195fab37eSRobert Watson #include <sys/mutex.h> 4295fab37eSRobert Watson #include <sys/mac.h> 4395fab37eSRobert Watson #include <sys/systm.h> 4495fab37eSRobert Watson #include <sys/vnode.h> 4595fab37eSRobert Watson #include <sys/sysctl.h> 4695fab37eSRobert Watson 4795fab37eSRobert Watson #include <sys/mac_policy.h> 4895fab37eSRobert Watson 496bd11732SRobert Watson #include <security/mac/mac_internal.h> 5095fab37eSRobert Watson 51a3df768bSRobert Watson static int mac_enforce_kld = 1; 52a3df768bSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_kld, CTLFLAG_RW, 53a3df768bSRobert Watson &mac_enforce_kld, 0, "Enforce MAC policy on kld operations"); 54a3df768bSRobert Watson TUNABLE_INT("security.mac.enforce_kld", &mac_enforce_kld); 55a3df768bSRobert Watson 569e913ebdSRobert Watson static int mac_enforce_system = 1; 579e913ebdSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_system, CTLFLAG_RW, 589e913ebdSRobert Watson &mac_enforce_system, 0, "Enforce MAC policy on system operations"); 599e913ebdSRobert Watson TUNABLE_INT("security.mac.enforce_system", &mac_enforce_system); 60d3fc69eeSRobert Watson 6195fab37eSRobert Watson int 62e686e5aeSRobert Watson mac_check_kenv_dump(struct ucred *cred) 63e686e5aeSRobert Watson { 64e686e5aeSRobert Watson int error; 65e686e5aeSRobert Watson 66e686e5aeSRobert Watson if (!mac_enforce_system) 67e686e5aeSRobert Watson return (0); 68e686e5aeSRobert Watson 69e686e5aeSRobert Watson MAC_CHECK(check_kenv_dump, cred); 70e686e5aeSRobert Watson 71e686e5aeSRobert Watson return (error); 72e686e5aeSRobert Watson } 73e686e5aeSRobert Watson 74e686e5aeSRobert Watson int 75e686e5aeSRobert Watson mac_check_kenv_get(struct ucred *cred, char *name) 76e686e5aeSRobert Watson { 77e686e5aeSRobert Watson int error; 78e686e5aeSRobert Watson 79e686e5aeSRobert Watson if (!mac_enforce_system) 80e686e5aeSRobert Watson return (0); 81e686e5aeSRobert Watson 82e686e5aeSRobert Watson MAC_CHECK(check_kenv_get, cred, name); 83e686e5aeSRobert Watson 84e686e5aeSRobert Watson return (error); 85e686e5aeSRobert Watson } 86e686e5aeSRobert Watson 87e686e5aeSRobert Watson int 88e686e5aeSRobert Watson mac_check_kenv_set(struct ucred *cred, char *name, char *value) 89e686e5aeSRobert Watson { 90e686e5aeSRobert Watson int error; 91e686e5aeSRobert Watson 92e686e5aeSRobert Watson if (!mac_enforce_system) 93e686e5aeSRobert Watson return (0); 94e686e5aeSRobert Watson 95e686e5aeSRobert Watson MAC_CHECK(check_kenv_set, cred, name, value); 96e686e5aeSRobert Watson 97e686e5aeSRobert Watson return (error); 98e686e5aeSRobert Watson } 99e686e5aeSRobert Watson 100e686e5aeSRobert Watson int 101e686e5aeSRobert Watson mac_check_kenv_unset(struct ucred *cred, char *name) 102e686e5aeSRobert Watson { 103e686e5aeSRobert Watson int error; 104e686e5aeSRobert Watson 105e686e5aeSRobert Watson if (!mac_enforce_system) 106e686e5aeSRobert Watson return (0); 107e686e5aeSRobert Watson 108e686e5aeSRobert Watson MAC_CHECK(check_kenv_unset, cred, name); 109e686e5aeSRobert Watson 110e686e5aeSRobert Watson return (error); 111e686e5aeSRobert Watson } 112e686e5aeSRobert Watson 113e686e5aeSRobert Watson int 114a3df768bSRobert Watson mac_check_kld_load(struct ucred *cred, struct vnode *vp) 115a3df768bSRobert Watson { 116a3df768bSRobert Watson int error; 117a3df768bSRobert Watson 118a3df768bSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_kld_load"); 119a3df768bSRobert Watson 120a3df768bSRobert Watson if (!mac_enforce_kld) 121a3df768bSRobert Watson return (0); 122a3df768bSRobert Watson 123a3df768bSRobert Watson MAC_CHECK(check_kld_load, cred, vp, &vp->v_label); 124a3df768bSRobert Watson 125a3df768bSRobert Watson return (error); 126a3df768bSRobert Watson } 127a3df768bSRobert Watson 128a3df768bSRobert Watson int 129a3df768bSRobert Watson mac_check_kld_stat(struct ucred *cred) 130a3df768bSRobert Watson { 131a3df768bSRobert Watson int error; 132a3df768bSRobert Watson 133a3df768bSRobert Watson if (!mac_enforce_kld) 134a3df768bSRobert Watson return (0); 135a3df768bSRobert Watson 136a3df768bSRobert Watson MAC_CHECK(check_kld_stat, cred); 137a3df768bSRobert Watson 138a3df768bSRobert Watson return (error); 139a3df768bSRobert Watson } 140a3df768bSRobert Watson 141a3df768bSRobert Watson int 142a3df768bSRobert Watson mac_check_kld_unload(struct ucred *cred) 143a3df768bSRobert Watson { 144a3df768bSRobert Watson int error; 145a3df768bSRobert Watson 146a3df768bSRobert Watson if (!mac_enforce_kld) 147a3df768bSRobert Watson return (0); 148a3df768bSRobert Watson 149a3df768bSRobert Watson MAC_CHECK(check_kld_unload, cred); 150a3df768bSRobert Watson 151a3df768bSRobert Watson return (error); 152a3df768bSRobert Watson } 153a3df768bSRobert Watson 154a3df768bSRobert Watson int 15592835789SRobert Watson mac_check_sysarch_ioperm(struct ucred *cred) 15692835789SRobert Watson { 15792835789SRobert Watson int error; 15892835789SRobert Watson 15992835789SRobert Watson if (!mac_enforce_system) 16092835789SRobert Watson return (0); 16192835789SRobert Watson 16292835789SRobert Watson MAC_CHECK(check_sysarch_ioperm, cred); 16392835789SRobert Watson return (error); 16492835789SRobert Watson } 16592835789SRobert Watson 16692835789SRobert Watson int 167e5e820fdSRobert Watson mac_check_system_acct(struct ucred *cred, struct vnode *vp) 168e5e820fdSRobert Watson { 169e5e820fdSRobert Watson int error; 170e5e820fdSRobert Watson 171e5e820fdSRobert Watson if (vp != NULL) { 172e5e820fdSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_system_acct"); 173e5e820fdSRobert Watson } 174e5e820fdSRobert Watson 175e5e820fdSRobert Watson if (!mac_enforce_system) 176e5e820fdSRobert Watson return (0); 177e5e820fdSRobert Watson 178e5e820fdSRobert Watson MAC_CHECK(check_system_acct, cred, vp, 179e5e820fdSRobert Watson vp != NULL ? &vp->v_label : NULL); 180e5e820fdSRobert Watson 181e5e820fdSRobert Watson return (error); 182e5e820fdSRobert Watson } 183e5e820fdSRobert Watson 184e5e820fdSRobert Watson int 185e5e820fdSRobert Watson mac_check_system_nfsd(struct ucred *cred) 186e5e820fdSRobert Watson { 187e5e820fdSRobert Watson int error; 188e5e820fdSRobert Watson 189e5e820fdSRobert Watson if (!mac_enforce_system) 190e5e820fdSRobert Watson return (0); 191e5e820fdSRobert Watson 192e5e820fdSRobert Watson MAC_CHECK(check_system_nfsd, cred); 193e5e820fdSRobert Watson 194e5e820fdSRobert Watson return (error); 195e5e820fdSRobert Watson } 196e5e820fdSRobert Watson 197e5e820fdSRobert Watson int 198a2ecb9b7SRobert Watson mac_check_system_reboot(struct ucred *cred, int howto) 199a2ecb9b7SRobert Watson { 200a2ecb9b7SRobert Watson int error; 201a2ecb9b7SRobert Watson 2029e913ebdSRobert Watson if (!mac_enforce_system) 203a2ecb9b7SRobert Watson return (0); 204a2ecb9b7SRobert Watson 205a2ecb9b7SRobert Watson MAC_CHECK(check_system_reboot, cred, howto); 2069e913ebdSRobert Watson 207a2ecb9b7SRobert Watson return (error); 208a2ecb9b7SRobert Watson } 209a2ecb9b7SRobert Watson 210a2ecb9b7SRobert Watson int 2114b8d5f2dSRobert Watson mac_check_system_settime(struct ucred *cred) 2124b8d5f2dSRobert Watson { 2134b8d5f2dSRobert Watson int error; 2144b8d5f2dSRobert Watson 2154b8d5f2dSRobert Watson if (!mac_enforce_system) 2164b8d5f2dSRobert Watson return (0); 2174b8d5f2dSRobert Watson 2184b8d5f2dSRobert Watson MAC_CHECK(check_system_settime, cred); 2194b8d5f2dSRobert Watson 2204b8d5f2dSRobert Watson return (error); 2214b8d5f2dSRobert Watson } 2224b8d5f2dSRobert Watson 2234b8d5f2dSRobert Watson int 22403ce2c0cSRobert Watson mac_check_system_swapon(struct ucred *cred, struct vnode *vp) 22503ce2c0cSRobert Watson { 22603ce2c0cSRobert Watson int error; 22703ce2c0cSRobert Watson 22803ce2c0cSRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_system_swapon"); 22903ce2c0cSRobert Watson 2309e913ebdSRobert Watson if (!mac_enforce_system) 23103ce2c0cSRobert Watson return (0); 23203ce2c0cSRobert Watson 23303ce2c0cSRobert Watson MAC_CHECK(check_system_swapon, cred, vp, &vp->v_label); 23403ce2c0cSRobert Watson return (error); 23503ce2c0cSRobert Watson } 23603ce2c0cSRobert Watson 23703ce2c0cSRobert Watson int 2381b2c2ab2SRobert Watson mac_check_system_swapoff(struct ucred *cred, struct vnode *vp) 2391b2c2ab2SRobert Watson { 2401b2c2ab2SRobert Watson int error; 2411b2c2ab2SRobert Watson 2421b2c2ab2SRobert Watson ASSERT_VOP_LOCKED(vp, "mac_check_system_swapoff"); 2431b2c2ab2SRobert Watson 2441b2c2ab2SRobert Watson if (!mac_enforce_system) 2451b2c2ab2SRobert Watson return (0); 2461b2c2ab2SRobert Watson 2471b2c2ab2SRobert Watson MAC_CHECK(check_system_swapoff, cred, vp, &vp->v_label); 2481b2c2ab2SRobert Watson return (error); 2491b2c2ab2SRobert Watson } 2501b2c2ab2SRobert Watson 2511b2c2ab2SRobert Watson int 252d3fc69eeSRobert Watson mac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen, 253d3fc69eeSRobert Watson void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen) 254d3fc69eeSRobert Watson { 255d3fc69eeSRobert Watson int error; 256d3fc69eeSRobert Watson 257d3fc69eeSRobert Watson /* 258d3fc69eeSRobert Watson * XXXMAC: We're very much like to assert the SYSCTL_LOCK here, 259d3fc69eeSRobert Watson * but since it's not exported from kern_sysctl.c, we can't. 260d3fc69eeSRobert Watson */ 2619e913ebdSRobert Watson if (!mac_enforce_system) 262d3fc69eeSRobert Watson return (0); 263d3fc69eeSRobert Watson 264d3fc69eeSRobert Watson MAC_CHECK(check_system_sysctl, cred, name, namelen, old, oldlenp, 265d3fc69eeSRobert Watson inkernel, new, newlen); 266d3fc69eeSRobert Watson 267d3fc69eeSRobert Watson return (error); 268d3fc69eeSRobert Watson } 269