mac_partition.c revision 105828
1/*-
2 * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
3 * Copyright (c) 2001, 2002 Networks Associates Technology, Inc.
4 * All rights reserved.
5 *
6 * This software was developed by Robert Watson for the TrustedBSD Project.
7 *
8 * This software was developed for the FreeBSD Project in part by NAI Labs,
9 * the Security Research Division of Network Associates, Inc. under
10 * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA
11 * CHATS research program.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 *    notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 *    notice, this list of conditions and the following disclaimer in the
20 *    documentation and/or other materials provided with the distribution.
21 * 3. The names of the authors may not be used to endorse or promote
22 *    products derived from this software without specific prior written
23 *    permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 *
37 * $FreeBSD: head/sys/security/mac_partition/mac_partition.c 105828 2002-10-23 23:36:27Z rwatson $
38 */
39
40/*
41 * Developed by the TrustedBSD Project.
42 * Experiment with a partition-like model.
43 */
44
45#include <sys/types.h>
46#include <sys/param.h>
47#include <sys/conf.h>
48#include <sys/kernel.h>
49#include <sys/mac.h>
50#include <sys/mount.h>
51#include <sys/proc.h>
52#include <sys/systm.h>
53#include <sys/sysproto.h>
54#include <sys/sysent.h>
55#include <sys/vnode.h>
56#include <sys/file.h>
57#include <sys/socket.h>
58#include <sys/socketvar.h>
59#include <sys/sysctl.h>
60
61#include <fs/devfs/devfs.h>
62
63#include <net/bpfdesc.h>
64#include <net/if.h>
65#include <net/if_types.h>
66#include <net/if_var.h>
67
68#include <vm/vm.h>
69
70#include <sys/mac_policy.h>
71
72#include <security/mac_partition/mac_partition.h>
73
74SYSCTL_DECL(_security_mac);
75
76SYSCTL_NODE(_security_mac, OID_AUTO, partition, CTLFLAG_RW, 0,
77    "TrustedBSD mac_partition policy controls");
78
79static int	mac_partition_enabled = 1;
80SYSCTL_INT(_security_mac_partition, OID_AUTO, enabled, CTLFLAG_RW,
81    &mac_partition_enabled, 0, "Enforce partition policy");
82
83static int	partition_slot;
84#define	SLOT(l)	(LABEL_TO_SLOT((l), partition_slot).l_long)
85
86static void
87mac_partition_init(struct mac_policy_conf *conf)
88{
89
90}
91
92static void
93mac_partition_init_label(struct label *label)
94{
95
96	SLOT(label) = 0;
97}
98
99static void
100mac_partition_destroy_label(struct label *label)
101{
102
103	SLOT(label) = 0;
104}
105
106static int
107mac_partition_externalize_label(struct label *label, char *element_name,
108    char *element_data, size_t size, size_t *len, int *claimed)
109{
110
111	if (strcmp(MAC_PARTITION_LABEL_NAME, element_name) != 0)
112		return (0);
113
114	(*claimed)++;
115	*len = snprintf(element_data, size, "%ld", SLOT(label));
116	return (0);
117}
118
119static int
120mac_partition_internalize_label(struct label *label, char *element_name,
121    char *element_data, int *claimed)
122{
123
124	if (strcmp(MAC_PARTITION_LABEL_NAME, element_name) != 0)
125		return (0);
126
127	(*claimed)++;
128	SLOT(label) = strtol(element_data, NULL, 10);
129	return (0);
130}
131
132static void
133mac_partition_create_cred(struct ucred *cred_parent, struct ucred *cred_child)
134{
135
136	SLOT(&cred_child->cr_label) = SLOT(&cred_parent->cr_label);
137}
138
139static void
140mac_partition_create_proc0(struct ucred *cred)
141{
142
143	SLOT(&cred->cr_label) = 0;
144}
145
146static void
147mac_partition_create_proc1(struct ucred *cred)
148{
149
150	SLOT(&cred->cr_label) = 0;
151}
152
153static void
154mac_partition_relabel_cred(struct ucred *cred, struct label *newlabel)
155{
156
157	if (SLOT(newlabel) != 0)
158		SLOT(&cred->cr_label) = SLOT(newlabel);
159}
160
161static int
162label_on_label(struct label *subject, struct label *object)
163{
164
165	if (mac_partition_enabled == 0)
166		return (0);
167
168	if (SLOT(subject) == 0)
169		return (0);
170
171	if (SLOT(subject) == SLOT(object))
172		return (0);
173
174	return (EPERM);
175}
176
177static int
178mac_partition_check_cred_relabel(struct ucred *cred, struct label *newlabel)
179{
180	int error;
181
182	error = 0;
183
184	/* Treat "0" as a no-op request. */
185	if (SLOT(newlabel) != 0) {
186		/* If we're already in a partition, can't repartition. */
187		if (SLOT(&cred->cr_label) != 0)
188			return (EPERM);
189
190		/*
191		 * If not in a partition, must have privilege to create
192		 * one.
193		 */
194		error = suser_cred(cred, 0);
195	}
196
197	return (error);
198}
199
200static int
201mac_partition_check_cred_visible(struct ucred *u1, struct ucred *u2)
202{
203	int error;
204
205	error = label_on_label(&u1->cr_label, &u2->cr_label);
206
207	return (error == 0 ? 0 : ESRCH);
208}
209
210static int
211mac_partition_check_proc_debug(struct ucred *cred, struct proc *proc)
212{
213	int error;
214
215	error = label_on_label(&cred->cr_label, &proc->p_ucred->cr_label);
216
217	return (error ? ESRCH : 0);
218}
219
220static int
221mac_partition_check_proc_sched(struct ucred *cred, struct proc *proc)
222{
223	int error;
224
225	error = label_on_label(&cred->cr_label, &proc->p_ucred->cr_label);
226
227	return (error ? ESRCH : 0);
228}
229
230static int
231mac_partition_check_proc_signal(struct ucred *cred, struct proc *proc,
232    int signum)
233{
234	int error;
235
236	error = label_on_label(&cred->cr_label, &proc->p_ucred->cr_label);
237
238	return (error ? ESRCH : 0);
239}
240
241static int
242mac_partition_check_socket_visible(struct ucred *cred, struct socket *socket,
243    struct label *socketlabel)
244{
245	int error;
246
247	error = label_on_label(&cred->cr_label, socketlabel);
248
249	return (error ? ENOENT : 0);
250}
251
252static struct mac_policy_op_entry mac_partition_ops[] =
253{
254	{ MAC_INIT,
255	    (macop_t)mac_partition_init },
256	{ MAC_INIT_CRED_LABEL,
257	    (macop_t)mac_partition_init_label },
258	{ MAC_DESTROY_CRED_LABEL,
259	    (macop_t)mac_partition_destroy_label },
260	{ MAC_EXTERNALIZE_CRED_LABEL,
261	    (macop_t)mac_partition_externalize_label },
262	{ MAC_INTERNALIZE_CRED_LABEL,
263	    (macop_t)mac_partition_internalize_label },
264	{ MAC_CREATE_CRED,
265	    (macop_t)mac_partition_create_cred },
266	{ MAC_CREATE_PROC0,
267	    (macop_t)mac_partition_create_proc0 },
268	{ MAC_CREATE_PROC1,
269	    (macop_t)mac_partition_create_proc1 },
270	{ MAC_RELABEL_CRED,
271	    (macop_t)mac_partition_relabel_cred },
272	{ MAC_CHECK_CRED_RELABEL,
273	    (macop_t)mac_partition_check_cred_relabel },
274	{ MAC_CHECK_CRED_VISIBLE,
275	    (macop_t)mac_partition_check_cred_visible },
276	{ MAC_CHECK_PROC_DEBUG,
277	    (macop_t)mac_partition_check_proc_debug },
278	{ MAC_CHECK_PROC_SCHED,
279	    (macop_t)mac_partition_check_proc_sched },
280	{ MAC_CHECK_PROC_SIGNAL,
281	    (macop_t)mac_partition_check_proc_signal },
282	{ MAC_CHECK_SOCKET_VISIBLE,
283	    (macop_t)mac_partition_check_socket_visible },
284	{ MAC_OP_LAST, NULL }
285};
286
287MAC_POLICY_SET(mac_partition_ops, trustedbsd_mac_partition,
288    "TrustedBSD MAC/Partition", MPC_LOADTIME_FLAG_UNLOADOK, &partition_slot);
289