xref: /freebsd/sys/security/mac/mac_system.c (revision 6bd11732588192f935e835e69ae9c48f0e4242d8)
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