1 /*-
2 * Copyright (c) 1999-2002, 2007 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$
35 */
36
37 /*
38 * Developed by the TrustedBSD Project.
39 *
40 * Low-watermark floating label mandatory integrity policy.
41 */
42
43 #include <sys/types.h>
44 #include <sys/param.h>
45 #include <sys/acl.h>
46 #include <sys/conf.h>
47 #include <sys/extattr.h>
48 #include <sys/kernel.h>
49 #include <sys/malloc.h>
50 #include <sys/mman.h>
51 #include <sys/mount.h>
52 #include <sys/priv.h>
53 #include <sys/proc.h>
54 #include <sys/sbuf.h>
55 #include <sys/systm.h>
56 #include <sys/sysproto.h>
57 #include <sys/sysent.h>
58 #include <sys/systm.h>
59 #include <sys/vnode.h>
60 #include <sys/file.h>
61 #include <sys/socket.h>
62 #include <sys/socketvar.h>
63 #include <sys/sx.h>
64 #include <sys/pipe.h>
65 #include <sys/sysctl.h>
66 #include <sys/syslog.h>
67
68 #include <fs/devfs/devfs.h>
69
70 #include <net/bpfdesc.h>
71 #include <net/if.h>
72 #include <net/if_types.h>
73 #include <net/if_var.h>
74
75 #include <netinet/in.h>
76 #include <netinet/in_pcb.h>
77 #include <netinet/ip_var.h>
78
79 #include <vm/vm.h>
80
81 #include <security/mac/mac_policy.h>
82 #include <security/mac/mac_framework.h>
83 #include <security/mac_lomac/mac_lomac.h>
84
85 struct mac_lomac_proc {
86 struct mac_lomac mac_lomac;
87 struct mtx mtx;
88 };
89
90 SYSCTL_DECL(_security_mac);
91
92 SYSCTL_NODE(_security_mac, OID_AUTO, lomac, CTLFLAG_RW, 0,
93 "TrustedBSD mac_lomac policy controls");
94
95 static int lomac_label_size = sizeof(struct mac_lomac);
96 SYSCTL_INT(_security_mac_lomac, OID_AUTO, label_size, CTLFLAG_RD,
97 &lomac_label_size, 0, "Size of struct mac_lomac");
98
99 static int lomac_enabled = 1;
100 SYSCTL_INT(_security_mac_lomac, OID_AUTO, enabled, CTLFLAG_RW,
101 &lomac_enabled, 0, "Enforce MAC/LOMAC policy");
102 TUNABLE_INT("security.mac.lomac.enabled", &lomac_enabled);
103
104 static int destroyed_not_inited;
105 SYSCTL_INT(_security_mac_lomac, OID_AUTO, destroyed_not_inited, CTLFLAG_RD,
106 &destroyed_not_inited, 0, "Count of labels destroyed but not inited");
107
108 static int trust_all_interfaces = 0;
109 SYSCTL_INT(_security_mac_lomac, OID_AUTO, trust_all_interfaces, CTLFLAG_RD,
110 &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/LOMAC");
111 TUNABLE_INT("security.mac.lomac.trust_all_interfaces", &trust_all_interfaces);
112
113 static char trusted_interfaces[128];
114 SYSCTL_STRING(_security_mac_lomac, OID_AUTO, trusted_interfaces, CTLFLAG_RD,
115 trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/LOMAC");
116 TUNABLE_STR("security.mac.lomac.trusted_interfaces", trusted_interfaces,
117 sizeof(trusted_interfaces));
118
119 static int ptys_equal = 0;
120 SYSCTL_INT(_security_mac_lomac, OID_AUTO, ptys_equal, CTLFLAG_RW,
121 &ptys_equal, 0, "Label pty devices as lomac/equal on create");
122 TUNABLE_INT("security.mac.lomac.ptys_equal", &ptys_equal);
123
124 static int revocation_enabled = 1;
125 SYSCTL_INT(_security_mac_lomac, OID_AUTO, revocation_enabled, CTLFLAG_RW,
126 &revocation_enabled, 0, "Revoke access to objects on relabel");
127 TUNABLE_INT("security.mac.lomac.revocation_enabled", &revocation_enabled);
128
129 static int lomac_slot;
130 #define SLOT(l) ((struct mac_lomac *)mac_label_get((l), lomac_slot))
131 #define SLOT_SET(l, val) mac_label_set((l), lomac_slot, (uintptr_t)(val))
132 #define PSLOT(l) ((struct mac_lomac_proc *) \
133 mac_label_get((l), lomac_slot))
134 #define PSLOT_SET(l, val) mac_label_set((l), lomac_slot, (uintptr_t)(val))
135
136 MALLOC_DEFINE(M_LOMAC, "mac_lomac_label", "MAC/LOMAC labels");
137
138 static struct mac_lomac *
139 lomac_alloc(int flag)
140 {
141 struct mac_lomac *ml;
142
143 ml = malloc(sizeof(*ml), M_LOMAC, M_ZERO | flag);
144
145 return (ml);
146 }
147
148 static void
149 lomac_free(struct mac_lomac *ml)
150 {
151
152 if (ml != NULL)
153 free(ml, M_LOMAC);
154 else
155 atomic_add_int(&destroyed_not_inited, 1);
156 }
157
158 static int
159 lomac_atmostflags(struct mac_lomac *ml, int flags)
160 {
161
162 if ((ml->ml_flags & flags) != ml->ml_flags)
163 return (EINVAL);
164 return (0);
165 }
166
167 static int
168 lomac_dominate_element(struct mac_lomac_element *a,
169 struct mac_lomac_element *b)
170 {
171
172 switch (a->mle_type) {
173 case MAC_LOMAC_TYPE_EQUAL:
174 case MAC_LOMAC_TYPE_HIGH:
175 return (1);
176
177 case MAC_LOMAC_TYPE_LOW:
178 switch (b->mle_type) {
179 case MAC_LOMAC_TYPE_GRADE:
180 case MAC_LOMAC_TYPE_HIGH:
181 return (0);
182
183 case MAC_LOMAC_TYPE_EQUAL:
184 case MAC_LOMAC_TYPE_LOW:
185 return (1);
186
187 default:
188 panic("lomac_dominate_element: b->mle_type invalid");
189 }
190
191 case MAC_LOMAC_TYPE_GRADE:
192 switch (b->mle_type) {
193 case MAC_LOMAC_TYPE_EQUAL:
194 case MAC_LOMAC_TYPE_LOW:
195 return (1);
196
197 case MAC_LOMAC_TYPE_HIGH:
198 return (0);
199
200 case MAC_LOMAC_TYPE_GRADE:
201 return (a->mle_grade >= b->mle_grade);
202
203 default:
204 panic("lomac_dominate_element: b->mle_type invalid");
205 }
206
207 default:
208 panic("lomac_dominate_element: a->mle_type invalid");
209 }
210 }
211
212 static int
213 lomac_range_in_range(struct mac_lomac *rangea, struct mac_lomac *rangeb)
214 {
215
216 return (lomac_dominate_element(&rangeb->ml_rangehigh,
217 &rangea->ml_rangehigh) &&
218 lomac_dominate_element(&rangea->ml_rangelow,
219 &rangeb->ml_rangelow));
220 }
221
222 static int
223 lomac_single_in_range(struct mac_lomac *single, struct mac_lomac *range)
224 {
225
226 KASSERT((single->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
227 ("lomac_single_in_range: a not single"));
228 KASSERT((range->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0,
229 ("lomac_single_in_range: b not range"));
230
231 return (lomac_dominate_element(&range->ml_rangehigh,
232 &single->ml_single) && lomac_dominate_element(&single->ml_single,
233 &range->ml_rangelow));
234 }
235
236 static int
237 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 ("lomac_single_in_range: a not auxsingle"));
242 KASSERT((range->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0,
243 ("lomac_single_in_range: b not range"));
244
245 return (lomac_dominate_element(&range->ml_rangehigh,
246 &single->ml_auxsingle) &&
247 lomac_dominate_element(&single->ml_auxsingle,
248 &range->ml_rangelow));
249 }
250
251 static int
252 lomac_dominate_single(struct mac_lomac *a, struct mac_lomac *b)
253 {
254 KASSERT((a->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
255 ("lomac_dominate_single: a not single"));
256 KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
257 ("lomac_dominate_single: b not single"));
258
259 return (lomac_dominate_element(&a->ml_single, &b->ml_single));
260 }
261
262 static int
263 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 ("lomac_dominate_single: a not subject"));
268 KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
269 ("lomac_dominate_single: b not single"));
270
271 return (lomac_dominate_element(&a->ml_rangehigh, &b->ml_single));
272 }
273
274 static int
275 lomac_equal_element(struct mac_lomac_element *a, struct mac_lomac_element *b)
276 {
277
278 if (a->mle_type == MAC_LOMAC_TYPE_EQUAL ||
279 b->mle_type == MAC_LOMAC_TYPE_EQUAL)
280 return (1);
281
282 return (a->mle_type == b->mle_type && a->mle_grade == b->mle_grade);
283 }
284
285 static int
286 lomac_equal_single(struct mac_lomac *a, struct mac_lomac *b)
287 {
288
289 KASSERT((a->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
290 ("lomac_equal_single: a not single"));
291 KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
292 ("lomac_equal_single: b not single"));
293
294 return (lomac_equal_element(&a->ml_single, &b->ml_single));
295 }
296
297 static int
298 lomac_contains_equal(struct mac_lomac *ml)
299 {
300
301 if (ml->ml_flags & MAC_LOMAC_FLAG_SINGLE)
302 if (ml->ml_single.mle_type == MAC_LOMAC_TYPE_EQUAL)
303 return (1);
304 if (ml->ml_flags & MAC_LOMAC_FLAG_AUX)
305 if (ml->ml_auxsingle.mle_type == MAC_LOMAC_TYPE_EQUAL)
306 return (1);
307
308 if (ml->ml_flags & MAC_LOMAC_FLAG_RANGE) {
309 if (ml->ml_rangelow.mle_type == MAC_LOMAC_TYPE_EQUAL)
310 return (1);
311 if (ml->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_EQUAL)
312 return (1);
313 }
314
315 return (0);
316 }
317
318 static int
319 lomac_subject_privileged(struct mac_lomac *ml)
320 {
321
322 KASSERT((ml->ml_flags & MAC_LOMAC_FLAGS_BOTH) ==
323 MAC_LOMAC_FLAGS_BOTH,
324 ("lomac_subject_privileged: subject doesn't have both labels"));
325
326 /* If the single is EQUAL, it's ok. */
327 if (ml->ml_single.mle_type == MAC_LOMAC_TYPE_EQUAL)
328 return (0);
329
330 /* If either range endpoint is EQUAL, it's ok. */
331 if (ml->ml_rangelow.mle_type == MAC_LOMAC_TYPE_EQUAL ||
332 ml->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_EQUAL)
333 return (0);
334
335 /* If the range is low-high, it's ok. */
336 if (ml->ml_rangelow.mle_type == MAC_LOMAC_TYPE_LOW &&
337 ml->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_HIGH)
338 return (0);
339
340 /* It's not ok. */
341 return (EPERM);
342 }
343
344 static int
345 lomac_high_single(struct mac_lomac *ml)
346 {
347
348 KASSERT((ml->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
349 ("lomac_high_single: mac_lomac not single"));
350
351 return (ml->ml_single.mle_type == MAC_LOMAC_TYPE_HIGH);
352 }
353
354 static int
355 lomac_valid(struct mac_lomac *ml)
356 {
357
358 if (ml->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
359 switch (ml->ml_single.mle_type) {
360 case MAC_LOMAC_TYPE_GRADE:
361 case MAC_LOMAC_TYPE_EQUAL:
362 case MAC_LOMAC_TYPE_HIGH:
363 case MAC_LOMAC_TYPE_LOW:
364 break;
365
366 default:
367 return (EINVAL);
368 }
369 } else {
370 if (ml->ml_single.mle_type != MAC_LOMAC_TYPE_UNDEF)
371 return (EINVAL);
372 }
373
374 if (ml->ml_flags & MAC_LOMAC_FLAG_AUX) {
375 switch (ml->ml_auxsingle.mle_type) {
376 case MAC_LOMAC_TYPE_GRADE:
377 case MAC_LOMAC_TYPE_EQUAL:
378 case MAC_LOMAC_TYPE_HIGH:
379 case MAC_LOMAC_TYPE_LOW:
380 break;
381
382 default:
383 return (EINVAL);
384 }
385 } else {
386 if (ml->ml_auxsingle.mle_type != MAC_LOMAC_TYPE_UNDEF)
387 return (EINVAL);
388 }
389
390 if (ml->ml_flags & MAC_LOMAC_FLAG_RANGE) {
391 switch (ml->ml_rangelow.mle_type) {
392 case MAC_LOMAC_TYPE_GRADE:
393 case MAC_LOMAC_TYPE_EQUAL:
394 case MAC_LOMAC_TYPE_HIGH:
395 case MAC_LOMAC_TYPE_LOW:
396 break;
397
398 default:
399 return (EINVAL);
400 }
401
402 switch (ml->ml_rangehigh.mle_type) {
403 case MAC_LOMAC_TYPE_GRADE:
404 case MAC_LOMAC_TYPE_EQUAL:
405 case MAC_LOMAC_TYPE_HIGH:
406 case MAC_LOMAC_TYPE_LOW:
407 break;
408
409 default:
410 return (EINVAL);
411 }
412 if (!lomac_dominate_element(&ml->ml_rangehigh,
413 &ml->ml_rangelow))
414 return (EINVAL);
415 } else {
416 if (ml->ml_rangelow.mle_type != MAC_LOMAC_TYPE_UNDEF ||
417 ml->ml_rangehigh.mle_type != MAC_LOMAC_TYPE_UNDEF)
418 return (EINVAL);
419 }
420
421 return (0);
422 }
423
424 static void
425 lomac_set_range(struct mac_lomac *ml, u_short typelow, u_short gradelow,
426 u_short typehigh, u_short gradehigh)
427 {
428
429 ml->ml_rangelow.mle_type = typelow;
430 ml->ml_rangelow.mle_grade = gradelow;
431 ml->ml_rangehigh.mle_type = typehigh;
432 ml->ml_rangehigh.mle_grade = gradehigh;
433 ml->ml_flags |= MAC_LOMAC_FLAG_RANGE;
434 }
435
436 static void
437 lomac_set_single(struct mac_lomac *ml, u_short type, u_short grade)
438 {
439
440 ml->ml_single.mle_type = type;
441 ml->ml_single.mle_grade = grade;
442 ml->ml_flags |= MAC_LOMAC_FLAG_SINGLE;
443 }
444
445 static void
446 lomac_copy_range(struct mac_lomac *labelfrom, struct mac_lomac *labelto)
447 {
448
449 KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0,
450 ("lomac_copy_range: labelfrom not range"));
451
452 labelto->ml_rangelow = labelfrom->ml_rangelow;
453 labelto->ml_rangehigh = labelfrom->ml_rangehigh;
454 labelto->ml_flags |= MAC_LOMAC_FLAG_RANGE;
455 }
456
457 static void
458 lomac_copy_single(struct mac_lomac *labelfrom, struct mac_lomac *labelto)
459 {
460
461 KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
462 ("lomac_copy_single: labelfrom not single"));
463
464 labelto->ml_single = labelfrom->ml_single;
465 labelto->ml_flags |= MAC_LOMAC_FLAG_SINGLE;
466 }
467
468 static void
469 lomac_copy_auxsingle(struct mac_lomac *labelfrom, struct mac_lomac *labelto)
470 {
471
472 KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_AUX) != 0,
473 ("lomac_copy_auxsingle: labelfrom not auxsingle"));
474
475 labelto->ml_auxsingle = labelfrom->ml_auxsingle;
476 labelto->ml_flags |= MAC_LOMAC_FLAG_AUX;
477 }
478
479 static void
480 lomac_copy(struct mac_lomac *source, struct mac_lomac *dest)
481 {
482
483 if (source->ml_flags & MAC_LOMAC_FLAG_SINGLE)
484 lomac_copy_single(source, dest);
485 if (source->ml_flags & MAC_LOMAC_FLAG_AUX)
486 lomac_copy_auxsingle(source, dest);
487 if (source->ml_flags & MAC_LOMAC_FLAG_RANGE)
488 lomac_copy_range(source, dest);
489 }
490
491 static int lomac_to_string(struct sbuf *sb, struct mac_lomac *ml);
492
493 static int
494 maybe_demote(struct mac_lomac *subjlabel, struct mac_lomac *objlabel,
495 const char *actionname, const char *objname, struct vnode *vp)
496 {
497 struct sbuf subjlabel_sb, subjtext_sb, objlabel_sb;
498 char *subjlabeltext, *objlabeltext, *subjtext;
499 struct mac_lomac cached_subjlabel;
500 struct mac_lomac_proc *subj;
501 struct vattr va;
502 struct proc *p;
503 pid_t pgid;
504
505 subj = PSLOT(curthread->td_proc->p_label);
506
507 p = curthread->td_proc;
508 mtx_lock(&subj->mtx);
509 if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) {
510 /*
511 * Check to see if the pending demotion would be more or less
512 * severe than this one, and keep the more severe. This can
513 * only happen for a multi-threaded application.
514 */
515 if (lomac_dominate_single(objlabel, &subj->mac_lomac)) {
516 mtx_unlock(&subj->mtx);
517 return (0);
518 }
519 }
520 bzero(&subj->mac_lomac, sizeof(subj->mac_lomac));
521 /*
522 * Always demote the single label.
523 */
524 lomac_copy_single(objlabel, &subj->mac_lomac);
525 /*
526 * Start with the original range, then minimize each side of the
527 * range to the point of not dominating the object. The high side
528 * will always be demoted, of course.
529 */
530 lomac_copy_range(subjlabel, &subj->mac_lomac);
531 if (!lomac_dominate_element(&objlabel->ml_single,
532 &subj->mac_lomac.ml_rangelow))
533 subj->mac_lomac.ml_rangelow = objlabel->ml_single;
534 subj->mac_lomac.ml_rangehigh = objlabel->ml_single;
535 subj->mac_lomac.ml_flags |= MAC_LOMAC_FLAG_UPDATE;
536 thread_lock(curthread);
537 curthread->td_flags |= TDF_ASTPENDING | TDF_MACPEND;
538 thread_unlock(curthread);
539
540 /*
541 * Avoid memory allocation while holding a mutex; cache the label.
542 */
543 lomac_copy_single(&subj->mac_lomac, &cached_subjlabel);
544 mtx_unlock(&subj->mtx);
545
546 sbuf_new(&subjlabel_sb, NULL, 0, SBUF_AUTOEXTEND);
547 lomac_to_string(&subjlabel_sb, subjlabel);
548 sbuf_finish(&subjlabel_sb);
549 subjlabeltext = sbuf_data(&subjlabel_sb);
550
551 sbuf_new(&subjtext_sb, NULL, 0, SBUF_AUTOEXTEND);
552 lomac_to_string(&subjtext_sb, &subj->mac_lomac);
553 sbuf_finish(&subjtext_sb);
554 subjtext = sbuf_data(&subjtext_sb);
555
556 sbuf_new(&objlabel_sb, NULL, 0, SBUF_AUTOEXTEND);
557 lomac_to_string(&objlabel_sb, objlabel);
558 sbuf_finish(&objlabel_sb);
559 objlabeltext = sbuf_data(&objlabel_sb);
560
561 pgid = p->p_pgrp->pg_id; /* XXX could be stale? */
562 if (vp != NULL && VOP_GETATTR(vp, &va, curthread->td_ucred,
563 curthread) == 0) {
564 log(LOG_INFO, "LOMAC: level-%s subject p%dg%du%d:%s demoted to"
565 " level %s after %s a level-%s %s (inode=%ld, "
566 "mountpount=%s)\n",
567 subjlabeltext, p->p_pid, pgid, curthread->td_ucred->cr_uid,
568 p->p_comm, subjtext, actionname, objlabeltext, objname,
569 va.va_fileid, vp->v_mount->mnt_stat.f_mntonname);
570 } else {
571 log(LOG_INFO, "LOMAC: level-%s subject p%dg%du%d:%s demoted to"
572 " level %s after %s a level-%s %s\n",
573 subjlabeltext, p->p_pid, pgid, curthread->td_ucred->cr_uid,
574 p->p_comm, subjtext, actionname, objlabeltext, objname);
575 }
576
577 sbuf_delete(&subjlabel_sb);
578 sbuf_delete(&subjtext_sb);
579 sbuf_delete(&objlabel_sb);
580
581 return (0);
582 }
583
584 /*
585 * Relabel "to" to "from" only if "from" is a valid label (contains at least
586 * a single), as for a relabel operation which may or may not involve a
587 * relevant label.
588 */
589 static void
590 try_relabel(struct mac_lomac *from, struct mac_lomac *to)
591 {
592
593 if (from->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
594 bzero(to, sizeof(*to));
595 lomac_copy(from, to);
596 }
597 }
598
599 /*
600 * Policy module operations.
601 */
602 static void
603 lomac_init(struct mac_policy_conf *conf)
604 {
605
606 }
607
608 /*
609 * Label operations.
610 */
611 static void
612 lomac_init_label(struct label *label)
613 {
614
615 SLOT_SET(label, lomac_alloc(M_WAITOK));
616 }
617
618 static int
619 lomac_init_label_waitcheck(struct label *label, int flag)
620 {
621
622 SLOT_SET(label, lomac_alloc(flag));
623 if (SLOT(label) == NULL)
624 return (ENOMEM);
625
626 return (0);
627 }
628
629 static void
630 lomac_init_proc_label(struct label *label)
631 {
632
633 PSLOT_SET(label, malloc(sizeof(struct mac_lomac_proc), M_LOMAC,
634 M_ZERO | M_WAITOK));
635 mtx_init(&PSLOT(label)->mtx, "MAC/Lomac proc lock", NULL, MTX_DEF);
636 }
637
638 static void
639 lomac_destroy_label(struct label *label)
640 {
641
642 lomac_free(SLOT(label));
643 SLOT_SET(label, NULL);
644 }
645
646 static void
647 lomac_destroy_proc_label(struct label *label)
648 {
649
650 mtx_destroy(&PSLOT(label)->mtx);
651 FREE(PSLOT(label), M_LOMAC);
652 PSLOT_SET(label, NULL);
653 }
654
655 static int
656 lomac_element_to_string(struct sbuf *sb, struct mac_lomac_element *element)
657 {
658
659 switch (element->mle_type) {
660 case MAC_LOMAC_TYPE_HIGH:
661 return (sbuf_printf(sb, "high"));
662
663 case MAC_LOMAC_TYPE_LOW:
664 return (sbuf_printf(sb, "low"));
665
666 case MAC_LOMAC_TYPE_EQUAL:
667 return (sbuf_printf(sb, "equal"));
668
669 case MAC_LOMAC_TYPE_GRADE:
670 return (sbuf_printf(sb, "%d", element->mle_grade));
671
672 default:
673 panic("lomac_element_to_string: invalid type (%d)",
674 element->mle_type);
675 }
676 }
677
678 static int
679 lomac_to_string(struct sbuf *sb, struct mac_lomac *ml)
680 {
681
682 if (ml->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
683 if (lomac_element_to_string(sb, &ml->ml_single) == -1)
684 return (EINVAL);
685 }
686
687 if (ml->ml_flags & MAC_LOMAC_FLAG_AUX) {
688 if (sbuf_putc(sb, '[') == -1)
689 return (EINVAL);
690
691 if (lomac_element_to_string(sb, &ml->ml_auxsingle) == -1)
692 return (EINVAL);
693
694 if (sbuf_putc(sb, ']') == -1)
695 return (EINVAL);
696 }
697
698 if (ml->ml_flags & MAC_LOMAC_FLAG_RANGE) {
699 if (sbuf_putc(sb, '(') == -1)
700 return (EINVAL);
701
702 if (lomac_element_to_string(sb, &ml->ml_rangelow) == -1)
703 return (EINVAL);
704
705 if (sbuf_putc(sb, '-') == -1)
706 return (EINVAL);
707
708 if (lomac_element_to_string(sb, &ml->ml_rangehigh) == -1)
709 return (EINVAL);
710
711 if (sbuf_putc(sb, ')') == -1)
712 return (EINVAL);
713 }
714
715 return (0);
716 }
717
718 static int
719 lomac_externalize_label(struct label *label, char *element_name,
720 struct sbuf *sb, int *claimed)
721 {
722 struct mac_lomac *ml;
723
724 if (strcmp(MAC_LOMAC_LABEL_NAME, element_name) != 0)
725 return (0);
726
727 (*claimed)++;
728
729 ml = SLOT(label);
730
731 return (lomac_to_string(sb, ml));
732 }
733
734 static int
735 lomac_parse_element(struct mac_lomac_element *element, char *string)
736 {
737
738 if (strcmp(string, "high") == 0 || strcmp(string, "hi") == 0) {
739 element->mle_type = MAC_LOMAC_TYPE_HIGH;
740 element->mle_grade = MAC_LOMAC_TYPE_UNDEF;
741 } else if (strcmp(string, "low") == 0 || strcmp(string, "lo") == 0) {
742 element->mle_type = MAC_LOMAC_TYPE_LOW;
743 element->mle_grade = MAC_LOMAC_TYPE_UNDEF;
744 } else if (strcmp(string, "equal") == 0 ||
745 strcmp(string, "eq") == 0) {
746 element->mle_type = MAC_LOMAC_TYPE_EQUAL;
747 element->mle_grade = MAC_LOMAC_TYPE_UNDEF;
748 } else {
749 char *p0, *p1;
750 int d;
751
752 p0 = string;
753 d = strtol(p0, &p1, 10);
754
755 if (d < 0 || d > 65535)
756 return (EINVAL);
757 element->mle_type = MAC_LOMAC_TYPE_GRADE;
758 element->mle_grade = d;
759
760 if (p1 == p0 || *p1 != '\0')
761 return (EINVAL);
762 }
763
764 return (0);
765 }
766
767 /*
768 * Note: destructively consumes the string, make a local copy before calling
769 * if that's a problem.
770 */
771 static int
772 lomac_parse(struct mac_lomac *ml, char *string)
773 {
774 char *range, *rangeend, *rangehigh, *rangelow, *single, *auxsingle,
775 *auxsingleend;
776 int error;
777
778 /* Do we have a range? */
779 single = string;
780 range = index(string, '(');
781 if (range == single)
782 single = NULL;
783 auxsingle = index(string, '[');
784 if (auxsingle == single)
785 single = NULL;
786 if (range != NULL && auxsingle != NULL)
787 return (EINVAL);
788 rangelow = rangehigh = NULL;
789 if (range != NULL) {
790 /* Nul terminate the end of the single string. */
791 *range = '\0';
792 range++;
793 rangelow = range;
794 rangehigh = index(rangelow, '-');
795 if (rangehigh == NULL)
796 return (EINVAL);
797 rangehigh++;
798 if (*rangelow == '\0' || *rangehigh == '\0')
799 return (EINVAL);
800 rangeend = index(rangehigh, ')');
801 if (rangeend == NULL)
802 return (EINVAL);
803 if (*(rangeend + 1) != '\0')
804 return (EINVAL);
805 /* Nul terminate the ends of the ranges. */
806 *(rangehigh - 1) = '\0';
807 *rangeend = '\0';
808 }
809 KASSERT((rangelow != NULL && rangehigh != NULL) ||
810 (rangelow == NULL && rangehigh == NULL),
811 ("lomac_internalize_label: range mismatch"));
812 if (auxsingle != NULL) {
813 /* Nul terminate the end of the single string. */
814 *auxsingle = '\0';
815 auxsingle++;
816 auxsingleend = index(auxsingle, ']');
817 if (auxsingleend == NULL)
818 return (EINVAL);
819 if (*(auxsingleend + 1) != '\0')
820 return (EINVAL);
821 /* Nul terminate the end of the auxsingle. */
822 *auxsingleend = '\0';
823 }
824
825 bzero(ml, sizeof(*ml));
826 if (single != NULL) {
827 error = lomac_parse_element(&ml->ml_single, single);
828 if (error)
829 return (error);
830 ml->ml_flags |= MAC_LOMAC_FLAG_SINGLE;
831 }
832
833 if (auxsingle != NULL) {
834 error = lomac_parse_element(&ml->ml_auxsingle, auxsingle);
835 if (error)
836 return (error);
837 ml->ml_flags |= MAC_LOMAC_FLAG_AUX;
838 }
839
840 if (rangelow != NULL) {
841 error = lomac_parse_element(&ml->ml_rangelow, rangelow);
842 if (error)
843 return (error);
844 error = lomac_parse_element(&ml->ml_rangehigh, rangehigh);
845 if (error)
846 return (error);
847 ml->ml_flags |= MAC_LOMAC_FLAG_RANGE;
848 }
849
850 error = lomac_valid(ml);
851 if (error)
852 return (error);
853
854 return (0);
855 }
856
857 static int
858 lomac_internalize_label(struct label *label, char *element_name,
859 char *element_data, int *claimed)
860 {
861 struct mac_lomac *ml, ml_temp;
862 int error;
863
864 if (strcmp(MAC_LOMAC_LABEL_NAME, element_name) != 0)
865 return (0);
866
867 (*claimed)++;
868
869 error = lomac_parse(&ml_temp, element_data);
870 if (error)
871 return (error);
872
873 ml = SLOT(label);
874 *ml = ml_temp;
875
876 return (0);
877 }
878
879 static void
880 lomac_copy_label(struct label *src, struct label *dest)
881 {
882
883 *SLOT(dest) = *SLOT(src);
884 }
885
886 /*
887 * Labeling event operations: file system objects, and things that look a lot
888 * like file system objects.
889 */
890 static void
891 lomac_create_devfs_device(struct ucred *cred, struct mount *mp,
892 struct cdev *dev, struct devfs_dirent *de, struct label *delabel)
893 {
894 struct mac_lomac *ml;
895 int lomac_type;
896
897 ml = SLOT(delabel);
898 if (strcmp(dev->si_name, "null") == 0 ||
899 strcmp(dev->si_name, "zero") == 0 ||
900 strcmp(dev->si_name, "random") == 0 ||
901 strncmp(dev->si_name, "fd/", strlen("fd/")) == 0 ||
902 strncmp(dev->si_name, "ttyv", strlen("ttyv")) == 0)
903 lomac_type = MAC_LOMAC_TYPE_EQUAL;
904 else if (ptys_equal &&
905 (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
906 strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
907 lomac_type = MAC_LOMAC_TYPE_EQUAL;
908 else
909 lomac_type = MAC_LOMAC_TYPE_HIGH;
910 lomac_set_single(ml, lomac_type, 0);
911 }
912
913 static void
914 lomac_create_devfs_directory(struct mount *mp, char *dirname,
915 int dirnamelen, struct devfs_dirent *de, struct label *delabel)
916 {
917 struct mac_lomac *ml;
918
919 ml = SLOT(delabel);
920 lomac_set_single(ml, MAC_LOMAC_TYPE_HIGH, 0);
921 }
922
923 static void
924 lomac_create_devfs_symlink(struct ucred *cred, struct mount *mp,
925 struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de,
926 struct label *delabel)
927 {
928 struct mac_lomac *source, *dest;
929
930 source = SLOT(cred->cr_label);
931 dest = SLOT(delabel);
932
933 lomac_copy_single(source, dest);
934 }
935
936 static void
937 lomac_create_mount(struct ucred *cred, struct mount *mp,
938 struct label *mplabel)
939 {
940 struct mac_lomac *source, *dest;
941
942 source = SLOT(cred->cr_label);
943 dest = SLOT(mplabel);
944 lomac_copy_single(source, dest);
945 }
946
947 static void
948 lomac_relabel_vnode(struct ucred *cred, struct vnode *vp,
949 struct label *vplabel, struct label *newlabel)
950 {
951 struct mac_lomac *source, *dest;
952
953 source = SLOT(newlabel);
954 dest = SLOT(vplabel);
955
956 try_relabel(source, dest);
957 }
958
959 static void
960 lomac_update_devfs(struct mount *mp, struct devfs_dirent *de,
961 struct label *delabel, struct vnode *vp, struct label *vplabel)
962 {
963 struct mac_lomac *source, *dest;
964
965 source = SLOT(vplabel);
966 dest = SLOT(delabel);
967
968 lomac_copy(source, dest);
969 }
970
971 static void
972 lomac_associate_vnode_devfs(struct mount *mp, struct label *mplabel,
973 struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
974 struct label *vplabel)
975 {
976 struct mac_lomac *source, *dest;
977
978 source = SLOT(delabel);
979 dest = SLOT(vplabel);
980
981 lomac_copy_single(source, dest);
982 }
983
984 static int
985 lomac_associate_vnode_extattr(struct mount *mp, struct label *mplabel,
986 struct vnode *vp, struct label *vplabel)
987 {
988 struct mac_lomac temp, *source, *dest;
989 int buflen, error;
990
991 source = SLOT(mplabel);
992 dest = SLOT(vplabel);
993
994 buflen = sizeof(temp);
995 bzero(&temp, buflen);
996
997 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE,
998 MAC_LOMAC_EXTATTR_NAME, &buflen, (char *)&temp, curthread);
999 if (error == ENOATTR || error == EOPNOTSUPP) {
1000 /* Fall back to the mntlabel. */
1001 lomac_copy_single(source, dest);
1002 return (0);
1003 } else if (error)
1004 return (error);
1005
1006 if (buflen != sizeof(temp)) {
1007 if (buflen != sizeof(temp) - sizeof(temp.ml_auxsingle)) {
1008 printf("lomac_associate_vnode_extattr: bad size %d\n",
1009 buflen);
1010 return (EPERM);
1011 }
1012 bzero(&temp.ml_auxsingle, sizeof(temp.ml_auxsingle));
1013 buflen = sizeof(temp);
1014 (void)vn_extattr_set(vp, IO_NODELOCKED,
1015 MAC_LOMAC_EXTATTR_NAMESPACE, MAC_LOMAC_EXTATTR_NAME,
1016 buflen, (char *)&temp, curthread);
1017 }
1018 if (lomac_valid(&temp) != 0) {
1019 printf("lomac_associate_vnode_extattr: invalid\n");
1020 return (EPERM);
1021 }
1022 if ((temp.ml_flags & MAC_LOMAC_FLAGS_BOTH) != MAC_LOMAC_FLAG_SINGLE) {
1023 printf("lomac_associate_vnode_extattr: not single\n");
1024 return (EPERM);
1025 }
1026
1027 lomac_copy_single(&temp, dest);
1028 return (0);
1029 }
1030
1031 static void
1032 lomac_associate_vnode_singlelabel(struct mount *mp,
1033 struct label *mplabel, struct vnode *vp, struct label *vplabel)
1034 {
1035 struct mac_lomac *source, *dest;
1036
1037 source = SLOT(mplabel);
1038 dest = SLOT(vplabel);
1039
1040 lomac_copy_single(source, dest);
1041 }
1042
1043 static int
1044 lomac_create_vnode_extattr(struct ucred *cred, struct mount *mp,
1045 struct label *mplabel, struct vnode *dvp, struct label *dvplabel,
1046 struct vnode *vp, struct label *vplabel, struct componentname *cnp)
1047 {
1048 struct mac_lomac *source, *dest, *dir, temp;
1049 size_t buflen;
1050 int error;
1051
1052 buflen = sizeof(temp);
1053 bzero(&temp, buflen);
1054
1055 source = SLOT(cred->cr_label);
1056 dest = SLOT(vplabel);
1057 dir = SLOT(dvplabel);
1058 if (dir->ml_flags & MAC_LOMAC_FLAG_AUX) {
1059 lomac_copy_auxsingle(dir, &temp);
1060 lomac_set_single(&temp, dir->ml_auxsingle.mle_type,
1061 dir->ml_auxsingle.mle_grade);
1062 } else {
1063 lomac_copy_single(source, &temp);
1064 }
1065
1066 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE,
1067 MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread);
1068 if (error == 0)
1069 lomac_copy(&temp, dest);
1070 return (error);
1071 }
1072
1073 static int
1074 lomac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
1075 struct label *vplabel, struct label *intlabel)
1076 {
1077 struct mac_lomac *source, temp;
1078 size_t buflen;
1079 int error;
1080
1081 buflen = sizeof(temp);
1082 bzero(&temp, buflen);
1083
1084 source = SLOT(intlabel);
1085 if ((source->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0)
1086 return (0);
1087
1088 lomac_copy_single(source, &temp);
1089 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE,
1090 MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread);
1091 return (error);
1092 }
1093
1094 /*
1095 * Labeling event operations: IPC object.
1096 */
1097 static void
1098 lomac_create_inpcb_from_socket(struct socket *so, struct label *solabel,
1099 struct inpcb *inp, struct label *inplabel)
1100 {
1101 struct mac_lomac *source, *dest;
1102
1103 source = SLOT(solabel);
1104 dest = SLOT(inplabel);
1105
1106 lomac_copy_single(source, dest);
1107 }
1108
1109 static void
1110 lomac_create_mbuf_from_socket(struct socket *so, struct label *solabel,
1111 struct mbuf *m, struct label *mlabel)
1112 {
1113 struct mac_lomac *source, *dest;
1114
1115 source = SLOT(solabel);
1116 dest = SLOT(mlabel);
1117
1118 lomac_copy_single(source, dest);
1119 }
1120
1121 static void
1122 lomac_create_socket(struct ucred *cred, struct socket *so,
1123 struct label *solabel)
1124 {
1125 struct mac_lomac *source, *dest;
1126
1127 source = SLOT(cred->cr_label);
1128 dest = SLOT(solabel);
1129
1130 lomac_copy_single(source, dest);
1131 }
1132
1133 static void
1134 lomac_create_pipe(struct ucred *cred, struct pipepair *pp,
1135 struct label *pplabel)
1136 {
1137 struct mac_lomac *source, *dest;
1138
1139 source = SLOT(cred->cr_label);
1140 dest = SLOT(pplabel);
1141
1142 lomac_copy_single(source, dest);
1143 }
1144
1145 static void
1146 lomac_create_socket_from_socket(struct socket *oldso,
1147 struct label *oldsolabel, struct socket *newso, struct label *newsolabel)
1148 {
1149 struct mac_lomac *source, *dest;
1150
1151 source = SLOT(oldsolabel);
1152 dest = SLOT(newsolabel);
1153
1154 lomac_copy_single(source, dest);
1155 }
1156
1157 static void
1158 lomac_relabel_socket(struct ucred *cred, struct socket *so,
1159 struct label *solabel, struct label *newlabel)
1160 {
1161 struct mac_lomac *source, *dest;
1162
1163 source = SLOT(newlabel);
1164 dest = SLOT(solabel);
1165
1166 try_relabel(source, dest);
1167 }
1168
1169 static void
1170 lomac_relabel_pipe(struct ucred *cred, struct pipepair *pp,
1171 struct label *pplabel, struct label *newlabel)
1172 {
1173 struct mac_lomac *source, *dest;
1174
1175 source = SLOT(newlabel);
1176 dest = SLOT(pplabel);
1177
1178 try_relabel(source, dest);
1179 }
1180
1181 static void
1182 lomac_set_socket_peer_from_mbuf(struct mbuf *m, struct label *mlabel,
1183 struct socket *so, struct label *sopeerlabel)
1184 {
1185 struct mac_lomac *source, *dest;
1186
1187 source = SLOT(mlabel);
1188 dest = SLOT(sopeerlabel);
1189
1190 lomac_copy_single(source, dest);
1191 }
1192
1193 /*
1194 * Labeling event operations: network objects.
1195 */
1196 static void
1197 lomac_set_socket_peer_from_socket(struct socket *oldso,
1198 struct label *oldsolabel, struct socket *newso,
1199 struct label *newsopeerlabel)
1200 {
1201 struct mac_lomac *source, *dest;
1202
1203 source = SLOT(oldsolabel);
1204 dest = SLOT(newsopeerlabel);
1205
1206 lomac_copy_single(source, dest);
1207 }
1208
1209 static void
1210 lomac_create_bpfdesc(struct ucred *cred, struct bpf_d *d,
1211 struct label *dlabel)
1212 {
1213 struct mac_lomac *source, *dest;
1214
1215 source = SLOT(cred->cr_label);
1216 dest = SLOT(dlabel);
1217
1218 lomac_copy_single(source, dest);
1219 }
1220
1221 static void
1222 lomac_create_ifnet(struct ifnet *ifp, struct label *ifplabel)
1223 {
1224 char tifname[IFNAMSIZ], *p, *q;
1225 char tiflist[sizeof(trusted_interfaces)];
1226 struct mac_lomac *dest;
1227 int len, grade;
1228
1229 dest = SLOT(ifplabel);
1230
1231 if (ifp->if_type == IFT_LOOP) {
1232 grade = MAC_LOMAC_TYPE_EQUAL;
1233 goto set;
1234 }
1235
1236 if (trust_all_interfaces) {
1237 grade = MAC_LOMAC_TYPE_HIGH;
1238 goto set;
1239 }
1240
1241 grade = MAC_LOMAC_TYPE_LOW;
1242
1243 if (trusted_interfaces[0] == '\0' ||
1244 !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
1245 goto set;
1246
1247 bzero(tiflist, sizeof(tiflist));
1248 for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
1249 if(*p != ' ' && *p != '\t')
1250 *q = *p;
1251
1252 for (p = q = tiflist;; p++) {
1253 if (*p == ',' || *p == '\0') {
1254 len = p - q;
1255 if (len < IFNAMSIZ) {
1256 bzero(tifname, sizeof(tifname));
1257 bcopy(q, tifname, len);
1258 if (strcmp(tifname, ifp->if_xname) == 0) {
1259 grade = MAC_LOMAC_TYPE_HIGH;
1260 break;
1261 }
1262 }
1263 else {
1264 *p = '\0';
1265 printf("MAC/LOMAC warning: interface name "
1266 "\"%s\" is too long (must be < %d)\n",
1267 q, IFNAMSIZ);
1268 }
1269 if (*p == '\0')
1270 break;
1271 q = p + 1;
1272 }
1273 }
1274 set:
1275 lomac_set_single(dest, grade, 0);
1276 lomac_set_range(dest, grade, 0, grade, 0);
1277 }
1278
1279 static void
1280 lomac_create_ipq(struct mbuf *m, struct label *mlabel, struct ipq *q,
1281 struct label *qlabel)
1282 {
1283 struct mac_lomac *source, *dest;
1284
1285 source = SLOT(mlabel);
1286 dest = SLOT(qlabel);
1287
1288 lomac_copy_single(source, dest);
1289 }
1290
1291 static void
1292 lomac_create_datagram_from_ipq(struct ipq *q, struct label *qlabel,
1293 struct mbuf *m, struct label *mlabel)
1294 {
1295 struct mac_lomac *source, *dest;
1296
1297 source = SLOT(qlabel);
1298 dest = SLOT(mlabel);
1299
1300 /* Just use the head, since we require them all to match. */
1301 lomac_copy_single(source, dest);
1302 }
1303
1304 static void
1305 lomac_create_fragment(struct mbuf *m, struct label *mlabel,
1306 struct mbuf *frag, struct label *fraglabel)
1307 {
1308 struct mac_lomac *source, *dest;
1309
1310 source = SLOT(mlabel);
1311 dest = SLOT(fraglabel);
1312
1313 lomac_copy_single(source, dest);
1314 }
1315
1316 static void
1317 lomac_create_mbuf_from_inpcb(struct inpcb *inp, struct label *inplabel,
1318 struct mbuf *m, struct label *mlabel)
1319 {
1320 struct mac_lomac *source, *dest;
1321
1322 source = SLOT(inplabel);
1323 dest = SLOT(mlabel);
1324
1325 lomac_copy_single(source, dest);
1326 }
1327
1328 static void
1329 lomac_create_mbuf_linklayer(struct ifnet *ifp, struct label *ifplabel,
1330 struct mbuf *m, struct label *mlabel)
1331 {
1332 struct mac_lomac *dest;
1333
1334 dest = SLOT(mlabel);
1335
1336 lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0);
1337 }
1338
1339 static void
1340 lomac_create_mbuf_from_bpfdesc(struct bpf_d *d, struct label *dlabel,
1341 struct mbuf *m, struct label *mlabel)
1342 {
1343 struct mac_lomac *source, *dest;
1344
1345 source = SLOT(dlabel);
1346 dest = SLOT(mlabel);
1347
1348 lomac_copy_single(source, dest);
1349 }
1350
1351 static void
1352 lomac_create_mbuf_from_ifnet(struct ifnet *ifp, struct label *ifplabel,
1353 struct mbuf *m, struct label *mlabel)
1354 {
1355 struct mac_lomac *source, *dest;
1356
1357 source = SLOT(ifplabel);
1358 dest = SLOT(mlabel);
1359
1360 lomac_copy_single(source, dest);
1361 }
1362
1363 static void
1364 lomac_create_mbuf_multicast_encap(struct mbuf *m, struct label *mlabel,
1365 struct ifnet *ifp, struct label *ifplabel, struct mbuf *mnew,
1366 struct label *mnewlabel)
1367 {
1368 struct mac_lomac *source, *dest;
1369
1370 source = SLOT(mlabel);
1371 dest = SLOT(mnewlabel);
1372
1373 lomac_copy_single(source, dest);
1374 }
1375
1376 static void
1377 lomac_create_mbuf_netlayer(struct mbuf *m, struct label *mlabel,
1378 struct mbuf *mnew, struct label *mnewlabel)
1379 {
1380 struct mac_lomac *source, *dest;
1381
1382 source = SLOT(mlabel);
1383 dest = SLOT(mnewlabel);
1384
1385 lomac_copy_single(source, dest);
1386 }
1387
1388 static int
1389 lomac_fragment_match(struct mbuf *m, struct label *mlabel, struct ipq *q,
1390 struct label *qlabel)
1391 {
1392 struct mac_lomac *a, *b;
1393
1394 a = SLOT(qlabel);
1395 b = SLOT(mlabel);
1396
1397 return (lomac_equal_single(a, b));
1398 }
1399
1400 static void
1401 lomac_relabel_ifnet(struct ucred *cred, struct ifnet *ifp,
1402 struct label *ifplabel, struct label *newlabel)
1403 {
1404 struct mac_lomac *source, *dest;
1405
1406 source = SLOT(newlabel);
1407 dest = SLOT(ifplabel);
1408
1409 try_relabel(source, dest);
1410 }
1411
1412 static void
1413 lomac_update_ipq(struct mbuf *m, struct label *mlabel, struct ipq *q,
1414 struct label *qlabel)
1415 {
1416
1417 /* NOOP: we only accept matching labels, so no need to update */
1418 }
1419
1420 static void
1421 lomac_inpcb_sosetlabel(struct socket *so, struct label *solabel,
1422 struct inpcb *inp, struct label *inplabel)
1423 {
1424 struct mac_lomac *source, *dest;
1425
1426 source = SLOT(solabel);
1427 dest = SLOT(inplabel);
1428
1429 lomac_copy_single(source, dest);
1430 }
1431
1432 static void
1433 lomac_init_syncache_from_inpcb(struct label *label, struct inpcb *inp)
1434 {
1435 struct mac_lomac *source, *dest;
1436
1437 source = SLOT(inp->inp_label);
1438 dest = SLOT(label);
1439 lomac_copy(source, dest);
1440 }
1441
1442 static void
1443 lomac_create_mbuf_from_syncache(struct label *sc_label, struct mbuf *m,
1444 struct label *mlabel)
1445 {
1446 struct mac_lomac *source, *dest;
1447
1448 source = SLOT(sc_label);
1449 dest = SLOT(mlabel);
1450 lomac_copy(source, dest);
1451 }
1452
1453 static void
1454 lomac_create_mbuf_from_firewall(struct mbuf *m, struct label *mlabel)
1455 {
1456 struct mac_lomac *dest;
1457
1458 dest = SLOT(mlabel);
1459
1460 /* XXX: where is the label for the firewall really comming from? */
1461 lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0);
1462 }
1463
1464 /*
1465 * Labeling event operations: processes.
1466 */
1467 static void
1468 lomac_execve_transition(struct ucred *old, struct ucred *new,
1469 struct vnode *vp, struct label *vplabel, struct label *interpvnodelabel,
1470 struct image_params *imgp, struct label *execlabel)
1471 {
1472 struct mac_lomac *source, *dest, *obj, *robj;
1473
1474 source = SLOT(old->cr_label);
1475 dest = SLOT(new->cr_label);
1476 obj = SLOT(vplabel);
1477 robj = interpvnodelabel != NULL ? SLOT(interpvnodelabel) : obj;
1478
1479 lomac_copy(source, dest);
1480 /*
1481 * If there's an auxiliary label on the real object, respect it and
1482 * assume that this level should be assumed immediately if a higher
1483 * level is currently in place.
1484 */
1485 if (robj->ml_flags & MAC_LOMAC_FLAG_AUX &&
1486 !lomac_dominate_element(&robj->ml_auxsingle, &dest->ml_single)
1487 && lomac_auxsingle_in_range(robj, dest))
1488 lomac_set_single(dest, robj->ml_auxsingle.mle_type,
1489 robj->ml_auxsingle.mle_grade);
1490 /*
1491 * Restructuring to use the execve transitioning mechanism instead of
1492 * the normal demotion mechanism here would be difficult, so just
1493 * copy the label over and perform standard demotion. This is also
1494 * non-optimal because it will result in the intermediate label "new"
1495 * being created and immediately recycled.
1496 */
1497 if (lomac_enabled && revocation_enabled &&
1498 !lomac_dominate_single(obj, source))
1499 (void)maybe_demote(source, obj, "executing", "file", vp);
1500 }
1501
1502 static int
1503 lomac_execve_will_transition(struct ucred *old, struct vnode *vp,
1504 struct label *vplabel, struct label *interpvnodelabel,
1505 struct image_params *imgp, struct label *execlabel)
1506 {
1507 struct mac_lomac *subj, *obj, *robj;
1508
1509 if (!lomac_enabled || !revocation_enabled)
1510 return (0);
1511
1512 subj = SLOT(old->cr_label);
1513 obj = SLOT(vplabel);
1514 robj = interpvnodelabel != NULL ? SLOT(interpvnodelabel) : obj;
1515
1516 return ((robj->ml_flags & MAC_LOMAC_FLAG_AUX &&
1517 !lomac_dominate_element(&robj->ml_auxsingle, &subj->ml_single)
1518 && lomac_auxsingle_in_range(robj, subj)) ||
1519 !lomac_dominate_single(obj, subj));
1520 }
1521
1522 static void
1523 lomac_create_proc0(struct ucred *cred)
1524 {
1525 struct mac_lomac *dest;
1526
1527 dest = SLOT(cred->cr_label);
1528
1529 lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0);
1530 lomac_set_range(dest, MAC_LOMAC_TYPE_LOW, 0, MAC_LOMAC_TYPE_HIGH, 0);
1531 }
1532
1533 static void
1534 lomac_create_proc1(struct ucred *cred)
1535 {
1536 struct mac_lomac *dest;
1537
1538 dest = SLOT(cred->cr_label);
1539
1540 lomac_set_single(dest, MAC_LOMAC_TYPE_HIGH, 0);
1541 lomac_set_range(dest, MAC_LOMAC_TYPE_LOW, 0, MAC_LOMAC_TYPE_HIGH, 0);
1542 }
1543
1544 static void
1545 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 */
1558 static int
1559 lomac_check_bpfdesc_receive(struct bpf_d *d, struct label *dlabel,
1560 struct ifnet *ifp, struct label *ifplabel)
1561 {
1562 struct mac_lomac *a, *b;
1563
1564 if (!lomac_enabled)
1565 return (0);
1566
1567 a = SLOT(dlabel);
1568 b = SLOT(ifplabel);
1569
1570 if (lomac_equal_single(a, b))
1571 return (0);
1572 return (EACCES);
1573 }
1574
1575 static int
1576 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 be an
1586 * 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 lomac_copy_single(subj, new);
1601 if ((new->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0)
1602 lomac_copy_range(subj, new);
1603
1604 /*
1605 * To change the LOMAC range on a credential, the new range
1606 * label must be in the current range.
1607 */
1608 if (!lomac_range_in_range(new, subj))
1609 return (EPERM);
1610
1611 /*
1612 * To change the LOMAC single label on a credential, the new
1613 * single label must be in the new range. Implicitly from
1614 * the previous check, the new single is in the old range.
1615 */
1616 if (!lomac_single_in_range(new, new))
1617 return (EPERM);
1618
1619 /*
1620 * To have EQUAL in any component of the new credential LOMAC
1621 * label, the subject must already have EQUAL in their label.
1622 */
1623 if (lomac_contains_equal(new)) {
1624 error = lomac_subject_privileged(subj);
1625 if (error)
1626 return (error);
1627 }
1628
1629 /*
1630 * XXXMAC: Additional consistency tests regarding the
1631 * single and range of the new label might be performed
1632 * here.
1633 */
1634 }
1635
1636 return (0);
1637 }
1638
1639 static int
1640 lomac_check_cred_visible(struct ucred *cr1, struct ucred *cr2)
1641 {
1642 struct mac_lomac *subj, *obj;
1643
1644 if (!lomac_enabled)
1645 return (0);
1646
1647 subj = SLOT(cr1->cr_label);
1648 obj = SLOT(cr2->cr_label);
1649
1650 /* XXX: range */
1651 if (!lomac_dominate_single(obj, subj))
1652 return (ESRCH);
1653
1654 return (0);
1655 }
1656
1657 static int
1658 lomac_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifp,
1659 struct label *ifplabel, struct label *newlabel)
1660 {
1661 struct mac_lomac *subj, *new;
1662 int error;
1663
1664 subj = SLOT(cred->cr_label);
1665 new = SLOT(newlabel);
1666
1667 /*
1668 * If there is a LOMAC label update for the interface, it may be an
1669 * update of the single, range, or both.
1670 */
1671 error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH);
1672 if (error)
1673 return (error);
1674
1675 /*
1676 * Relabling network interfaces requires LOMAC privilege.
1677 */
1678 error = lomac_subject_privileged(subj);
1679 if (error)
1680 return (error);
1681
1682 /*
1683 * If the LOMAC label is to be changed, authorize as appropriate.
1684 */
1685 if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) {
1686 /*
1687 * Fill in the missing parts from the previous label.
1688 */
1689 if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0)
1690 lomac_copy_single(subj, new);
1691 if ((new->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0)
1692 lomac_copy_range(subj, new);
1693
1694 /*
1695 * Rely on the traditional superuser status for the LOMAC
1696 * interface relabel requirements. XXXMAC: This will go
1697 * away.
1698 *
1699 * XXXRW: This is also redundant to a higher layer check.
1700 */
1701 error = priv_check_cred(cred, PRIV_NET_SETIFMAC, 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
1714 static int
1715 lomac_check_ifnet_transmit(struct ifnet *ifp, struct label *ifplabel,
1716 struct mbuf *m, struct label *mlabel)
1717 {
1718 struct mac_lomac *p, *i;
1719
1720 if (!lomac_enabled)
1721 return (0);
1722
1723 p = SLOT(mlabel);
1724 i = SLOT(ifplabel);
1725
1726 return (lomac_single_in_range(p, i) ? 0 : EACCES);
1727 }
1728
1729 static int
1730 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 (!lomac_enabled)
1736 return (0);
1737
1738 p = SLOT(mlabel);
1739 i = SLOT(inplabel);
1740
1741 return (lomac_equal_single(p, i) ? 0 : EACCES);
1742 }
1743
1744 static int
1745 lomac_check_inpcb_visible(struct ucred *cred, struct inpcb *inp,
1746 struct label *inplabel)
1747 {
1748 struct mac_lomac *subj, *obj;
1749
1750 if (!lomac_enabled)
1751 return (0);
1752
1753 subj = SLOT(cred->cr_label);
1754 obj = SLOT(inplabel);
1755
1756 if (!lomac_dominate_single(obj, subj))
1757 return (ENOENT);
1758
1759 return (0);
1760 }
1761
1762 static int
1763 lomac_check_kld_load(struct ucred *cred, struct vnode *vp,
1764 struct label *vplabel)
1765 {
1766 struct mac_lomac *subj, *obj;
1767
1768 if (!lomac_enabled)
1769 return (0);
1770
1771 subj = SLOT(cred->cr_label);
1772 obj = SLOT(vplabel);
1773
1774 if (lomac_subject_privileged(subj))
1775 return (EPERM);
1776
1777 if (!lomac_high_single(obj))
1778 return (EACCES);
1779
1780 return (0);
1781 }
1782
1783 static int
1784 lomac_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp,
1785 struct label *pplabel, unsigned long cmd, void /* caddr_t */ *data)
1786 {
1787
1788 if (!lomac_enabled)
1789 return (0);
1790
1791 /* XXX: This will be implemented soon... */
1792
1793 return (0);
1794 }
1795
1796 static int
1797 lomac_check_pipe_read(struct ucred *cred, struct pipepair *pp,
1798 struct label *pplabel)
1799 {
1800 struct mac_lomac *subj, *obj;
1801
1802 if (!lomac_enabled)
1803 return (0);
1804
1805 subj = SLOT(cred->cr_label);
1806 obj = SLOT(pplabel);
1807
1808 if (!lomac_dominate_single(obj, subj))
1809 return (maybe_demote(subj, obj, "reading", "pipe", NULL));
1810
1811 return (0);
1812 }
1813
1814 static int
1815 lomac_check_pipe_relabel(struct ucred *cred, struct pipepair *pp,
1816 struct label *pplabel, struct label *newlabel)
1817 {
1818 struct mac_lomac *subj, *obj, *new;
1819 int error;
1820
1821 new = SLOT(newlabel);
1822 subj = SLOT(cred->cr_label);
1823 obj = SLOT(pplabel);
1824
1825 /*
1826 * If there is a LOMAC label update for a pipe, it must be a single
1827 * update.
1828 */
1829 error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE);
1830 if (error)
1831 return (error);
1832
1833 /*
1834 * To perform a relabel of a pipe (LOMAC label or not), LOMAC must
1835 * authorize the relabel.
1836 */
1837 if (!lomac_single_in_range(obj, subj))
1838 return (EPERM);
1839
1840 /*
1841 * If the LOMAC label is to be changed, authorize as appropriate.
1842 */
1843 if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
1844 /*
1845 * To change the LOMAC label on a pipe, the new pipe label
1846 * must be in the subject range.
1847 */
1848 if (!lomac_single_in_range(new, subj))
1849 return (EPERM);
1850
1851 /*
1852 * To change the LOMAC label on a pipe to be EQUAL, the
1853 * subject must have appropriate privilege.
1854 */
1855 if (lomac_contains_equal(new)) {
1856 error = lomac_subject_privileged(subj);
1857 if (error)
1858 return (error);
1859 }
1860 }
1861
1862 return (0);
1863 }
1864
1865 static int
1866 lomac_check_pipe_write(struct ucred *cred, struct pipepair *pp,
1867 struct label *pplabel)
1868 {
1869 struct mac_lomac *subj, *obj;
1870
1871 if (!lomac_enabled)
1872 return (0);
1873
1874 subj = SLOT(cred->cr_label);
1875 obj = SLOT(pplabel);
1876
1877 if (!lomac_subject_dominate(subj, obj))
1878 return (EACCES);
1879
1880 return (0);
1881 }
1882
1883 static int
1884 lomac_check_proc_debug(struct ucred *cred, struct proc *p)
1885 {
1886 struct mac_lomac *subj, *obj;
1887
1888 if (!lomac_enabled)
1889 return (0);
1890
1891 subj = SLOT(cred->cr_label);
1892 obj = SLOT(p->p_ucred->cr_label);
1893
1894 /* XXX: range checks */
1895 if (!lomac_dominate_single(obj, subj))
1896 return (ESRCH);
1897 if (!lomac_subject_dominate(subj, obj))
1898 return (EACCES);
1899
1900 return (0);
1901 }
1902
1903 static int
1904 lomac_check_proc_sched(struct ucred *cred, struct proc *p)
1905 {
1906 struct mac_lomac *subj, *obj;
1907
1908 if (!lomac_enabled)
1909 return (0);
1910
1911 subj = SLOT(cred->cr_label);
1912 obj = SLOT(p->p_ucred->cr_label);
1913
1914 /* XXX: range checks */
1915 if (!lomac_dominate_single(obj, subj))
1916 return (ESRCH);
1917 if (!lomac_subject_dominate(subj, obj))
1918 return (EACCES);
1919
1920 return (0);
1921 }
1922
1923 static int
1924 lomac_check_proc_signal(struct ucred *cred, struct proc *p, int signum)
1925 {
1926 struct mac_lomac *subj, *obj;
1927
1928 if (!lomac_enabled)
1929 return (0);
1930
1931 subj = SLOT(cred->cr_label);
1932 obj = SLOT(p->p_ucred->cr_label);
1933
1934 /* XXX: range checks */
1935 if (!lomac_dominate_single(obj, subj))
1936 return (ESRCH);
1937 if (!lomac_subject_dominate(subj, obj))
1938 return (EACCES);
1939
1940 return (0);
1941 }
1942
1943 static int
1944 lomac_check_socket_deliver(struct socket *so, struct label *solabel,
1945 struct mbuf *m, struct label *mlabel)
1946 {
1947 struct mac_lomac *p, *s;
1948
1949 if (!lomac_enabled)
1950 return (0);
1951
1952 p = SLOT(mlabel);
1953 s = SLOT(solabel);
1954
1955 return (lomac_equal_single(p, s) ? 0 : EACCES);
1956 }
1957
1958 static int
1959 lomac_check_socket_relabel(struct ucred *cred, struct socket *so,
1960 struct label *solabel, struct label *newlabel)
1961 {
1962 struct mac_lomac *subj, *obj, *new;
1963 int error;
1964
1965 new = SLOT(newlabel);
1966 subj = SLOT(cred->cr_label);
1967 obj = SLOT(solabel);
1968
1969 /*
1970 * If there is a LOMAC label update for the socket, it may be an
1971 * update of single.
1972 */
1973 error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE);
1974 if (error)
1975 return (error);
1976
1977 /*
1978 * To relabel a socket, the old socket single must be in the subject
1979 * range.
1980 */
1981 if (!lomac_single_in_range(obj, subj))
1982 return (EPERM);
1983
1984 /*
1985 * If the LOMAC label is to be changed, authorize as appropriate.
1986 */
1987 if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
1988 /*
1989 * To relabel a socket, the new socket single must be in the
1990 * subject range.
1991 */
1992 if (!lomac_single_in_range(new, subj))
1993 return (EPERM);
1994
1995 /*
1996 * To change the LOMAC label on the socket to contain EQUAL,
1997 * the subject must have appropriate privilege.
1998 */
1999 if (lomac_contains_equal(new)) {
2000 error = lomac_subject_privileged(subj);
2001 if (error)
2002 return (error);
2003 }
2004 }
2005
2006 return (0);
2007 }
2008
2009 static int
2010 lomac_check_socket_visible(struct ucred *cred, struct socket *so,
2011 struct label *solabel)
2012 {
2013 struct mac_lomac *subj, *obj;
2014
2015 if (!lomac_enabled)
2016 return (0);
2017
2018 subj = SLOT(cred->cr_label);
2019 obj = SLOT(solabel);
2020
2021 if (!lomac_dominate_single(obj, subj))
2022 return (ENOENT);
2023
2024 return (0);
2025 }
2026
2027 /*
2028 * Some system privileges are allowed regardless of integrity grade; others
2029 * are allowed only when running with privilege with respect to the LOMAC
2030 * policy as they might otherwise allow bypassing of the integrity policy.
2031 */
2032 static int
2033 lomac_priv_check(struct ucred *cred, int priv)
2034 {
2035 struct mac_lomac *subj;
2036 int error;
2037
2038 if (!lomac_enabled)
2039 return (0);
2040
2041 /*
2042 * Exempt only specific privileges from the LOMAC integrity policy.
2043 */
2044 switch (priv) {
2045 case PRIV_KTRACE:
2046 case PRIV_MSGBUF:
2047
2048 /*
2049 * Allow processes to manipulate basic process audit properties, and
2050 * to submit audit records.
2051 */
2052 case PRIV_AUDIT_GETAUDIT:
2053 case PRIV_AUDIT_SETAUDIT:
2054 case PRIV_AUDIT_SUBMIT:
2055
2056 /*
2057 * Allow processes to manipulate their regular UNIX credentials.
2058 */
2059 case PRIV_CRED_SETUID:
2060 case PRIV_CRED_SETEUID:
2061 case PRIV_CRED_SETGID:
2062 case PRIV_CRED_SETEGID:
2063 case PRIV_CRED_SETGROUPS:
2064 case PRIV_CRED_SETREUID:
2065 case PRIV_CRED_SETREGID:
2066 case PRIV_CRED_SETRESUID:
2067 case PRIV_CRED_SETRESGID:
2068
2069 /*
2070 * Allow processes to perform system monitoring.
2071 */
2072 case PRIV_SEEOTHERGIDS:
2073 case PRIV_SEEOTHERUIDS:
2074 break;
2075
2076 /*
2077 * Allow access to general process debugging facilities. We
2078 * separately control debugging based on MAC label.
2079 */
2080 case PRIV_DEBUG_DIFFCRED:
2081 case PRIV_DEBUG_SUGID:
2082 case PRIV_DEBUG_UNPRIV:
2083
2084 /*
2085 * Allow manipulating jails.
2086 */
2087 case PRIV_JAIL_ATTACH:
2088
2089 /*
2090 * Allow privilege with respect to the Partition policy, but not the
2091 * Privs policy.
2092 */
2093 case PRIV_MAC_PARTITION:
2094
2095 /*
2096 * Allow privilege with respect to process resource limits and login
2097 * context.
2098 */
2099 case PRIV_PROC_LIMIT:
2100 case PRIV_PROC_SETLOGIN:
2101 case PRIV_PROC_SETRLIMIT:
2102
2103 /*
2104 * Allow System V and POSIX IPC privileges.
2105 */
2106 case PRIV_IPC_READ:
2107 case PRIV_IPC_WRITE:
2108 case PRIV_IPC_ADMIN:
2109 case PRIV_IPC_MSGSIZE:
2110 case PRIV_MQ_ADMIN:
2111
2112 /*
2113 * Allow certain scheduler manipulations -- possibly this should be
2114 * controlled by more fine-grained policy, as potentially low
2115 * integrity processes can deny CPU to higher integrity ones.
2116 */
2117 case PRIV_SCHED_DIFFCRED:
2118 case PRIV_SCHED_SETPRIORITY:
2119 case PRIV_SCHED_RTPRIO:
2120 case PRIV_SCHED_SETPOLICY:
2121 case PRIV_SCHED_SET:
2122 case PRIV_SCHED_SETPARAM:
2123
2124 /*
2125 * More IPC privileges.
2126 */
2127 case PRIV_SEM_WRITE:
2128
2129 /*
2130 * Allow signaling privileges subject to integrity policy.
2131 */
2132 case PRIV_SIGNAL_DIFFCRED:
2133 case PRIV_SIGNAL_SUGID:
2134
2135 /*
2136 * Allow access to only limited sysctls from lower integrity levels;
2137 * piggy-back on the Jail definition.
2138 */
2139 case PRIV_SYSCTL_WRITEJAIL:
2140
2141 /*
2142 * Allow TTY-based privileges, subject to general device access using
2143 * labels on TTY device nodes, but not console privilege.
2144 */
2145 case PRIV_TTY_DRAINWAIT:
2146 case PRIV_TTY_DTRWAIT:
2147 case PRIV_TTY_EXCLUSIVE:
2148 case PRIV_TTY_PRISON:
2149 case PRIV_TTY_STI:
2150 case PRIV_TTY_SETA:
2151
2152 /*
2153 * Grant most VFS privileges, as almost all are in practice bounded
2154 * by more specific checks using labels.
2155 */
2156 case PRIV_VFS_READ:
2157 case PRIV_VFS_WRITE:
2158 case PRIV_VFS_ADMIN:
2159 case PRIV_VFS_EXEC:
2160 case PRIV_VFS_LOOKUP:
2161 case PRIV_VFS_CHFLAGS_DEV:
2162 case PRIV_VFS_CHOWN:
2163 case PRIV_VFS_CHROOT:
2164 case PRIV_VFS_RETAINSUGID:
2165 case PRIV_VFS_EXCEEDQUOTA:
2166 case PRIV_VFS_FCHROOT:
2167 case PRIV_VFS_FHOPEN:
2168 case PRIV_VFS_FHSTATFS:
2169 case PRIV_VFS_GENERATION:
2170 case PRIV_VFS_GETFH:
2171 case PRIV_VFS_GETQUOTA:
2172 case PRIV_VFS_LINK:
2173 case PRIV_VFS_MOUNT:
2174 case PRIV_VFS_MOUNT_OWNER:
2175 case PRIV_VFS_MOUNT_PERM:
2176 case PRIV_VFS_MOUNT_SUIDDIR:
2177 case PRIV_VFS_MOUNT_NONUSER:
2178 case PRIV_VFS_SETGID:
2179 case PRIV_VFS_STICKYFILE:
2180 case PRIV_VFS_SYSFLAGS:
2181 case PRIV_VFS_UNMOUNT:
2182
2183 /*
2184 * Allow VM privileges; it would be nice if these were subject to
2185 * resource limits.
2186 */
2187 case PRIV_VM_MADV_PROTECT:
2188 case PRIV_VM_MLOCK:
2189 case PRIV_VM_MUNLOCK:
2190
2191 /*
2192 * Allow some but not all network privileges. In general, dont allow
2193 * reconfiguring the network stack, just normal use.
2194 */
2195 case PRIV_NETATALK_RESERVEDPORT:
2196 case PRIV_NETINET_RESERVEDPORT:
2197 case PRIV_NETINET_RAW:
2198 case PRIV_NETINET_REUSEPORT:
2199 case PRIV_NETIPX_RESERVEDPORT:
2200 case PRIV_NETIPX_RAW:
2201 break;
2202
2203 /*
2204 * All remaining system privileges are allow only if the process
2205 * holds privilege with respect to the LOMAC policy.
2206 */
2207 default:
2208 subj = SLOT(cred->cr_label);
2209 error = lomac_subject_privileged(subj);
2210 if (error)
2211 return (error);
2212 }
2213 return (0);
2214 }
2215
2216
2217 static int
2218 lomac_check_system_acct(struct ucred *cred, struct vnode *vp,
2219 struct label *vplabel)
2220 {
2221 struct mac_lomac *subj, *obj;
2222
2223 if (!lomac_enabled)
2224 return (0);
2225
2226 subj = SLOT(cred->cr_label);
2227 obj = SLOT(vplabel);
2228
2229 if (lomac_subject_privileged(subj))
2230 return (EPERM);
2231
2232 if (!lomac_high_single(obj))
2233 return (EACCES);
2234
2235 return (0);
2236 }
2237
2238 static int
2239 lomac_check_system_auditctl(struct ucred *cred, struct vnode *vp,
2240 struct label *vplabel)
2241 {
2242 struct mac_lomac *subj, *obj;
2243
2244 if (!lomac_enabled)
2245 return (0);
2246
2247 subj = SLOT(cred->cr_label);
2248 obj = SLOT(vplabel);
2249
2250 if (lomac_subject_privileged(subj))
2251 return (EPERM);
2252
2253 if (!lomac_high_single(obj))
2254 return (EACCES);
2255
2256 return (0);
2257 }
2258
2259 static int
2260 lomac_check_system_swapoff(struct ucred *cred, struct vnode *vp,
2261 struct label *vplabel)
2262 {
2263 struct mac_lomac *subj;
2264
2265 if (!lomac_enabled)
2266 return (0);
2267
2268 subj = SLOT(cred->cr_label);
2269
2270 if (lomac_subject_privileged(subj))
2271 return (EPERM);
2272
2273 return (0);
2274 }
2275
2276 static int
2277 lomac_check_system_swapon(struct ucred *cred, struct vnode *vp,
2278 struct label *vplabel)
2279 {
2280 struct mac_lomac *subj, *obj;
2281
2282 if (!lomac_enabled)
2283 return (0);
2284
2285 subj = SLOT(cred->cr_label);
2286 obj = SLOT(vplabel);
2287
2288 if (lomac_subject_privileged(subj))
2289 return (EPERM);
2290
2291 if (!lomac_high_single(obj))
2292 return (EACCES);
2293
2294 return (0);
2295 }
2296
2297 static int
2298 lomac_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp,
2299 void *arg1, int arg2, struct sysctl_req *req)
2300 {
2301 struct mac_lomac *subj;
2302
2303 if (!lomac_enabled)
2304 return (0);
2305
2306 subj = SLOT(cred->cr_label);
2307
2308 /*
2309 * Treat sysctl variables without CTLFLAG_ANYBODY flag as lomac/high,
2310 * but also require privilege to change them.
2311 */
2312 if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) {
2313 #ifdef notdef
2314 if (!lomac_subject_dominate_high(subj))
2315 return (EACCES);
2316 #endif
2317
2318 if (lomac_subject_privileged(subj))
2319 return (EPERM);
2320 }
2321
2322 return (0);
2323 }
2324
2325 static int
2326 lomac_check_vnode_create(struct ucred *cred, struct vnode *dvp,
2327 struct label *dvplabel, struct componentname *cnp, struct vattr *vap)
2328 {
2329 struct mac_lomac *subj, *obj;
2330
2331 if (!lomac_enabled)
2332 return (0);
2333
2334 subj = SLOT(cred->cr_label);
2335 obj = SLOT(dvplabel);
2336
2337 if (!lomac_subject_dominate(subj, obj))
2338 return (EACCES);
2339 if (obj->ml_flags & MAC_LOMAC_FLAG_AUX &&
2340 !lomac_dominate_element(&subj->ml_single, &obj->ml_auxsingle))
2341 return (EACCES);
2342
2343 return (0);
2344 }
2345
2346 static int
2347 lomac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
2348 struct label *vplabel, acl_type_t type)
2349 {
2350 struct mac_lomac *subj, *obj;
2351
2352 if (!lomac_enabled)
2353 return (0);
2354
2355 subj = SLOT(cred->cr_label);
2356 obj = SLOT(vplabel);
2357
2358 if (!lomac_subject_dominate(subj, obj))
2359 return (EACCES);
2360
2361 return (0);
2362 }
2363
2364 static int
2365 lomac_check_vnode_link(struct ucred *cred, struct vnode *dvp,
2366 struct label *dvplabel, struct vnode *vp, struct label *vplabel,
2367 struct componentname *cnp)
2368 {
2369 struct mac_lomac *subj, *obj;
2370
2371 if (!lomac_enabled)
2372 return (0);
2373
2374 subj = SLOT(cred->cr_label);
2375 obj = SLOT(dvplabel);
2376
2377 if (!lomac_subject_dominate(subj, obj))
2378 return (EACCES);
2379
2380 obj = SLOT(vplabel);
2381
2382 if (!lomac_subject_dominate(subj, obj))
2383 return (EACCES);
2384
2385 return (0);
2386 }
2387
2388 static int
2389 lomac_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
2390 struct label *vplabel, int prot, int flags)
2391 {
2392 struct mac_lomac *subj, *obj;
2393
2394 /*
2395 * Rely on the use of open()-time protections to handle
2396 * non-revocation cases.
2397 */
2398 if (!lomac_enabled)
2399 return (0);
2400
2401 subj = SLOT(cred->cr_label);
2402 obj = SLOT(vplabel);
2403
2404 if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) {
2405 if (!lomac_subject_dominate(subj, obj))
2406 return (EACCES);
2407 }
2408 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2409 if (!lomac_dominate_single(obj, subj))
2410 return (maybe_demote(subj, obj, "mapping", "file", vp));
2411 }
2412
2413 return (0);
2414 }
2415
2416 static void
2417 lomac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp,
2418 struct label *vplabel, /* XXX vm_prot_t */ int *prot)
2419 {
2420 struct mac_lomac *subj, *obj;
2421
2422 /*
2423 * Rely on the use of open()-time protections to handle
2424 * non-revocation cases.
2425 */
2426 if (!lomac_enabled || !revocation_enabled)
2427 return;
2428
2429 subj = SLOT(cred->cr_label);
2430 obj = SLOT(vplabel);
2431
2432 if (!lomac_subject_dominate(subj, obj))
2433 *prot &= ~VM_PROT_WRITE;
2434 }
2435
2436 static int
2437 lomac_check_vnode_open(struct ucred *cred, struct vnode *vp,
2438 struct label *vplabel, int acc_mode)
2439 {
2440 struct mac_lomac *subj, *obj;
2441
2442 if (!lomac_enabled)
2443 return (0);
2444
2445 subj = SLOT(cred->cr_label);
2446 obj = SLOT(vplabel);
2447
2448 /* XXX privilege override for admin? */
2449 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2450 if (!lomac_subject_dominate(subj, obj))
2451 return (EACCES);
2452 }
2453
2454 return (0);
2455 }
2456
2457 static int
2458 lomac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2459 struct vnode *vp, struct label *vplabel)
2460 {
2461 struct mac_lomac *subj, *obj;
2462
2463 if (!lomac_enabled || !revocation_enabled)
2464 return (0);
2465
2466 subj = SLOT(active_cred->cr_label);
2467 obj = SLOT(vplabel);
2468
2469 if (!lomac_dominate_single(obj, subj))
2470 return (maybe_demote(subj, obj, "reading", "file", vp));
2471
2472 return (0);
2473 }
2474
2475 static int
2476 lomac_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2477 struct label *vplabel, struct label *newlabel)
2478 {
2479 struct mac_lomac *old, *new, *subj;
2480 int error;
2481
2482 old = SLOT(vplabel);
2483 new = SLOT(newlabel);
2484 subj = SLOT(cred->cr_label);
2485
2486 /*
2487 * If there is a LOMAC label update for the vnode, it must be a
2488 * single label, with an optional explicit auxiliary single.
2489 */
2490 error = lomac_atmostflags(new,
2491 MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_AUX);
2492 if (error)
2493 return (error);
2494
2495 /*
2496 * To perform a relabel of the vnode (LOMAC label or not), LOMAC must
2497 * authorize the relabel.
2498 */
2499 if (!lomac_single_in_range(old, subj))
2500 return (EPERM);
2501
2502 /*
2503 * If the LOMAC label is to be changed, authorize as appropriate.
2504 */
2505 if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
2506 /*
2507 * To change the LOMAC label on a vnode, the new vnode label
2508 * must be in the subject range.
2509 */
2510 if (!lomac_single_in_range(new, subj))
2511 return (EPERM);
2512
2513 /*
2514 * To change the LOMAC label on the vnode to be EQUAL,
2515 * the subject must have appropriate privilege.
2516 */
2517 if (lomac_contains_equal(new)) {
2518 error = lomac_subject_privileged(subj);
2519 if (error)
2520 return (error);
2521 }
2522 }
2523 if (new->ml_flags & MAC_LOMAC_FLAG_AUX) {
2524 /*
2525 * Fill in the missing parts from the previous label.
2526 */
2527 if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0)
2528 lomac_copy_single(subj, new);
2529
2530 /*
2531 * To change the auxiliary LOMAC label on a vnode, the new
2532 * vnode label must be in the subject range.
2533 */
2534 if (!lomac_auxsingle_in_range(new, subj))
2535 return (EPERM);
2536
2537 /*
2538 * To change the auxiliary LOMAC label on the vnode to be
2539 * EQUAL, the subject must have appropriate privilege.
2540 */
2541 if (lomac_contains_equal(new)) {
2542 error = lomac_subject_privileged(subj);
2543 if (error)
2544 return (error);
2545 }
2546 }
2547
2548 return (0);
2549 }
2550
2551 static int
2552 lomac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2553 struct label *dvplabel, struct vnode *vp, struct label *vplabel,
2554 struct componentname *cnp)
2555 {
2556 struct mac_lomac *subj, *obj;
2557
2558 if (!lomac_enabled)
2559 return (0);
2560
2561 subj = SLOT(cred->cr_label);
2562 obj = SLOT(dvplabel);
2563
2564 if (!lomac_subject_dominate(subj, obj))
2565 return (EACCES);
2566
2567 obj = SLOT(vplabel);
2568
2569 if (!lomac_subject_dominate(subj, obj))
2570 return (EACCES);
2571
2572 return (0);
2573 }
2574
2575 static int
2576 lomac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2577 struct label *dvplabel, struct vnode *vp, struct label *vplabel,
2578 int samedir, struct componentname *cnp)
2579 {
2580 struct mac_lomac *subj, *obj;
2581
2582 if (!lomac_enabled)
2583 return (0);
2584
2585 subj = SLOT(cred->cr_label);
2586 obj = SLOT(dvplabel);
2587
2588 if (!lomac_subject_dominate(subj, obj))
2589 return (EACCES);
2590
2591 if (vp != NULL) {
2592 obj = SLOT(vplabel);
2593
2594 if (!lomac_subject_dominate(subj, obj))
2595 return (EACCES);
2596 }
2597
2598 return (0);
2599 }
2600
2601 static int
2602 lomac_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
2603 struct label *vplabel)
2604 {
2605 struct mac_lomac *subj, *obj;
2606
2607 if (!lomac_enabled)
2608 return (0);
2609
2610 subj = SLOT(cred->cr_label);
2611 obj = SLOT(vplabel);
2612
2613 if (!lomac_subject_dominate(subj, obj))
2614 return (EACCES);
2615
2616 return (0);
2617 }
2618
2619 static int
2620 lomac_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
2621 struct label *vplabel, acl_type_t type, struct acl *acl)
2622 {
2623 struct mac_lomac *subj, *obj;
2624
2625 if (!lomac_enabled)
2626 return (0);
2627
2628 subj = SLOT(cred->cr_label);
2629 obj = SLOT(vplabel);
2630
2631 if (!lomac_subject_dominate(subj, obj))
2632 return (EACCES);
2633
2634 return (0);
2635 }
2636
2637 static int
2638 lomac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2639 struct label *vplabel, int attrnamespace, const char *name,
2640 struct uio *uio)
2641 {
2642 struct mac_lomac *subj, *obj;
2643
2644 if (!lomac_enabled)
2645 return (0);
2646
2647 subj = SLOT(cred->cr_label);
2648 obj = SLOT(vplabel);
2649
2650 if (!lomac_subject_dominate(subj, obj))
2651 return (EACCES);
2652
2653 /* XXX: protect the MAC EA in a special way? */
2654
2655 return (0);
2656 }
2657
2658 static int
2659 lomac_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2660 struct label *vplabel, u_long flags)
2661 {
2662 struct mac_lomac *subj, *obj;
2663
2664 if (!lomac_enabled)
2665 return (0);
2666
2667 subj = SLOT(cred->cr_label);
2668 obj = SLOT(vplabel);
2669
2670 if (!lomac_subject_dominate(subj, obj))
2671 return (EACCES);
2672
2673 return (0);
2674 }
2675
2676 static int
2677 lomac_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2678 struct label *vplabel, mode_t mode)
2679 {
2680 struct mac_lomac *subj, *obj;
2681
2682 if (!lomac_enabled)
2683 return (0);
2684
2685 subj = SLOT(cred->cr_label);
2686 obj = SLOT(vplabel);
2687
2688 if (!lomac_subject_dominate(subj, obj))
2689 return (EACCES);
2690
2691 return (0);
2692 }
2693
2694 static int
2695 lomac_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2696 struct label *vplabel, uid_t uid, gid_t gid)
2697 {
2698 struct mac_lomac *subj, *obj;
2699
2700 if (!lomac_enabled)
2701 return (0);
2702
2703 subj = SLOT(cred->cr_label);
2704 obj = SLOT(vplabel);
2705
2706 if (!lomac_subject_dominate(subj, obj))
2707 return (EACCES);
2708
2709 return (0);
2710 }
2711
2712 static int
2713 lomac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2714 struct label *vplabel, struct timespec atime, struct timespec mtime)
2715 {
2716 struct mac_lomac *subj, *obj;
2717
2718 if (!lomac_enabled)
2719 return (0);
2720
2721 subj = SLOT(cred->cr_label);
2722 obj = SLOT(vplabel);
2723
2724 if (!lomac_subject_dominate(subj, obj))
2725 return (EACCES);
2726
2727 return (0);
2728 }
2729
2730 static int
2731 lomac_check_vnode_unlink(struct ucred *cred, struct vnode *dvp,
2732 struct label *dvplabel, struct vnode *vp, struct label *vplabel,
2733 struct componentname *cnp)
2734 {
2735 struct mac_lomac *subj, *obj;
2736
2737 if (!lomac_enabled)
2738 return (0);
2739
2740 subj = SLOT(cred->cr_label);
2741 obj = SLOT(dvplabel);
2742
2743 if (!lomac_subject_dominate(subj, obj))
2744 return (EACCES);
2745
2746 obj = SLOT(vplabel);
2747
2748 if (!lomac_subject_dominate(subj, obj))
2749 return (EACCES);
2750
2751 return (0);
2752 }
2753
2754 static int
2755 lomac_check_vnode_write(struct ucred *active_cred,
2756 struct ucred *file_cred, struct vnode *vp, struct label *vplabel)
2757 {
2758 struct mac_lomac *subj, *obj;
2759
2760 if (!lomac_enabled || !revocation_enabled)
2761 return (0);
2762
2763 subj = SLOT(active_cred->cr_label);
2764 obj = SLOT(vplabel);
2765
2766 if (!lomac_subject_dominate(subj, obj))
2767 return (EACCES);
2768
2769 return (0);
2770 }
2771
2772 static void
2773 lomac_thread_userret(struct thread *td)
2774 {
2775 struct proc *p = td->td_proc;
2776 struct mac_lomac_proc *subj = PSLOT(p->p_label);
2777 struct ucred *newcred, *oldcred;
2778 int dodrop;
2779
2780 mtx_lock(&subj->mtx);
2781 if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) {
2782 dodrop = 0;
2783 mtx_unlock(&subj->mtx);
2784 newcred = crget();
2785 /*
2786 * Prevent a lock order reversal in
2787 * mac_cred_mmapped_drop_perms; ideally, the other
2788 * user of subj->mtx wouldn't be holding Giant.
2789 */
2790 mtx_lock(&Giant);
2791 PROC_LOCK(p);
2792 mtx_lock(&subj->mtx);
2793 /*
2794 * Check if we lost the race while allocating the cred.
2795 */
2796 if ((subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) == 0) {
2797 crfree(newcred);
2798 goto out;
2799 }
2800 oldcred = p->p_ucred;
2801 crcopy(newcred, oldcred);
2802 crhold(newcred);
2803 lomac_copy(&subj->mac_lomac, SLOT(newcred->cr_label));
2804 p->p_ucred = newcred;
2805 crfree(oldcred);
2806 dodrop = 1;
2807 out:
2808 mtx_unlock(&subj->mtx);
2809 PROC_UNLOCK(p);
2810 if (dodrop)
2811 mac_cred_mmapped_drop_perms(curthread, newcred);
2812 mtx_unlock(&Giant);
2813 } else {
2814 mtx_unlock(&subj->mtx);
2815 }
2816 }
2817
2818 static struct mac_policy_ops lomac_ops =
2819 {
2820 .mpo_init = lomac_init,
2821 .mpo_init_bpfdesc_label = lomac_init_label,
2822 .mpo_init_cred_label = lomac_init_label,
2823 .mpo_init_devfs_label = lomac_init_label,
2824 .mpo_init_ifnet_label = lomac_init_label,
2825 .mpo_init_syncache_label = lomac_init_label_waitcheck,
2826 .mpo_init_inpcb_label = lomac_init_label_waitcheck,
2827 .mpo_init_ipq_label = lomac_init_label_waitcheck,
2828 .mpo_init_mbuf_label = lomac_init_label_waitcheck,
2829 .mpo_init_mount_label = lomac_init_label,
2830 .mpo_init_pipe_label = lomac_init_label,
2831 .mpo_init_proc_label = lomac_init_proc_label,
2832 .mpo_init_socket_label = lomac_init_label_waitcheck,
2833 .mpo_init_socket_peer_label = lomac_init_label_waitcheck,
2834 .mpo_init_vnode_label = lomac_init_label,
2835 .mpo_init_syncache_from_inpcb = lomac_init_syncache_from_inpcb,
2836 .mpo_destroy_bpfdesc_label = lomac_destroy_label,
2837 .mpo_destroy_cred_label = lomac_destroy_label,
2838 .mpo_destroy_devfs_label = lomac_destroy_label,
2839 .mpo_destroy_ifnet_label = lomac_destroy_label,
2840 .mpo_destroy_inpcb_label = lomac_destroy_label,
2841 .mpo_destroy_ipq_label = lomac_destroy_label,
2842 .mpo_destroy_mbuf_label = lomac_destroy_label,
2843 .mpo_destroy_mount_label = lomac_destroy_label,
2844 .mpo_destroy_pipe_label = lomac_destroy_label,
2845 .mpo_destroy_proc_label = lomac_destroy_proc_label,
2846 .mpo_destroy_syncache_label = lomac_destroy_label,
2847 .mpo_destroy_socket_label = lomac_destroy_label,
2848 .mpo_destroy_socket_peer_label = lomac_destroy_label,
2849 .mpo_destroy_vnode_label = lomac_destroy_label,
2850 .mpo_copy_cred_label = lomac_copy_label,
2851 .mpo_copy_ifnet_label = lomac_copy_label,
2852 .mpo_copy_mbuf_label = lomac_copy_label,
2853 .mpo_copy_pipe_label = lomac_copy_label,
2854 .mpo_copy_socket_label = lomac_copy_label,
2855 .mpo_copy_vnode_label = lomac_copy_label,
2856 .mpo_externalize_cred_label = lomac_externalize_label,
2857 .mpo_externalize_ifnet_label = lomac_externalize_label,
2858 .mpo_externalize_pipe_label = lomac_externalize_label,
2859 .mpo_externalize_socket_label = lomac_externalize_label,
2860 .mpo_externalize_socket_peer_label = lomac_externalize_label,
2861 .mpo_externalize_vnode_label = lomac_externalize_label,
2862 .mpo_internalize_cred_label = lomac_internalize_label,
2863 .mpo_internalize_ifnet_label = lomac_internalize_label,
2864 .mpo_internalize_pipe_label = lomac_internalize_label,
2865 .mpo_internalize_socket_label = lomac_internalize_label,
2866 .mpo_internalize_vnode_label = lomac_internalize_label,
2867 .mpo_create_devfs_device = lomac_create_devfs_device,
2868 .mpo_create_devfs_directory = lomac_create_devfs_directory,
2869 .mpo_create_devfs_symlink = lomac_create_devfs_symlink,
2870 .mpo_create_mount = lomac_create_mount,
2871 .mpo_relabel_vnode = lomac_relabel_vnode,
2872 .mpo_update_devfs = lomac_update_devfs,
2873 .mpo_associate_vnode_devfs = lomac_associate_vnode_devfs,
2874 .mpo_associate_vnode_extattr = lomac_associate_vnode_extattr,
2875 .mpo_associate_vnode_singlelabel = lomac_associate_vnode_singlelabel,
2876 .mpo_create_vnode_extattr = lomac_create_vnode_extattr,
2877 .mpo_setlabel_vnode_extattr = lomac_setlabel_vnode_extattr,
2878 .mpo_create_mbuf_from_socket = lomac_create_mbuf_from_socket,
2879 .mpo_create_mbuf_from_syncache = lomac_create_mbuf_from_syncache,
2880 .mpo_create_pipe = lomac_create_pipe,
2881 .mpo_create_socket = lomac_create_socket,
2882 .mpo_create_socket_from_socket = lomac_create_socket_from_socket,
2883 .mpo_relabel_pipe = lomac_relabel_pipe,
2884 .mpo_relabel_socket = lomac_relabel_socket,
2885 .mpo_set_socket_peer_from_mbuf = lomac_set_socket_peer_from_mbuf,
2886 .mpo_set_socket_peer_from_socket = lomac_set_socket_peer_from_socket,
2887 .mpo_create_bpfdesc = lomac_create_bpfdesc,
2888 .mpo_create_datagram_from_ipq = lomac_create_datagram_from_ipq,
2889 .mpo_create_fragment = lomac_create_fragment,
2890 .mpo_create_ifnet = lomac_create_ifnet,
2891 .mpo_create_inpcb_from_socket = lomac_create_inpcb_from_socket,
2892 .mpo_create_ipq = lomac_create_ipq,
2893 .mpo_create_mbuf_from_inpcb = lomac_create_mbuf_from_inpcb,
2894 .mpo_create_mbuf_linklayer = lomac_create_mbuf_linklayer,
2895 .mpo_create_mbuf_from_bpfdesc = lomac_create_mbuf_from_bpfdesc,
2896 .mpo_create_mbuf_from_ifnet = lomac_create_mbuf_from_ifnet,
2897 .mpo_create_mbuf_multicast_encap = lomac_create_mbuf_multicast_encap,
2898 .mpo_create_mbuf_netlayer = lomac_create_mbuf_netlayer,
2899 .mpo_fragment_match = lomac_fragment_match,
2900 .mpo_relabel_ifnet = lomac_relabel_ifnet,
2901 .mpo_update_ipq = lomac_update_ipq,
2902 .mpo_inpcb_sosetlabel = lomac_inpcb_sosetlabel,
2903 .mpo_execve_transition = lomac_execve_transition,
2904 .mpo_execve_will_transition = lomac_execve_will_transition,
2905 .mpo_create_proc0 = lomac_create_proc0,
2906 .mpo_create_proc1 = lomac_create_proc1,
2907 .mpo_relabel_cred = lomac_relabel_cred,
2908 .mpo_check_bpfdesc_receive = lomac_check_bpfdesc_receive,
2909 .mpo_check_cred_relabel = lomac_check_cred_relabel,
2910 .mpo_check_cred_visible = lomac_check_cred_visible,
2911 .mpo_check_ifnet_relabel = lomac_check_ifnet_relabel,
2912 .mpo_check_ifnet_transmit = lomac_check_ifnet_transmit,
2913 .mpo_check_inpcb_deliver = lomac_check_inpcb_deliver,
2914 .mpo_check_inpcb_visible = lomac_check_inpcb_visible,
2915 .mpo_check_kld_load = lomac_check_kld_load,
2916 .mpo_check_pipe_ioctl = lomac_check_pipe_ioctl,
2917 .mpo_check_pipe_read = lomac_check_pipe_read,
2918 .mpo_check_pipe_relabel = lomac_check_pipe_relabel,
2919 .mpo_check_pipe_write = lomac_check_pipe_write,
2920 .mpo_check_proc_debug = lomac_check_proc_debug,
2921 .mpo_check_proc_sched = lomac_check_proc_sched,
2922 .mpo_check_proc_signal = lomac_check_proc_signal,
2923 .mpo_check_socket_deliver = lomac_check_socket_deliver,
2924 .mpo_check_socket_relabel = lomac_check_socket_relabel,
2925 .mpo_check_socket_visible = lomac_check_socket_visible,
2926 .mpo_check_system_acct = lomac_check_system_acct,
2927 .mpo_check_system_auditctl = lomac_check_system_auditctl,
2928 .mpo_check_system_swapoff = lomac_check_system_swapoff,
2929 .mpo_check_system_swapon = lomac_check_system_swapon,
2930 .mpo_check_system_sysctl = lomac_check_system_sysctl,
2931 .mpo_check_vnode_access = lomac_check_vnode_open,
2932 .mpo_check_vnode_create = lomac_check_vnode_create,
2933 .mpo_check_vnode_deleteacl = lomac_check_vnode_deleteacl,
2934 .mpo_check_vnode_link = lomac_check_vnode_link,
2935 .mpo_check_vnode_mmap = lomac_check_vnode_mmap,
2936 .mpo_check_vnode_mmap_downgrade = lomac_check_vnode_mmap_downgrade,
2937 .mpo_check_vnode_open = lomac_check_vnode_open,
2938 .mpo_check_vnode_read = lomac_check_vnode_read,
2939 .mpo_check_vnode_relabel = lomac_check_vnode_relabel,
2940 .mpo_check_vnode_rename_from = lomac_check_vnode_rename_from,
2941 .mpo_check_vnode_rename_to = lomac_check_vnode_rename_to,
2942 .mpo_check_vnode_revoke = lomac_check_vnode_revoke,
2943 .mpo_check_vnode_setacl = lomac_check_vnode_setacl,
2944 .mpo_check_vnode_setextattr = lomac_check_vnode_setextattr,
2945 .mpo_check_vnode_setflags = lomac_check_vnode_setflags,
2946 .mpo_check_vnode_setmode = lomac_check_vnode_setmode,
2947 .mpo_check_vnode_setowner = lomac_check_vnode_setowner,
2948 .mpo_check_vnode_setutimes = lomac_check_vnode_setutimes,
2949 .mpo_check_vnode_unlink = lomac_check_vnode_unlink,
2950 .mpo_check_vnode_write = lomac_check_vnode_write,
2951 .mpo_thread_userret = lomac_thread_userret,
2952 .mpo_create_mbuf_from_firewall = lomac_create_mbuf_from_firewall,
2953 .mpo_priv_check = lomac_priv_check,
2954 };
2955
2956 MAC_POLICY_SET(&lomac_ops, mac_lomac, "TrustedBSD MAC/LOMAC",
2957 MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &lomac_slot);
Cache object: 9a012d6df961905e361cfe5a684c6873
|