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