mac_partition.c revision 105828
1105828Srwatson/*-
2105828Srwatson * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
3105828Srwatson * Copyright (c) 2001, 2002 Networks Associates Technology, Inc.
4105828Srwatson * All rights reserved.
5105828Srwatson *
6105828Srwatson * This software was developed by Robert Watson for the TrustedBSD Project.
7105828Srwatson *
8105828Srwatson * This software was developed for the FreeBSD Project in part by NAI Labs,
9105828Srwatson * the Security Research Division of Network Associates, Inc. under
10105828Srwatson * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA
11105828Srwatson * CHATS research program.
12105828Srwatson *
13105828Srwatson * Redistribution and use in source and binary forms, with or without
14105828Srwatson * modification, are permitted provided that the following conditions
15105828Srwatson * are met:
16105828Srwatson * 1. Redistributions of source code must retain the above copyright
17105828Srwatson *    notice, this list of conditions and the following disclaimer.
18105828Srwatson * 2. Redistributions in binary form must reproduce the above copyright
19105828Srwatson *    notice, this list of conditions and the following disclaimer in the
20105828Srwatson *    documentation and/or other materials provided with the distribution.
21105828Srwatson * 3. The names of the authors may not be used to endorse or promote
22105828Srwatson *    products derived from this software without specific prior written
23105828Srwatson *    permission.
24105828Srwatson *
25105828Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
26105828Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27105828Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28105828Srwatson * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
29105828Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30105828Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31105828Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32105828Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33105828Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34105828Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35105828Srwatson * SUCH DAMAGE.
36105828Srwatson *
37105828Srwatson * $FreeBSD: head/sys/security/mac_partition/mac_partition.c 105828 2002-10-23 23:36:27Z rwatson $
38105828Srwatson */
39105828Srwatson
40105828Srwatson/*
41105828Srwatson * Developed by the TrustedBSD Project.
42105828Srwatson * Experiment with a partition-like model.
43105828Srwatson */
44105828Srwatson
45105828Srwatson#include <sys/types.h>
46105828Srwatson#include <sys/param.h>
47105828Srwatson#include <sys/conf.h>
48105828Srwatson#include <sys/kernel.h>
49105828Srwatson#include <sys/mac.h>
50105828Srwatson#include <sys/mount.h>
51105828Srwatson#include <sys/proc.h>
52105828Srwatson#include <sys/systm.h>
53105828Srwatson#include <sys/sysproto.h>
54105828Srwatson#include <sys/sysent.h>
55105828Srwatson#include <sys/vnode.h>
56105828Srwatson#include <sys/file.h>
57105828Srwatson#include <sys/socket.h>
58105828Srwatson#include <sys/socketvar.h>
59105828Srwatson#include <sys/sysctl.h>
60105828Srwatson
61105828Srwatson#include <fs/devfs/devfs.h>
62105828Srwatson
63105828Srwatson#include <net/bpfdesc.h>
64105828Srwatson#include <net/if.h>
65105828Srwatson#include <net/if_types.h>
66105828Srwatson#include <net/if_var.h>
67105828Srwatson
68105828Srwatson#include <vm/vm.h>
69105828Srwatson
70105828Srwatson#include <sys/mac_policy.h>
71105828Srwatson
72105828Srwatson#include <security/mac_partition/mac_partition.h>
73105828Srwatson
74105828SrwatsonSYSCTL_DECL(_security_mac);
75105828Srwatson
76105828SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, partition, CTLFLAG_RW, 0,
77105828Srwatson    "TrustedBSD mac_partition policy controls");
78105828Srwatson
79105828Srwatsonstatic int	mac_partition_enabled = 1;
80105828SrwatsonSYSCTL_INT(_security_mac_partition, OID_AUTO, enabled, CTLFLAG_RW,
81105828Srwatson    &mac_partition_enabled, 0, "Enforce partition policy");
82105828Srwatson
83105828Srwatsonstatic int	partition_slot;
84105828Srwatson#define	SLOT(l)	(LABEL_TO_SLOT((l), partition_slot).l_long)
85105828Srwatson
86105828Srwatsonstatic void
87105828Srwatsonmac_partition_init(struct mac_policy_conf *conf)
88105828Srwatson{
89105828Srwatson
90105828Srwatson}
91105828Srwatson
92105828Srwatsonstatic void
93105828Srwatsonmac_partition_init_label(struct label *label)
94105828Srwatson{
95105828Srwatson
96105828Srwatson	SLOT(label) = 0;
97105828Srwatson}
98105828Srwatson
99105828Srwatsonstatic void
100105828Srwatsonmac_partition_destroy_label(struct label *label)
101105828Srwatson{
102105828Srwatson
103105828Srwatson	SLOT(label) = 0;
104105828Srwatson}
105105828Srwatson
106105828Srwatsonstatic int
107105828Srwatsonmac_partition_externalize_label(struct label *label, char *element_name,
108105828Srwatson    char *element_data, size_t size, size_t *len, int *claimed)
109105828Srwatson{
110105828Srwatson
111105828Srwatson	if (strcmp(MAC_PARTITION_LABEL_NAME, element_name) != 0)
112105828Srwatson		return (0);
113105828Srwatson
114105828Srwatson	(*claimed)++;
115105828Srwatson	*len = snprintf(element_data, size, "%ld", SLOT(label));
116105828Srwatson	return (0);
117105828Srwatson}
118105828Srwatson
119105828Srwatsonstatic int
120105828Srwatsonmac_partition_internalize_label(struct label *label, char *element_name,
121105828Srwatson    char *element_data, int *claimed)
122105828Srwatson{
123105828Srwatson
124105828Srwatson	if (strcmp(MAC_PARTITION_LABEL_NAME, element_name) != 0)
125105828Srwatson		return (0);
126105828Srwatson
127105828Srwatson	(*claimed)++;
128105828Srwatson	SLOT(label) = strtol(element_data, NULL, 10);
129105828Srwatson	return (0);
130105828Srwatson}
131105828Srwatson
132105828Srwatsonstatic void
133105828Srwatsonmac_partition_create_cred(struct ucred *cred_parent, struct ucred *cred_child)
134105828Srwatson{
135105828Srwatson
136105828Srwatson	SLOT(&cred_child->cr_label) = SLOT(&cred_parent->cr_label);
137105828Srwatson}
138105828Srwatson
139105828Srwatsonstatic void
140105828Srwatsonmac_partition_create_proc0(struct ucred *cred)
141105828Srwatson{
142105828Srwatson
143105828Srwatson	SLOT(&cred->cr_label) = 0;
144105828Srwatson}
145105828Srwatson
146105828Srwatsonstatic void
147105828Srwatsonmac_partition_create_proc1(struct ucred *cred)
148105828Srwatson{
149105828Srwatson
150105828Srwatson	SLOT(&cred->cr_label) = 0;
151105828Srwatson}
152105828Srwatson
153105828Srwatsonstatic void
154105828Srwatsonmac_partition_relabel_cred(struct ucred *cred, struct label *newlabel)
155105828Srwatson{
156105828Srwatson
157105828Srwatson	if (SLOT(newlabel) != 0)
158105828Srwatson		SLOT(&cred->cr_label) = SLOT(newlabel);
159105828Srwatson}
160105828Srwatson
161105828Srwatsonstatic int
162105828Srwatsonlabel_on_label(struct label *subject, struct label *object)
163105828Srwatson{
164105828Srwatson
165105828Srwatson	if (mac_partition_enabled == 0)
166105828Srwatson		return (0);
167105828Srwatson
168105828Srwatson	if (SLOT(subject) == 0)
169105828Srwatson		return (0);
170105828Srwatson
171105828Srwatson	if (SLOT(subject) == SLOT(object))
172105828Srwatson		return (0);
173105828Srwatson
174105828Srwatson	return (EPERM);
175105828Srwatson}
176105828Srwatson
177105828Srwatsonstatic int
178105828Srwatsonmac_partition_check_cred_relabel(struct ucred *cred, struct label *newlabel)
179105828Srwatson{
180105828Srwatson	int error;
181105828Srwatson
182105828Srwatson	error = 0;
183105828Srwatson
184105828Srwatson	/* Treat "0" as a no-op request. */
185105828Srwatson	if (SLOT(newlabel) != 0) {
186105828Srwatson		/* If we're already in a partition, can't repartition. */
187105828Srwatson		if (SLOT(&cred->cr_label) != 0)
188105828Srwatson			return (EPERM);
189105828Srwatson
190105828Srwatson		/*
191105828Srwatson		 * If not in a partition, must have privilege to create
192105828Srwatson		 * one.
193105828Srwatson		 */
194105828Srwatson		error = suser_cred(cred, 0);
195105828Srwatson	}
196105828Srwatson
197105828Srwatson	return (error);
198105828Srwatson}
199105828Srwatson
200105828Srwatsonstatic int
201105828Srwatsonmac_partition_check_cred_visible(struct ucred *u1, struct ucred *u2)
202105828Srwatson{
203105828Srwatson	int error;
204105828Srwatson
205105828Srwatson	error = label_on_label(&u1->cr_label, &u2->cr_label);
206105828Srwatson
207105828Srwatson	return (error == 0 ? 0 : ESRCH);
208105828Srwatson}
209105828Srwatson
210105828Srwatsonstatic int
211105828Srwatsonmac_partition_check_proc_debug(struct ucred *cred, struct proc *proc)
212105828Srwatson{
213105828Srwatson	int error;
214105828Srwatson
215105828Srwatson	error = label_on_label(&cred->cr_label, &proc->p_ucred->cr_label);
216105828Srwatson
217105828Srwatson	return (error ? ESRCH : 0);
218105828Srwatson}
219105828Srwatson
220105828Srwatsonstatic int
221105828Srwatsonmac_partition_check_proc_sched(struct ucred *cred, struct proc *proc)
222105828Srwatson{
223105828Srwatson	int error;
224105828Srwatson
225105828Srwatson	error = label_on_label(&cred->cr_label, &proc->p_ucred->cr_label);
226105828Srwatson
227105828Srwatson	return (error ? ESRCH : 0);
228105828Srwatson}
229105828Srwatson
230105828Srwatsonstatic int
231105828Srwatsonmac_partition_check_proc_signal(struct ucred *cred, struct proc *proc,
232105828Srwatson    int signum)
233105828Srwatson{
234105828Srwatson	int error;
235105828Srwatson
236105828Srwatson	error = label_on_label(&cred->cr_label, &proc->p_ucred->cr_label);
237105828Srwatson
238105828Srwatson	return (error ? ESRCH : 0);
239105828Srwatson}
240105828Srwatson
241105828Srwatsonstatic int
242105828Srwatsonmac_partition_check_socket_visible(struct ucred *cred, struct socket *socket,
243105828Srwatson    struct label *socketlabel)
244105828Srwatson{
245105828Srwatson	int error;
246105828Srwatson
247105828Srwatson	error = label_on_label(&cred->cr_label, socketlabel);
248105828Srwatson
249105828Srwatson	return (error ? ENOENT : 0);
250105828Srwatson}
251105828Srwatson
252105828Srwatsonstatic struct mac_policy_op_entry mac_partition_ops[] =
253105828Srwatson{
254105828Srwatson	{ MAC_INIT,
255105828Srwatson	    (macop_t)mac_partition_init },
256105828Srwatson	{ MAC_INIT_CRED_LABEL,
257105828Srwatson	    (macop_t)mac_partition_init_label },
258105828Srwatson	{ MAC_DESTROY_CRED_LABEL,
259105828Srwatson	    (macop_t)mac_partition_destroy_label },
260105828Srwatson	{ MAC_EXTERNALIZE_CRED_LABEL,
261105828Srwatson	    (macop_t)mac_partition_externalize_label },
262105828Srwatson	{ MAC_INTERNALIZE_CRED_LABEL,
263105828Srwatson	    (macop_t)mac_partition_internalize_label },
264105828Srwatson	{ MAC_CREATE_CRED,
265105828Srwatson	    (macop_t)mac_partition_create_cred },
266105828Srwatson	{ MAC_CREATE_PROC0,
267105828Srwatson	    (macop_t)mac_partition_create_proc0 },
268105828Srwatson	{ MAC_CREATE_PROC1,
269105828Srwatson	    (macop_t)mac_partition_create_proc1 },
270105828Srwatson	{ MAC_RELABEL_CRED,
271105828Srwatson	    (macop_t)mac_partition_relabel_cred },
272105828Srwatson	{ MAC_CHECK_CRED_RELABEL,
273105828Srwatson	    (macop_t)mac_partition_check_cred_relabel },
274105828Srwatson	{ MAC_CHECK_CRED_VISIBLE,
275105828Srwatson	    (macop_t)mac_partition_check_cred_visible },
276105828Srwatson	{ MAC_CHECK_PROC_DEBUG,
277105828Srwatson	    (macop_t)mac_partition_check_proc_debug },
278105828Srwatson	{ MAC_CHECK_PROC_SCHED,
279105828Srwatson	    (macop_t)mac_partition_check_proc_sched },
280105828Srwatson	{ MAC_CHECK_PROC_SIGNAL,
281105828Srwatson	    (macop_t)mac_partition_check_proc_signal },
282105828Srwatson	{ MAC_CHECK_SOCKET_VISIBLE,
283105828Srwatson	    (macop_t)mac_partition_check_socket_visible },
284105828Srwatson	{ MAC_OP_LAST, NULL }
285105828Srwatson};
286105828Srwatson
287105828SrwatsonMAC_POLICY_SET(mac_partition_ops, trustedbsd_mac_partition,
288105828Srwatson    "TrustedBSD MAC/Partition", MPC_LOADTIME_FLAG_UNLOADOK, &partition_slot);
289