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