Deleted Added
full compact
mac_lomac.c (151897) mac_lomac.c (162238)
1/*-
2 * Copyright (c) 1999-2002 Robert N. M. Watson
3 * Copyright (c) 2001-2005 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 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
1/*-
2 * Copyright (c) 1999-2002 Robert N. M. Watson
3 * Copyright (c) 2001-2005 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 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 * $FreeBSD: head/sys/security/mac_lomac/mac_lomac.c 151897 2005-10-31 15:41:29Z rwatson $
34 * $FreeBSD: head/sys/security/mac_lomac/mac_lomac.c 162238 2006-09-12 04:25:13Z csjp $
35 */
36
37/*
38 * Developed by the TrustedBSD Project.
39 * Low-watermark floating label mandatory integrity policy.
40 */
41
42#include <sys/types.h>
43#include <sys/param.h>
44#include <sys/acl.h>
45#include <sys/conf.h>
46#include <sys/extattr.h>
47#include <sys/kernel.h>
48#include <sys/mac.h>
49#include <sys/malloc.h>
50#include <sys/mman.h>
51#include <sys/mount.h>
52#include <sys/proc.h>
53#include <sys/sbuf.h>
54#include <sys/systm.h>
55#include <sys/sysproto.h>
56#include <sys/sysent.h>
57#include <sys/systm.h>
58#include <sys/vnode.h>
59#include <sys/file.h>
60#include <sys/socket.h>
61#include <sys/socketvar.h>
62#include <sys/sx.h>
63#include <sys/pipe.h>
64#include <sys/sysctl.h>
65#include <sys/syslog.h>
66
67#include <fs/devfs/devfs.h>
68
69#include <net/bpfdesc.h>
70#include <net/if.h>
71#include <net/if_types.h>
72#include <net/if_var.h>
73
74#include <netinet/in.h>
75#include <netinet/in_pcb.h>
76#include <netinet/ip_var.h>
77
78#include <vm/vm.h>
79
80#include <sys/mac_policy.h>
81
82#include <security/mac_lomac/mac_lomac.h>
83
84struct mac_lomac_proc {
85 struct mac_lomac mac_lomac;
86 struct mtx mtx;
87};
88
89SYSCTL_DECL(_security_mac);
90
91SYSCTL_NODE(_security_mac, OID_AUTO, lomac, CTLFLAG_RW, 0,
92 "TrustedBSD mac_lomac policy controls");
93
94static int mac_lomac_label_size = sizeof(struct mac_lomac);
95SYSCTL_INT(_security_mac_lomac, OID_AUTO, label_size, CTLFLAG_RD,
96 &mac_lomac_label_size, 0, "Size of struct mac_lomac");
97
98static int mac_lomac_enabled = 1;
99SYSCTL_INT(_security_mac_lomac, OID_AUTO, enabled, CTLFLAG_RW,
100 &mac_lomac_enabled, 0, "Enforce MAC/LOMAC policy");
101TUNABLE_INT("security.mac.lomac.enabled", &mac_lomac_enabled);
102
103static int destroyed_not_inited;
104SYSCTL_INT(_security_mac_lomac, OID_AUTO, destroyed_not_inited, CTLFLAG_RD,
105 &destroyed_not_inited, 0, "Count of labels destroyed but not inited");
106
107static int trust_all_interfaces = 0;
108SYSCTL_INT(_security_mac_lomac, OID_AUTO, trust_all_interfaces, CTLFLAG_RD,
109 &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/LOMAC");
110TUNABLE_INT("security.mac.lomac.trust_all_interfaces", &trust_all_interfaces);
111
112static char trusted_interfaces[128];
113SYSCTL_STRING(_security_mac_lomac, OID_AUTO, trusted_interfaces, CTLFLAG_RD,
114 trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/LOMAC");
115TUNABLE_STR("security.mac.lomac.trusted_interfaces", trusted_interfaces,
116 sizeof(trusted_interfaces));
117
118static int ptys_equal = 0;
119SYSCTL_INT(_security_mac_lomac, OID_AUTO, ptys_equal, CTLFLAG_RW,
120 &ptys_equal, 0, "Label pty devices as lomac/equal on create");
121TUNABLE_INT("security.mac.lomac.ptys_equal", &ptys_equal);
122
123static int revocation_enabled = 1;
124SYSCTL_INT(_security_mac_lomac, OID_AUTO, revocation_enabled, CTLFLAG_RW,
125 &revocation_enabled, 0, "Revoke access to objects on relabel");
126TUNABLE_INT("security.mac.lomac.revocation_enabled", &revocation_enabled);
127
128static int mac_lomac_slot;
129#define SLOT(l) ((struct mac_lomac *)LABEL_TO_SLOT((l), mac_lomac_slot).l_ptr)
130#define SLOT_SET(l, val) (LABEL_TO_SLOT((l), mac_lomac_slot).l_ptr = (val))
131#define PSLOT(l) ((struct mac_lomac_proc *) \
132 LABEL_TO_SLOT((l), mac_lomac_slot).l_ptr)
133#define PSLOT_SET(l, val) (LABEL_TO_SLOT((l), mac_lomac_slot).l_ptr = (val))
134
135MALLOC_DEFINE(M_MACLOMAC, "mac_lomac_label", "MAC/LOMAC labels");
136
137static struct mac_lomac *
138lomac_alloc(int flag)
139{
140 struct mac_lomac *mac_lomac;
141
142 mac_lomac = malloc(sizeof(struct mac_lomac), M_MACLOMAC, M_ZERO | flag);
143
144 return (mac_lomac);
145}
146
147static void
148lomac_free(struct mac_lomac *mac_lomac)
149{
150
151 if (mac_lomac != NULL)
152 free(mac_lomac, M_MACLOMAC);
153 else
154 atomic_add_int(&destroyed_not_inited, 1);
155}
156
157static int
158lomac_atmostflags(struct mac_lomac *mac_lomac, int flags)
159{
160
161 if ((mac_lomac->ml_flags & flags) != mac_lomac->ml_flags)
162 return (EINVAL);
163 return (0);
164}
165
166static int
167mac_lomac_dominate_element(struct mac_lomac_element *a,
168 struct mac_lomac_element *b)
169{
170
171 switch (a->mle_type) {
172 case MAC_LOMAC_TYPE_EQUAL:
173 case MAC_LOMAC_TYPE_HIGH:
174 return (1);
175
176 case MAC_LOMAC_TYPE_LOW:
177 switch (b->mle_type) {
178 case MAC_LOMAC_TYPE_GRADE:
179 case MAC_LOMAC_TYPE_HIGH:
180 return (0);
181
182 case MAC_LOMAC_TYPE_EQUAL:
183 case MAC_LOMAC_TYPE_LOW:
184 return (1);
185
186 default:
187 panic("mac_lomac_dominate_element: b->mle_type invalid");
188 }
189
190 case MAC_LOMAC_TYPE_GRADE:
191 switch (b->mle_type) {
192 case MAC_LOMAC_TYPE_EQUAL:
193 case MAC_LOMAC_TYPE_LOW:
194 return (1);
195
196 case MAC_LOMAC_TYPE_HIGH:
197 return (0);
198
199 case MAC_LOMAC_TYPE_GRADE:
200 return (a->mle_grade >= b->mle_grade);
201
202 default:
203 panic("mac_lomac_dominate_element: b->mle_type invalid");
204 }
205
206 default:
207 panic("mac_lomac_dominate_element: a->mle_type invalid");
208 }
209}
210
211static int
212mac_lomac_range_in_range(struct mac_lomac *rangea, struct mac_lomac *rangeb)
213{
214
215 return (mac_lomac_dominate_element(&rangeb->ml_rangehigh,
216 &rangea->ml_rangehigh) &&
217 mac_lomac_dominate_element(&rangea->ml_rangelow,
218 &rangeb->ml_rangelow));
219}
220
221static int
222mac_lomac_single_in_range(struct mac_lomac *single, struct mac_lomac *range)
223{
224
225 KASSERT((single->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
226 ("mac_lomac_single_in_range: a not single"));
227 KASSERT((range->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0,
228 ("mac_lomac_single_in_range: b not range"));
229
230 return (mac_lomac_dominate_element(&range->ml_rangehigh,
231 &single->ml_single) &&
232 mac_lomac_dominate_element(&single->ml_single,
233 &range->ml_rangelow));
234}
235
236static int
237mac_lomac_auxsingle_in_range(struct mac_lomac *single, struct mac_lomac *range)
238{
239
240 KASSERT((single->ml_flags & MAC_LOMAC_FLAG_AUX) != 0,
241 ("mac_lomac_single_in_range: a not auxsingle"));
242 KASSERT((range->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0,
243 ("mac_lomac_single_in_range: b not range"));
244
245 return (mac_lomac_dominate_element(&range->ml_rangehigh,
246 &single->ml_auxsingle) &&
247 mac_lomac_dominate_element(&single->ml_auxsingle,
248 &range->ml_rangelow));
249}
250
251static int
252mac_lomac_dominate_single(struct mac_lomac *a, struct mac_lomac *b)
253{
254 KASSERT((a->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
255 ("mac_lomac_dominate_single: a not single"));
256 KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
257 ("mac_lomac_dominate_single: b not single"));
258
259 return (mac_lomac_dominate_element(&a->ml_single, &b->ml_single));
260}
261
262static int
263mac_lomac_subject_dominate(struct mac_lomac *a, struct mac_lomac *b)
264{
265 KASSERT((~a->ml_flags &
266 (MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_RANGE)) == 0,
267 ("mac_lomac_dominate_single: a not subject"));
268 KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
269 ("mac_lomac_dominate_single: b not single"));
270
271 return (mac_lomac_dominate_element(&a->ml_rangehigh,
272 &b->ml_single));
273}
274
275static int
276mac_lomac_equal_element(struct mac_lomac_element *a, struct mac_lomac_element *b)
277{
278
279 if (a->mle_type == MAC_LOMAC_TYPE_EQUAL ||
280 b->mle_type == MAC_LOMAC_TYPE_EQUAL)
281 return (1);
282
283 return (a->mle_type == b->mle_type && a->mle_grade == b->mle_grade);
284}
285
286static int
287mac_lomac_equal_single(struct mac_lomac *a, struct mac_lomac *b)
288{
289
290 KASSERT((a->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
291 ("mac_lomac_equal_single: a not single"));
292 KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
293 ("mac_lomac_equal_single: b not single"));
294
295 return (mac_lomac_equal_element(&a->ml_single, &b->ml_single));
296}
297
298static int
299mac_lomac_contains_equal(struct mac_lomac *mac_lomac)
300{
301
302 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE)
303 if (mac_lomac->ml_single.mle_type == MAC_LOMAC_TYPE_EQUAL)
304 return (1);
305 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_AUX)
306 if (mac_lomac->ml_auxsingle.mle_type == MAC_LOMAC_TYPE_EQUAL)
307 return (1);
308
309 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_RANGE) {
310 if (mac_lomac->ml_rangelow.mle_type == MAC_LOMAC_TYPE_EQUAL)
311 return (1);
312 if (mac_lomac->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_EQUAL)
313 return (1);
314 }
315
316 return (0);
317}
318
319static int
320mac_lomac_subject_privileged(struct mac_lomac *mac_lomac)
321{
322
323 KASSERT((mac_lomac->ml_flags & MAC_LOMAC_FLAGS_BOTH) ==
324 MAC_LOMAC_FLAGS_BOTH,
325 ("mac_lomac_subject_privileged: subject doesn't have both labels"));
326
327 /* If the single is EQUAL, it's ok. */
328 if (mac_lomac->ml_single.mle_type == MAC_LOMAC_TYPE_EQUAL)
329 return (0);
330
331 /* If either range endpoint is EQUAL, it's ok. */
332 if (mac_lomac->ml_rangelow.mle_type == MAC_LOMAC_TYPE_EQUAL ||
333 mac_lomac->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_EQUAL)
334 return (0);
335
336 /* If the range is low-high, it's ok. */
337 if (mac_lomac->ml_rangelow.mle_type == MAC_LOMAC_TYPE_LOW &&
338 mac_lomac->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_HIGH)
339 return (0);
340
341 /* It's not ok. */
342 return (EPERM);
343}
344
345static int
346mac_lomac_high_single(struct mac_lomac *mac_lomac)
347{
348
349 KASSERT((mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
350 ("mac_lomac_high_single: mac_lomac not single"));
351
352 return (mac_lomac->ml_single.mle_type == MAC_LOMAC_TYPE_HIGH);
353}
354
355static int
356mac_lomac_valid(struct mac_lomac *mac_lomac)
357{
358
359 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
360 switch (mac_lomac->ml_single.mle_type) {
361 case MAC_LOMAC_TYPE_GRADE:
362 case MAC_LOMAC_TYPE_EQUAL:
363 case MAC_LOMAC_TYPE_HIGH:
364 case MAC_LOMAC_TYPE_LOW:
365 break;
366
367 default:
368 return (EINVAL);
369 }
370 } else {
371 if (mac_lomac->ml_single.mle_type != MAC_LOMAC_TYPE_UNDEF)
372 return (EINVAL);
373 }
374
375 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_AUX) {
376 switch (mac_lomac->ml_auxsingle.mle_type) {
377 case MAC_LOMAC_TYPE_GRADE:
378 case MAC_LOMAC_TYPE_EQUAL:
379 case MAC_LOMAC_TYPE_HIGH:
380 case MAC_LOMAC_TYPE_LOW:
381 break;
382
383 default:
384 return (EINVAL);
385 }
386 } else {
387 if (mac_lomac->ml_auxsingle.mle_type != MAC_LOMAC_TYPE_UNDEF)
388 return (EINVAL);
389 }
390
391 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_RANGE) {
392 switch (mac_lomac->ml_rangelow.mle_type) {
393 case MAC_LOMAC_TYPE_GRADE:
394 case MAC_LOMAC_TYPE_EQUAL:
395 case MAC_LOMAC_TYPE_HIGH:
396 case MAC_LOMAC_TYPE_LOW:
397 break;
398
399 default:
400 return (EINVAL);
401 }
402
403 switch (mac_lomac->ml_rangehigh.mle_type) {
404 case MAC_LOMAC_TYPE_GRADE:
405 case MAC_LOMAC_TYPE_EQUAL:
406 case MAC_LOMAC_TYPE_HIGH:
407 case MAC_LOMAC_TYPE_LOW:
408 break;
409
410 default:
411 return (EINVAL);
412 }
413 if (!mac_lomac_dominate_element(&mac_lomac->ml_rangehigh,
414 &mac_lomac->ml_rangelow))
415 return (EINVAL);
416 } else {
417 if (mac_lomac->ml_rangelow.mle_type != MAC_LOMAC_TYPE_UNDEF ||
418 mac_lomac->ml_rangehigh.mle_type != MAC_LOMAC_TYPE_UNDEF)
419 return (EINVAL);
420 }
421
422 return (0);
423}
424
425static void
426mac_lomac_set_range(struct mac_lomac *mac_lomac, u_short typelow,
427 u_short gradelow, u_short typehigh, u_short gradehigh)
428{
429
430 mac_lomac->ml_rangelow.mle_type = typelow;
431 mac_lomac->ml_rangelow.mle_grade = gradelow;
432 mac_lomac->ml_rangehigh.mle_type = typehigh;
433 mac_lomac->ml_rangehigh.mle_grade = gradehigh;
434 mac_lomac->ml_flags |= MAC_LOMAC_FLAG_RANGE;
435}
436
437static void
438mac_lomac_set_single(struct mac_lomac *mac_lomac, u_short type, u_short grade)
439{
440
441 mac_lomac->ml_single.mle_type = type;
442 mac_lomac->ml_single.mle_grade = grade;
443 mac_lomac->ml_flags |= MAC_LOMAC_FLAG_SINGLE;
444}
445
446static void
447mac_lomac_copy_range(struct mac_lomac *labelfrom, struct mac_lomac *labelto)
448{
449
450 KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0,
451 ("mac_lomac_copy_range: labelfrom not range"));
452
453 labelto->ml_rangelow = labelfrom->ml_rangelow;
454 labelto->ml_rangehigh = labelfrom->ml_rangehigh;
455 labelto->ml_flags |= MAC_LOMAC_FLAG_RANGE;
456}
457
458static void
459mac_lomac_copy_single(struct mac_lomac *labelfrom, struct mac_lomac *labelto)
460{
461
462 KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
463 ("mac_lomac_copy_single: labelfrom not single"));
464
465 labelto->ml_single = labelfrom->ml_single;
466 labelto->ml_flags |= MAC_LOMAC_FLAG_SINGLE;
467}
468
469static void
470mac_lomac_copy_auxsingle(struct mac_lomac *labelfrom, struct mac_lomac *labelto)
471{
472
473 KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_AUX) != 0,
474 ("mac_lomac_copy_auxsingle: labelfrom not auxsingle"));
475
476 labelto->ml_auxsingle = labelfrom->ml_auxsingle;
477 labelto->ml_flags |= MAC_LOMAC_FLAG_AUX;
478}
479
480static void
481mac_lomac_copy(struct mac_lomac *source, struct mac_lomac *dest)
482{
483
484 if (source->ml_flags & MAC_LOMAC_FLAG_SINGLE)
485 mac_lomac_copy_single(source, dest);
486 if (source->ml_flags & MAC_LOMAC_FLAG_AUX)
487 mac_lomac_copy_auxsingle(source, dest);
488 if (source->ml_flags & MAC_LOMAC_FLAG_RANGE)
489 mac_lomac_copy_range(source, dest);
490}
491
492static int mac_lomac_to_string(struct sbuf *sb,
493 struct mac_lomac *mac_lomac);
494
495static int
496maybe_demote(struct mac_lomac *subjlabel, struct mac_lomac *objlabel,
497 const char *actionname, const char *objname, struct vnode *vpq)
498{
499 struct sbuf subjlabel_sb, subjtext_sb, objlabel_sb;
500 char *subjlabeltext, *objlabeltext, *subjtext;
501 struct mac_lomac cached_subjlabel;
502 struct mac_lomac_proc *subj;
503 struct vattr va;
504 struct proc *p;
505 pid_t pgid;
506
507 subj = PSLOT(curthread->td_proc->p_label);
508
509 p = curthread->td_proc;
510 mtx_lock(&subj->mtx);
511 if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) {
512 /*
513 * Check to see if the pending demotion would be more or
514 * less severe than this one, and keep the more severe.
515 * This can only happen for a multi-threaded application.
516 */
517 if (mac_lomac_dominate_single(objlabel, &subj->mac_lomac)) {
518 mtx_unlock(&subj->mtx);
519 return (0);
520 }
521 }
522 bzero(&subj->mac_lomac, sizeof(subj->mac_lomac));
523 /*
524 * Always demote the single label.
525 */
526 mac_lomac_copy_single(objlabel, &subj->mac_lomac);
527 /*
528 * Start with the original range, then minimize each side of
529 * the range to the point of not dominating the object. The
530 * high side will always be demoted, of course.
531 */
532 mac_lomac_copy_range(subjlabel, &subj->mac_lomac);
533 if (!mac_lomac_dominate_element(&objlabel->ml_single,
534 &subj->mac_lomac.ml_rangelow))
535 subj->mac_lomac.ml_rangelow = objlabel->ml_single;
536 subj->mac_lomac.ml_rangehigh = objlabel->ml_single;
537 subj->mac_lomac.ml_flags |= MAC_LOMAC_FLAG_UPDATE;
538 mtx_lock_spin(&sched_lock);
539 curthread->td_flags |= TDF_ASTPENDING;
540 curthread->td_proc->p_sflag |= PS_MACPEND;
541 mtx_unlock_spin(&sched_lock);
542
543 /*
544 * Avoid memory allocation while holding a mutex; cache the
545 * label.
546 */
547 mac_lomac_copy_single(&subj->mac_lomac, &cached_subjlabel);
548 mtx_unlock(&subj->mtx);
549
550 sbuf_new(&subjlabel_sb, NULL, 0, SBUF_AUTOEXTEND);
551 mac_lomac_to_string(&subjlabel_sb, subjlabel);
552 sbuf_finish(&subjlabel_sb);
553 subjlabeltext = sbuf_data(&subjlabel_sb);
554
555 sbuf_new(&subjtext_sb, NULL, 0, SBUF_AUTOEXTEND);
556 mac_lomac_to_string(&subjtext_sb, &subj->mac_lomac);
557 sbuf_finish(&subjtext_sb);
558 subjtext = sbuf_data(&subjtext_sb);
559
560 sbuf_new(&objlabel_sb, NULL, 0, SBUF_AUTOEXTEND);
561 mac_lomac_to_string(&objlabel_sb, objlabel);
562 sbuf_finish(&objlabel_sb);
563 objlabeltext = sbuf_data(&objlabel_sb);
564
565 pgid = p->p_pgrp->pg_id; /* XXX could be stale? */
566 if (vpq != NULL && VOP_GETATTR(vpq, &va, curthread->td_ucred,
567 curthread) == 0) {
568 log(LOG_INFO, "LOMAC: level-%s subject p%dg%du%d:%s demoted to"
569 " level %s after %s a level-%s %s (inode=%ld, "
570 "mountpount=%s)\n",
571 subjlabeltext, p->p_pid, pgid, curthread->td_ucred->cr_uid,
572 p->p_comm, subjtext, actionname, objlabeltext, objname,
573 va.va_fileid, vpq->v_mount->mnt_stat.f_mntonname);
574 } else {
575 log(LOG_INFO, "LOMAC: level-%s subject p%dg%du%d:%s demoted to"
576 " level %s after %s a level-%s %s\n",
577 subjlabeltext, p->p_pid, pgid, curthread->td_ucred->cr_uid,
578 p->p_comm, subjtext, actionname, objlabeltext, objname);
579 }
580
581 sbuf_delete(&subjlabel_sb);
582 sbuf_delete(&subjtext_sb);
583 sbuf_delete(&objlabel_sb);
584
585 return (0);
586}
587
588/*
589 * Relabel "to" to "from" only if "from" is a valid label (contains
590 * at least a single), as for a relabel operation which may or may
591 * not involve a relevant label.
592 */
593static void
594try_relabel(struct mac_lomac *from, struct mac_lomac *to)
595{
596
597 if (from->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
598 bzero(to, sizeof(*to));
599 mac_lomac_copy(from, to);
600 }
601}
602
603/*
604 * Policy module operations.
605 */
606static void
607mac_lomac_init(struct mac_policy_conf *conf)
608{
609
610}
611
612/*
613 * Label operations.
614 */
615static void
616mac_lomac_init_label(struct label *label)
617{
618
619 SLOT_SET(label, lomac_alloc(M_WAITOK));
620}
621
622static int
623mac_lomac_init_label_waitcheck(struct label *label, int flag)
624{
625
626 SLOT_SET(label, lomac_alloc(flag));
627 if (SLOT(label) == NULL)
628 return (ENOMEM);
629
630 return (0);
631}
632
633static void
634mac_lomac_init_proc_label(struct label *label)
635{
636
637 PSLOT_SET(label, malloc(sizeof(struct mac_lomac_proc), M_MACLOMAC,
638 M_ZERO | M_WAITOK));
639 mtx_init(&PSLOT(label)->mtx, "MAC/Lomac proc lock", NULL, MTX_DEF);
640}
641
642static void
643mac_lomac_destroy_label(struct label *label)
644{
645
646 lomac_free(SLOT(label));
647 SLOT_SET(label, NULL);
648}
649
650static void
651mac_lomac_destroy_proc_label(struct label *label)
652{
653
654 mtx_destroy(&PSLOT(label)->mtx);
655 FREE(PSLOT(label), M_MACLOMAC);
656 PSLOT_SET(label, NULL);
657}
658
659static int
660mac_lomac_element_to_string(struct sbuf *sb, struct mac_lomac_element *element)
661{
662
663 switch (element->mle_type) {
664 case MAC_LOMAC_TYPE_HIGH:
665 return (sbuf_printf(sb, "high"));
666
667 case MAC_LOMAC_TYPE_LOW:
668 return (sbuf_printf(sb, "low"));
669
670 case MAC_LOMAC_TYPE_EQUAL:
671 return (sbuf_printf(sb, "equal"));
672
673 case MAC_LOMAC_TYPE_GRADE:
674 return (sbuf_printf(sb, "%d", element->mle_grade));
675
676 default:
677 panic("mac_lomac_element_to_string: invalid type (%d)",
678 element->mle_type);
679 }
680}
681
682static int
683mac_lomac_to_string(struct sbuf *sb, struct mac_lomac *mac_lomac)
684{
685
686 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
687 if (mac_lomac_element_to_string(sb, &mac_lomac->ml_single)
688 == -1)
689 return (EINVAL);
690 }
691
692 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_AUX) {
693 if (sbuf_putc(sb, '[') == -1)
694 return (EINVAL);
695
696 if (mac_lomac_element_to_string(sb, &mac_lomac->ml_auxsingle)
697 == -1)
698 return (EINVAL);
699
700 if (sbuf_putc(sb, ']') == -1)
701 return (EINVAL);
702 }
703
704 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_RANGE) {
705 if (sbuf_putc(sb, '(') == -1)
706 return (EINVAL);
707
708 if (mac_lomac_element_to_string(sb, &mac_lomac->ml_rangelow)
709 == -1)
710 return (EINVAL);
711
712 if (sbuf_putc(sb, '-') == -1)
713 return (EINVAL);
714
715 if (mac_lomac_element_to_string(sb, &mac_lomac->ml_rangehigh)
716 == -1)
717 return (EINVAL);
718
719 if (sbuf_putc(sb, ')') == -1)
720 return (EINVAL);
721 }
722
723 return (0);
724}
725
726static int
727mac_lomac_externalize_label(struct label *label, char *element_name,
728 struct sbuf *sb, int *claimed)
729{
730 struct mac_lomac *mac_lomac;
731
732 if (strcmp(MAC_LOMAC_LABEL_NAME, element_name) != 0)
733 return (0);
734
735 (*claimed)++;
736
737 mac_lomac = SLOT(label);
738
739 return (mac_lomac_to_string(sb, mac_lomac));
740}
741
742static int
743mac_lomac_parse_element(struct mac_lomac_element *element, char *string)
744{
745
746 if (strcmp(string, "high") == 0 ||
747 strcmp(string, "hi") == 0) {
748 element->mle_type = MAC_LOMAC_TYPE_HIGH;
749 element->mle_grade = MAC_LOMAC_TYPE_UNDEF;
750 } else if (strcmp(string, "low") == 0 ||
751 strcmp(string, "lo") == 0) {
752 element->mle_type = MAC_LOMAC_TYPE_LOW;
753 element->mle_grade = MAC_LOMAC_TYPE_UNDEF;
754 } else if (strcmp(string, "equal") == 0 ||
755 strcmp(string, "eq") == 0) {
756 element->mle_type = MAC_LOMAC_TYPE_EQUAL;
757 element->mle_grade = MAC_LOMAC_TYPE_UNDEF;
758 } else {
759 char *p0, *p1;
760 int d;
761
762 p0 = string;
763 d = strtol(p0, &p1, 10);
764
765 if (d < 0 || d > 65535)
766 return (EINVAL);
767 element->mle_type = MAC_LOMAC_TYPE_GRADE;
768 element->mle_grade = d;
769
770 if (p1 == p0 || *p1 != '\0')
771 return (EINVAL);
772 }
773
774 return (0);
775}
776
777/*
778 * Note: destructively consumes the string, make a local copy before
779 * calling if that's a problem.
780 */
781static int
782mac_lomac_parse(struct mac_lomac *mac_lomac, char *string)
783{
784 char *range, *rangeend, *rangehigh, *rangelow, *single, *auxsingle,
785 *auxsingleend;
786 int error;
787
788 /* Do we have a range? */
789 single = string;
790 range = index(string, '(');
791 if (range == single)
792 single = NULL;
793 auxsingle = index(string, '[');
794 if (auxsingle == single)
795 single = NULL;
796 if (range != NULL && auxsingle != NULL)
797 return (EINVAL);
798 rangelow = rangehigh = NULL;
799 if (range != NULL) {
800 /* Nul terminate the end of the single string. */
801 *range = '\0';
802 range++;
803 rangelow = range;
804 rangehigh = index(rangelow, '-');
805 if (rangehigh == NULL)
806 return (EINVAL);
807 rangehigh++;
808 if (*rangelow == '\0' || *rangehigh == '\0')
809 return (EINVAL);
810 rangeend = index(rangehigh, ')');
811 if (rangeend == NULL)
812 return (EINVAL);
813 if (*(rangeend + 1) != '\0')
814 return (EINVAL);
815 /* Nul terminate the ends of the ranges. */
816 *(rangehigh - 1) = '\0';
817 *rangeend = '\0';
818 }
819 KASSERT((rangelow != NULL && rangehigh != NULL) ||
820 (rangelow == NULL && rangehigh == NULL),
821 ("mac_lomac_internalize_label: range mismatch"));
822 if (auxsingle != NULL) {
823 /* Nul terminate the end of the single string. */
824 *auxsingle = '\0';
825 auxsingle++;
826 auxsingleend = index(auxsingle, ']');
827 if (auxsingleend == NULL)
828 return (EINVAL);
829 if (*(auxsingleend + 1) != '\0')
830 return (EINVAL);
831 /* Nul terminate the end of the auxsingle. */
832 *auxsingleend = '\0';
833 }
834
835 bzero(mac_lomac, sizeof(*mac_lomac));
836 if (single != NULL) {
837 error = mac_lomac_parse_element(&mac_lomac->ml_single, single);
838 if (error)
839 return (error);
840 mac_lomac->ml_flags |= MAC_LOMAC_FLAG_SINGLE;
841 }
842
843 if (auxsingle != NULL) {
844 error = mac_lomac_parse_element(&mac_lomac->ml_auxsingle,
845 auxsingle);
846 if (error)
847 return (error);
848 mac_lomac->ml_flags |= MAC_LOMAC_FLAG_AUX;
849 }
850
851 if (rangelow != NULL) {
852 error = mac_lomac_parse_element(&mac_lomac->ml_rangelow,
853 rangelow);
854 if (error)
855 return (error);
856 error = mac_lomac_parse_element(&mac_lomac->ml_rangehigh,
857 rangehigh);
858 if (error)
859 return (error);
860 mac_lomac->ml_flags |= MAC_LOMAC_FLAG_RANGE;
861 }
862
863 error = mac_lomac_valid(mac_lomac);
864 if (error)
865 return (error);
866
867 return (0);
868}
869
870static int
871mac_lomac_internalize_label(struct label *label, char *element_name,
872 char *element_data, int *claimed)
873{
874 struct mac_lomac *mac_lomac, mac_lomac_temp;
875 int error;
876
877 if (strcmp(MAC_LOMAC_LABEL_NAME, element_name) != 0)
878 return (0);
879
880 (*claimed)++;
881
882 error = mac_lomac_parse(&mac_lomac_temp, element_data);
883 if (error)
884 return (error);
885
886 mac_lomac = SLOT(label);
887 *mac_lomac = mac_lomac_temp;
888
889 return (0);
890}
891
892static void
893mac_lomac_copy_label(struct label *src, struct label *dest)
894{
895
896 *SLOT(dest) = *SLOT(src);
897}
898
899/*
900 * Labeling event operations: file system objects, and things that look
901 * a lot like file system objects.
902 */
903static void
904mac_lomac_create_devfs_device(struct ucred *cred, struct mount *mp,
905 struct cdev *dev, struct devfs_dirent *devfs_dirent, struct label *label)
906{
907 struct mac_lomac *mac_lomac;
908 int lomac_type;
909
910 mac_lomac = SLOT(label);
911 if (strcmp(dev->si_name, "null") == 0 ||
912 strcmp(dev->si_name, "zero") == 0 ||
913 strcmp(dev->si_name, "random") == 0 ||
914 strncmp(dev->si_name, "fd/", strlen("fd/")) == 0 ||
915 strncmp(dev->si_name, "ttyv", strlen("ttyv")) == 0)
916 lomac_type = MAC_LOMAC_TYPE_EQUAL;
917 else if (ptys_equal &&
918 (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
919 strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
920 lomac_type = MAC_LOMAC_TYPE_EQUAL;
921 else
922 lomac_type = MAC_LOMAC_TYPE_HIGH;
923 mac_lomac_set_single(mac_lomac, lomac_type, 0);
924}
925
926static void
927mac_lomac_create_devfs_directory(struct mount *mp, char *dirname,
928 int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label)
929{
930 struct mac_lomac *mac_lomac;
931
932 mac_lomac = SLOT(label);
933 mac_lomac_set_single(mac_lomac, MAC_LOMAC_TYPE_HIGH, 0);
934}
935
936static void
937mac_lomac_create_devfs_symlink(struct ucred *cred, struct mount *mp,
938 struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de,
939 struct label *delabel)
940{
941 struct mac_lomac *source, *dest;
942
943 source = SLOT(cred->cr_label);
944 dest = SLOT(delabel);
945
946 mac_lomac_copy_single(source, dest);
947}
948
949static void
950mac_lomac_create_mount(struct ucred *cred, struct mount *mp,
951 struct label *mntlabel, struct label *fslabel)
952{
953 struct mac_lomac *source, *dest;
954
955 source = SLOT(cred->cr_label);
956 dest = SLOT(mntlabel);
957 mac_lomac_copy_single(source, dest);
958 dest = SLOT(fslabel);
959 mac_lomac_copy_single(source, dest);
960}
961
962static void
963mac_lomac_relabel_vnode(struct ucred *cred, struct vnode *vp,
964 struct label *vnodelabel, struct label *label)
965{
966 struct mac_lomac *source, *dest;
967
968 source = SLOT(label);
969 dest = SLOT(vnodelabel);
970
971 try_relabel(source, dest);
972}
973
974static void
975mac_lomac_update_devfsdirent(struct mount *mp,
976 struct devfs_dirent *devfs_dirent, struct label *direntlabel,
977 struct vnode *vp, struct label *vnodelabel)
978{
979 struct mac_lomac *source, *dest;
980
981 source = SLOT(vnodelabel);
982 dest = SLOT(direntlabel);
983
984 mac_lomac_copy(source, dest);
985}
986
987static void
988mac_lomac_associate_vnode_devfs(struct mount *mp, struct label *fslabel,
989 struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
990 struct label *vlabel)
991{
992 struct mac_lomac *source, *dest;
993
994 source = SLOT(delabel);
995 dest = SLOT(vlabel);
996
997 mac_lomac_copy_single(source, dest);
998}
999
1000static int
1001mac_lomac_associate_vnode_extattr(struct mount *mp, struct label *fslabel,
1002 struct vnode *vp, struct label *vlabel)
1003{
1004 struct mac_lomac temp, *source, *dest;
1005 int buflen, error;
1006
1007 source = SLOT(fslabel);
1008 dest = SLOT(vlabel);
1009
1010 buflen = sizeof(temp);
1011 bzero(&temp, buflen);
1012
1013 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE,
1014 MAC_LOMAC_EXTATTR_NAME, &buflen, (char *)&temp, curthread);
1015 if (error == ENOATTR || error == EOPNOTSUPP) {
1016 /* Fall back to the fslabel. */
1017 mac_lomac_copy_single(source, dest);
1018 return (0);
1019 } else if (error)
1020 return (error);
1021
1022 if (buflen != sizeof(temp)) {
1023 if (buflen != sizeof(temp) - sizeof(temp.ml_auxsingle)) {
1024 printf("mac_lomac_associate_vnode_extattr: bad size %d\n",
1025 buflen);
1026 return (EPERM);
1027 }
1028 bzero(&temp.ml_auxsingle, sizeof(temp.ml_auxsingle));
1029 buflen = sizeof(temp);
1030 (void)vn_extattr_set(vp, IO_NODELOCKED,
1031 MAC_LOMAC_EXTATTR_NAMESPACE, MAC_LOMAC_EXTATTR_NAME,
1032 buflen, (char *)&temp, curthread);
1033 }
1034 if (mac_lomac_valid(&temp) != 0) {
1035 printf("mac_lomac_associate_vnode_extattr: invalid\n");
1036 return (EPERM);
1037 }
1038 if ((temp.ml_flags & MAC_LOMAC_FLAGS_BOTH) != MAC_LOMAC_FLAG_SINGLE) {
1039 printf("mac_lomac_associate_vnode_extattr: not single\n");
1040 return (EPERM);
1041 }
1042
1043 mac_lomac_copy_single(&temp, dest);
1044 return (0);
1045}
1046
1047static void
1048mac_lomac_associate_vnode_singlelabel(struct mount *mp,
1049 struct label *fslabel, struct vnode *vp, struct label *vlabel)
1050{
1051 struct mac_lomac *source, *dest;
1052
1053 source = SLOT(fslabel);
1054 dest = SLOT(vlabel);
1055
1056 mac_lomac_copy_single(source, dest);
1057}
1058
1059static int
1060mac_lomac_create_vnode_extattr(struct ucred *cred, struct mount *mp,
1061 struct label *fslabel, struct vnode *dvp, struct label *dlabel,
1062 struct vnode *vp, struct label *vlabel, struct componentname *cnp)
1063{
1064 struct mac_lomac *source, *dest, *dir, temp;
1065 size_t buflen;
1066 int error;
1067
1068 buflen = sizeof(temp);
1069 bzero(&temp, buflen);
1070
1071 source = SLOT(cred->cr_label);
1072 dest = SLOT(vlabel);
1073 dir = SLOT(dlabel);
1074 if (dir->ml_flags & MAC_LOMAC_FLAG_AUX) {
1075 mac_lomac_copy_auxsingle(dir, &temp);
1076 mac_lomac_set_single(&temp, dir->ml_auxsingle.mle_type,
1077 dir->ml_auxsingle.mle_grade);
1078 } else {
1079 mac_lomac_copy_single(source, &temp);
1080 }
1081
1082 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE,
1083 MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread);
1084 if (error == 0)
1085 mac_lomac_copy(&temp, dest);
1086 return (error);
1087}
1088
1089static int
1090mac_lomac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
1091 struct label *vlabel, struct label *intlabel)
1092{
1093 struct mac_lomac *source, temp;
1094 size_t buflen;
1095 int error;
1096
1097 buflen = sizeof(temp);
1098 bzero(&temp, buflen);
1099
1100 source = SLOT(intlabel);
1101 if ((source->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0)
1102 return (0);
1103
1104 mac_lomac_copy_single(source, &temp);
1105 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE,
1106 MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread);
1107 return (error);
1108}
1109
1110/*
1111 * Labeling event operations: IPC object.
1112 */
1113static void
1114mac_lomac_create_inpcb_from_socket(struct socket *so, struct label *solabel,
1115 struct inpcb *inp, struct label *inplabel)
1116{
1117 struct mac_lomac *source, *dest;
1118
1119 source = SLOT(solabel);
1120 dest = SLOT(inplabel);
1121
1122 mac_lomac_copy_single(source, dest);
1123}
1124
1125static void
1126mac_lomac_create_mbuf_from_socket(struct socket *so, struct label *socketlabel,
1127 struct mbuf *m, struct label *mbuflabel)
1128{
1129 struct mac_lomac *source, *dest;
1130
1131 source = SLOT(socketlabel);
1132 dest = SLOT(mbuflabel);
1133
1134 mac_lomac_copy_single(source, dest);
1135}
1136
1137static void
1138mac_lomac_create_socket(struct ucred *cred, struct socket *socket,
1139 struct label *socketlabel)
1140{
1141 struct mac_lomac *source, *dest;
1142
1143 source = SLOT(cred->cr_label);
1144 dest = SLOT(socketlabel);
1145
1146 mac_lomac_copy_single(source, dest);
1147}
1148
1149static void
1150mac_lomac_create_pipe(struct ucred *cred, struct pipepair *pp,
1151 struct label *pipelabel)
1152{
1153 struct mac_lomac *source, *dest;
1154
1155 source = SLOT(cred->cr_label);
1156 dest = SLOT(pipelabel);
1157
1158 mac_lomac_copy_single(source, dest);
1159}
1160
1161static void
1162mac_lomac_create_socket_from_socket(struct socket *oldsocket,
1163 struct label *oldsocketlabel, struct socket *newsocket,
1164 struct label *newsocketlabel)
1165{
1166 struct mac_lomac *source, *dest;
1167
1168 source = SLOT(oldsocketlabel);
1169 dest = SLOT(newsocketlabel);
1170
1171 mac_lomac_copy_single(source, dest);
1172}
1173
1174static void
1175mac_lomac_relabel_socket(struct ucred *cred, struct socket *socket,
1176 struct label *socketlabel, struct label *newlabel)
1177{
1178 struct mac_lomac *source, *dest;
1179
1180 source = SLOT(newlabel);
1181 dest = SLOT(socketlabel);
1182
1183 try_relabel(source, dest);
1184}
1185
1186static void
1187mac_lomac_relabel_pipe(struct ucred *cred, struct pipepair *pp,
1188 struct label *pipelabel, struct label *newlabel)
1189{
1190 struct mac_lomac *source, *dest;
1191
1192 source = SLOT(newlabel);
1193 dest = SLOT(pipelabel);
1194
1195 try_relabel(source, dest);
1196}
1197
1198static void
1199mac_lomac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel,
1200 struct socket *socket, struct label *socketpeerlabel)
1201{
1202 struct mac_lomac *source, *dest;
1203
1204 source = SLOT(mbuflabel);
1205 dest = SLOT(socketpeerlabel);
1206
1207 mac_lomac_copy_single(source, dest);
1208}
1209
1210/*
1211 * Labeling event operations: network objects.
1212 */
1213static void
1214mac_lomac_set_socket_peer_from_socket(struct socket *oldsocket,
1215 struct label *oldsocketlabel, struct socket *newsocket,
1216 struct label *newsocketpeerlabel)
1217{
1218 struct mac_lomac *source, *dest;
1219
1220 source = SLOT(oldsocketlabel);
1221 dest = SLOT(newsocketpeerlabel);
1222
1223 mac_lomac_copy_single(source, dest);
1224}
1225
1226static void
1227mac_lomac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d,
1228 struct label *bpflabel)
1229{
1230 struct mac_lomac *source, *dest;
1231
1232 source = SLOT(cred->cr_label);
1233 dest = SLOT(bpflabel);
1234
1235 mac_lomac_copy_single(source, dest);
1236}
1237
1238static void
1239mac_lomac_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel)
1240{
1241 char tifname[IFNAMSIZ], *p, *q;
1242 char tiflist[sizeof(trusted_interfaces)];
1243 struct mac_lomac *dest;
1244 int len, grade;
1245
1246 dest = SLOT(ifnetlabel);
1247
1248 if (ifnet->if_type == IFT_LOOP) {
1249 grade = MAC_LOMAC_TYPE_EQUAL;
1250 goto set;
1251 }
1252
1253 if (trust_all_interfaces) {
1254 grade = MAC_LOMAC_TYPE_HIGH;
1255 goto set;
1256 }
1257
1258 grade = MAC_LOMAC_TYPE_LOW;
1259
1260 if (trusted_interfaces[0] == '\0' ||
1261 !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
1262 goto set;
1263
1264 bzero(tiflist, sizeof(tiflist));
1265 for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
1266 if(*p != ' ' && *p != '\t')
1267 *q = *p;
1268
1269 for (p = q = tiflist;; p++) {
1270 if (*p == ',' || *p == '\0') {
1271 len = p - q;
1272 if (len < IFNAMSIZ) {
1273 bzero(tifname, sizeof(tifname));
1274 bcopy(q, tifname, len);
1275 if (strcmp(tifname, ifnet->if_xname) == 0) {
1276 grade = MAC_LOMAC_TYPE_HIGH;
1277 break;
1278 }
1279 }
1280 else {
1281 *p = '\0';
1282 printf("MAC/LOMAC warning: interface name "
1283 "\"%s\" is too long (must be < %d)\n",
1284 q, IFNAMSIZ);
1285 }
1286 if (*p == '\0')
1287 break;
1288 q = p + 1;
1289 }
1290 }
1291set:
1292 mac_lomac_set_single(dest, grade, 0);
1293 mac_lomac_set_range(dest, grade, 0, grade, 0);
1294}
1295
1296static void
1297mac_lomac_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1298 struct ipq *ipq, struct label *ipqlabel)
1299{
1300 struct mac_lomac *source, *dest;
1301
1302 source = SLOT(fragmentlabel);
1303 dest = SLOT(ipqlabel);
1304
1305 mac_lomac_copy_single(source, dest);
1306}
1307
1308static void
1309mac_lomac_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
1310 struct mbuf *datagram, struct label *datagramlabel)
1311{
1312 struct mac_lomac *source, *dest;
1313
1314 source = SLOT(ipqlabel);
1315 dest = SLOT(datagramlabel);
1316
1317 /* Just use the head, since we require them all to match. */
1318 mac_lomac_copy_single(source, dest);
1319}
1320
1321static void
1322mac_lomac_create_fragment(struct mbuf *datagram, struct label *datagramlabel,
1323 struct mbuf *fragment, struct label *fragmentlabel)
1324{
1325 struct mac_lomac *source, *dest;
1326
1327 source = SLOT(datagramlabel);
1328 dest = SLOT(fragmentlabel);
1329
1330 mac_lomac_copy_single(source, dest);
1331}
1332
1333static void
1334mac_lomac_create_mbuf_from_inpcb(struct inpcb *inp, struct label *inplabel,
1335 struct mbuf *m, struct label *mlabel)
1336{
1337 struct mac_lomac *source, *dest;
1338
1339 source = SLOT(inplabel);
1340 dest = SLOT(mlabel);
1341
1342 mac_lomac_copy_single(source, dest);
1343}
1344
1345static void
1346mac_lomac_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel,
1347 struct mbuf *mbuf, struct label *mbuflabel)
1348{
1349 struct mac_lomac *dest;
1350
1351 dest = SLOT(mbuflabel);
1352
1353 mac_lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0);
1354}
1355
1356static void
1357mac_lomac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel,
1358 struct mbuf *mbuf, struct label *mbuflabel)
1359{
1360 struct mac_lomac *source, *dest;
1361
1362 source = SLOT(bpflabel);
1363 dest = SLOT(mbuflabel);
1364
1365 mac_lomac_copy_single(source, dest);
1366}
1367
1368static void
1369mac_lomac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel,
1370 struct mbuf *m, struct label *mbuflabel)
1371{
1372 struct mac_lomac *source, *dest;
1373
1374 source = SLOT(ifnetlabel);
1375 dest = SLOT(mbuflabel);
1376
1377 mac_lomac_copy_single(source, dest);
1378}
1379
1380static void
1381mac_lomac_create_mbuf_multicast_encap(struct mbuf *oldmbuf,
1382 struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel,
1383 struct mbuf *newmbuf, struct label *newmbuflabel)
1384{
1385 struct mac_lomac *source, *dest;
1386
1387 source = SLOT(oldmbuflabel);
1388 dest = SLOT(newmbuflabel);
1389
1390 mac_lomac_copy_single(source, dest);
1391}
1392
1393static void
1394mac_lomac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel,
1395 struct mbuf *newmbuf, struct label *newmbuflabel)
1396{
1397 struct mac_lomac *source, *dest;
1398
1399 source = SLOT(oldmbuflabel);
1400 dest = SLOT(newmbuflabel);
1401
1402 mac_lomac_copy_single(source, dest);
1403}
1404
1405static int
1406mac_lomac_fragment_match(struct mbuf *fragment, struct label *fragmentlabel,
1407 struct ipq *ipq, struct label *ipqlabel)
1408{
1409 struct mac_lomac *a, *b;
1410
1411 a = SLOT(ipqlabel);
1412 b = SLOT(fragmentlabel);
1413
1414 return (mac_lomac_equal_single(a, b));
1415}
1416
1417static void
1418mac_lomac_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
1419 struct label *ifnetlabel, struct label *newlabel)
1420{
1421 struct mac_lomac *source, *dest;
1422
1423 source = SLOT(newlabel);
1424 dest = SLOT(ifnetlabel);
1425
1426 try_relabel(source, dest);
1427}
1428
1429static void
1430mac_lomac_update_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1431 struct ipq *ipq, struct label *ipqlabel)
1432{
1433
1434 /* NOOP: we only accept matching labels, so no need to update */
1435}
1436
1437static void
1438mac_lomac_inpcb_sosetlabel(struct socket *so, struct label *solabel,
1439 struct inpcb *inp, struct label *inplabel)
1440{
1441 struct mac_lomac *source, *dest;
1442
1443 source = SLOT(solabel);
1444 dest = SLOT(inplabel);
1445
1446 mac_lomac_copy_single(source, dest);
1447}
1448
35 */
36
37/*
38 * Developed by the TrustedBSD Project.
39 * Low-watermark floating label mandatory integrity policy.
40 */
41
42#include <sys/types.h>
43#include <sys/param.h>
44#include <sys/acl.h>
45#include <sys/conf.h>
46#include <sys/extattr.h>
47#include <sys/kernel.h>
48#include <sys/mac.h>
49#include <sys/malloc.h>
50#include <sys/mman.h>
51#include <sys/mount.h>
52#include <sys/proc.h>
53#include <sys/sbuf.h>
54#include <sys/systm.h>
55#include <sys/sysproto.h>
56#include <sys/sysent.h>
57#include <sys/systm.h>
58#include <sys/vnode.h>
59#include <sys/file.h>
60#include <sys/socket.h>
61#include <sys/socketvar.h>
62#include <sys/sx.h>
63#include <sys/pipe.h>
64#include <sys/sysctl.h>
65#include <sys/syslog.h>
66
67#include <fs/devfs/devfs.h>
68
69#include <net/bpfdesc.h>
70#include <net/if.h>
71#include <net/if_types.h>
72#include <net/if_var.h>
73
74#include <netinet/in.h>
75#include <netinet/in_pcb.h>
76#include <netinet/ip_var.h>
77
78#include <vm/vm.h>
79
80#include <sys/mac_policy.h>
81
82#include <security/mac_lomac/mac_lomac.h>
83
84struct mac_lomac_proc {
85 struct mac_lomac mac_lomac;
86 struct mtx mtx;
87};
88
89SYSCTL_DECL(_security_mac);
90
91SYSCTL_NODE(_security_mac, OID_AUTO, lomac, CTLFLAG_RW, 0,
92 "TrustedBSD mac_lomac policy controls");
93
94static int mac_lomac_label_size = sizeof(struct mac_lomac);
95SYSCTL_INT(_security_mac_lomac, OID_AUTO, label_size, CTLFLAG_RD,
96 &mac_lomac_label_size, 0, "Size of struct mac_lomac");
97
98static int mac_lomac_enabled = 1;
99SYSCTL_INT(_security_mac_lomac, OID_AUTO, enabled, CTLFLAG_RW,
100 &mac_lomac_enabled, 0, "Enforce MAC/LOMAC policy");
101TUNABLE_INT("security.mac.lomac.enabled", &mac_lomac_enabled);
102
103static int destroyed_not_inited;
104SYSCTL_INT(_security_mac_lomac, OID_AUTO, destroyed_not_inited, CTLFLAG_RD,
105 &destroyed_not_inited, 0, "Count of labels destroyed but not inited");
106
107static int trust_all_interfaces = 0;
108SYSCTL_INT(_security_mac_lomac, OID_AUTO, trust_all_interfaces, CTLFLAG_RD,
109 &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/LOMAC");
110TUNABLE_INT("security.mac.lomac.trust_all_interfaces", &trust_all_interfaces);
111
112static char trusted_interfaces[128];
113SYSCTL_STRING(_security_mac_lomac, OID_AUTO, trusted_interfaces, CTLFLAG_RD,
114 trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/LOMAC");
115TUNABLE_STR("security.mac.lomac.trusted_interfaces", trusted_interfaces,
116 sizeof(trusted_interfaces));
117
118static int ptys_equal = 0;
119SYSCTL_INT(_security_mac_lomac, OID_AUTO, ptys_equal, CTLFLAG_RW,
120 &ptys_equal, 0, "Label pty devices as lomac/equal on create");
121TUNABLE_INT("security.mac.lomac.ptys_equal", &ptys_equal);
122
123static int revocation_enabled = 1;
124SYSCTL_INT(_security_mac_lomac, OID_AUTO, revocation_enabled, CTLFLAG_RW,
125 &revocation_enabled, 0, "Revoke access to objects on relabel");
126TUNABLE_INT("security.mac.lomac.revocation_enabled", &revocation_enabled);
127
128static int mac_lomac_slot;
129#define SLOT(l) ((struct mac_lomac *)LABEL_TO_SLOT((l), mac_lomac_slot).l_ptr)
130#define SLOT_SET(l, val) (LABEL_TO_SLOT((l), mac_lomac_slot).l_ptr = (val))
131#define PSLOT(l) ((struct mac_lomac_proc *) \
132 LABEL_TO_SLOT((l), mac_lomac_slot).l_ptr)
133#define PSLOT_SET(l, val) (LABEL_TO_SLOT((l), mac_lomac_slot).l_ptr = (val))
134
135MALLOC_DEFINE(M_MACLOMAC, "mac_lomac_label", "MAC/LOMAC labels");
136
137static struct mac_lomac *
138lomac_alloc(int flag)
139{
140 struct mac_lomac *mac_lomac;
141
142 mac_lomac = malloc(sizeof(struct mac_lomac), M_MACLOMAC, M_ZERO | flag);
143
144 return (mac_lomac);
145}
146
147static void
148lomac_free(struct mac_lomac *mac_lomac)
149{
150
151 if (mac_lomac != NULL)
152 free(mac_lomac, M_MACLOMAC);
153 else
154 atomic_add_int(&destroyed_not_inited, 1);
155}
156
157static int
158lomac_atmostflags(struct mac_lomac *mac_lomac, int flags)
159{
160
161 if ((mac_lomac->ml_flags & flags) != mac_lomac->ml_flags)
162 return (EINVAL);
163 return (0);
164}
165
166static int
167mac_lomac_dominate_element(struct mac_lomac_element *a,
168 struct mac_lomac_element *b)
169{
170
171 switch (a->mle_type) {
172 case MAC_LOMAC_TYPE_EQUAL:
173 case MAC_LOMAC_TYPE_HIGH:
174 return (1);
175
176 case MAC_LOMAC_TYPE_LOW:
177 switch (b->mle_type) {
178 case MAC_LOMAC_TYPE_GRADE:
179 case MAC_LOMAC_TYPE_HIGH:
180 return (0);
181
182 case MAC_LOMAC_TYPE_EQUAL:
183 case MAC_LOMAC_TYPE_LOW:
184 return (1);
185
186 default:
187 panic("mac_lomac_dominate_element: b->mle_type invalid");
188 }
189
190 case MAC_LOMAC_TYPE_GRADE:
191 switch (b->mle_type) {
192 case MAC_LOMAC_TYPE_EQUAL:
193 case MAC_LOMAC_TYPE_LOW:
194 return (1);
195
196 case MAC_LOMAC_TYPE_HIGH:
197 return (0);
198
199 case MAC_LOMAC_TYPE_GRADE:
200 return (a->mle_grade >= b->mle_grade);
201
202 default:
203 panic("mac_lomac_dominate_element: b->mle_type invalid");
204 }
205
206 default:
207 panic("mac_lomac_dominate_element: a->mle_type invalid");
208 }
209}
210
211static int
212mac_lomac_range_in_range(struct mac_lomac *rangea, struct mac_lomac *rangeb)
213{
214
215 return (mac_lomac_dominate_element(&rangeb->ml_rangehigh,
216 &rangea->ml_rangehigh) &&
217 mac_lomac_dominate_element(&rangea->ml_rangelow,
218 &rangeb->ml_rangelow));
219}
220
221static int
222mac_lomac_single_in_range(struct mac_lomac *single, struct mac_lomac *range)
223{
224
225 KASSERT((single->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
226 ("mac_lomac_single_in_range: a not single"));
227 KASSERT((range->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0,
228 ("mac_lomac_single_in_range: b not range"));
229
230 return (mac_lomac_dominate_element(&range->ml_rangehigh,
231 &single->ml_single) &&
232 mac_lomac_dominate_element(&single->ml_single,
233 &range->ml_rangelow));
234}
235
236static int
237mac_lomac_auxsingle_in_range(struct mac_lomac *single, struct mac_lomac *range)
238{
239
240 KASSERT((single->ml_flags & MAC_LOMAC_FLAG_AUX) != 0,
241 ("mac_lomac_single_in_range: a not auxsingle"));
242 KASSERT((range->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0,
243 ("mac_lomac_single_in_range: b not range"));
244
245 return (mac_lomac_dominate_element(&range->ml_rangehigh,
246 &single->ml_auxsingle) &&
247 mac_lomac_dominate_element(&single->ml_auxsingle,
248 &range->ml_rangelow));
249}
250
251static int
252mac_lomac_dominate_single(struct mac_lomac *a, struct mac_lomac *b)
253{
254 KASSERT((a->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
255 ("mac_lomac_dominate_single: a not single"));
256 KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
257 ("mac_lomac_dominate_single: b not single"));
258
259 return (mac_lomac_dominate_element(&a->ml_single, &b->ml_single));
260}
261
262static int
263mac_lomac_subject_dominate(struct mac_lomac *a, struct mac_lomac *b)
264{
265 KASSERT((~a->ml_flags &
266 (MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_RANGE)) == 0,
267 ("mac_lomac_dominate_single: a not subject"));
268 KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
269 ("mac_lomac_dominate_single: b not single"));
270
271 return (mac_lomac_dominate_element(&a->ml_rangehigh,
272 &b->ml_single));
273}
274
275static int
276mac_lomac_equal_element(struct mac_lomac_element *a, struct mac_lomac_element *b)
277{
278
279 if (a->mle_type == MAC_LOMAC_TYPE_EQUAL ||
280 b->mle_type == MAC_LOMAC_TYPE_EQUAL)
281 return (1);
282
283 return (a->mle_type == b->mle_type && a->mle_grade == b->mle_grade);
284}
285
286static int
287mac_lomac_equal_single(struct mac_lomac *a, struct mac_lomac *b)
288{
289
290 KASSERT((a->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
291 ("mac_lomac_equal_single: a not single"));
292 KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
293 ("mac_lomac_equal_single: b not single"));
294
295 return (mac_lomac_equal_element(&a->ml_single, &b->ml_single));
296}
297
298static int
299mac_lomac_contains_equal(struct mac_lomac *mac_lomac)
300{
301
302 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE)
303 if (mac_lomac->ml_single.mle_type == MAC_LOMAC_TYPE_EQUAL)
304 return (1);
305 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_AUX)
306 if (mac_lomac->ml_auxsingle.mle_type == MAC_LOMAC_TYPE_EQUAL)
307 return (1);
308
309 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_RANGE) {
310 if (mac_lomac->ml_rangelow.mle_type == MAC_LOMAC_TYPE_EQUAL)
311 return (1);
312 if (mac_lomac->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_EQUAL)
313 return (1);
314 }
315
316 return (0);
317}
318
319static int
320mac_lomac_subject_privileged(struct mac_lomac *mac_lomac)
321{
322
323 KASSERT((mac_lomac->ml_flags & MAC_LOMAC_FLAGS_BOTH) ==
324 MAC_LOMAC_FLAGS_BOTH,
325 ("mac_lomac_subject_privileged: subject doesn't have both labels"));
326
327 /* If the single is EQUAL, it's ok. */
328 if (mac_lomac->ml_single.mle_type == MAC_LOMAC_TYPE_EQUAL)
329 return (0);
330
331 /* If either range endpoint is EQUAL, it's ok. */
332 if (mac_lomac->ml_rangelow.mle_type == MAC_LOMAC_TYPE_EQUAL ||
333 mac_lomac->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_EQUAL)
334 return (0);
335
336 /* If the range is low-high, it's ok. */
337 if (mac_lomac->ml_rangelow.mle_type == MAC_LOMAC_TYPE_LOW &&
338 mac_lomac->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_HIGH)
339 return (0);
340
341 /* It's not ok. */
342 return (EPERM);
343}
344
345static int
346mac_lomac_high_single(struct mac_lomac *mac_lomac)
347{
348
349 KASSERT((mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
350 ("mac_lomac_high_single: mac_lomac not single"));
351
352 return (mac_lomac->ml_single.mle_type == MAC_LOMAC_TYPE_HIGH);
353}
354
355static int
356mac_lomac_valid(struct mac_lomac *mac_lomac)
357{
358
359 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
360 switch (mac_lomac->ml_single.mle_type) {
361 case MAC_LOMAC_TYPE_GRADE:
362 case MAC_LOMAC_TYPE_EQUAL:
363 case MAC_LOMAC_TYPE_HIGH:
364 case MAC_LOMAC_TYPE_LOW:
365 break;
366
367 default:
368 return (EINVAL);
369 }
370 } else {
371 if (mac_lomac->ml_single.mle_type != MAC_LOMAC_TYPE_UNDEF)
372 return (EINVAL);
373 }
374
375 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_AUX) {
376 switch (mac_lomac->ml_auxsingle.mle_type) {
377 case MAC_LOMAC_TYPE_GRADE:
378 case MAC_LOMAC_TYPE_EQUAL:
379 case MAC_LOMAC_TYPE_HIGH:
380 case MAC_LOMAC_TYPE_LOW:
381 break;
382
383 default:
384 return (EINVAL);
385 }
386 } else {
387 if (mac_lomac->ml_auxsingle.mle_type != MAC_LOMAC_TYPE_UNDEF)
388 return (EINVAL);
389 }
390
391 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_RANGE) {
392 switch (mac_lomac->ml_rangelow.mle_type) {
393 case MAC_LOMAC_TYPE_GRADE:
394 case MAC_LOMAC_TYPE_EQUAL:
395 case MAC_LOMAC_TYPE_HIGH:
396 case MAC_LOMAC_TYPE_LOW:
397 break;
398
399 default:
400 return (EINVAL);
401 }
402
403 switch (mac_lomac->ml_rangehigh.mle_type) {
404 case MAC_LOMAC_TYPE_GRADE:
405 case MAC_LOMAC_TYPE_EQUAL:
406 case MAC_LOMAC_TYPE_HIGH:
407 case MAC_LOMAC_TYPE_LOW:
408 break;
409
410 default:
411 return (EINVAL);
412 }
413 if (!mac_lomac_dominate_element(&mac_lomac->ml_rangehigh,
414 &mac_lomac->ml_rangelow))
415 return (EINVAL);
416 } else {
417 if (mac_lomac->ml_rangelow.mle_type != MAC_LOMAC_TYPE_UNDEF ||
418 mac_lomac->ml_rangehigh.mle_type != MAC_LOMAC_TYPE_UNDEF)
419 return (EINVAL);
420 }
421
422 return (0);
423}
424
425static void
426mac_lomac_set_range(struct mac_lomac *mac_lomac, u_short typelow,
427 u_short gradelow, u_short typehigh, u_short gradehigh)
428{
429
430 mac_lomac->ml_rangelow.mle_type = typelow;
431 mac_lomac->ml_rangelow.mle_grade = gradelow;
432 mac_lomac->ml_rangehigh.mle_type = typehigh;
433 mac_lomac->ml_rangehigh.mle_grade = gradehigh;
434 mac_lomac->ml_flags |= MAC_LOMAC_FLAG_RANGE;
435}
436
437static void
438mac_lomac_set_single(struct mac_lomac *mac_lomac, u_short type, u_short grade)
439{
440
441 mac_lomac->ml_single.mle_type = type;
442 mac_lomac->ml_single.mle_grade = grade;
443 mac_lomac->ml_flags |= MAC_LOMAC_FLAG_SINGLE;
444}
445
446static void
447mac_lomac_copy_range(struct mac_lomac *labelfrom, struct mac_lomac *labelto)
448{
449
450 KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0,
451 ("mac_lomac_copy_range: labelfrom not range"));
452
453 labelto->ml_rangelow = labelfrom->ml_rangelow;
454 labelto->ml_rangehigh = labelfrom->ml_rangehigh;
455 labelto->ml_flags |= MAC_LOMAC_FLAG_RANGE;
456}
457
458static void
459mac_lomac_copy_single(struct mac_lomac *labelfrom, struct mac_lomac *labelto)
460{
461
462 KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
463 ("mac_lomac_copy_single: labelfrom not single"));
464
465 labelto->ml_single = labelfrom->ml_single;
466 labelto->ml_flags |= MAC_LOMAC_FLAG_SINGLE;
467}
468
469static void
470mac_lomac_copy_auxsingle(struct mac_lomac *labelfrom, struct mac_lomac *labelto)
471{
472
473 KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_AUX) != 0,
474 ("mac_lomac_copy_auxsingle: labelfrom not auxsingle"));
475
476 labelto->ml_auxsingle = labelfrom->ml_auxsingle;
477 labelto->ml_flags |= MAC_LOMAC_FLAG_AUX;
478}
479
480static void
481mac_lomac_copy(struct mac_lomac *source, struct mac_lomac *dest)
482{
483
484 if (source->ml_flags & MAC_LOMAC_FLAG_SINGLE)
485 mac_lomac_copy_single(source, dest);
486 if (source->ml_flags & MAC_LOMAC_FLAG_AUX)
487 mac_lomac_copy_auxsingle(source, dest);
488 if (source->ml_flags & MAC_LOMAC_FLAG_RANGE)
489 mac_lomac_copy_range(source, dest);
490}
491
492static int mac_lomac_to_string(struct sbuf *sb,
493 struct mac_lomac *mac_lomac);
494
495static int
496maybe_demote(struct mac_lomac *subjlabel, struct mac_lomac *objlabel,
497 const char *actionname, const char *objname, struct vnode *vpq)
498{
499 struct sbuf subjlabel_sb, subjtext_sb, objlabel_sb;
500 char *subjlabeltext, *objlabeltext, *subjtext;
501 struct mac_lomac cached_subjlabel;
502 struct mac_lomac_proc *subj;
503 struct vattr va;
504 struct proc *p;
505 pid_t pgid;
506
507 subj = PSLOT(curthread->td_proc->p_label);
508
509 p = curthread->td_proc;
510 mtx_lock(&subj->mtx);
511 if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) {
512 /*
513 * Check to see if the pending demotion would be more or
514 * less severe than this one, and keep the more severe.
515 * This can only happen for a multi-threaded application.
516 */
517 if (mac_lomac_dominate_single(objlabel, &subj->mac_lomac)) {
518 mtx_unlock(&subj->mtx);
519 return (0);
520 }
521 }
522 bzero(&subj->mac_lomac, sizeof(subj->mac_lomac));
523 /*
524 * Always demote the single label.
525 */
526 mac_lomac_copy_single(objlabel, &subj->mac_lomac);
527 /*
528 * Start with the original range, then minimize each side of
529 * the range to the point of not dominating the object. The
530 * high side will always be demoted, of course.
531 */
532 mac_lomac_copy_range(subjlabel, &subj->mac_lomac);
533 if (!mac_lomac_dominate_element(&objlabel->ml_single,
534 &subj->mac_lomac.ml_rangelow))
535 subj->mac_lomac.ml_rangelow = objlabel->ml_single;
536 subj->mac_lomac.ml_rangehigh = objlabel->ml_single;
537 subj->mac_lomac.ml_flags |= MAC_LOMAC_FLAG_UPDATE;
538 mtx_lock_spin(&sched_lock);
539 curthread->td_flags |= TDF_ASTPENDING;
540 curthread->td_proc->p_sflag |= PS_MACPEND;
541 mtx_unlock_spin(&sched_lock);
542
543 /*
544 * Avoid memory allocation while holding a mutex; cache the
545 * label.
546 */
547 mac_lomac_copy_single(&subj->mac_lomac, &cached_subjlabel);
548 mtx_unlock(&subj->mtx);
549
550 sbuf_new(&subjlabel_sb, NULL, 0, SBUF_AUTOEXTEND);
551 mac_lomac_to_string(&subjlabel_sb, subjlabel);
552 sbuf_finish(&subjlabel_sb);
553 subjlabeltext = sbuf_data(&subjlabel_sb);
554
555 sbuf_new(&subjtext_sb, NULL, 0, SBUF_AUTOEXTEND);
556 mac_lomac_to_string(&subjtext_sb, &subj->mac_lomac);
557 sbuf_finish(&subjtext_sb);
558 subjtext = sbuf_data(&subjtext_sb);
559
560 sbuf_new(&objlabel_sb, NULL, 0, SBUF_AUTOEXTEND);
561 mac_lomac_to_string(&objlabel_sb, objlabel);
562 sbuf_finish(&objlabel_sb);
563 objlabeltext = sbuf_data(&objlabel_sb);
564
565 pgid = p->p_pgrp->pg_id; /* XXX could be stale? */
566 if (vpq != NULL && VOP_GETATTR(vpq, &va, curthread->td_ucred,
567 curthread) == 0) {
568 log(LOG_INFO, "LOMAC: level-%s subject p%dg%du%d:%s demoted to"
569 " level %s after %s a level-%s %s (inode=%ld, "
570 "mountpount=%s)\n",
571 subjlabeltext, p->p_pid, pgid, curthread->td_ucred->cr_uid,
572 p->p_comm, subjtext, actionname, objlabeltext, objname,
573 va.va_fileid, vpq->v_mount->mnt_stat.f_mntonname);
574 } else {
575 log(LOG_INFO, "LOMAC: level-%s subject p%dg%du%d:%s demoted to"
576 " level %s after %s a level-%s %s\n",
577 subjlabeltext, p->p_pid, pgid, curthread->td_ucred->cr_uid,
578 p->p_comm, subjtext, actionname, objlabeltext, objname);
579 }
580
581 sbuf_delete(&subjlabel_sb);
582 sbuf_delete(&subjtext_sb);
583 sbuf_delete(&objlabel_sb);
584
585 return (0);
586}
587
588/*
589 * Relabel "to" to "from" only if "from" is a valid label (contains
590 * at least a single), as for a relabel operation which may or may
591 * not involve a relevant label.
592 */
593static void
594try_relabel(struct mac_lomac *from, struct mac_lomac *to)
595{
596
597 if (from->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
598 bzero(to, sizeof(*to));
599 mac_lomac_copy(from, to);
600 }
601}
602
603/*
604 * Policy module operations.
605 */
606static void
607mac_lomac_init(struct mac_policy_conf *conf)
608{
609
610}
611
612/*
613 * Label operations.
614 */
615static void
616mac_lomac_init_label(struct label *label)
617{
618
619 SLOT_SET(label, lomac_alloc(M_WAITOK));
620}
621
622static int
623mac_lomac_init_label_waitcheck(struct label *label, int flag)
624{
625
626 SLOT_SET(label, lomac_alloc(flag));
627 if (SLOT(label) == NULL)
628 return (ENOMEM);
629
630 return (0);
631}
632
633static void
634mac_lomac_init_proc_label(struct label *label)
635{
636
637 PSLOT_SET(label, malloc(sizeof(struct mac_lomac_proc), M_MACLOMAC,
638 M_ZERO | M_WAITOK));
639 mtx_init(&PSLOT(label)->mtx, "MAC/Lomac proc lock", NULL, MTX_DEF);
640}
641
642static void
643mac_lomac_destroy_label(struct label *label)
644{
645
646 lomac_free(SLOT(label));
647 SLOT_SET(label, NULL);
648}
649
650static void
651mac_lomac_destroy_proc_label(struct label *label)
652{
653
654 mtx_destroy(&PSLOT(label)->mtx);
655 FREE(PSLOT(label), M_MACLOMAC);
656 PSLOT_SET(label, NULL);
657}
658
659static int
660mac_lomac_element_to_string(struct sbuf *sb, struct mac_lomac_element *element)
661{
662
663 switch (element->mle_type) {
664 case MAC_LOMAC_TYPE_HIGH:
665 return (sbuf_printf(sb, "high"));
666
667 case MAC_LOMAC_TYPE_LOW:
668 return (sbuf_printf(sb, "low"));
669
670 case MAC_LOMAC_TYPE_EQUAL:
671 return (sbuf_printf(sb, "equal"));
672
673 case MAC_LOMAC_TYPE_GRADE:
674 return (sbuf_printf(sb, "%d", element->mle_grade));
675
676 default:
677 panic("mac_lomac_element_to_string: invalid type (%d)",
678 element->mle_type);
679 }
680}
681
682static int
683mac_lomac_to_string(struct sbuf *sb, struct mac_lomac *mac_lomac)
684{
685
686 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
687 if (mac_lomac_element_to_string(sb, &mac_lomac->ml_single)
688 == -1)
689 return (EINVAL);
690 }
691
692 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_AUX) {
693 if (sbuf_putc(sb, '[') == -1)
694 return (EINVAL);
695
696 if (mac_lomac_element_to_string(sb, &mac_lomac->ml_auxsingle)
697 == -1)
698 return (EINVAL);
699
700 if (sbuf_putc(sb, ']') == -1)
701 return (EINVAL);
702 }
703
704 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_RANGE) {
705 if (sbuf_putc(sb, '(') == -1)
706 return (EINVAL);
707
708 if (mac_lomac_element_to_string(sb, &mac_lomac->ml_rangelow)
709 == -1)
710 return (EINVAL);
711
712 if (sbuf_putc(sb, '-') == -1)
713 return (EINVAL);
714
715 if (mac_lomac_element_to_string(sb, &mac_lomac->ml_rangehigh)
716 == -1)
717 return (EINVAL);
718
719 if (sbuf_putc(sb, ')') == -1)
720 return (EINVAL);
721 }
722
723 return (0);
724}
725
726static int
727mac_lomac_externalize_label(struct label *label, char *element_name,
728 struct sbuf *sb, int *claimed)
729{
730 struct mac_lomac *mac_lomac;
731
732 if (strcmp(MAC_LOMAC_LABEL_NAME, element_name) != 0)
733 return (0);
734
735 (*claimed)++;
736
737 mac_lomac = SLOT(label);
738
739 return (mac_lomac_to_string(sb, mac_lomac));
740}
741
742static int
743mac_lomac_parse_element(struct mac_lomac_element *element, char *string)
744{
745
746 if (strcmp(string, "high") == 0 ||
747 strcmp(string, "hi") == 0) {
748 element->mle_type = MAC_LOMAC_TYPE_HIGH;
749 element->mle_grade = MAC_LOMAC_TYPE_UNDEF;
750 } else if (strcmp(string, "low") == 0 ||
751 strcmp(string, "lo") == 0) {
752 element->mle_type = MAC_LOMAC_TYPE_LOW;
753 element->mle_grade = MAC_LOMAC_TYPE_UNDEF;
754 } else if (strcmp(string, "equal") == 0 ||
755 strcmp(string, "eq") == 0) {
756 element->mle_type = MAC_LOMAC_TYPE_EQUAL;
757 element->mle_grade = MAC_LOMAC_TYPE_UNDEF;
758 } else {
759 char *p0, *p1;
760 int d;
761
762 p0 = string;
763 d = strtol(p0, &p1, 10);
764
765 if (d < 0 || d > 65535)
766 return (EINVAL);
767 element->mle_type = MAC_LOMAC_TYPE_GRADE;
768 element->mle_grade = d;
769
770 if (p1 == p0 || *p1 != '\0')
771 return (EINVAL);
772 }
773
774 return (0);
775}
776
777/*
778 * Note: destructively consumes the string, make a local copy before
779 * calling if that's a problem.
780 */
781static int
782mac_lomac_parse(struct mac_lomac *mac_lomac, char *string)
783{
784 char *range, *rangeend, *rangehigh, *rangelow, *single, *auxsingle,
785 *auxsingleend;
786 int error;
787
788 /* Do we have a range? */
789 single = string;
790 range = index(string, '(');
791 if (range == single)
792 single = NULL;
793 auxsingle = index(string, '[');
794 if (auxsingle == single)
795 single = NULL;
796 if (range != NULL && auxsingle != NULL)
797 return (EINVAL);
798 rangelow = rangehigh = NULL;
799 if (range != NULL) {
800 /* Nul terminate the end of the single string. */
801 *range = '\0';
802 range++;
803 rangelow = range;
804 rangehigh = index(rangelow, '-');
805 if (rangehigh == NULL)
806 return (EINVAL);
807 rangehigh++;
808 if (*rangelow == '\0' || *rangehigh == '\0')
809 return (EINVAL);
810 rangeend = index(rangehigh, ')');
811 if (rangeend == NULL)
812 return (EINVAL);
813 if (*(rangeend + 1) != '\0')
814 return (EINVAL);
815 /* Nul terminate the ends of the ranges. */
816 *(rangehigh - 1) = '\0';
817 *rangeend = '\0';
818 }
819 KASSERT((rangelow != NULL && rangehigh != NULL) ||
820 (rangelow == NULL && rangehigh == NULL),
821 ("mac_lomac_internalize_label: range mismatch"));
822 if (auxsingle != NULL) {
823 /* Nul terminate the end of the single string. */
824 *auxsingle = '\0';
825 auxsingle++;
826 auxsingleend = index(auxsingle, ']');
827 if (auxsingleend == NULL)
828 return (EINVAL);
829 if (*(auxsingleend + 1) != '\0')
830 return (EINVAL);
831 /* Nul terminate the end of the auxsingle. */
832 *auxsingleend = '\0';
833 }
834
835 bzero(mac_lomac, sizeof(*mac_lomac));
836 if (single != NULL) {
837 error = mac_lomac_parse_element(&mac_lomac->ml_single, single);
838 if (error)
839 return (error);
840 mac_lomac->ml_flags |= MAC_LOMAC_FLAG_SINGLE;
841 }
842
843 if (auxsingle != NULL) {
844 error = mac_lomac_parse_element(&mac_lomac->ml_auxsingle,
845 auxsingle);
846 if (error)
847 return (error);
848 mac_lomac->ml_flags |= MAC_LOMAC_FLAG_AUX;
849 }
850
851 if (rangelow != NULL) {
852 error = mac_lomac_parse_element(&mac_lomac->ml_rangelow,
853 rangelow);
854 if (error)
855 return (error);
856 error = mac_lomac_parse_element(&mac_lomac->ml_rangehigh,
857 rangehigh);
858 if (error)
859 return (error);
860 mac_lomac->ml_flags |= MAC_LOMAC_FLAG_RANGE;
861 }
862
863 error = mac_lomac_valid(mac_lomac);
864 if (error)
865 return (error);
866
867 return (0);
868}
869
870static int
871mac_lomac_internalize_label(struct label *label, char *element_name,
872 char *element_data, int *claimed)
873{
874 struct mac_lomac *mac_lomac, mac_lomac_temp;
875 int error;
876
877 if (strcmp(MAC_LOMAC_LABEL_NAME, element_name) != 0)
878 return (0);
879
880 (*claimed)++;
881
882 error = mac_lomac_parse(&mac_lomac_temp, element_data);
883 if (error)
884 return (error);
885
886 mac_lomac = SLOT(label);
887 *mac_lomac = mac_lomac_temp;
888
889 return (0);
890}
891
892static void
893mac_lomac_copy_label(struct label *src, struct label *dest)
894{
895
896 *SLOT(dest) = *SLOT(src);
897}
898
899/*
900 * Labeling event operations: file system objects, and things that look
901 * a lot like file system objects.
902 */
903static void
904mac_lomac_create_devfs_device(struct ucred *cred, struct mount *mp,
905 struct cdev *dev, struct devfs_dirent *devfs_dirent, struct label *label)
906{
907 struct mac_lomac *mac_lomac;
908 int lomac_type;
909
910 mac_lomac = SLOT(label);
911 if (strcmp(dev->si_name, "null") == 0 ||
912 strcmp(dev->si_name, "zero") == 0 ||
913 strcmp(dev->si_name, "random") == 0 ||
914 strncmp(dev->si_name, "fd/", strlen("fd/")) == 0 ||
915 strncmp(dev->si_name, "ttyv", strlen("ttyv")) == 0)
916 lomac_type = MAC_LOMAC_TYPE_EQUAL;
917 else if (ptys_equal &&
918 (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
919 strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
920 lomac_type = MAC_LOMAC_TYPE_EQUAL;
921 else
922 lomac_type = MAC_LOMAC_TYPE_HIGH;
923 mac_lomac_set_single(mac_lomac, lomac_type, 0);
924}
925
926static void
927mac_lomac_create_devfs_directory(struct mount *mp, char *dirname,
928 int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label)
929{
930 struct mac_lomac *mac_lomac;
931
932 mac_lomac = SLOT(label);
933 mac_lomac_set_single(mac_lomac, MAC_LOMAC_TYPE_HIGH, 0);
934}
935
936static void
937mac_lomac_create_devfs_symlink(struct ucred *cred, struct mount *mp,
938 struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de,
939 struct label *delabel)
940{
941 struct mac_lomac *source, *dest;
942
943 source = SLOT(cred->cr_label);
944 dest = SLOT(delabel);
945
946 mac_lomac_copy_single(source, dest);
947}
948
949static void
950mac_lomac_create_mount(struct ucred *cred, struct mount *mp,
951 struct label *mntlabel, struct label *fslabel)
952{
953 struct mac_lomac *source, *dest;
954
955 source = SLOT(cred->cr_label);
956 dest = SLOT(mntlabel);
957 mac_lomac_copy_single(source, dest);
958 dest = SLOT(fslabel);
959 mac_lomac_copy_single(source, dest);
960}
961
962static void
963mac_lomac_relabel_vnode(struct ucred *cred, struct vnode *vp,
964 struct label *vnodelabel, struct label *label)
965{
966 struct mac_lomac *source, *dest;
967
968 source = SLOT(label);
969 dest = SLOT(vnodelabel);
970
971 try_relabel(source, dest);
972}
973
974static void
975mac_lomac_update_devfsdirent(struct mount *mp,
976 struct devfs_dirent *devfs_dirent, struct label *direntlabel,
977 struct vnode *vp, struct label *vnodelabel)
978{
979 struct mac_lomac *source, *dest;
980
981 source = SLOT(vnodelabel);
982 dest = SLOT(direntlabel);
983
984 mac_lomac_copy(source, dest);
985}
986
987static void
988mac_lomac_associate_vnode_devfs(struct mount *mp, struct label *fslabel,
989 struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
990 struct label *vlabel)
991{
992 struct mac_lomac *source, *dest;
993
994 source = SLOT(delabel);
995 dest = SLOT(vlabel);
996
997 mac_lomac_copy_single(source, dest);
998}
999
1000static int
1001mac_lomac_associate_vnode_extattr(struct mount *mp, struct label *fslabel,
1002 struct vnode *vp, struct label *vlabel)
1003{
1004 struct mac_lomac temp, *source, *dest;
1005 int buflen, error;
1006
1007 source = SLOT(fslabel);
1008 dest = SLOT(vlabel);
1009
1010 buflen = sizeof(temp);
1011 bzero(&temp, buflen);
1012
1013 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE,
1014 MAC_LOMAC_EXTATTR_NAME, &buflen, (char *)&temp, curthread);
1015 if (error == ENOATTR || error == EOPNOTSUPP) {
1016 /* Fall back to the fslabel. */
1017 mac_lomac_copy_single(source, dest);
1018 return (0);
1019 } else if (error)
1020 return (error);
1021
1022 if (buflen != sizeof(temp)) {
1023 if (buflen != sizeof(temp) - sizeof(temp.ml_auxsingle)) {
1024 printf("mac_lomac_associate_vnode_extattr: bad size %d\n",
1025 buflen);
1026 return (EPERM);
1027 }
1028 bzero(&temp.ml_auxsingle, sizeof(temp.ml_auxsingle));
1029 buflen = sizeof(temp);
1030 (void)vn_extattr_set(vp, IO_NODELOCKED,
1031 MAC_LOMAC_EXTATTR_NAMESPACE, MAC_LOMAC_EXTATTR_NAME,
1032 buflen, (char *)&temp, curthread);
1033 }
1034 if (mac_lomac_valid(&temp) != 0) {
1035 printf("mac_lomac_associate_vnode_extattr: invalid\n");
1036 return (EPERM);
1037 }
1038 if ((temp.ml_flags & MAC_LOMAC_FLAGS_BOTH) != MAC_LOMAC_FLAG_SINGLE) {
1039 printf("mac_lomac_associate_vnode_extattr: not single\n");
1040 return (EPERM);
1041 }
1042
1043 mac_lomac_copy_single(&temp, dest);
1044 return (0);
1045}
1046
1047static void
1048mac_lomac_associate_vnode_singlelabel(struct mount *mp,
1049 struct label *fslabel, struct vnode *vp, struct label *vlabel)
1050{
1051 struct mac_lomac *source, *dest;
1052
1053 source = SLOT(fslabel);
1054 dest = SLOT(vlabel);
1055
1056 mac_lomac_copy_single(source, dest);
1057}
1058
1059static int
1060mac_lomac_create_vnode_extattr(struct ucred *cred, struct mount *mp,
1061 struct label *fslabel, struct vnode *dvp, struct label *dlabel,
1062 struct vnode *vp, struct label *vlabel, struct componentname *cnp)
1063{
1064 struct mac_lomac *source, *dest, *dir, temp;
1065 size_t buflen;
1066 int error;
1067
1068 buflen = sizeof(temp);
1069 bzero(&temp, buflen);
1070
1071 source = SLOT(cred->cr_label);
1072 dest = SLOT(vlabel);
1073 dir = SLOT(dlabel);
1074 if (dir->ml_flags & MAC_LOMAC_FLAG_AUX) {
1075 mac_lomac_copy_auxsingle(dir, &temp);
1076 mac_lomac_set_single(&temp, dir->ml_auxsingle.mle_type,
1077 dir->ml_auxsingle.mle_grade);
1078 } else {
1079 mac_lomac_copy_single(source, &temp);
1080 }
1081
1082 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE,
1083 MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread);
1084 if (error == 0)
1085 mac_lomac_copy(&temp, dest);
1086 return (error);
1087}
1088
1089static int
1090mac_lomac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
1091 struct label *vlabel, struct label *intlabel)
1092{
1093 struct mac_lomac *source, temp;
1094 size_t buflen;
1095 int error;
1096
1097 buflen = sizeof(temp);
1098 bzero(&temp, buflen);
1099
1100 source = SLOT(intlabel);
1101 if ((source->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0)
1102 return (0);
1103
1104 mac_lomac_copy_single(source, &temp);
1105 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE,
1106 MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread);
1107 return (error);
1108}
1109
1110/*
1111 * Labeling event operations: IPC object.
1112 */
1113static void
1114mac_lomac_create_inpcb_from_socket(struct socket *so, struct label *solabel,
1115 struct inpcb *inp, struct label *inplabel)
1116{
1117 struct mac_lomac *source, *dest;
1118
1119 source = SLOT(solabel);
1120 dest = SLOT(inplabel);
1121
1122 mac_lomac_copy_single(source, dest);
1123}
1124
1125static void
1126mac_lomac_create_mbuf_from_socket(struct socket *so, struct label *socketlabel,
1127 struct mbuf *m, struct label *mbuflabel)
1128{
1129 struct mac_lomac *source, *dest;
1130
1131 source = SLOT(socketlabel);
1132 dest = SLOT(mbuflabel);
1133
1134 mac_lomac_copy_single(source, dest);
1135}
1136
1137static void
1138mac_lomac_create_socket(struct ucred *cred, struct socket *socket,
1139 struct label *socketlabel)
1140{
1141 struct mac_lomac *source, *dest;
1142
1143 source = SLOT(cred->cr_label);
1144 dest = SLOT(socketlabel);
1145
1146 mac_lomac_copy_single(source, dest);
1147}
1148
1149static void
1150mac_lomac_create_pipe(struct ucred *cred, struct pipepair *pp,
1151 struct label *pipelabel)
1152{
1153 struct mac_lomac *source, *dest;
1154
1155 source = SLOT(cred->cr_label);
1156 dest = SLOT(pipelabel);
1157
1158 mac_lomac_copy_single(source, dest);
1159}
1160
1161static void
1162mac_lomac_create_socket_from_socket(struct socket *oldsocket,
1163 struct label *oldsocketlabel, struct socket *newsocket,
1164 struct label *newsocketlabel)
1165{
1166 struct mac_lomac *source, *dest;
1167
1168 source = SLOT(oldsocketlabel);
1169 dest = SLOT(newsocketlabel);
1170
1171 mac_lomac_copy_single(source, dest);
1172}
1173
1174static void
1175mac_lomac_relabel_socket(struct ucred *cred, struct socket *socket,
1176 struct label *socketlabel, struct label *newlabel)
1177{
1178 struct mac_lomac *source, *dest;
1179
1180 source = SLOT(newlabel);
1181 dest = SLOT(socketlabel);
1182
1183 try_relabel(source, dest);
1184}
1185
1186static void
1187mac_lomac_relabel_pipe(struct ucred *cred, struct pipepair *pp,
1188 struct label *pipelabel, struct label *newlabel)
1189{
1190 struct mac_lomac *source, *dest;
1191
1192 source = SLOT(newlabel);
1193 dest = SLOT(pipelabel);
1194
1195 try_relabel(source, dest);
1196}
1197
1198static void
1199mac_lomac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel,
1200 struct socket *socket, struct label *socketpeerlabel)
1201{
1202 struct mac_lomac *source, *dest;
1203
1204 source = SLOT(mbuflabel);
1205 dest = SLOT(socketpeerlabel);
1206
1207 mac_lomac_copy_single(source, dest);
1208}
1209
1210/*
1211 * Labeling event operations: network objects.
1212 */
1213static void
1214mac_lomac_set_socket_peer_from_socket(struct socket *oldsocket,
1215 struct label *oldsocketlabel, struct socket *newsocket,
1216 struct label *newsocketpeerlabel)
1217{
1218 struct mac_lomac *source, *dest;
1219
1220 source = SLOT(oldsocketlabel);
1221 dest = SLOT(newsocketpeerlabel);
1222
1223 mac_lomac_copy_single(source, dest);
1224}
1225
1226static void
1227mac_lomac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d,
1228 struct label *bpflabel)
1229{
1230 struct mac_lomac *source, *dest;
1231
1232 source = SLOT(cred->cr_label);
1233 dest = SLOT(bpflabel);
1234
1235 mac_lomac_copy_single(source, dest);
1236}
1237
1238static void
1239mac_lomac_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel)
1240{
1241 char tifname[IFNAMSIZ], *p, *q;
1242 char tiflist[sizeof(trusted_interfaces)];
1243 struct mac_lomac *dest;
1244 int len, grade;
1245
1246 dest = SLOT(ifnetlabel);
1247
1248 if (ifnet->if_type == IFT_LOOP) {
1249 grade = MAC_LOMAC_TYPE_EQUAL;
1250 goto set;
1251 }
1252
1253 if (trust_all_interfaces) {
1254 grade = MAC_LOMAC_TYPE_HIGH;
1255 goto set;
1256 }
1257
1258 grade = MAC_LOMAC_TYPE_LOW;
1259
1260 if (trusted_interfaces[0] == '\0' ||
1261 !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
1262 goto set;
1263
1264 bzero(tiflist, sizeof(tiflist));
1265 for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
1266 if(*p != ' ' && *p != '\t')
1267 *q = *p;
1268
1269 for (p = q = tiflist;; p++) {
1270 if (*p == ',' || *p == '\0') {
1271 len = p - q;
1272 if (len < IFNAMSIZ) {
1273 bzero(tifname, sizeof(tifname));
1274 bcopy(q, tifname, len);
1275 if (strcmp(tifname, ifnet->if_xname) == 0) {
1276 grade = MAC_LOMAC_TYPE_HIGH;
1277 break;
1278 }
1279 }
1280 else {
1281 *p = '\0';
1282 printf("MAC/LOMAC warning: interface name "
1283 "\"%s\" is too long (must be < %d)\n",
1284 q, IFNAMSIZ);
1285 }
1286 if (*p == '\0')
1287 break;
1288 q = p + 1;
1289 }
1290 }
1291set:
1292 mac_lomac_set_single(dest, grade, 0);
1293 mac_lomac_set_range(dest, grade, 0, grade, 0);
1294}
1295
1296static void
1297mac_lomac_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1298 struct ipq *ipq, struct label *ipqlabel)
1299{
1300 struct mac_lomac *source, *dest;
1301
1302 source = SLOT(fragmentlabel);
1303 dest = SLOT(ipqlabel);
1304
1305 mac_lomac_copy_single(source, dest);
1306}
1307
1308static void
1309mac_lomac_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
1310 struct mbuf *datagram, struct label *datagramlabel)
1311{
1312 struct mac_lomac *source, *dest;
1313
1314 source = SLOT(ipqlabel);
1315 dest = SLOT(datagramlabel);
1316
1317 /* Just use the head, since we require them all to match. */
1318 mac_lomac_copy_single(source, dest);
1319}
1320
1321static void
1322mac_lomac_create_fragment(struct mbuf *datagram, struct label *datagramlabel,
1323 struct mbuf *fragment, struct label *fragmentlabel)
1324{
1325 struct mac_lomac *source, *dest;
1326
1327 source = SLOT(datagramlabel);
1328 dest = SLOT(fragmentlabel);
1329
1330 mac_lomac_copy_single(source, dest);
1331}
1332
1333static void
1334mac_lomac_create_mbuf_from_inpcb(struct inpcb *inp, struct label *inplabel,
1335 struct mbuf *m, struct label *mlabel)
1336{
1337 struct mac_lomac *source, *dest;
1338
1339 source = SLOT(inplabel);
1340 dest = SLOT(mlabel);
1341
1342 mac_lomac_copy_single(source, dest);
1343}
1344
1345static void
1346mac_lomac_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel,
1347 struct mbuf *mbuf, struct label *mbuflabel)
1348{
1349 struct mac_lomac *dest;
1350
1351 dest = SLOT(mbuflabel);
1352
1353 mac_lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0);
1354}
1355
1356static void
1357mac_lomac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel,
1358 struct mbuf *mbuf, struct label *mbuflabel)
1359{
1360 struct mac_lomac *source, *dest;
1361
1362 source = SLOT(bpflabel);
1363 dest = SLOT(mbuflabel);
1364
1365 mac_lomac_copy_single(source, dest);
1366}
1367
1368static void
1369mac_lomac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel,
1370 struct mbuf *m, struct label *mbuflabel)
1371{
1372 struct mac_lomac *source, *dest;
1373
1374 source = SLOT(ifnetlabel);
1375 dest = SLOT(mbuflabel);
1376
1377 mac_lomac_copy_single(source, dest);
1378}
1379
1380static void
1381mac_lomac_create_mbuf_multicast_encap(struct mbuf *oldmbuf,
1382 struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel,
1383 struct mbuf *newmbuf, struct label *newmbuflabel)
1384{
1385 struct mac_lomac *source, *dest;
1386
1387 source = SLOT(oldmbuflabel);
1388 dest = SLOT(newmbuflabel);
1389
1390 mac_lomac_copy_single(source, dest);
1391}
1392
1393static void
1394mac_lomac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel,
1395 struct mbuf *newmbuf, struct label *newmbuflabel)
1396{
1397 struct mac_lomac *source, *dest;
1398
1399 source = SLOT(oldmbuflabel);
1400 dest = SLOT(newmbuflabel);
1401
1402 mac_lomac_copy_single(source, dest);
1403}
1404
1405static int
1406mac_lomac_fragment_match(struct mbuf *fragment, struct label *fragmentlabel,
1407 struct ipq *ipq, struct label *ipqlabel)
1408{
1409 struct mac_lomac *a, *b;
1410
1411 a = SLOT(ipqlabel);
1412 b = SLOT(fragmentlabel);
1413
1414 return (mac_lomac_equal_single(a, b));
1415}
1416
1417static void
1418mac_lomac_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
1419 struct label *ifnetlabel, struct label *newlabel)
1420{
1421 struct mac_lomac *source, *dest;
1422
1423 source = SLOT(newlabel);
1424 dest = SLOT(ifnetlabel);
1425
1426 try_relabel(source, dest);
1427}
1428
1429static void
1430mac_lomac_update_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1431 struct ipq *ipq, struct label *ipqlabel)
1432{
1433
1434 /* NOOP: we only accept matching labels, so no need to update */
1435}
1436
1437static void
1438mac_lomac_inpcb_sosetlabel(struct socket *so, struct label *solabel,
1439 struct inpcb *inp, struct label *inplabel)
1440{
1441 struct mac_lomac *source, *dest;
1442
1443 source = SLOT(solabel);
1444 dest = SLOT(inplabel);
1445
1446 mac_lomac_copy_single(source, dest);
1447}
1448
1449static void
1450mac_lomac_create_mbuf_from_firewall(struct mbuf *m, struct label *label)
1451{
1452 struct mac_lomac *dest;
1453
1454 dest = SLOT(label);
1455
1456 /* XXX: where is the label for the firewall really comming from? */
1457 mac_lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0);
1458}
1459
1449/*
1450 * Labeling event operations: processes.
1451 */
1452static void
1453mac_lomac_execve_transition(struct ucred *old, struct ucred *new,
1454 struct vnode *vp, struct label *vnodelabel,
1455 struct label *interpvnodelabel, struct image_params *imgp,
1456 struct label *execlabel)
1457{
1458 struct mac_lomac *source, *dest, *obj, *robj;
1459
1460 source = SLOT(old->cr_label);
1461 dest = SLOT(new->cr_label);
1462 obj = SLOT(vnodelabel);
1463 robj = interpvnodelabel != NULL ? SLOT(interpvnodelabel) : obj;
1464
1465 mac_lomac_copy(source, dest);
1466 /*
1467 * If there's an auxiliary label on the real object, respect it
1468 * and assume that this level should be assumed immediately if
1469 * a higher level is currently in place.
1470 */
1471 if (robj->ml_flags & MAC_LOMAC_FLAG_AUX &&
1472 !mac_lomac_dominate_element(&robj->ml_auxsingle, &dest->ml_single)
1473 && mac_lomac_auxsingle_in_range(robj, dest))
1474 mac_lomac_set_single(dest, robj->ml_auxsingle.mle_type,
1475 robj->ml_auxsingle.mle_grade);
1476 /*
1477 * Restructuring to use the execve transitioning mechanism
1478 * instead of the normal demotion mechanism here would be
1479 * difficult, so just copy the label over and perform standard
1480 * demotion. This is also non-optimal because it will result
1481 * in the intermediate label "new" being created and immediately
1482 * recycled.
1483 */
1484 if (mac_lomac_enabled && revocation_enabled &&
1485 !mac_lomac_dominate_single(obj, source))
1486 (void)maybe_demote(source, obj, "executing", "file", vp);
1487}
1488
1489static int
1490mac_lomac_execve_will_transition(struct ucred *old, struct vnode *vp,
1491 struct label *vnodelabel, struct label *interpvnodelabel,
1492 struct image_params *imgp, struct label *execlabel)
1493{
1494 struct mac_lomac *subj, *obj, *robj;
1495
1496 if (!mac_lomac_enabled || !revocation_enabled)
1497 return (0);
1498
1499 subj = SLOT(old->cr_label);
1500 obj = SLOT(vnodelabel);
1501 robj = interpvnodelabel != NULL ? SLOT(interpvnodelabel) : obj;
1502
1503 return ((robj->ml_flags & MAC_LOMAC_FLAG_AUX &&
1504 !mac_lomac_dominate_element(&robj->ml_auxsingle, &subj->ml_single)
1505 && mac_lomac_auxsingle_in_range(robj, subj)) ||
1506 !mac_lomac_dominate_single(obj, subj));
1507}
1508
1509static void
1510mac_lomac_create_proc0(struct ucred *cred)
1511{
1512 struct mac_lomac *dest;
1513
1514 dest = SLOT(cred->cr_label);
1515
1516 mac_lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0);
1517 mac_lomac_set_range(dest, MAC_LOMAC_TYPE_LOW, 0, MAC_LOMAC_TYPE_HIGH,
1518 0);
1519}
1520
1521static void
1522mac_lomac_create_proc1(struct ucred *cred)
1523{
1524 struct mac_lomac *dest;
1525
1526 dest = SLOT(cred->cr_label);
1527
1528 mac_lomac_set_single(dest, MAC_LOMAC_TYPE_HIGH, 0);
1529 mac_lomac_set_range(dest, MAC_LOMAC_TYPE_LOW, 0, MAC_LOMAC_TYPE_HIGH,
1530 0);
1531}
1532
1533static void
1534mac_lomac_relabel_cred(struct ucred *cred, struct label *newlabel)
1535{
1536 struct mac_lomac *source, *dest;
1537
1538 source = SLOT(newlabel);
1539 dest = SLOT(cred->cr_label);
1540
1541 try_relabel(source, dest);
1542}
1543
1544/*
1545 * Access control checks.
1546 */
1547static int
1548mac_lomac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
1549 struct ifnet *ifnet, struct label *ifnetlabel)
1550{
1551 struct mac_lomac *a, *b;
1552
1553 if (!mac_lomac_enabled)
1554 return (0);
1555
1556 a = SLOT(bpflabel);
1557 b = SLOT(ifnetlabel);
1558
1559 if (mac_lomac_equal_single(a, b))
1560 return (0);
1561 return (EACCES);
1562}
1563
1564static int
1565mac_lomac_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1566{
1567 struct mac_lomac *subj, *new;
1568 int error;
1569
1570 subj = SLOT(cred->cr_label);
1571 new = SLOT(newlabel);
1572
1573 /*
1574 * If there is a LOMAC label update for the credential, it may
1575 * be an update of the single, range, or both.
1576 */
1577 error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH);
1578 if (error)
1579 return (error);
1580
1581 /*
1582 * If the LOMAC label is to be changed, authorize as appropriate.
1583 */
1584 if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) {
1585 /*
1586 * Fill in the missing parts from the previous label.
1587 */
1588 if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0)
1589 mac_lomac_copy_single(subj, new);
1590 if ((new->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0)
1591 mac_lomac_copy_range(subj, new);
1592
1593 /*
1594 * To change the LOMAC range on a credential, the new
1595 * range label must be in the current range.
1596 */
1597 if (!mac_lomac_range_in_range(new, subj))
1598 return (EPERM);
1599
1600 /*
1601 * To change the LOMAC single label on a credential, the
1602 * new single label must be in the new range. Implicitly
1603 * from the previous check, the new single is in the old
1604 * range.
1605 */
1606 if (!mac_lomac_single_in_range(new, new))
1607 return (EPERM);
1608
1609 /*
1610 * To have EQUAL in any component of the new credential
1611 * LOMAC label, the subject must already have EQUAL in
1612 * their label.
1613 */
1614 if (mac_lomac_contains_equal(new)) {
1615 error = mac_lomac_subject_privileged(subj);
1616 if (error)
1617 return (error);
1618 }
1619
1620 /*
1621 * XXXMAC: Additional consistency tests regarding the
1622 * single and range of the new label might be performed
1623 * here.
1624 */
1625 }
1626
1627 return (0);
1628}
1629
1630static int
1631mac_lomac_check_cred_visible(struct ucred *u1, struct ucred *u2)
1632{
1633 struct mac_lomac *subj, *obj;
1634
1635 if (!mac_lomac_enabled)
1636 return (0);
1637
1638 subj = SLOT(u1->cr_label);
1639 obj = SLOT(u2->cr_label);
1640
1641 /* XXX: range */
1642 if (!mac_lomac_dominate_single(obj, subj))
1643 return (ESRCH);
1644
1645 return (0);
1646}
1647
1648static int
1649mac_lomac_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
1650 struct label *ifnetlabel, struct label *newlabel)
1651{
1652 struct mac_lomac *subj, *new;
1653 int error;
1654
1655 subj = SLOT(cred->cr_label);
1656 new = SLOT(newlabel);
1657
1658 /*
1659 * If there is a LOMAC label update for the interface, it may
1660 * be an update of the single, range, or both.
1661 */
1662 error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH);
1663 if (error)
1664 return (error);
1665
1666 /*
1667 * Relabling network interfaces requires LOMAC privilege.
1668 */
1669 error = mac_lomac_subject_privileged(subj);
1670 if (error)
1671 return (error);
1672
1673 /*
1674 * If the LOMAC label is to be changed, authorize as appropriate.
1675 */
1676 if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) {
1677 /*
1678 * Fill in the missing parts from the previous label.
1679 */
1680 if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0)
1681 mac_lomac_copy_single(subj, new);
1682 if ((new->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0)
1683 mac_lomac_copy_range(subj, new);
1684
1685 /*
1686 * Rely on the traditional superuser status for the LOMAC
1687 * interface relabel requirements. XXXMAC: This will go
1688 * away.
1689 */
1690 error = suser_cred(cred, 0);
1691 if (error)
1692 return (EPERM);
1693
1694 /*
1695 * XXXMAC: Additional consistency tests regarding the single
1696 * and the range of the new label might be performed here.
1697 */
1698 }
1699
1700 return (0);
1701}
1702
1703static int
1704mac_lomac_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1705 struct mbuf *m, struct label *mbuflabel)
1706{
1707 struct mac_lomac *p, *i;
1708
1709 if (!mac_lomac_enabled)
1710 return (0);
1711
1712 p = SLOT(mbuflabel);
1713 i = SLOT(ifnetlabel);
1714
1715 return (mac_lomac_single_in_range(p, i) ? 0 : EACCES);
1716}
1717
1718static int
1719mac_lomac_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel,
1720 struct mbuf *m, struct label *mlabel)
1721{
1722 struct mac_lomac *p, *i;
1723
1724 if (!mac_lomac_enabled)
1725 return (0);
1726
1727 p = SLOT(mlabel);
1728 i = SLOT(inplabel);
1729
1730 return (mac_lomac_equal_single(p, i) ? 0 : EACCES);
1731}
1732
1733static int
1734mac_lomac_check_kld_load(struct ucred *cred, struct vnode *vp,
1735 struct label *label)
1736{
1737 struct mac_lomac *subj, *obj;
1738
1739 if (!mac_lomac_enabled)
1740 return (0);
1741
1742 subj = SLOT(cred->cr_label);
1743 obj = SLOT(label);
1744
1745 if (mac_lomac_subject_privileged(subj))
1746 return (EPERM);
1747
1748 if (!mac_lomac_high_single(obj))
1749 return (EACCES);
1750
1751 return (0);
1752}
1753
1754static int
1755mac_lomac_check_kld_unload(struct ucred *cred)
1756{
1757 struct mac_lomac *subj;
1758
1759 if (!mac_lomac_enabled)
1760 return (0);
1761
1762 subj = SLOT(cred->cr_label);
1763
1764 if (mac_lomac_subject_privileged(subj))
1765 return (EPERM);
1766
1767 return (0);
1768}
1769
1770static int
1771mac_lomac_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp,
1772 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1773{
1774
1775 if(!mac_lomac_enabled)
1776 return (0);
1777
1778 /* XXX: This will be implemented soon... */
1779
1780 return (0);
1781}
1782
1783static int
1784mac_lomac_check_pipe_read(struct ucred *cred, struct pipepair *pp,
1785 struct label *pipelabel)
1786{
1787 struct mac_lomac *subj, *obj;
1788
1789 if (!mac_lomac_enabled)
1790 return (0);
1791
1792 subj = SLOT(cred->cr_label);
1793 obj = SLOT((pipelabel));
1794
1795 if (!mac_lomac_dominate_single(obj, subj))
1796 return (maybe_demote(subj, obj, "reading", "pipe", NULL));
1797
1798 return (0);
1799}
1800
1801static int
1802mac_lomac_check_pipe_relabel(struct ucred *cred, struct pipepair *pp,
1803 struct label *pipelabel, struct label *newlabel)
1804{
1805 struct mac_lomac *subj, *obj, *new;
1806 int error;
1807
1808 new = SLOT(newlabel);
1809 subj = SLOT(cred->cr_label);
1810 obj = SLOT(pipelabel);
1811
1812 /*
1813 * If there is a LOMAC label update for a pipe, it must be a
1814 * single update.
1815 */
1816 error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE);
1817 if (error)
1818 return (error);
1819
1820 /*
1821 * To perform a relabel of a pipe (LOMAC label or not), LOMAC must
1822 * authorize the relabel.
1823 */
1824 if (!mac_lomac_single_in_range(obj, subj))
1825 return (EPERM);
1826
1827 /*
1828 * If the LOMAC label is to be changed, authorize as appropriate.
1829 */
1830 if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
1831 /*
1832 * To change the LOMAC label on a pipe, the new pipe label
1833 * must be in the subject range.
1834 */
1835 if (!mac_lomac_single_in_range(new, subj))
1836 return (EPERM);
1837
1838 /*
1839 * To change the LOMAC label on a pipe to be EQUAL, the
1840 * subject must have appropriate privilege.
1841 */
1842 if (mac_lomac_contains_equal(new)) {
1843 error = mac_lomac_subject_privileged(subj);
1844 if (error)
1845 return (error);
1846 }
1847 }
1848
1849 return (0);
1850}
1851
1852static int
1853mac_lomac_check_pipe_write(struct ucred *cred, struct pipepair *pp,
1854 struct label *pipelabel)
1855{
1856 struct mac_lomac *subj, *obj;
1857
1858 if (!mac_lomac_enabled)
1859 return (0);
1860
1861 subj = SLOT(cred->cr_label);
1862 obj = SLOT((pipelabel));
1863
1864 if (!mac_lomac_subject_dominate(subj, obj))
1865 return (EACCES);
1866
1867 return (0);
1868}
1869
1870static int
1871mac_lomac_check_proc_debug(struct ucred *cred, struct proc *proc)
1872{
1873 struct mac_lomac *subj, *obj;
1874
1875 if (!mac_lomac_enabled)
1876 return (0);
1877
1878 subj = SLOT(cred->cr_label);
1879 obj = SLOT(proc->p_ucred->cr_label);
1880
1881 /* XXX: range checks */
1882 if (!mac_lomac_dominate_single(obj, subj))
1883 return (ESRCH);
1884 if (!mac_lomac_subject_dominate(subj, obj))
1885 return (EACCES);
1886
1887 return (0);
1888}
1889
1890static int
1891mac_lomac_check_proc_sched(struct ucred *cred, struct proc *proc)
1892{
1893 struct mac_lomac *subj, *obj;
1894
1895 if (!mac_lomac_enabled)
1896 return (0);
1897
1898 subj = SLOT(cred->cr_label);
1899 obj = SLOT(proc->p_ucred->cr_label);
1900
1901 /* XXX: range checks */
1902 if (!mac_lomac_dominate_single(obj, subj))
1903 return (ESRCH);
1904 if (!mac_lomac_subject_dominate(subj, obj))
1905 return (EACCES);
1906
1907 return (0);
1908}
1909
1910static int
1911mac_lomac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
1912{
1913 struct mac_lomac *subj, *obj;
1914
1915 if (!mac_lomac_enabled)
1916 return (0);
1917
1918 subj = SLOT(cred->cr_label);
1919 obj = SLOT(proc->p_ucred->cr_label);
1920
1921 /* XXX: range checks */
1922 if (!mac_lomac_dominate_single(obj, subj))
1923 return (ESRCH);
1924 if (!mac_lomac_subject_dominate(subj, obj))
1925 return (EACCES);
1926
1927 return (0);
1928}
1929
1930static int
1931mac_lomac_check_socket_deliver(struct socket *so, struct label *socketlabel,
1932 struct mbuf *m, struct label *mbuflabel)
1933{
1934 struct mac_lomac *p, *s;
1935
1936 if (!mac_lomac_enabled)
1937 return (0);
1938
1939 p = SLOT(mbuflabel);
1940 s = SLOT(socketlabel);
1941
1942 return (mac_lomac_equal_single(p, s) ? 0 : EACCES);
1943}
1944
1945static int
1946mac_lomac_check_socket_relabel(struct ucred *cred, struct socket *socket,
1947 struct label *socketlabel, struct label *newlabel)
1948{
1949 struct mac_lomac *subj, *obj, *new;
1950 int error;
1951
1952 new = SLOT(newlabel);
1953 subj = SLOT(cred->cr_label);
1954 obj = SLOT(socketlabel);
1955
1956 /*
1957 * If there is a LOMAC label update for the socket, it may be
1958 * an update of single.
1959 */
1960 error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE);
1961 if (error)
1962 return (error);
1963
1964 /*
1965 * To relabel a socket, the old socket single must be in the subject
1966 * range.
1967 */
1968 if (!mac_lomac_single_in_range(obj, subj))
1969 return (EPERM);
1970
1971 /*
1972 * If the LOMAC label is to be changed, authorize as appropriate.
1973 */
1974 if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
1975 /*
1976 * To relabel a socket, the new socket single must be in
1977 * the subject range.
1978 */
1979 if (!mac_lomac_single_in_range(new, subj))
1980 return (EPERM);
1981
1982 /*
1983 * To change the LOMAC label on the socket to contain EQUAL,
1984 * the subject must have appropriate privilege.
1985 */
1986 if (mac_lomac_contains_equal(new)) {
1987 error = mac_lomac_subject_privileged(subj);
1988 if (error)
1989 return (error);
1990 }
1991 }
1992
1993 return (0);
1994}
1995
1996static int
1997mac_lomac_check_socket_visible(struct ucred *cred, struct socket *socket,
1998 struct label *socketlabel)
1999{
2000 struct mac_lomac *subj, *obj;
2001
2002 if (!mac_lomac_enabled)
2003 return (0);
2004
2005 subj = SLOT(cred->cr_label);
2006 obj = SLOT(socketlabel);
2007
2008 if (!mac_lomac_dominate_single(obj, subj))
2009 return (ENOENT);
2010
2011 return (0);
2012}
2013
2014static int
2015mac_lomac_check_system_swapon(struct ucred *cred, struct vnode *vp,
2016 struct label *label)
2017{
2018 struct mac_lomac *subj, *obj;
2019
2020 if (!mac_lomac_enabled)
2021 return (0);
2022
2023 subj = SLOT(cred->cr_label);
2024 obj = SLOT(label);
2025
2026 if (mac_lomac_subject_privileged(subj))
2027 return (EPERM);
2028
2029 if (!mac_lomac_high_single(obj))
2030 return (EACCES);
2031
2032 return (0);
2033}
2034
2035static int
2036mac_lomac_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp,
2037 void *arg1, int arg2, struct sysctl_req *req)
2038{
2039 struct mac_lomac *subj;
2040
2041 if (!mac_lomac_enabled)
2042 return (0);
2043
2044 subj = SLOT(cred->cr_label);
2045
2046 /*
2047 * Treat sysctl variables without CTLFLAG_ANYBODY flag as
2048 * lomac/high, but also require privilege to change them.
2049 */
2050 if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) {
2051#ifdef notdef
2052 if (!mac_lomac_subject_dominate_high(subj))
2053 return (EACCES);
2054#endif
2055
2056 if (mac_lomac_subject_privileged(subj))
2057 return (EPERM);
2058 }
2059
2060 return (0);
2061}
2062
2063static int
2064mac_lomac_check_vnode_create(struct ucred *cred, struct vnode *dvp,
2065 struct label *dlabel, struct componentname *cnp, struct vattr *vap)
2066{
2067 struct mac_lomac *subj, *obj;
2068
2069 if (!mac_lomac_enabled)
2070 return (0);
2071
2072 subj = SLOT(cred->cr_label);
2073 obj = SLOT(dlabel);
2074
2075 if (!mac_lomac_subject_dominate(subj, obj))
2076 return (EACCES);
2077 if (obj->ml_flags & MAC_LOMAC_FLAG_AUX &&
2078 !mac_lomac_dominate_element(&subj->ml_single, &obj->ml_auxsingle))
2079 return (EACCES);
2080
2081 return (0);
2082}
2083
2084static int
2085mac_lomac_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
2086 struct label *dlabel, struct vnode *vp, struct label *label,
2087 struct componentname *cnp)
2088{
2089 struct mac_lomac *subj, *obj;
2090
2091 if (!mac_lomac_enabled)
2092 return (0);
2093
2094 subj = SLOT(cred->cr_label);
2095 obj = SLOT(dlabel);
2096
2097 if (!mac_lomac_subject_dominate(subj, obj))
2098 return (EACCES);
2099
2100 obj = SLOT(label);
2101
2102 if (!mac_lomac_subject_dominate(subj, obj))
2103 return (EACCES);
2104
2105 return (0);
2106}
2107
2108static int
2109mac_lomac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
2110 struct label *label, acl_type_t type)
2111{
2112 struct mac_lomac *subj, *obj;
2113
2114 if (!mac_lomac_enabled)
2115 return (0);
2116
2117 subj = SLOT(cred->cr_label);
2118 obj = SLOT(label);
2119
2120 if (!mac_lomac_subject_dominate(subj, obj))
2121 return (EACCES);
2122
2123 return (0);
2124}
2125
2126static int
2127mac_lomac_check_vnode_link(struct ucred *cred, struct vnode *dvp,
2128 struct label *dlabel, struct vnode *vp, struct label *label,
2129 struct componentname *cnp)
2130{
2131 struct mac_lomac *subj, *obj;
2132
2133 if (!mac_lomac_enabled)
2134 return (0);
2135
2136 subj = SLOT(cred->cr_label);
2137 obj = SLOT(dlabel);
2138
2139 if (!mac_lomac_subject_dominate(subj, obj))
2140 return (EACCES);
2141
2142 obj = SLOT(label);
2143
2144 if (!mac_lomac_subject_dominate(subj, obj))
2145 return (EACCES);
2146
2147 return (0);
2148}
2149
2150static int
2151mac_lomac_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
2152 struct label *label, int prot, int flags)
2153{
2154 struct mac_lomac *subj, *obj;
2155
2156 /*
2157 * Rely on the use of open()-time protections to handle
2158 * non-revocation cases.
2159 */
2160 if (!mac_lomac_enabled)
2161 return (0);
2162
2163 subj = SLOT(cred->cr_label);
2164 obj = SLOT(label);
2165
2166 if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) {
2167 if (!mac_lomac_subject_dominate(subj, obj))
2168 return (EACCES);
2169 }
2170 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2171 if (!mac_lomac_dominate_single(obj, subj))
2172 return (maybe_demote(subj, obj, "mapping", "file", vp));
2173 }
2174
2175 return (0);
2176}
2177
2178static void
2179mac_lomac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp,
2180 struct label *label, /* XXX vm_prot_t */ int *prot)
2181{
2182 struct mac_lomac *subj, *obj;
2183
2184 /*
2185 * Rely on the use of open()-time protections to handle
2186 * non-revocation cases.
2187 */
2188 if (!mac_lomac_enabled || !revocation_enabled)
2189 return;
2190
2191 subj = SLOT(cred->cr_label);
2192 obj = SLOT(label);
2193
2194 if (!mac_lomac_subject_dominate(subj, obj))
2195 *prot &= ~VM_PROT_WRITE;
2196}
2197
2198static int
2199mac_lomac_check_vnode_open(struct ucred *cred, struct vnode *vp,
2200 struct label *vnodelabel, int acc_mode)
2201{
2202 struct mac_lomac *subj, *obj;
2203
2204 if (!mac_lomac_enabled)
2205 return (0);
2206
2207 subj = SLOT(cred->cr_label);
2208 obj = SLOT(vnodelabel);
2209
2210 /* XXX privilege override for admin? */
2211 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2212 if (!mac_lomac_subject_dominate(subj, obj))
2213 return (EACCES);
2214 }
2215
2216 return (0);
2217}
2218
2219static int
2220mac_lomac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2221 struct vnode *vp, struct label *label)
2222{
2223 struct mac_lomac *subj, *obj;
2224
2225 if (!mac_lomac_enabled || !revocation_enabled)
2226 return (0);
2227
2228 subj = SLOT(active_cred->cr_label);
2229 obj = SLOT(label);
2230
2231 if (!mac_lomac_dominate_single(obj, subj))
2232 return (maybe_demote(subj, obj, "reading", "file", vp));
2233
2234 return (0);
2235}
2236
2237static int
2238mac_lomac_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2239 struct label *vnodelabel, struct label *newlabel)
2240{
2241 struct mac_lomac *old, *new, *subj;
2242 int error;
2243
2244 old = SLOT(vnodelabel);
2245 new = SLOT(newlabel);
2246 subj = SLOT(cred->cr_label);
2247
2248 /*
2249 * If there is a LOMAC label update for the vnode, it must be a
2250 * single label, with an optional explicit auxiliary single.
2251 */
2252 error = lomac_atmostflags(new,
2253 MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_AUX);
2254 if (error)
2255 return (error);
2256
2257 /*
2258 * To perform a relabel of the vnode (LOMAC label or not), LOMAC must
2259 * authorize the relabel.
2260 */
2261 if (!mac_lomac_single_in_range(old, subj))
2262 return (EPERM);
2263
2264 /*
2265 * If the LOMAC label is to be changed, authorize as appropriate.
2266 */
2267 if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
2268 /*
2269 * To change the LOMAC label on a vnode, the new vnode label
2270 * must be in the subject range.
2271 */
2272 if (!mac_lomac_single_in_range(new, subj))
2273 return (EPERM);
2274
2275 /*
2276 * To change the LOMAC label on the vnode to be EQUAL,
2277 * the subject must have appropriate privilege.
2278 */
2279 if (mac_lomac_contains_equal(new)) {
2280 error = mac_lomac_subject_privileged(subj);
2281 if (error)
2282 return (error);
2283 }
2284 }
2285 if (new->ml_flags & MAC_LOMAC_FLAG_AUX) {
2286 /*
2287 * Fill in the missing parts from the previous label.
2288 */
2289 if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0)
2290 mac_lomac_copy_single(subj, new);
2291
2292 /*
2293 * To change the auxiliary LOMAC label on a vnode, the new
2294 * vnode label must be in the subject range.
2295 */
2296 if (!mac_lomac_auxsingle_in_range(new, subj))
2297 return (EPERM);
2298
2299 /*
2300 * To change the auxiliary LOMAC label on the vnode to be
2301 * EQUAL, the subject must have appropriate privilege.
2302 */
2303 if (mac_lomac_contains_equal(new)) {
2304 error = mac_lomac_subject_privileged(subj);
2305 if (error)
2306 return (error);
2307 }
2308 }
2309
2310 return (0);
2311}
2312
2313static int
2314mac_lomac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2315 struct label *dlabel, struct vnode *vp, struct label *label,
2316 struct componentname *cnp)
2317{
2318 struct mac_lomac *subj, *obj;
2319
2320 if (!mac_lomac_enabled)
2321 return (0);
2322
2323 subj = SLOT(cred->cr_label);
2324 obj = SLOT(dlabel);
2325
2326 if (!mac_lomac_subject_dominate(subj, obj))
2327 return (EACCES);
2328
2329 obj = SLOT(label);
2330
2331 if (!mac_lomac_subject_dominate(subj, obj))
2332 return (EACCES);
2333
2334 return (0);
2335}
2336
2337static int
2338mac_lomac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2339 struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
2340 struct componentname *cnp)
2341{
2342 struct mac_lomac *subj, *obj;
2343
2344 if (!mac_lomac_enabled)
2345 return (0);
2346
2347 subj = SLOT(cred->cr_label);
2348 obj = SLOT(dlabel);
2349
2350 if (!mac_lomac_subject_dominate(subj, obj))
2351 return (EACCES);
2352
2353 if (vp != NULL) {
2354 obj = SLOT(label);
2355
2356 if (!mac_lomac_subject_dominate(subj, obj))
2357 return (EACCES);
2358 }
2359
2360 return (0);
2361}
2362
2363static int
2364mac_lomac_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
2365 struct label *label)
2366{
2367 struct mac_lomac *subj, *obj;
2368
2369 if (!mac_lomac_enabled)
2370 return (0);
2371
2372 subj = SLOT(cred->cr_label);
2373 obj = SLOT(label);
2374
2375 if (!mac_lomac_subject_dominate(subj, obj))
2376 return (EACCES);
2377
2378 return (0);
2379}
2380
2381static int
2382mac_lomac_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
2383 struct label *label, acl_type_t type, struct acl *acl)
2384{
2385 struct mac_lomac *subj, *obj;
2386
2387 if (!mac_lomac_enabled)
2388 return (0);
2389
2390 subj = SLOT(cred->cr_label);
2391 obj = SLOT(label);
2392
2393 if (!mac_lomac_subject_dominate(subj, obj))
2394 return (EACCES);
2395
2396 return (0);
2397}
2398
2399static int
2400mac_lomac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2401 struct label *vnodelabel, int attrnamespace, const char *name,
2402 struct uio *uio)
2403{
2404 struct mac_lomac *subj, *obj;
2405
2406 if (!mac_lomac_enabled)
2407 return (0);
2408
2409 subj = SLOT(cred->cr_label);
2410 obj = SLOT(vnodelabel);
2411
2412 if (!mac_lomac_subject_dominate(subj, obj))
2413 return (EACCES);
2414
2415 /* XXX: protect the MAC EA in a special way? */
2416
2417 return (0);
2418}
2419
2420static int
2421mac_lomac_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2422 struct label *vnodelabel, u_long flags)
2423{
2424 struct mac_lomac *subj, *obj;
2425
2426 if (!mac_lomac_enabled)
2427 return (0);
2428
2429 subj = SLOT(cred->cr_label);
2430 obj = SLOT(vnodelabel);
2431
2432 if (!mac_lomac_subject_dominate(subj, obj))
2433 return (EACCES);
2434
2435 return (0);
2436}
2437
2438static int
2439mac_lomac_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2440 struct label *vnodelabel, mode_t mode)
2441{
2442 struct mac_lomac *subj, *obj;
2443
2444 if (!mac_lomac_enabled)
2445 return (0);
2446
2447 subj = SLOT(cred->cr_label);
2448 obj = SLOT(vnodelabel);
2449
2450 if (!mac_lomac_subject_dominate(subj, obj))
2451 return (EACCES);
2452
2453 return (0);
2454}
2455
2456static int
2457mac_lomac_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2458 struct label *vnodelabel, uid_t uid, gid_t gid)
2459{
2460 struct mac_lomac *subj, *obj;
2461
2462 if (!mac_lomac_enabled)
2463 return (0);
2464
2465 subj = SLOT(cred->cr_label);
2466 obj = SLOT(vnodelabel);
2467
2468 if (!mac_lomac_subject_dominate(subj, obj))
2469 return (EACCES);
2470
2471 return (0);
2472}
2473
2474static int
2475mac_lomac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2476 struct label *vnodelabel, struct timespec atime, struct timespec mtime)
2477{
2478 struct mac_lomac *subj, *obj;
2479
2480 if (!mac_lomac_enabled)
2481 return (0);
2482
2483 subj = SLOT(cred->cr_label);
2484 obj = SLOT(vnodelabel);
2485
2486 if (!mac_lomac_subject_dominate(subj, obj))
2487 return (EACCES);
2488
2489 return (0);
2490}
2491
2492static int
2493mac_lomac_check_vnode_write(struct ucred *active_cred,
2494 struct ucred *file_cred, struct vnode *vp, struct label *label)
2495{
2496 struct mac_lomac *subj, *obj;
2497
2498 if (!mac_lomac_enabled || !revocation_enabled)
2499 return (0);
2500
2501 subj = SLOT(active_cred->cr_label);
2502 obj = SLOT(label);
2503
2504 if (!mac_lomac_subject_dominate(subj, obj))
2505 return (EACCES);
2506
2507 return (0);
2508}
2509
2510static void
2511mac_lomac_thread_userret(struct thread *td)
2512{
2513 struct proc *p = td->td_proc;
2514 struct mac_lomac_proc *subj = PSLOT(p->p_label);
2515 struct ucred *newcred, *oldcred;
2516 int dodrop;
2517
2518 mtx_lock(&subj->mtx);
2519 if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) {
2520 dodrop = 0;
2521 mtx_unlock(&subj->mtx);
2522 newcred = crget();
2523 /*
2524 * Prevent a lock order reversal in
2525 * mac_cred_mmapped_drop_perms; ideally, the other
2526 * user of subj->mtx wouldn't be holding Giant.
2527 */
2528 mtx_lock(&Giant);
2529 PROC_LOCK(p);
2530 mtx_lock(&subj->mtx);
2531 /*
2532 * Check if we lost the race while allocating the cred.
2533 */
2534 if ((subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) == 0) {
2535 crfree(newcred);
2536 goto out;
2537 }
2538 oldcred = p->p_ucred;
2539 crcopy(newcred, oldcred);
2540 crhold(newcred);
2541 mac_lomac_copy(&subj->mac_lomac, SLOT(newcred->cr_label));
2542 p->p_ucred = newcred;
2543 crfree(oldcred);
2544 dodrop = 1;
2545 out:
2546 mtx_unlock(&subj->mtx);
2547 PROC_UNLOCK(p);
2548 if (dodrop)
2549 mac_cred_mmapped_drop_perms(curthread, newcred);
2550 mtx_unlock(&Giant);
2551 } else {
2552 mtx_unlock(&subj->mtx);
2553 }
2554}
2555
2556static struct mac_policy_ops mac_lomac_ops =
2557{
2558 .mpo_init = mac_lomac_init,
2559 .mpo_init_bpfdesc_label = mac_lomac_init_label,
2560 .mpo_init_cred_label = mac_lomac_init_label,
2561 .mpo_init_devfsdirent_label = mac_lomac_init_label,
2562 .mpo_init_ifnet_label = mac_lomac_init_label,
2563 .mpo_init_inpcb_label = mac_lomac_init_label_waitcheck,
2564 .mpo_init_ipq_label = mac_lomac_init_label_waitcheck,
2565 .mpo_init_mbuf_label = mac_lomac_init_label_waitcheck,
2566 .mpo_init_mount_label = mac_lomac_init_label,
2567 .mpo_init_mount_fs_label = mac_lomac_init_label,
2568 .mpo_init_pipe_label = mac_lomac_init_label,
2569 .mpo_init_proc_label = mac_lomac_init_proc_label,
2570 .mpo_init_socket_label = mac_lomac_init_label_waitcheck,
2571 .mpo_init_socket_peer_label = mac_lomac_init_label_waitcheck,
2572 .mpo_init_vnode_label = mac_lomac_init_label,
2573 .mpo_destroy_bpfdesc_label = mac_lomac_destroy_label,
2574 .mpo_destroy_cred_label = mac_lomac_destroy_label,
2575 .mpo_destroy_devfsdirent_label = mac_lomac_destroy_label,
2576 .mpo_destroy_ifnet_label = mac_lomac_destroy_label,
2577 .mpo_destroy_inpcb_label = mac_lomac_destroy_label,
2578 .mpo_destroy_ipq_label = mac_lomac_destroy_label,
2579 .mpo_destroy_mbuf_label = mac_lomac_destroy_label,
2580 .mpo_destroy_mount_label = mac_lomac_destroy_label,
2581 .mpo_destroy_mount_fs_label = mac_lomac_destroy_label,
2582 .mpo_destroy_pipe_label = mac_lomac_destroy_label,
2583 .mpo_destroy_proc_label = mac_lomac_destroy_proc_label,
2584 .mpo_destroy_socket_label = mac_lomac_destroy_label,
2585 .mpo_destroy_socket_peer_label = mac_lomac_destroy_label,
2586 .mpo_destroy_vnode_label = mac_lomac_destroy_label,
2587 .mpo_copy_cred_label = mac_lomac_copy_label,
2588 .mpo_copy_ifnet_label = mac_lomac_copy_label,
2589 .mpo_copy_mbuf_label = mac_lomac_copy_label,
2590 .mpo_copy_pipe_label = mac_lomac_copy_label,
2591 .mpo_copy_socket_label = mac_lomac_copy_label,
2592 .mpo_copy_vnode_label = mac_lomac_copy_label,
2593 .mpo_externalize_cred_label = mac_lomac_externalize_label,
2594 .mpo_externalize_ifnet_label = mac_lomac_externalize_label,
2595 .mpo_externalize_pipe_label = mac_lomac_externalize_label,
2596 .mpo_externalize_socket_label = mac_lomac_externalize_label,
2597 .mpo_externalize_socket_peer_label = mac_lomac_externalize_label,
2598 .mpo_externalize_vnode_label = mac_lomac_externalize_label,
2599 .mpo_internalize_cred_label = mac_lomac_internalize_label,
2600 .mpo_internalize_ifnet_label = mac_lomac_internalize_label,
2601 .mpo_internalize_pipe_label = mac_lomac_internalize_label,
2602 .mpo_internalize_socket_label = mac_lomac_internalize_label,
2603 .mpo_internalize_vnode_label = mac_lomac_internalize_label,
2604 .mpo_create_devfs_device = mac_lomac_create_devfs_device,
2605 .mpo_create_devfs_directory = mac_lomac_create_devfs_directory,
2606 .mpo_create_devfs_symlink = mac_lomac_create_devfs_symlink,
2607 .mpo_create_mount = mac_lomac_create_mount,
2608 .mpo_relabel_vnode = mac_lomac_relabel_vnode,
2609 .mpo_update_devfsdirent = mac_lomac_update_devfsdirent,
2610 .mpo_associate_vnode_devfs = mac_lomac_associate_vnode_devfs,
2611 .mpo_associate_vnode_extattr = mac_lomac_associate_vnode_extattr,
2612 .mpo_associate_vnode_singlelabel =
2613 mac_lomac_associate_vnode_singlelabel,
2614 .mpo_create_vnode_extattr = mac_lomac_create_vnode_extattr,
2615 .mpo_setlabel_vnode_extattr = mac_lomac_setlabel_vnode_extattr,
2616 .mpo_create_mbuf_from_socket = mac_lomac_create_mbuf_from_socket,
2617 .mpo_create_pipe = mac_lomac_create_pipe,
2618 .mpo_create_socket = mac_lomac_create_socket,
2619 .mpo_create_socket_from_socket = mac_lomac_create_socket_from_socket,
2620 .mpo_relabel_pipe = mac_lomac_relabel_pipe,
2621 .mpo_relabel_socket = mac_lomac_relabel_socket,
2622 .mpo_set_socket_peer_from_mbuf = mac_lomac_set_socket_peer_from_mbuf,
2623 .mpo_set_socket_peer_from_socket =
2624 mac_lomac_set_socket_peer_from_socket,
2625 .mpo_create_bpfdesc = mac_lomac_create_bpfdesc,
2626 .mpo_create_datagram_from_ipq = mac_lomac_create_datagram_from_ipq,
2627 .mpo_create_fragment = mac_lomac_create_fragment,
2628 .mpo_create_ifnet = mac_lomac_create_ifnet,
2629 .mpo_create_inpcb_from_socket = mac_lomac_create_inpcb_from_socket,
2630 .mpo_create_ipq = mac_lomac_create_ipq,
2631 .mpo_create_mbuf_from_inpcb = mac_lomac_create_mbuf_from_inpcb,
2632 .mpo_create_mbuf_linklayer = mac_lomac_create_mbuf_linklayer,
2633 .mpo_create_mbuf_from_bpfdesc = mac_lomac_create_mbuf_from_bpfdesc,
2634 .mpo_create_mbuf_from_ifnet = mac_lomac_create_mbuf_from_ifnet,
2635 .mpo_create_mbuf_multicast_encap =
2636 mac_lomac_create_mbuf_multicast_encap,
2637 .mpo_create_mbuf_netlayer = mac_lomac_create_mbuf_netlayer,
2638 .mpo_fragment_match = mac_lomac_fragment_match,
2639 .mpo_relabel_ifnet = mac_lomac_relabel_ifnet,
2640 .mpo_update_ipq = mac_lomac_update_ipq,
2641 .mpo_inpcb_sosetlabel = mac_lomac_inpcb_sosetlabel,
2642 .mpo_execve_transition = mac_lomac_execve_transition,
2643 .mpo_execve_will_transition = mac_lomac_execve_will_transition,
2644 .mpo_create_proc0 = mac_lomac_create_proc0,
2645 .mpo_create_proc1 = mac_lomac_create_proc1,
2646 .mpo_relabel_cred = mac_lomac_relabel_cred,
2647 .mpo_check_bpfdesc_receive = mac_lomac_check_bpfdesc_receive,
2648 .mpo_check_cred_relabel = mac_lomac_check_cred_relabel,
2649 .mpo_check_cred_visible = mac_lomac_check_cred_visible,
2650 .mpo_check_ifnet_relabel = mac_lomac_check_ifnet_relabel,
2651 .mpo_check_ifnet_transmit = mac_lomac_check_ifnet_transmit,
2652 .mpo_check_inpcb_deliver = mac_lomac_check_inpcb_deliver,
2653 .mpo_check_kld_load = mac_lomac_check_kld_load,
2654 .mpo_check_kld_unload = mac_lomac_check_kld_unload,
2655 .mpo_check_pipe_ioctl = mac_lomac_check_pipe_ioctl,
2656 .mpo_check_pipe_read = mac_lomac_check_pipe_read,
2657 .mpo_check_pipe_relabel = mac_lomac_check_pipe_relabel,
2658 .mpo_check_pipe_write = mac_lomac_check_pipe_write,
2659 .mpo_check_proc_debug = mac_lomac_check_proc_debug,
2660 .mpo_check_proc_sched = mac_lomac_check_proc_sched,
2661 .mpo_check_proc_signal = mac_lomac_check_proc_signal,
2662 .mpo_check_socket_deliver = mac_lomac_check_socket_deliver,
2663 .mpo_check_socket_relabel = mac_lomac_check_socket_relabel,
2664 .mpo_check_socket_visible = mac_lomac_check_socket_visible,
2665 .mpo_check_system_swapon = mac_lomac_check_system_swapon,
2666 .mpo_check_system_sysctl = mac_lomac_check_system_sysctl,
2667 .mpo_check_vnode_access = mac_lomac_check_vnode_open,
2668 .mpo_check_vnode_create = mac_lomac_check_vnode_create,
2669 .mpo_check_vnode_delete = mac_lomac_check_vnode_delete,
2670 .mpo_check_vnode_deleteacl = mac_lomac_check_vnode_deleteacl,
2671 .mpo_check_vnode_link = mac_lomac_check_vnode_link,
2672 .mpo_check_vnode_mmap = mac_lomac_check_vnode_mmap,
2673 .mpo_check_vnode_mmap_downgrade = mac_lomac_check_vnode_mmap_downgrade,
2674 .mpo_check_vnode_open = mac_lomac_check_vnode_open,
2675 .mpo_check_vnode_read = mac_lomac_check_vnode_read,
2676 .mpo_check_vnode_relabel = mac_lomac_check_vnode_relabel,
2677 .mpo_check_vnode_rename_from = mac_lomac_check_vnode_rename_from,
2678 .mpo_check_vnode_rename_to = mac_lomac_check_vnode_rename_to,
2679 .mpo_check_vnode_revoke = mac_lomac_check_vnode_revoke,
2680 .mpo_check_vnode_setacl = mac_lomac_check_vnode_setacl,
2681 .mpo_check_vnode_setextattr = mac_lomac_check_vnode_setextattr,
2682 .mpo_check_vnode_setflags = mac_lomac_check_vnode_setflags,
2683 .mpo_check_vnode_setmode = mac_lomac_check_vnode_setmode,
2684 .mpo_check_vnode_setowner = mac_lomac_check_vnode_setowner,
2685 .mpo_check_vnode_setutimes = mac_lomac_check_vnode_setutimes,
2686 .mpo_check_vnode_write = mac_lomac_check_vnode_write,
2687 .mpo_thread_userret = mac_lomac_thread_userret,
1460/*
1461 * Labeling event operations: processes.
1462 */
1463static void
1464mac_lomac_execve_transition(struct ucred *old, struct ucred *new,
1465 struct vnode *vp, struct label *vnodelabel,
1466 struct label *interpvnodelabel, struct image_params *imgp,
1467 struct label *execlabel)
1468{
1469 struct mac_lomac *source, *dest, *obj, *robj;
1470
1471 source = SLOT(old->cr_label);
1472 dest = SLOT(new->cr_label);
1473 obj = SLOT(vnodelabel);
1474 robj = interpvnodelabel != NULL ? SLOT(interpvnodelabel) : obj;
1475
1476 mac_lomac_copy(source, dest);
1477 /*
1478 * If there's an auxiliary label on the real object, respect it
1479 * and assume that this level should be assumed immediately if
1480 * a higher level is currently in place.
1481 */
1482 if (robj->ml_flags & MAC_LOMAC_FLAG_AUX &&
1483 !mac_lomac_dominate_element(&robj->ml_auxsingle, &dest->ml_single)
1484 && mac_lomac_auxsingle_in_range(robj, dest))
1485 mac_lomac_set_single(dest, robj->ml_auxsingle.mle_type,
1486 robj->ml_auxsingle.mle_grade);
1487 /*
1488 * Restructuring to use the execve transitioning mechanism
1489 * instead of the normal demotion mechanism here would be
1490 * difficult, so just copy the label over and perform standard
1491 * demotion. This is also non-optimal because it will result
1492 * in the intermediate label "new" being created and immediately
1493 * recycled.
1494 */
1495 if (mac_lomac_enabled && revocation_enabled &&
1496 !mac_lomac_dominate_single(obj, source))
1497 (void)maybe_demote(source, obj, "executing", "file", vp);
1498}
1499
1500static int
1501mac_lomac_execve_will_transition(struct ucred *old, struct vnode *vp,
1502 struct label *vnodelabel, struct label *interpvnodelabel,
1503 struct image_params *imgp, struct label *execlabel)
1504{
1505 struct mac_lomac *subj, *obj, *robj;
1506
1507 if (!mac_lomac_enabled || !revocation_enabled)
1508 return (0);
1509
1510 subj = SLOT(old->cr_label);
1511 obj = SLOT(vnodelabel);
1512 robj = interpvnodelabel != NULL ? SLOT(interpvnodelabel) : obj;
1513
1514 return ((robj->ml_flags & MAC_LOMAC_FLAG_AUX &&
1515 !mac_lomac_dominate_element(&robj->ml_auxsingle, &subj->ml_single)
1516 && mac_lomac_auxsingle_in_range(robj, subj)) ||
1517 !mac_lomac_dominate_single(obj, subj));
1518}
1519
1520static void
1521mac_lomac_create_proc0(struct ucred *cred)
1522{
1523 struct mac_lomac *dest;
1524
1525 dest = SLOT(cred->cr_label);
1526
1527 mac_lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0);
1528 mac_lomac_set_range(dest, MAC_LOMAC_TYPE_LOW, 0, MAC_LOMAC_TYPE_HIGH,
1529 0);
1530}
1531
1532static void
1533mac_lomac_create_proc1(struct ucred *cred)
1534{
1535 struct mac_lomac *dest;
1536
1537 dest = SLOT(cred->cr_label);
1538
1539 mac_lomac_set_single(dest, MAC_LOMAC_TYPE_HIGH, 0);
1540 mac_lomac_set_range(dest, MAC_LOMAC_TYPE_LOW, 0, MAC_LOMAC_TYPE_HIGH,
1541 0);
1542}
1543
1544static void
1545mac_lomac_relabel_cred(struct ucred *cred, struct label *newlabel)
1546{
1547 struct mac_lomac *source, *dest;
1548
1549 source = SLOT(newlabel);
1550 dest = SLOT(cred->cr_label);
1551
1552 try_relabel(source, dest);
1553}
1554
1555/*
1556 * Access control checks.
1557 */
1558static int
1559mac_lomac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
1560 struct ifnet *ifnet, struct label *ifnetlabel)
1561{
1562 struct mac_lomac *a, *b;
1563
1564 if (!mac_lomac_enabled)
1565 return (0);
1566
1567 a = SLOT(bpflabel);
1568 b = SLOT(ifnetlabel);
1569
1570 if (mac_lomac_equal_single(a, b))
1571 return (0);
1572 return (EACCES);
1573}
1574
1575static int
1576mac_lomac_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1577{
1578 struct mac_lomac *subj, *new;
1579 int error;
1580
1581 subj = SLOT(cred->cr_label);
1582 new = SLOT(newlabel);
1583
1584 /*
1585 * If there is a LOMAC label update for the credential, it may
1586 * be an update of the single, range, or both.
1587 */
1588 error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH);
1589 if (error)
1590 return (error);
1591
1592 /*
1593 * If the LOMAC label is to be changed, authorize as appropriate.
1594 */
1595 if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) {
1596 /*
1597 * Fill in the missing parts from the previous label.
1598 */
1599 if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0)
1600 mac_lomac_copy_single(subj, new);
1601 if ((new->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0)
1602 mac_lomac_copy_range(subj, new);
1603
1604 /*
1605 * To change the LOMAC range on a credential, the new
1606 * range label must be in the current range.
1607 */
1608 if (!mac_lomac_range_in_range(new, subj))
1609 return (EPERM);
1610
1611 /*
1612 * To change the LOMAC single label on a credential, the
1613 * new single label must be in the new range. Implicitly
1614 * from the previous check, the new single is in the old
1615 * range.
1616 */
1617 if (!mac_lomac_single_in_range(new, new))
1618 return (EPERM);
1619
1620 /*
1621 * To have EQUAL in any component of the new credential
1622 * LOMAC label, the subject must already have EQUAL in
1623 * their label.
1624 */
1625 if (mac_lomac_contains_equal(new)) {
1626 error = mac_lomac_subject_privileged(subj);
1627 if (error)
1628 return (error);
1629 }
1630
1631 /*
1632 * XXXMAC: Additional consistency tests regarding the
1633 * single and range of the new label might be performed
1634 * here.
1635 */
1636 }
1637
1638 return (0);
1639}
1640
1641static int
1642mac_lomac_check_cred_visible(struct ucred *u1, struct ucred *u2)
1643{
1644 struct mac_lomac *subj, *obj;
1645
1646 if (!mac_lomac_enabled)
1647 return (0);
1648
1649 subj = SLOT(u1->cr_label);
1650 obj = SLOT(u2->cr_label);
1651
1652 /* XXX: range */
1653 if (!mac_lomac_dominate_single(obj, subj))
1654 return (ESRCH);
1655
1656 return (0);
1657}
1658
1659static int
1660mac_lomac_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
1661 struct label *ifnetlabel, struct label *newlabel)
1662{
1663 struct mac_lomac *subj, *new;
1664 int error;
1665
1666 subj = SLOT(cred->cr_label);
1667 new = SLOT(newlabel);
1668
1669 /*
1670 * If there is a LOMAC label update for the interface, it may
1671 * be an update of the single, range, or both.
1672 */
1673 error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH);
1674 if (error)
1675 return (error);
1676
1677 /*
1678 * Relabling network interfaces requires LOMAC privilege.
1679 */
1680 error = mac_lomac_subject_privileged(subj);
1681 if (error)
1682 return (error);
1683
1684 /*
1685 * If the LOMAC label is to be changed, authorize as appropriate.
1686 */
1687 if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) {
1688 /*
1689 * Fill in the missing parts from the previous label.
1690 */
1691 if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0)
1692 mac_lomac_copy_single(subj, new);
1693 if ((new->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0)
1694 mac_lomac_copy_range(subj, new);
1695
1696 /*
1697 * Rely on the traditional superuser status for the LOMAC
1698 * interface relabel requirements. XXXMAC: This will go
1699 * away.
1700 */
1701 error = suser_cred(cred, 0);
1702 if (error)
1703 return (EPERM);
1704
1705 /*
1706 * XXXMAC: Additional consistency tests regarding the single
1707 * and the range of the new label might be performed here.
1708 */
1709 }
1710
1711 return (0);
1712}
1713
1714static int
1715mac_lomac_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1716 struct mbuf *m, struct label *mbuflabel)
1717{
1718 struct mac_lomac *p, *i;
1719
1720 if (!mac_lomac_enabled)
1721 return (0);
1722
1723 p = SLOT(mbuflabel);
1724 i = SLOT(ifnetlabel);
1725
1726 return (mac_lomac_single_in_range(p, i) ? 0 : EACCES);
1727}
1728
1729static int
1730mac_lomac_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel,
1731 struct mbuf *m, struct label *mlabel)
1732{
1733 struct mac_lomac *p, *i;
1734
1735 if (!mac_lomac_enabled)
1736 return (0);
1737
1738 p = SLOT(mlabel);
1739 i = SLOT(inplabel);
1740
1741 return (mac_lomac_equal_single(p, i) ? 0 : EACCES);
1742}
1743
1744static int
1745mac_lomac_check_kld_load(struct ucred *cred, struct vnode *vp,
1746 struct label *label)
1747{
1748 struct mac_lomac *subj, *obj;
1749
1750 if (!mac_lomac_enabled)
1751 return (0);
1752
1753 subj = SLOT(cred->cr_label);
1754 obj = SLOT(label);
1755
1756 if (mac_lomac_subject_privileged(subj))
1757 return (EPERM);
1758
1759 if (!mac_lomac_high_single(obj))
1760 return (EACCES);
1761
1762 return (0);
1763}
1764
1765static int
1766mac_lomac_check_kld_unload(struct ucred *cred)
1767{
1768 struct mac_lomac *subj;
1769
1770 if (!mac_lomac_enabled)
1771 return (0);
1772
1773 subj = SLOT(cred->cr_label);
1774
1775 if (mac_lomac_subject_privileged(subj))
1776 return (EPERM);
1777
1778 return (0);
1779}
1780
1781static int
1782mac_lomac_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp,
1783 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1784{
1785
1786 if(!mac_lomac_enabled)
1787 return (0);
1788
1789 /* XXX: This will be implemented soon... */
1790
1791 return (0);
1792}
1793
1794static int
1795mac_lomac_check_pipe_read(struct ucred *cred, struct pipepair *pp,
1796 struct label *pipelabel)
1797{
1798 struct mac_lomac *subj, *obj;
1799
1800 if (!mac_lomac_enabled)
1801 return (0);
1802
1803 subj = SLOT(cred->cr_label);
1804 obj = SLOT((pipelabel));
1805
1806 if (!mac_lomac_dominate_single(obj, subj))
1807 return (maybe_demote(subj, obj, "reading", "pipe", NULL));
1808
1809 return (0);
1810}
1811
1812static int
1813mac_lomac_check_pipe_relabel(struct ucred *cred, struct pipepair *pp,
1814 struct label *pipelabel, struct label *newlabel)
1815{
1816 struct mac_lomac *subj, *obj, *new;
1817 int error;
1818
1819 new = SLOT(newlabel);
1820 subj = SLOT(cred->cr_label);
1821 obj = SLOT(pipelabel);
1822
1823 /*
1824 * If there is a LOMAC label update for a pipe, it must be a
1825 * single update.
1826 */
1827 error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE);
1828 if (error)
1829 return (error);
1830
1831 /*
1832 * To perform a relabel of a pipe (LOMAC label or not), LOMAC must
1833 * authorize the relabel.
1834 */
1835 if (!mac_lomac_single_in_range(obj, subj))
1836 return (EPERM);
1837
1838 /*
1839 * If the LOMAC label is to be changed, authorize as appropriate.
1840 */
1841 if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
1842 /*
1843 * To change the LOMAC label on a pipe, the new pipe label
1844 * must be in the subject range.
1845 */
1846 if (!mac_lomac_single_in_range(new, subj))
1847 return (EPERM);
1848
1849 /*
1850 * To change the LOMAC label on a pipe to be EQUAL, the
1851 * subject must have appropriate privilege.
1852 */
1853 if (mac_lomac_contains_equal(new)) {
1854 error = mac_lomac_subject_privileged(subj);
1855 if (error)
1856 return (error);
1857 }
1858 }
1859
1860 return (0);
1861}
1862
1863static int
1864mac_lomac_check_pipe_write(struct ucred *cred, struct pipepair *pp,
1865 struct label *pipelabel)
1866{
1867 struct mac_lomac *subj, *obj;
1868
1869 if (!mac_lomac_enabled)
1870 return (0);
1871
1872 subj = SLOT(cred->cr_label);
1873 obj = SLOT((pipelabel));
1874
1875 if (!mac_lomac_subject_dominate(subj, obj))
1876 return (EACCES);
1877
1878 return (0);
1879}
1880
1881static int
1882mac_lomac_check_proc_debug(struct ucred *cred, struct proc *proc)
1883{
1884 struct mac_lomac *subj, *obj;
1885
1886 if (!mac_lomac_enabled)
1887 return (0);
1888
1889 subj = SLOT(cred->cr_label);
1890 obj = SLOT(proc->p_ucred->cr_label);
1891
1892 /* XXX: range checks */
1893 if (!mac_lomac_dominate_single(obj, subj))
1894 return (ESRCH);
1895 if (!mac_lomac_subject_dominate(subj, obj))
1896 return (EACCES);
1897
1898 return (0);
1899}
1900
1901static int
1902mac_lomac_check_proc_sched(struct ucred *cred, struct proc *proc)
1903{
1904 struct mac_lomac *subj, *obj;
1905
1906 if (!mac_lomac_enabled)
1907 return (0);
1908
1909 subj = SLOT(cred->cr_label);
1910 obj = SLOT(proc->p_ucred->cr_label);
1911
1912 /* XXX: range checks */
1913 if (!mac_lomac_dominate_single(obj, subj))
1914 return (ESRCH);
1915 if (!mac_lomac_subject_dominate(subj, obj))
1916 return (EACCES);
1917
1918 return (0);
1919}
1920
1921static int
1922mac_lomac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
1923{
1924 struct mac_lomac *subj, *obj;
1925
1926 if (!mac_lomac_enabled)
1927 return (0);
1928
1929 subj = SLOT(cred->cr_label);
1930 obj = SLOT(proc->p_ucred->cr_label);
1931
1932 /* XXX: range checks */
1933 if (!mac_lomac_dominate_single(obj, subj))
1934 return (ESRCH);
1935 if (!mac_lomac_subject_dominate(subj, obj))
1936 return (EACCES);
1937
1938 return (0);
1939}
1940
1941static int
1942mac_lomac_check_socket_deliver(struct socket *so, struct label *socketlabel,
1943 struct mbuf *m, struct label *mbuflabel)
1944{
1945 struct mac_lomac *p, *s;
1946
1947 if (!mac_lomac_enabled)
1948 return (0);
1949
1950 p = SLOT(mbuflabel);
1951 s = SLOT(socketlabel);
1952
1953 return (mac_lomac_equal_single(p, s) ? 0 : EACCES);
1954}
1955
1956static int
1957mac_lomac_check_socket_relabel(struct ucred *cred, struct socket *socket,
1958 struct label *socketlabel, struct label *newlabel)
1959{
1960 struct mac_lomac *subj, *obj, *new;
1961 int error;
1962
1963 new = SLOT(newlabel);
1964 subj = SLOT(cred->cr_label);
1965 obj = SLOT(socketlabel);
1966
1967 /*
1968 * If there is a LOMAC label update for the socket, it may be
1969 * an update of single.
1970 */
1971 error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE);
1972 if (error)
1973 return (error);
1974
1975 /*
1976 * To relabel a socket, the old socket single must be in the subject
1977 * range.
1978 */
1979 if (!mac_lomac_single_in_range(obj, subj))
1980 return (EPERM);
1981
1982 /*
1983 * If the LOMAC label is to be changed, authorize as appropriate.
1984 */
1985 if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
1986 /*
1987 * To relabel a socket, the new socket single must be in
1988 * the subject range.
1989 */
1990 if (!mac_lomac_single_in_range(new, subj))
1991 return (EPERM);
1992
1993 /*
1994 * To change the LOMAC label on the socket to contain EQUAL,
1995 * the subject must have appropriate privilege.
1996 */
1997 if (mac_lomac_contains_equal(new)) {
1998 error = mac_lomac_subject_privileged(subj);
1999 if (error)
2000 return (error);
2001 }
2002 }
2003
2004 return (0);
2005}
2006
2007static int
2008mac_lomac_check_socket_visible(struct ucred *cred, struct socket *socket,
2009 struct label *socketlabel)
2010{
2011 struct mac_lomac *subj, *obj;
2012
2013 if (!mac_lomac_enabled)
2014 return (0);
2015
2016 subj = SLOT(cred->cr_label);
2017 obj = SLOT(socketlabel);
2018
2019 if (!mac_lomac_dominate_single(obj, subj))
2020 return (ENOENT);
2021
2022 return (0);
2023}
2024
2025static int
2026mac_lomac_check_system_swapon(struct ucred *cred, struct vnode *vp,
2027 struct label *label)
2028{
2029 struct mac_lomac *subj, *obj;
2030
2031 if (!mac_lomac_enabled)
2032 return (0);
2033
2034 subj = SLOT(cred->cr_label);
2035 obj = SLOT(label);
2036
2037 if (mac_lomac_subject_privileged(subj))
2038 return (EPERM);
2039
2040 if (!mac_lomac_high_single(obj))
2041 return (EACCES);
2042
2043 return (0);
2044}
2045
2046static int
2047mac_lomac_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp,
2048 void *arg1, int arg2, struct sysctl_req *req)
2049{
2050 struct mac_lomac *subj;
2051
2052 if (!mac_lomac_enabled)
2053 return (0);
2054
2055 subj = SLOT(cred->cr_label);
2056
2057 /*
2058 * Treat sysctl variables without CTLFLAG_ANYBODY flag as
2059 * lomac/high, but also require privilege to change them.
2060 */
2061 if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) {
2062#ifdef notdef
2063 if (!mac_lomac_subject_dominate_high(subj))
2064 return (EACCES);
2065#endif
2066
2067 if (mac_lomac_subject_privileged(subj))
2068 return (EPERM);
2069 }
2070
2071 return (0);
2072}
2073
2074static int
2075mac_lomac_check_vnode_create(struct ucred *cred, struct vnode *dvp,
2076 struct label *dlabel, struct componentname *cnp, struct vattr *vap)
2077{
2078 struct mac_lomac *subj, *obj;
2079
2080 if (!mac_lomac_enabled)
2081 return (0);
2082
2083 subj = SLOT(cred->cr_label);
2084 obj = SLOT(dlabel);
2085
2086 if (!mac_lomac_subject_dominate(subj, obj))
2087 return (EACCES);
2088 if (obj->ml_flags & MAC_LOMAC_FLAG_AUX &&
2089 !mac_lomac_dominate_element(&subj->ml_single, &obj->ml_auxsingle))
2090 return (EACCES);
2091
2092 return (0);
2093}
2094
2095static int
2096mac_lomac_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
2097 struct label *dlabel, struct vnode *vp, struct label *label,
2098 struct componentname *cnp)
2099{
2100 struct mac_lomac *subj, *obj;
2101
2102 if (!mac_lomac_enabled)
2103 return (0);
2104
2105 subj = SLOT(cred->cr_label);
2106 obj = SLOT(dlabel);
2107
2108 if (!mac_lomac_subject_dominate(subj, obj))
2109 return (EACCES);
2110
2111 obj = SLOT(label);
2112
2113 if (!mac_lomac_subject_dominate(subj, obj))
2114 return (EACCES);
2115
2116 return (0);
2117}
2118
2119static int
2120mac_lomac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
2121 struct label *label, acl_type_t type)
2122{
2123 struct mac_lomac *subj, *obj;
2124
2125 if (!mac_lomac_enabled)
2126 return (0);
2127
2128 subj = SLOT(cred->cr_label);
2129 obj = SLOT(label);
2130
2131 if (!mac_lomac_subject_dominate(subj, obj))
2132 return (EACCES);
2133
2134 return (0);
2135}
2136
2137static int
2138mac_lomac_check_vnode_link(struct ucred *cred, struct vnode *dvp,
2139 struct label *dlabel, struct vnode *vp, struct label *label,
2140 struct componentname *cnp)
2141{
2142 struct mac_lomac *subj, *obj;
2143
2144 if (!mac_lomac_enabled)
2145 return (0);
2146
2147 subj = SLOT(cred->cr_label);
2148 obj = SLOT(dlabel);
2149
2150 if (!mac_lomac_subject_dominate(subj, obj))
2151 return (EACCES);
2152
2153 obj = SLOT(label);
2154
2155 if (!mac_lomac_subject_dominate(subj, obj))
2156 return (EACCES);
2157
2158 return (0);
2159}
2160
2161static int
2162mac_lomac_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
2163 struct label *label, int prot, int flags)
2164{
2165 struct mac_lomac *subj, *obj;
2166
2167 /*
2168 * Rely on the use of open()-time protections to handle
2169 * non-revocation cases.
2170 */
2171 if (!mac_lomac_enabled)
2172 return (0);
2173
2174 subj = SLOT(cred->cr_label);
2175 obj = SLOT(label);
2176
2177 if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) {
2178 if (!mac_lomac_subject_dominate(subj, obj))
2179 return (EACCES);
2180 }
2181 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2182 if (!mac_lomac_dominate_single(obj, subj))
2183 return (maybe_demote(subj, obj, "mapping", "file", vp));
2184 }
2185
2186 return (0);
2187}
2188
2189static void
2190mac_lomac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp,
2191 struct label *label, /* XXX vm_prot_t */ int *prot)
2192{
2193 struct mac_lomac *subj, *obj;
2194
2195 /*
2196 * Rely on the use of open()-time protections to handle
2197 * non-revocation cases.
2198 */
2199 if (!mac_lomac_enabled || !revocation_enabled)
2200 return;
2201
2202 subj = SLOT(cred->cr_label);
2203 obj = SLOT(label);
2204
2205 if (!mac_lomac_subject_dominate(subj, obj))
2206 *prot &= ~VM_PROT_WRITE;
2207}
2208
2209static int
2210mac_lomac_check_vnode_open(struct ucred *cred, struct vnode *vp,
2211 struct label *vnodelabel, int acc_mode)
2212{
2213 struct mac_lomac *subj, *obj;
2214
2215 if (!mac_lomac_enabled)
2216 return (0);
2217
2218 subj = SLOT(cred->cr_label);
2219 obj = SLOT(vnodelabel);
2220
2221 /* XXX privilege override for admin? */
2222 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2223 if (!mac_lomac_subject_dominate(subj, obj))
2224 return (EACCES);
2225 }
2226
2227 return (0);
2228}
2229
2230static int
2231mac_lomac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2232 struct vnode *vp, struct label *label)
2233{
2234 struct mac_lomac *subj, *obj;
2235
2236 if (!mac_lomac_enabled || !revocation_enabled)
2237 return (0);
2238
2239 subj = SLOT(active_cred->cr_label);
2240 obj = SLOT(label);
2241
2242 if (!mac_lomac_dominate_single(obj, subj))
2243 return (maybe_demote(subj, obj, "reading", "file", vp));
2244
2245 return (0);
2246}
2247
2248static int
2249mac_lomac_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2250 struct label *vnodelabel, struct label *newlabel)
2251{
2252 struct mac_lomac *old, *new, *subj;
2253 int error;
2254
2255 old = SLOT(vnodelabel);
2256 new = SLOT(newlabel);
2257 subj = SLOT(cred->cr_label);
2258
2259 /*
2260 * If there is a LOMAC label update for the vnode, it must be a
2261 * single label, with an optional explicit auxiliary single.
2262 */
2263 error = lomac_atmostflags(new,
2264 MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_AUX);
2265 if (error)
2266 return (error);
2267
2268 /*
2269 * To perform a relabel of the vnode (LOMAC label or not), LOMAC must
2270 * authorize the relabel.
2271 */
2272 if (!mac_lomac_single_in_range(old, subj))
2273 return (EPERM);
2274
2275 /*
2276 * If the LOMAC label is to be changed, authorize as appropriate.
2277 */
2278 if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
2279 /*
2280 * To change the LOMAC label on a vnode, the new vnode label
2281 * must be in the subject range.
2282 */
2283 if (!mac_lomac_single_in_range(new, subj))
2284 return (EPERM);
2285
2286 /*
2287 * To change the LOMAC label on the vnode to be EQUAL,
2288 * the subject must have appropriate privilege.
2289 */
2290 if (mac_lomac_contains_equal(new)) {
2291 error = mac_lomac_subject_privileged(subj);
2292 if (error)
2293 return (error);
2294 }
2295 }
2296 if (new->ml_flags & MAC_LOMAC_FLAG_AUX) {
2297 /*
2298 * Fill in the missing parts from the previous label.
2299 */
2300 if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0)
2301 mac_lomac_copy_single(subj, new);
2302
2303 /*
2304 * To change the auxiliary LOMAC label on a vnode, the new
2305 * vnode label must be in the subject range.
2306 */
2307 if (!mac_lomac_auxsingle_in_range(new, subj))
2308 return (EPERM);
2309
2310 /*
2311 * To change the auxiliary LOMAC label on the vnode to be
2312 * EQUAL, the subject must have appropriate privilege.
2313 */
2314 if (mac_lomac_contains_equal(new)) {
2315 error = mac_lomac_subject_privileged(subj);
2316 if (error)
2317 return (error);
2318 }
2319 }
2320
2321 return (0);
2322}
2323
2324static int
2325mac_lomac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2326 struct label *dlabel, struct vnode *vp, struct label *label,
2327 struct componentname *cnp)
2328{
2329 struct mac_lomac *subj, *obj;
2330
2331 if (!mac_lomac_enabled)
2332 return (0);
2333
2334 subj = SLOT(cred->cr_label);
2335 obj = SLOT(dlabel);
2336
2337 if (!mac_lomac_subject_dominate(subj, obj))
2338 return (EACCES);
2339
2340 obj = SLOT(label);
2341
2342 if (!mac_lomac_subject_dominate(subj, obj))
2343 return (EACCES);
2344
2345 return (0);
2346}
2347
2348static int
2349mac_lomac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2350 struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
2351 struct componentname *cnp)
2352{
2353 struct mac_lomac *subj, *obj;
2354
2355 if (!mac_lomac_enabled)
2356 return (0);
2357
2358 subj = SLOT(cred->cr_label);
2359 obj = SLOT(dlabel);
2360
2361 if (!mac_lomac_subject_dominate(subj, obj))
2362 return (EACCES);
2363
2364 if (vp != NULL) {
2365 obj = SLOT(label);
2366
2367 if (!mac_lomac_subject_dominate(subj, obj))
2368 return (EACCES);
2369 }
2370
2371 return (0);
2372}
2373
2374static int
2375mac_lomac_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
2376 struct label *label)
2377{
2378 struct mac_lomac *subj, *obj;
2379
2380 if (!mac_lomac_enabled)
2381 return (0);
2382
2383 subj = SLOT(cred->cr_label);
2384 obj = SLOT(label);
2385
2386 if (!mac_lomac_subject_dominate(subj, obj))
2387 return (EACCES);
2388
2389 return (0);
2390}
2391
2392static int
2393mac_lomac_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
2394 struct label *label, acl_type_t type, struct acl *acl)
2395{
2396 struct mac_lomac *subj, *obj;
2397
2398 if (!mac_lomac_enabled)
2399 return (0);
2400
2401 subj = SLOT(cred->cr_label);
2402 obj = SLOT(label);
2403
2404 if (!mac_lomac_subject_dominate(subj, obj))
2405 return (EACCES);
2406
2407 return (0);
2408}
2409
2410static int
2411mac_lomac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2412 struct label *vnodelabel, int attrnamespace, const char *name,
2413 struct uio *uio)
2414{
2415 struct mac_lomac *subj, *obj;
2416
2417 if (!mac_lomac_enabled)
2418 return (0);
2419
2420 subj = SLOT(cred->cr_label);
2421 obj = SLOT(vnodelabel);
2422
2423 if (!mac_lomac_subject_dominate(subj, obj))
2424 return (EACCES);
2425
2426 /* XXX: protect the MAC EA in a special way? */
2427
2428 return (0);
2429}
2430
2431static int
2432mac_lomac_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2433 struct label *vnodelabel, u_long flags)
2434{
2435 struct mac_lomac *subj, *obj;
2436
2437 if (!mac_lomac_enabled)
2438 return (0);
2439
2440 subj = SLOT(cred->cr_label);
2441 obj = SLOT(vnodelabel);
2442
2443 if (!mac_lomac_subject_dominate(subj, obj))
2444 return (EACCES);
2445
2446 return (0);
2447}
2448
2449static int
2450mac_lomac_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2451 struct label *vnodelabel, mode_t mode)
2452{
2453 struct mac_lomac *subj, *obj;
2454
2455 if (!mac_lomac_enabled)
2456 return (0);
2457
2458 subj = SLOT(cred->cr_label);
2459 obj = SLOT(vnodelabel);
2460
2461 if (!mac_lomac_subject_dominate(subj, obj))
2462 return (EACCES);
2463
2464 return (0);
2465}
2466
2467static int
2468mac_lomac_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2469 struct label *vnodelabel, uid_t uid, gid_t gid)
2470{
2471 struct mac_lomac *subj, *obj;
2472
2473 if (!mac_lomac_enabled)
2474 return (0);
2475
2476 subj = SLOT(cred->cr_label);
2477 obj = SLOT(vnodelabel);
2478
2479 if (!mac_lomac_subject_dominate(subj, obj))
2480 return (EACCES);
2481
2482 return (0);
2483}
2484
2485static int
2486mac_lomac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2487 struct label *vnodelabel, struct timespec atime, struct timespec mtime)
2488{
2489 struct mac_lomac *subj, *obj;
2490
2491 if (!mac_lomac_enabled)
2492 return (0);
2493
2494 subj = SLOT(cred->cr_label);
2495 obj = SLOT(vnodelabel);
2496
2497 if (!mac_lomac_subject_dominate(subj, obj))
2498 return (EACCES);
2499
2500 return (0);
2501}
2502
2503static int
2504mac_lomac_check_vnode_write(struct ucred *active_cred,
2505 struct ucred *file_cred, struct vnode *vp, struct label *label)
2506{
2507 struct mac_lomac *subj, *obj;
2508
2509 if (!mac_lomac_enabled || !revocation_enabled)
2510 return (0);
2511
2512 subj = SLOT(active_cred->cr_label);
2513 obj = SLOT(label);
2514
2515 if (!mac_lomac_subject_dominate(subj, obj))
2516 return (EACCES);
2517
2518 return (0);
2519}
2520
2521static void
2522mac_lomac_thread_userret(struct thread *td)
2523{
2524 struct proc *p = td->td_proc;
2525 struct mac_lomac_proc *subj = PSLOT(p->p_label);
2526 struct ucred *newcred, *oldcred;
2527 int dodrop;
2528
2529 mtx_lock(&subj->mtx);
2530 if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) {
2531 dodrop = 0;
2532 mtx_unlock(&subj->mtx);
2533 newcred = crget();
2534 /*
2535 * Prevent a lock order reversal in
2536 * mac_cred_mmapped_drop_perms; ideally, the other
2537 * user of subj->mtx wouldn't be holding Giant.
2538 */
2539 mtx_lock(&Giant);
2540 PROC_LOCK(p);
2541 mtx_lock(&subj->mtx);
2542 /*
2543 * Check if we lost the race while allocating the cred.
2544 */
2545 if ((subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) == 0) {
2546 crfree(newcred);
2547 goto out;
2548 }
2549 oldcred = p->p_ucred;
2550 crcopy(newcred, oldcred);
2551 crhold(newcred);
2552 mac_lomac_copy(&subj->mac_lomac, SLOT(newcred->cr_label));
2553 p->p_ucred = newcred;
2554 crfree(oldcred);
2555 dodrop = 1;
2556 out:
2557 mtx_unlock(&subj->mtx);
2558 PROC_UNLOCK(p);
2559 if (dodrop)
2560 mac_cred_mmapped_drop_perms(curthread, newcred);
2561 mtx_unlock(&Giant);
2562 } else {
2563 mtx_unlock(&subj->mtx);
2564 }
2565}
2566
2567static struct mac_policy_ops mac_lomac_ops =
2568{
2569 .mpo_init = mac_lomac_init,
2570 .mpo_init_bpfdesc_label = mac_lomac_init_label,
2571 .mpo_init_cred_label = mac_lomac_init_label,
2572 .mpo_init_devfsdirent_label = mac_lomac_init_label,
2573 .mpo_init_ifnet_label = mac_lomac_init_label,
2574 .mpo_init_inpcb_label = mac_lomac_init_label_waitcheck,
2575 .mpo_init_ipq_label = mac_lomac_init_label_waitcheck,
2576 .mpo_init_mbuf_label = mac_lomac_init_label_waitcheck,
2577 .mpo_init_mount_label = mac_lomac_init_label,
2578 .mpo_init_mount_fs_label = mac_lomac_init_label,
2579 .mpo_init_pipe_label = mac_lomac_init_label,
2580 .mpo_init_proc_label = mac_lomac_init_proc_label,
2581 .mpo_init_socket_label = mac_lomac_init_label_waitcheck,
2582 .mpo_init_socket_peer_label = mac_lomac_init_label_waitcheck,
2583 .mpo_init_vnode_label = mac_lomac_init_label,
2584 .mpo_destroy_bpfdesc_label = mac_lomac_destroy_label,
2585 .mpo_destroy_cred_label = mac_lomac_destroy_label,
2586 .mpo_destroy_devfsdirent_label = mac_lomac_destroy_label,
2587 .mpo_destroy_ifnet_label = mac_lomac_destroy_label,
2588 .mpo_destroy_inpcb_label = mac_lomac_destroy_label,
2589 .mpo_destroy_ipq_label = mac_lomac_destroy_label,
2590 .mpo_destroy_mbuf_label = mac_lomac_destroy_label,
2591 .mpo_destroy_mount_label = mac_lomac_destroy_label,
2592 .mpo_destroy_mount_fs_label = mac_lomac_destroy_label,
2593 .mpo_destroy_pipe_label = mac_lomac_destroy_label,
2594 .mpo_destroy_proc_label = mac_lomac_destroy_proc_label,
2595 .mpo_destroy_socket_label = mac_lomac_destroy_label,
2596 .mpo_destroy_socket_peer_label = mac_lomac_destroy_label,
2597 .mpo_destroy_vnode_label = mac_lomac_destroy_label,
2598 .mpo_copy_cred_label = mac_lomac_copy_label,
2599 .mpo_copy_ifnet_label = mac_lomac_copy_label,
2600 .mpo_copy_mbuf_label = mac_lomac_copy_label,
2601 .mpo_copy_pipe_label = mac_lomac_copy_label,
2602 .mpo_copy_socket_label = mac_lomac_copy_label,
2603 .mpo_copy_vnode_label = mac_lomac_copy_label,
2604 .mpo_externalize_cred_label = mac_lomac_externalize_label,
2605 .mpo_externalize_ifnet_label = mac_lomac_externalize_label,
2606 .mpo_externalize_pipe_label = mac_lomac_externalize_label,
2607 .mpo_externalize_socket_label = mac_lomac_externalize_label,
2608 .mpo_externalize_socket_peer_label = mac_lomac_externalize_label,
2609 .mpo_externalize_vnode_label = mac_lomac_externalize_label,
2610 .mpo_internalize_cred_label = mac_lomac_internalize_label,
2611 .mpo_internalize_ifnet_label = mac_lomac_internalize_label,
2612 .mpo_internalize_pipe_label = mac_lomac_internalize_label,
2613 .mpo_internalize_socket_label = mac_lomac_internalize_label,
2614 .mpo_internalize_vnode_label = mac_lomac_internalize_label,
2615 .mpo_create_devfs_device = mac_lomac_create_devfs_device,
2616 .mpo_create_devfs_directory = mac_lomac_create_devfs_directory,
2617 .mpo_create_devfs_symlink = mac_lomac_create_devfs_symlink,
2618 .mpo_create_mount = mac_lomac_create_mount,
2619 .mpo_relabel_vnode = mac_lomac_relabel_vnode,
2620 .mpo_update_devfsdirent = mac_lomac_update_devfsdirent,
2621 .mpo_associate_vnode_devfs = mac_lomac_associate_vnode_devfs,
2622 .mpo_associate_vnode_extattr = mac_lomac_associate_vnode_extattr,
2623 .mpo_associate_vnode_singlelabel =
2624 mac_lomac_associate_vnode_singlelabel,
2625 .mpo_create_vnode_extattr = mac_lomac_create_vnode_extattr,
2626 .mpo_setlabel_vnode_extattr = mac_lomac_setlabel_vnode_extattr,
2627 .mpo_create_mbuf_from_socket = mac_lomac_create_mbuf_from_socket,
2628 .mpo_create_pipe = mac_lomac_create_pipe,
2629 .mpo_create_socket = mac_lomac_create_socket,
2630 .mpo_create_socket_from_socket = mac_lomac_create_socket_from_socket,
2631 .mpo_relabel_pipe = mac_lomac_relabel_pipe,
2632 .mpo_relabel_socket = mac_lomac_relabel_socket,
2633 .mpo_set_socket_peer_from_mbuf = mac_lomac_set_socket_peer_from_mbuf,
2634 .mpo_set_socket_peer_from_socket =
2635 mac_lomac_set_socket_peer_from_socket,
2636 .mpo_create_bpfdesc = mac_lomac_create_bpfdesc,
2637 .mpo_create_datagram_from_ipq = mac_lomac_create_datagram_from_ipq,
2638 .mpo_create_fragment = mac_lomac_create_fragment,
2639 .mpo_create_ifnet = mac_lomac_create_ifnet,
2640 .mpo_create_inpcb_from_socket = mac_lomac_create_inpcb_from_socket,
2641 .mpo_create_ipq = mac_lomac_create_ipq,
2642 .mpo_create_mbuf_from_inpcb = mac_lomac_create_mbuf_from_inpcb,
2643 .mpo_create_mbuf_linklayer = mac_lomac_create_mbuf_linklayer,
2644 .mpo_create_mbuf_from_bpfdesc = mac_lomac_create_mbuf_from_bpfdesc,
2645 .mpo_create_mbuf_from_ifnet = mac_lomac_create_mbuf_from_ifnet,
2646 .mpo_create_mbuf_multicast_encap =
2647 mac_lomac_create_mbuf_multicast_encap,
2648 .mpo_create_mbuf_netlayer = mac_lomac_create_mbuf_netlayer,
2649 .mpo_fragment_match = mac_lomac_fragment_match,
2650 .mpo_relabel_ifnet = mac_lomac_relabel_ifnet,
2651 .mpo_update_ipq = mac_lomac_update_ipq,
2652 .mpo_inpcb_sosetlabel = mac_lomac_inpcb_sosetlabel,
2653 .mpo_execve_transition = mac_lomac_execve_transition,
2654 .mpo_execve_will_transition = mac_lomac_execve_will_transition,
2655 .mpo_create_proc0 = mac_lomac_create_proc0,
2656 .mpo_create_proc1 = mac_lomac_create_proc1,
2657 .mpo_relabel_cred = mac_lomac_relabel_cred,
2658 .mpo_check_bpfdesc_receive = mac_lomac_check_bpfdesc_receive,
2659 .mpo_check_cred_relabel = mac_lomac_check_cred_relabel,
2660 .mpo_check_cred_visible = mac_lomac_check_cred_visible,
2661 .mpo_check_ifnet_relabel = mac_lomac_check_ifnet_relabel,
2662 .mpo_check_ifnet_transmit = mac_lomac_check_ifnet_transmit,
2663 .mpo_check_inpcb_deliver = mac_lomac_check_inpcb_deliver,
2664 .mpo_check_kld_load = mac_lomac_check_kld_load,
2665 .mpo_check_kld_unload = mac_lomac_check_kld_unload,
2666 .mpo_check_pipe_ioctl = mac_lomac_check_pipe_ioctl,
2667 .mpo_check_pipe_read = mac_lomac_check_pipe_read,
2668 .mpo_check_pipe_relabel = mac_lomac_check_pipe_relabel,
2669 .mpo_check_pipe_write = mac_lomac_check_pipe_write,
2670 .mpo_check_proc_debug = mac_lomac_check_proc_debug,
2671 .mpo_check_proc_sched = mac_lomac_check_proc_sched,
2672 .mpo_check_proc_signal = mac_lomac_check_proc_signal,
2673 .mpo_check_socket_deliver = mac_lomac_check_socket_deliver,
2674 .mpo_check_socket_relabel = mac_lomac_check_socket_relabel,
2675 .mpo_check_socket_visible = mac_lomac_check_socket_visible,
2676 .mpo_check_system_swapon = mac_lomac_check_system_swapon,
2677 .mpo_check_system_sysctl = mac_lomac_check_system_sysctl,
2678 .mpo_check_vnode_access = mac_lomac_check_vnode_open,
2679 .mpo_check_vnode_create = mac_lomac_check_vnode_create,
2680 .mpo_check_vnode_delete = mac_lomac_check_vnode_delete,
2681 .mpo_check_vnode_deleteacl = mac_lomac_check_vnode_deleteacl,
2682 .mpo_check_vnode_link = mac_lomac_check_vnode_link,
2683 .mpo_check_vnode_mmap = mac_lomac_check_vnode_mmap,
2684 .mpo_check_vnode_mmap_downgrade = mac_lomac_check_vnode_mmap_downgrade,
2685 .mpo_check_vnode_open = mac_lomac_check_vnode_open,
2686 .mpo_check_vnode_read = mac_lomac_check_vnode_read,
2687 .mpo_check_vnode_relabel = mac_lomac_check_vnode_relabel,
2688 .mpo_check_vnode_rename_from = mac_lomac_check_vnode_rename_from,
2689 .mpo_check_vnode_rename_to = mac_lomac_check_vnode_rename_to,
2690 .mpo_check_vnode_revoke = mac_lomac_check_vnode_revoke,
2691 .mpo_check_vnode_setacl = mac_lomac_check_vnode_setacl,
2692 .mpo_check_vnode_setextattr = mac_lomac_check_vnode_setextattr,
2693 .mpo_check_vnode_setflags = mac_lomac_check_vnode_setflags,
2694 .mpo_check_vnode_setmode = mac_lomac_check_vnode_setmode,
2695 .mpo_check_vnode_setowner = mac_lomac_check_vnode_setowner,
2696 .mpo_check_vnode_setutimes = mac_lomac_check_vnode_setutimes,
2697 .mpo_check_vnode_write = mac_lomac_check_vnode_write,
2698 .mpo_thread_userret = mac_lomac_thread_userret,
2699 .mpo_create_mbuf_from_firewall = mac_lomac_create_mbuf_from_firewall,
2688};
2689
2690MAC_POLICY_SET(&mac_lomac_ops, mac_lomac, "TrustedBSD MAC/LOMAC",
2691 MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS,
2692 &mac_lomac_slot);
2700};
2701
2702MAC_POLICY_SET(&mac_lomac_ops, mac_lomac, "TrustedBSD MAC/LOMAC",
2703 MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS,
2704 &mac_lomac_slot);