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.6 2002/12/10 16:20:33 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_kse->ke_flags |= KEF_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 size_t buflen;
1061 int error;
1062
1063 source = SLOT(fslabel);
1064 dest = SLOT(vlabel);
1065
1066 buflen = sizeof(temp);
1067 bzero(&temp, buflen);
1068
1069 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE,
1070 MAC_LOMAC_EXTATTR_NAME, &buflen, (char *)&temp, curthread);
1071 if (error == ENOATTR || error == EOPNOTSUPP) {
1072 /* Fall back to the fslabel. */
1073 mac_lomac_copy_single(source, dest);
1074 return (0);
1075 } else if (error)
1076 return (error);
1077
1078 if (buflen != sizeof(temp)) {
1079 if (buflen != sizeof(temp) - sizeof(temp.ml_auxsingle)) {
1080 printf("mac_lomac_associate_vnode_extattr: bad size %d\n",
1081 buflen);
1082 return (EPERM);
1083 }
1084 bzero(&temp.ml_auxsingle, sizeof(temp.ml_auxsingle));
1085 buflen = sizeof(temp);
1086 (void)vn_extattr_set(vp, IO_NODELOCKED,
1087 MAC_LOMAC_EXTATTR_NAMESPACE, MAC_LOMAC_EXTATTR_NAME,
1088 buflen, (char *)&temp, curthread);
1089 }
1090 if (mac_lomac_valid(&temp) != 0) {
1091 printf("mac_lomac_associate_vnode_extattr: invalid\n");
1092 return (EPERM);
1093 }
1094 if ((temp.ml_flags & MAC_LOMAC_FLAGS_BOTH) != MAC_LOMAC_FLAG_SINGLE) {
1095 printf("mac_lomac_associate_vnode_extattr: not single\n");
1096 return (EPERM);
1097 }
1098
1099 mac_lomac_copy_single(&temp, dest);
1100 return (0);
1101 }
1102
1103 static void
1104 mac_lomac_associate_vnode_singlelabel(struct mount *mp,
1105 struct label *fslabel, struct vnode *vp, struct label *vlabel)
1106 {
1107 struct mac_lomac *source, *dest;
1108
1109 source = SLOT(fslabel);
1110 dest = SLOT(vlabel);
1111
1112 mac_lomac_copy_single(source, dest);
1113 }
1114
1115 static int
1116 mac_lomac_create_vnode_extattr(struct ucred *cred, struct mount *mp,
1117 struct label *fslabel, struct vnode *dvp, struct label *dlabel,
1118 struct vnode *vp, struct label *vlabel, struct componentname *cnp)
1119 {
1120 struct mac_lomac *source, *dest, *dir, temp;
1121 size_t buflen;
1122 int error;
1123
1124 buflen = sizeof(temp);
1125 bzero(&temp, buflen);
1126
1127 source = SLOT(&cred->cr_label);
1128 dest = SLOT(vlabel);
1129 dir = SLOT(dlabel);
1130 if (dir->ml_flags & MAC_LOMAC_FLAG_AUX) {
1131 mac_lomac_copy_auxsingle(dir, &temp);
1132 mac_lomac_set_single(&temp, dir->ml_auxsingle.mle_type,
1133 dir->ml_auxsingle.mle_grade);
1134 } else {
1135 mac_lomac_copy_single(source, &temp);
1136 }
1137
1138 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE,
1139 MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread);
1140 if (error == 0)
1141 mac_lomac_copy(&temp, dest);
1142 return (error);
1143 }
1144
1145 static int
1146 mac_lomac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
1147 struct label *vlabel, struct label *intlabel)
1148 {
1149 struct mac_lomac *source, temp;
1150 size_t buflen;
1151 int error;
1152
1153 buflen = sizeof(temp);
1154 bzero(&temp, buflen);
1155
1156 source = SLOT(intlabel);
1157 if ((source->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0)
1158 return (0);
1159
1160 mac_lomac_copy_single(source, &temp);
1161 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE,
1162 MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread);
1163 return (error);
1164 }
1165
1166 /*
1167 * Labeling event operations: IPC object.
1168 */
1169 static void
1170 mac_lomac_create_mbuf_from_socket(struct socket *so, struct label *socketlabel,
1171 struct mbuf *m, struct label *mbuflabel)
1172 {
1173 struct mac_lomac *source, *dest;
1174
1175 source = SLOT(socketlabel);
1176 dest = SLOT(mbuflabel);
1177
1178 mac_lomac_copy_single(source, dest);
1179 }
1180
1181 static void
1182 mac_lomac_create_socket(struct ucred *cred, struct socket *socket,
1183 struct label *socketlabel)
1184 {
1185 struct mac_lomac *source, *dest;
1186
1187 source = SLOT(&cred->cr_label);
1188 dest = SLOT(socketlabel);
1189
1190 mac_lomac_copy_single(source, dest);
1191 }
1192
1193 static void
1194 mac_lomac_create_pipe(struct ucred *cred, struct pipe *pipe,
1195 struct label *pipelabel)
1196 {
1197 struct mac_lomac *source, *dest;
1198
1199 source = SLOT(&cred->cr_label);
1200 dest = SLOT(pipelabel);
1201
1202 mac_lomac_copy_single(source, dest);
1203 }
1204
1205 static void
1206 mac_lomac_create_socket_from_socket(struct socket *oldsocket,
1207 struct label *oldsocketlabel, struct socket *newsocket,
1208 struct label *newsocketlabel)
1209 {
1210 struct mac_lomac *source, *dest;
1211
1212 source = SLOT(oldsocketlabel);
1213 dest = SLOT(newsocketlabel);
1214
1215 mac_lomac_copy_single(source, dest);
1216 }
1217
1218 static void
1219 mac_lomac_relabel_socket(struct ucred *cred, struct socket *socket,
1220 struct label *socketlabel, struct label *newlabel)
1221 {
1222 struct mac_lomac *source, *dest;
1223
1224 source = SLOT(newlabel);
1225 dest = SLOT(socketlabel);
1226
1227 try_relabel(source, dest);
1228 }
1229
1230 static void
1231 mac_lomac_relabel_pipe(struct ucred *cred, struct pipe *pipe,
1232 struct label *pipelabel, struct label *newlabel)
1233 {
1234 struct mac_lomac *source, *dest;
1235
1236 source = SLOT(newlabel);
1237 dest = SLOT(pipelabel);
1238
1239 try_relabel(source, dest);
1240 }
1241
1242 static void
1243 mac_lomac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel,
1244 struct socket *socket, struct label *socketpeerlabel)
1245 {
1246 struct mac_lomac *source, *dest;
1247
1248 source = SLOT(mbuflabel);
1249 dest = SLOT(socketpeerlabel);
1250
1251 mac_lomac_copy_single(source, dest);
1252 }
1253
1254 /*
1255 * Labeling event operations: network objects.
1256 */
1257 static void
1258 mac_lomac_set_socket_peer_from_socket(struct socket *oldsocket,
1259 struct label *oldsocketlabel, struct socket *newsocket,
1260 struct label *newsocketpeerlabel)
1261 {
1262 struct mac_lomac *source, *dest;
1263
1264 source = SLOT(oldsocketlabel);
1265 dest = SLOT(newsocketpeerlabel);
1266
1267 mac_lomac_copy_single(source, dest);
1268 }
1269
1270 static void
1271 mac_lomac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d,
1272 struct label *bpflabel)
1273 {
1274 struct mac_lomac *source, *dest;
1275
1276 source = SLOT(&cred->cr_label);
1277 dest = SLOT(bpflabel);
1278
1279 mac_lomac_copy_single(source, dest);
1280 }
1281
1282 static void
1283 mac_lomac_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel)
1284 {
1285 char tifname[IFNAMSIZ], ifname[IFNAMSIZ], *p, *q;
1286 char tiflist[sizeof(trusted_interfaces)];
1287 struct mac_lomac *dest;
1288 int len, grade;
1289
1290 dest = SLOT(ifnetlabel);
1291
1292 if (ifnet->if_type == IFT_LOOP) {
1293 grade = MAC_LOMAC_TYPE_EQUAL;
1294 goto set;
1295 }
1296
1297 if (trust_all_interfaces) {
1298 grade = MAC_LOMAC_TYPE_HIGH;
1299 goto set;
1300 }
1301
1302 grade = MAC_LOMAC_TYPE_LOW;
1303
1304 if (trusted_interfaces[0] == '\0' ||
1305 !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
1306 goto set;
1307
1308 bzero(tiflist, sizeof(tiflist));
1309 for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
1310 if(*p != ' ' && *p != '\t')
1311 *q = *p;
1312
1313 snprintf(ifname, IFNAMSIZ, "%s%d", ifnet->if_name, ifnet->if_unit);
1314
1315 for (p = q = tiflist;; p++) {
1316 if (*p == ',' || *p == '\0') {
1317 len = p - q;
1318 if (len < IFNAMSIZ) {
1319 bzero(tifname, sizeof(tifname));
1320 bcopy(q, tifname, len);
1321 if (strcmp(tifname, ifname) == 0) {
1322 grade = MAC_LOMAC_TYPE_HIGH;
1323 break;
1324 }
1325 }
1326 else {
1327 *p = '\0';
1328 printf("MAC/LOMAC warning: interface name "
1329 "\"%s\" is too long (must be < %d)\n",
1330 q, IFNAMSIZ);
1331 }
1332 if (*p == '\0')
1333 break;
1334 q = p + 1;
1335 }
1336 }
1337 set:
1338 mac_lomac_set_single(dest, grade, 0);
1339 mac_lomac_set_range(dest, grade, 0, grade, 0);
1340 }
1341
1342 static void
1343 mac_lomac_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1344 struct ipq *ipq, struct label *ipqlabel)
1345 {
1346 struct mac_lomac *source, *dest;
1347
1348 source = SLOT(fragmentlabel);
1349 dest = SLOT(ipqlabel);
1350
1351 mac_lomac_copy_single(source, dest);
1352 }
1353
1354 static void
1355 mac_lomac_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
1356 struct mbuf *datagram, struct label *datagramlabel)
1357 {
1358 struct mac_lomac *source, *dest;
1359
1360 source = SLOT(ipqlabel);
1361 dest = SLOT(datagramlabel);
1362
1363 /* Just use the head, since we require them all to match. */
1364 mac_lomac_copy_single(source, dest);
1365 }
1366
1367 static void
1368 mac_lomac_create_fragment(struct mbuf *datagram, struct label *datagramlabel,
1369 struct mbuf *fragment, struct label *fragmentlabel)
1370 {
1371 struct mac_lomac *source, *dest;
1372
1373 source = SLOT(datagramlabel);
1374 dest = SLOT(fragmentlabel);
1375
1376 mac_lomac_copy_single(source, dest);
1377 }
1378
1379 static void
1380 mac_lomac_create_mbuf_from_mbuf(struct mbuf *oldmbuf,
1381 struct label *oldmbuflabel, struct mbuf *newmbuf,
1382 struct label *newmbuflabel)
1383 {
1384 struct mac_lomac *source, *dest;
1385
1386 source = SLOT(oldmbuflabel);
1387 dest = SLOT(newmbuflabel);
1388
1389 /*
1390 * Because the source mbuf may not yet have been "created",
1391 * just initialized, we do a conditional copy. Since we don't
1392 * allow mbufs to have ranges, do a KASSERT to make sure that
1393 * doesn't happen.
1394 */
1395 KASSERT((source->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0,
1396 ("mac_lomac_create_mbuf_from_mbuf: source mbuf has range"));
1397 mac_lomac_copy(source, dest);
1398 }
1399
1400 static void
1401 mac_lomac_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel,
1402 struct mbuf *mbuf, struct label *mbuflabel)
1403 {
1404 struct mac_lomac *dest;
1405
1406 dest = SLOT(mbuflabel);
1407
1408 mac_lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0);
1409 }
1410
1411 static void
1412 mac_lomac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel,
1413 struct mbuf *mbuf, struct label *mbuflabel)
1414 {
1415 struct mac_lomac *source, *dest;
1416
1417 source = SLOT(bpflabel);
1418 dest = SLOT(mbuflabel);
1419
1420 mac_lomac_copy_single(source, dest);
1421 }
1422
1423 static void
1424 mac_lomac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel,
1425 struct mbuf *m, struct label *mbuflabel)
1426 {
1427 struct mac_lomac *source, *dest;
1428
1429 source = SLOT(ifnetlabel);
1430 dest = SLOT(mbuflabel);
1431
1432 mac_lomac_copy_single(source, dest);
1433 }
1434
1435 static void
1436 mac_lomac_create_mbuf_multicast_encap(struct mbuf *oldmbuf,
1437 struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel,
1438 struct mbuf *newmbuf, struct label *newmbuflabel)
1439 {
1440 struct mac_lomac *source, *dest;
1441
1442 source = SLOT(oldmbuflabel);
1443 dest = SLOT(newmbuflabel);
1444
1445 mac_lomac_copy_single(source, dest);
1446 }
1447
1448 static void
1449 mac_lomac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel,
1450 struct mbuf *newmbuf, struct label *newmbuflabel)
1451 {
1452 struct mac_lomac *source, *dest;
1453
1454 source = SLOT(oldmbuflabel);
1455 dest = SLOT(newmbuflabel);
1456
1457 mac_lomac_copy_single(source, dest);
1458 }
1459
1460 static int
1461 mac_lomac_fragment_match(struct mbuf *fragment, struct label *fragmentlabel,
1462 struct ipq *ipq, struct label *ipqlabel)
1463 {
1464 struct mac_lomac *a, *b;
1465
1466 a = SLOT(ipqlabel);
1467 b = SLOT(fragmentlabel);
1468
1469 return (mac_lomac_equal_single(a, b));
1470 }
1471
1472 static void
1473 mac_lomac_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
1474 struct label *ifnetlabel, struct label *newlabel)
1475 {
1476 struct mac_lomac *source, *dest;
1477
1478 source = SLOT(newlabel);
1479 dest = SLOT(ifnetlabel);
1480
1481 try_relabel(source, dest);
1482 }
1483
1484 static void
1485 mac_lomac_update_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1486 struct ipq *ipq, struct label *ipqlabel)
1487 {
1488
1489 /* NOOP: we only accept matching labels, so no need to update */
1490 }
1491
1492 /*
1493 * Labeling event operations: processes.
1494 */
1495 static void
1496 mac_lomac_create_cred(struct ucred *cred_parent, struct ucred *cred_child)
1497 {
1498 struct mac_lomac *source, *dest;
1499
1500 source = SLOT(&cred_parent->cr_label);
1501 dest = SLOT(&cred_child->cr_label);
1502
1503 mac_lomac_copy_single(source, dest);
1504 mac_lomac_copy_range(source, dest);
1505 }
1506
1507 static void
1508 mac_lomac_execve_transition(struct ucred *old, struct ucred *new,
1509 struct vnode *vp, struct label *vnodelabel,
1510 struct label *interpvnodelabel, struct image_params *imgp,
1511 struct label *execlabel)
1512 {
1513 struct mac_lomac *source, *dest, *obj, *robj;
1514
1515 source = SLOT(&old->cr_label);
1516 dest = SLOT(&new->cr_label);
1517 obj = SLOT(vnodelabel);
1518 robj = interpvnodelabel != NULL ? SLOT(interpvnodelabel) : obj;
1519
1520 mac_lomac_copy(source, dest);
1521 /*
1522 * If there's an auxiliary label on the real object, respect it
1523 * and assume that this level should be assumed immediately if
1524 * a higher level is currently in place.
1525 */
1526 if (robj->ml_flags & MAC_LOMAC_FLAG_AUX &&
1527 !mac_lomac_dominate_element(&robj->ml_auxsingle, &dest->ml_single)
1528 && mac_lomac_auxsingle_in_range(robj, dest))
1529 mac_lomac_set_single(dest, robj->ml_auxsingle.mle_type,
1530 robj->ml_auxsingle.mle_grade);
1531 /*
1532 * Restructuring to use the execve transitioning mechanism
1533 * instead of the normal demotion mechanism here would be
1534 * difficult, so just copy the label over and perform standard
1535 * demotion. This is also non-optimal because it will result
1536 * in the intermediate label "new" being created and immediately
1537 * recycled.
1538 */
1539 if (mac_lomac_enabled && revocation_enabled &&
1540 !mac_lomac_dominate_single(obj, source))
1541 (void)maybe_demote(source, obj, "executing", "file", vp);
1542 }
1543
1544 static int
1545 mac_lomac_execve_will_transition(struct ucred *old, struct vnode *vp,
1546 struct label *vnodelabel, struct label *interpvnodelabel,
1547 struct image_params *imgp, struct label *execlabel)
1548 {
1549 struct mac_lomac *subj, *obj, *robj;
1550
1551 if (!mac_lomac_enabled || !revocation_enabled)
1552 return (0);
1553
1554 subj = SLOT(&old->cr_label);
1555 obj = SLOT(vnodelabel);
1556 robj = interpvnodelabel != NULL ? SLOT(interpvnodelabel) : obj;
1557
1558 return ((robj->ml_flags & MAC_LOMAC_FLAG_AUX &&
1559 !mac_lomac_dominate_element(&robj->ml_auxsingle, &subj->ml_single)
1560 && mac_lomac_auxsingle_in_range(robj, subj)) ||
1561 !mac_lomac_dominate_single(obj, subj));
1562 }
1563
1564 static void
1565 mac_lomac_create_proc0(struct ucred *cred)
1566 {
1567 struct mac_lomac *dest;
1568
1569 dest = SLOT(&cred->cr_label);
1570
1571 mac_lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0);
1572 mac_lomac_set_range(dest, MAC_LOMAC_TYPE_LOW, 0, MAC_LOMAC_TYPE_HIGH,
1573 0);
1574 }
1575
1576 static void
1577 mac_lomac_create_proc1(struct ucred *cred)
1578 {
1579 struct mac_lomac *dest;
1580
1581 dest = SLOT(&cred->cr_label);
1582
1583 mac_lomac_set_single(dest, MAC_LOMAC_TYPE_HIGH, 0);
1584 mac_lomac_set_range(dest, MAC_LOMAC_TYPE_LOW, 0, MAC_LOMAC_TYPE_HIGH,
1585 0);
1586 }
1587
1588 static void
1589 mac_lomac_relabel_cred(struct ucred *cred, struct label *newlabel)
1590 {
1591 struct mac_lomac *source, *dest;
1592
1593 source = SLOT(newlabel);
1594 dest = SLOT(&cred->cr_label);
1595
1596 try_relabel(source, dest);
1597 }
1598
1599 /*
1600 * Access control checks.
1601 */
1602 static int
1603 mac_lomac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
1604 struct ifnet *ifnet, struct label *ifnetlabel)
1605 {
1606 struct mac_lomac *a, *b;
1607
1608 if (!mac_lomac_enabled)
1609 return (0);
1610
1611 a = SLOT(bpflabel);
1612 b = SLOT(ifnetlabel);
1613
1614 if (mac_lomac_equal_single(a, b))
1615 return (0);
1616 return (EACCES);
1617 }
1618
1619 static int
1620 mac_lomac_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1621 {
1622 struct mac_lomac *subj, *new;
1623 int error;
1624
1625 subj = SLOT(&cred->cr_label);
1626 new = SLOT(newlabel);
1627
1628 /*
1629 * If there is a LOMAC label update for the credential, it may
1630 * be an update of the single, range, or both.
1631 */
1632 error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH);
1633 if (error)
1634 return (error);
1635
1636 /*
1637 * If the LOMAC label is to be changed, authorize as appropriate.
1638 */
1639 if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) {
1640 /*
1641 * To change the LOMAC single label on a credential, the
1642 * new single label must be in the current range.
1643 */
1644 if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE &&
1645 !mac_lomac_single_in_range(new, subj))
1646 return (EPERM);
1647
1648 /*
1649 * To change the LOMAC range on a credential, the new
1650 * range label must be in the current range.
1651 */
1652 if (new->ml_flags & MAC_LOMAC_FLAG_RANGE &&
1653 !mac_lomac_range_in_range(new, subj))
1654 return (EPERM);
1655
1656 /*
1657 * To have EQUAL in any component of the new credential
1658 * LOMAC label, the subject must already have EQUAL in
1659 * their label.
1660 */
1661 if (mac_lomac_contains_equal(new)) {
1662 error = mac_lomac_subject_privileged(subj);
1663 if (error)
1664 return (error);
1665 }
1666
1667 /*
1668 * XXXMAC: Additional consistency tests regarding the
1669 * single and range of the new label might be performed
1670 * here.
1671 */
1672 }
1673
1674 return (0);
1675 }
1676
1677 static int
1678 mac_lomac_check_cred_visible(struct ucred *u1, struct ucred *u2)
1679 {
1680 struct mac_lomac *subj, *obj;
1681
1682 if (!mac_lomac_enabled)
1683 return (0);
1684
1685 subj = SLOT(&u1->cr_label);
1686 obj = SLOT(&u2->cr_label);
1687
1688 /* XXX: range */
1689 if (!mac_lomac_dominate_single(obj, subj))
1690 return (ESRCH);
1691
1692 return (0);
1693 }
1694
1695 static int
1696 mac_lomac_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
1697 struct label *ifnetlabel, struct label *newlabel)
1698 {
1699 struct mac_lomac *subj, *new;
1700 int error;
1701
1702 subj = SLOT(&cred->cr_label);
1703 new = SLOT(newlabel);
1704
1705 /*
1706 * If there is a LOMAC label update for the interface, it may
1707 * be an update of the single, range, or both.
1708 */
1709 error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH);
1710 if (error)
1711 return (error);
1712
1713 /*
1714 * Relabling network interfaces requires LOMAC privilege.
1715 */
1716 error = mac_lomac_subject_privileged(subj);
1717 if (error)
1718 return (error);
1719
1720 /*
1721 * If the LOMAC label is to be changed, authorize as appropriate.
1722 */
1723 if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) {
1724 /*
1725 * Rely on the traditional superuser status for the LOMAC
1726 * interface relabel requirements. XXXMAC: This will go
1727 * away.
1728 */
1729 error = suser_cred(cred, 0);
1730 if (error)
1731 return (EPERM);
1732
1733 /*
1734 * XXXMAC: Additional consistency tests regarding the single
1735 * and the range of the new label might be performed here.
1736 */
1737 }
1738
1739 return (0);
1740 }
1741
1742 static int
1743 mac_lomac_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1744 struct mbuf *m, struct label *mbuflabel)
1745 {
1746 struct mac_lomac *p, *i;
1747
1748 if (!mac_lomac_enabled)
1749 return (0);
1750
1751 p = SLOT(mbuflabel);
1752 i = SLOT(ifnetlabel);
1753
1754 return (mac_lomac_single_in_range(p, i) ? 0 : EACCES);
1755 }
1756
1757 static int
1758 mac_lomac_check_kld_load(struct ucred *cred, struct vnode *vp,
1759 struct label *label)
1760 {
1761 struct mac_lomac *subj, *obj;
1762
1763 if (!mac_lomac_enabled)
1764 return (0);
1765
1766 subj = SLOT(&cred->cr_label);
1767 obj = SLOT(label);
1768
1769 if (mac_lomac_subject_privileged(subj))
1770 return (EPERM);
1771
1772 if (!mac_lomac_high_single(obj))
1773 return (EACCES);
1774
1775 return (0);
1776 }
1777
1778 static int
1779 mac_lomac_check_kld_unload(struct ucred *cred)
1780 {
1781 struct mac_lomac *subj;
1782
1783 if (!mac_lomac_enabled)
1784 return (0);
1785
1786 subj = SLOT(&cred->cr_label);
1787
1788 if (mac_lomac_subject_privileged(subj))
1789 return (EPERM);
1790
1791 return (0);
1792 }
1793
1794 static int
1795 mac_lomac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe,
1796 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1797 {
1798
1799 if(!mac_lomac_enabled)
1800 return (0);
1801
1802 /* XXX: This will be implemented soon... */
1803
1804 return (0);
1805 }
1806
1807 static int
1808 mac_lomac_check_pipe_read(struct ucred *cred, struct pipe *pipe,
1809 struct label *pipelabel)
1810 {
1811 struct mac_lomac *subj, *obj;
1812
1813 if (!mac_lomac_enabled)
1814 return (0);
1815
1816 subj = SLOT(&cred->cr_label);
1817 obj = SLOT((pipelabel));
1818
1819 if (!mac_lomac_dominate_single(obj, subj))
1820 return (maybe_demote(subj, obj, "reading", "pipe", NULL));
1821
1822 return (0);
1823 }
1824
1825 static int
1826 mac_lomac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
1827 struct label *pipelabel, struct label *newlabel)
1828 {
1829 struct mac_lomac *subj, *obj, *new;
1830 int error;
1831
1832 new = SLOT(newlabel);
1833 subj = SLOT(&cred->cr_label);
1834 obj = SLOT(pipelabel);
1835
1836 /*
1837 * If there is a LOMAC label update for a pipe, it must be a
1838 * single update.
1839 */
1840 error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE);
1841 if (error)
1842 return (error);
1843
1844 /*
1845 * To perform a relabel of a pipe (LOMAC label or not), LOMAC must
1846 * authorize the relabel.
1847 */
1848 if (!mac_lomac_single_in_range(obj, subj))
1849 return (EPERM);
1850
1851 /*
1852 * If the LOMAC label is to be changed, authorize as appropriate.
1853 */
1854 if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
1855 /*
1856 * To change the LOMAC label on a pipe, the new pipe label
1857 * must be in the subject range.
1858 */
1859 if (!mac_lomac_single_in_range(new, subj))
1860 return (EPERM);
1861
1862 /*
1863 * To change the LOMAC label on a pipe to be EQUAL, the
1864 * subject must have appropriate privilege.
1865 */
1866 if (mac_lomac_contains_equal(new)) {
1867 error = mac_lomac_subject_privileged(subj);
1868 if (error)
1869 return (error);
1870 }
1871 }
1872
1873 return (0);
1874 }
1875
1876 static int
1877 mac_lomac_check_pipe_write(struct ucred *cred, struct pipe *pipe,
1878 struct label *pipelabel)
1879 {
1880 struct mac_lomac *subj, *obj;
1881
1882 if (!mac_lomac_enabled)
1883 return (0);
1884
1885 subj = SLOT(&cred->cr_label);
1886 obj = SLOT((pipelabel));
1887
1888 if (!mac_lomac_subject_dominate(subj, obj))
1889 return (EACCES);
1890
1891 return (0);
1892 }
1893
1894 static int
1895 mac_lomac_check_proc_debug(struct ucred *cred, struct proc *proc)
1896 {
1897 struct mac_lomac *subj, *obj;
1898
1899 if (!mac_lomac_enabled)
1900 return (0);
1901
1902 subj = SLOT(&cred->cr_label);
1903 obj = SLOT(&proc->p_ucred->cr_label);
1904
1905 /* XXX: range checks */
1906 if (!mac_lomac_dominate_single(obj, subj))
1907 return (ESRCH);
1908 if (!mac_lomac_subject_dominate(subj, obj))
1909 return (EACCES);
1910
1911 return (0);
1912 }
1913
1914 static int
1915 mac_lomac_check_proc_sched(struct ucred *cred, struct proc *proc)
1916 {
1917 struct mac_lomac *subj, *obj;
1918
1919 if (!mac_lomac_enabled)
1920 return (0);
1921
1922 subj = SLOT(&cred->cr_label);
1923 obj = SLOT(&proc->p_ucred->cr_label);
1924
1925 /* XXX: range checks */
1926 if (!mac_lomac_dominate_single(obj, subj))
1927 return (ESRCH);
1928 if (!mac_lomac_subject_dominate(subj, obj))
1929 return (EACCES);
1930
1931 return (0);
1932 }
1933
1934 static int
1935 mac_lomac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
1936 {
1937 struct mac_lomac *subj, *obj;
1938
1939 if (!mac_lomac_enabled)
1940 return (0);
1941
1942 subj = SLOT(&cred->cr_label);
1943 obj = SLOT(&proc->p_ucred->cr_label);
1944
1945 /* XXX: range checks */
1946 if (!mac_lomac_dominate_single(obj, subj))
1947 return (ESRCH);
1948 if (!mac_lomac_subject_dominate(subj, obj))
1949 return (EACCES);
1950
1951 return (0);
1952 }
1953
1954 static int
1955 mac_lomac_check_socket_deliver(struct socket *so, struct label *socketlabel,
1956 struct mbuf *m, struct label *mbuflabel)
1957 {
1958 struct mac_lomac *p, *s;
1959
1960 if (!mac_lomac_enabled)
1961 return (0);
1962
1963 p = SLOT(mbuflabel);
1964 s = SLOT(socketlabel);
1965
1966 return (mac_lomac_equal_single(p, s) ? 0 : EACCES);
1967 }
1968
1969 static int
1970 mac_lomac_check_socket_relabel(struct ucred *cred, struct socket *socket,
1971 struct label *socketlabel, struct label *newlabel)
1972 {
1973 struct mac_lomac *subj, *obj, *new;
1974 int error;
1975
1976 new = SLOT(newlabel);
1977 subj = SLOT(&cred->cr_label);
1978 obj = SLOT(socketlabel);
1979
1980 /*
1981 * If there is a LOMAC label update for the socket, it may be
1982 * an update of single.
1983 */
1984 error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE);
1985 if (error)
1986 return (error);
1987
1988 /*
1989 * To relabel a socket, the old socket single must be in the subject
1990 * range.
1991 */
1992 if (!mac_lomac_single_in_range(obj, subj))
1993 return (EPERM);
1994
1995 /*
1996 * If the LOMAC label is to be changed, authorize as appropriate.
1997 */
1998 if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
1999 /*
2000 * To relabel a socket, the new socket single must be in
2001 * the subject range.
2002 */
2003 if (!mac_lomac_single_in_range(new, subj))
2004 return (EPERM);
2005
2006 /*
2007 * To change the LOMAC label on the socket to contain EQUAL,
2008 * the subject must have appropriate privilege.
2009 */
2010 if (mac_lomac_contains_equal(new)) {
2011 error = mac_lomac_subject_privileged(subj);
2012 if (error)
2013 return (error);
2014 }
2015 }
2016
2017 return (0);
2018 }
2019
2020 static int
2021 mac_lomac_check_socket_visible(struct ucred *cred, struct socket *socket,
2022 struct label *socketlabel)
2023 {
2024 struct mac_lomac *subj, *obj;
2025
2026 if (!mac_lomac_enabled)
2027 return (0);
2028
2029 subj = SLOT(&cred->cr_label);
2030 obj = SLOT(socketlabel);
2031
2032 if (!mac_lomac_dominate_single(obj, subj))
2033 return (ENOENT);
2034
2035 return (0);
2036 }
2037
2038 static int
2039 mac_lomac_check_system_swapon(struct ucred *cred, struct vnode *vp,
2040 struct label *label)
2041 {
2042 struct mac_lomac *subj, *obj;
2043
2044 if (!mac_lomac_enabled)
2045 return (0);
2046
2047 subj = SLOT(&cred->cr_label);
2048 obj = SLOT(label);
2049
2050 if (mac_lomac_subject_privileged(subj))
2051 return (EPERM);
2052
2053 if (!mac_lomac_high_single(obj))
2054 return (EACCES);
2055
2056 return (0);
2057 }
2058
2059 static int
2060 mac_lomac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
2061 void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen)
2062 {
2063 struct mac_lomac *subj;
2064
2065 if (!mac_lomac_enabled)
2066 return (0);
2067
2068 subj = SLOT(&cred->cr_label);
2069
2070 /*
2071 * In general, treat sysctl variables as lomac/high, but also
2072 * require privilege to change them, since they are a
2073 * communications channel between grades. Exempt MIB
2074 * queries from this due to undocmented sysctl magic.
2075 * XXXMAC: This probably requires some more review.
2076 */
2077 if (new != NULL) {
2078 if (namelen > 0 && name[0] == 0)
2079 return (0);
2080
2081 #ifdef notdef
2082 if (!mac_lomac_subject_dominate_high(subj))
2083 return (EACCES);
2084 #endif
2085
2086 if (mac_lomac_subject_privileged(subj))
2087 return (EPERM);
2088 }
2089
2090 return (0);
2091 }
2092
2093 static int
2094 mac_lomac_check_vnode_create(struct ucred *cred, struct vnode *dvp,
2095 struct label *dlabel, struct componentname *cnp, struct vattr *vap)
2096 {
2097 struct mac_lomac *subj, *obj;
2098
2099 if (!mac_lomac_enabled)
2100 return (0);
2101
2102 subj = SLOT(&cred->cr_label);
2103 obj = SLOT(dlabel);
2104
2105 if (!mac_lomac_subject_dominate(subj, obj))
2106 return (EACCES);
2107 if (obj->ml_flags & MAC_LOMAC_FLAG_AUX &&
2108 !mac_lomac_dominate_element(&subj->ml_single, &obj->ml_auxsingle))
2109 return (EACCES);
2110
2111 return (0);
2112 }
2113
2114 static int
2115 mac_lomac_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
2116 struct label *dlabel, struct vnode *vp, struct label *label,
2117 struct componentname *cnp)
2118 {
2119 struct mac_lomac *subj, *obj;
2120
2121 if (!mac_lomac_enabled)
2122 return (0);
2123
2124 subj = SLOT(&cred->cr_label);
2125 obj = SLOT(dlabel);
2126
2127 if (!mac_lomac_subject_dominate(subj, obj))
2128 return (EACCES);
2129
2130 obj = SLOT(label);
2131
2132 if (!mac_lomac_subject_dominate(subj, obj))
2133 return (EACCES);
2134
2135 return (0);
2136 }
2137
2138 static int
2139 mac_lomac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
2140 struct label *label, acl_type_t type)
2141 {
2142 struct mac_lomac *subj, *obj;
2143
2144 if (!mac_lomac_enabled)
2145 return (0);
2146
2147 subj = SLOT(&cred->cr_label);
2148 obj = SLOT(label);
2149
2150 if (!mac_lomac_subject_dominate(subj, obj))
2151 return (EACCES);
2152
2153 return (0);
2154 }
2155
2156 static int
2157 mac_lomac_check_vnode_link(struct ucred *cred, struct vnode *dvp,
2158 struct label *dlabel, struct vnode *vp, struct label *label,
2159 struct componentname *cnp)
2160 {
2161 struct mac_lomac *subj, *obj;
2162
2163 if (!mac_lomac_enabled)
2164 return (0);
2165
2166 subj = SLOT(&cred->cr_label);
2167 obj = SLOT(dlabel);
2168
2169 if (!mac_lomac_subject_dominate(subj, obj))
2170 return (EACCES);
2171
2172 obj = SLOT(label);
2173
2174 if (!mac_lomac_subject_dominate(subj, obj))
2175 return (EACCES);
2176
2177 return (0);
2178 }
2179
2180 static int
2181 mac_lomac_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
2182 struct label *label, int prot)
2183 {
2184 struct mac_lomac *subj, *obj;
2185
2186 /*
2187 * Rely on the use of open()-time protections to handle
2188 * non-revocation cases.
2189 */
2190 if (!mac_lomac_enabled)
2191 return (0);
2192
2193 subj = SLOT(&cred->cr_label);
2194 obj = SLOT(label);
2195
2196 if (prot & VM_PROT_WRITE) {
2197 if (!mac_lomac_subject_dominate(subj, obj))
2198 return (EACCES);
2199 }
2200 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2201 if (!mac_lomac_dominate_single(obj, subj))
2202 return (maybe_demote(subj, obj, "mapping", "file", vp));
2203 }
2204
2205 return (0);
2206 }
2207
2208 static int
2209 mac_lomac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp,
2210 struct label *label, int prot)
2211 {
2212 struct mac_lomac *subj, *obj;
2213
2214 /*
2215 * Rely on the use of open()-time protections to handle
2216 * non-revocation cases.
2217 */
2218 if (!mac_lomac_enabled || !revocation_enabled)
2219 return (0);
2220
2221 subj = SLOT(&cred->cr_label);
2222 obj = SLOT(label);
2223
2224 if (prot & VM_PROT_WRITE) {
2225 if (!mac_lomac_subject_dominate(subj, obj))
2226 return (EACCES);
2227 }
2228 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2229 if (!mac_lomac_dominate_single(obj, subj))
2230 return (EACCES);
2231 }
2232
2233 return (0);
2234 }
2235
2236 static void
2237 mac_lomac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp,
2238 struct label *label, /* XXX vm_prot_t */ int *prot)
2239 {
2240 struct mac_lomac *subj, *obj;
2241
2242 /*
2243 * Rely on the use of open()-time protections to handle
2244 * non-revocation cases.
2245 */
2246 if (!mac_lomac_enabled || !revocation_enabled)
2247 return;
2248
2249 subj = SLOT(&cred->cr_label);
2250 obj = SLOT(label);
2251
2252 if (!mac_lomac_subject_dominate(subj, obj))
2253 *prot &= ~VM_PROT_WRITE;
2254 }
2255
2256 static int
2257 mac_lomac_check_vnode_open(struct ucred *cred, struct vnode *vp,
2258 struct label *vnodelabel, int acc_mode)
2259 {
2260 struct mac_lomac *subj, *obj;
2261
2262 if (!mac_lomac_enabled)
2263 return (0);
2264
2265 subj = SLOT(&cred->cr_label);
2266 obj = SLOT(vnodelabel);
2267
2268 /* XXX privilege override for admin? */
2269 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2270 if (!mac_lomac_subject_dominate(subj, obj))
2271 return (EACCES);
2272 }
2273
2274 return (0);
2275 }
2276
2277 static int
2278 mac_lomac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2279 struct vnode *vp, struct label *label)
2280 {
2281 struct mac_lomac *subj, *obj;
2282
2283 if (!mac_lomac_enabled || !revocation_enabled)
2284 return (0);
2285
2286 subj = SLOT(&active_cred->cr_label);
2287 obj = SLOT(label);
2288
2289 if (!mac_lomac_dominate_single(obj, subj))
2290 return (maybe_demote(subj, obj, "reading", "file", vp));
2291
2292 return (0);
2293 }
2294
2295 static int
2296 mac_lomac_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2297 struct label *vnodelabel, struct label *newlabel)
2298 {
2299 struct mac_lomac *old, *new, *subj;
2300 int error;
2301
2302 old = SLOT(vnodelabel);
2303 new = SLOT(newlabel);
2304 subj = SLOT(&cred->cr_label);
2305
2306 /*
2307 * If there is a LOMAC label update for the vnode, it must be a
2308 * single label, with an optional explicit auxiliary single.
2309 */
2310 error = lomac_atmostflags(new,
2311 MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_AUX);
2312 if (error)
2313 return (error);
2314
2315 /*
2316 * To perform a relabel of the vnode (LOMAC label or not), LOMAC must
2317 * authorize the relabel.
2318 */
2319 if (!mac_lomac_single_in_range(old, subj))
2320 return (EPERM);
2321
2322 /*
2323 * If the LOMAC label is to be changed, authorize as appropriate.
2324 */
2325 if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
2326 /*
2327 * To change the LOMAC label on a vnode, the new vnode label
2328 * must be in the subject range.
2329 */
2330 if (!mac_lomac_single_in_range(new, subj))
2331 return (EPERM);
2332
2333 /*
2334 * To change the LOMAC label on the vnode to be EQUAL,
2335 * the subject must have appropriate privilege.
2336 */
2337 if (mac_lomac_contains_equal(new)) {
2338 error = mac_lomac_subject_privileged(subj);
2339 if (error)
2340 return (error);
2341 }
2342 }
2343 if (new->ml_flags & MAC_LOMAC_FLAG_AUX) {
2344 /*
2345 * To change the auxiliary LOMAC label on a vnode, the new
2346 * vnode label must be in the subject range.
2347 */
2348 if (!mac_lomac_auxsingle_in_range(new, subj))
2349 return (EPERM);
2350
2351 /*
2352 * To change the auxiliary LOMAC label on the vnode to be
2353 * EQUAL, the subject must have appropriate privilege.
2354 */
2355 if (mac_lomac_contains_equal(new)) {
2356 error = mac_lomac_subject_privileged(subj);
2357 if (error)
2358 return (error);
2359 }
2360 }
2361
2362 return (0);
2363 }
2364
2365 static int
2366 mac_lomac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2367 struct label *dlabel, struct vnode *vp, struct label *label,
2368 struct componentname *cnp)
2369 {
2370 struct mac_lomac *subj, *obj;
2371
2372 if (!mac_lomac_enabled)
2373 return (0);
2374
2375 subj = SLOT(&cred->cr_label);
2376 obj = SLOT(dlabel);
2377
2378 if (!mac_lomac_subject_dominate(subj, obj))
2379 return (EACCES);
2380
2381 obj = SLOT(label);
2382
2383 if (!mac_lomac_subject_dominate(subj, obj))
2384 return (EACCES);
2385
2386 return (0);
2387 }
2388
2389 static int
2390 mac_lomac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2391 struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
2392 struct componentname *cnp)
2393 {
2394 struct mac_lomac *subj, *obj;
2395
2396 if (!mac_lomac_enabled)
2397 return (0);
2398
2399 subj = SLOT(&cred->cr_label);
2400 obj = SLOT(dlabel);
2401
2402 if (!mac_lomac_subject_dominate(subj, obj))
2403 return (EACCES);
2404
2405 if (vp != NULL) {
2406 obj = SLOT(label);
2407
2408 if (!mac_lomac_subject_dominate(subj, obj))
2409 return (EACCES);
2410 }
2411
2412 return (0);
2413 }
2414
2415 static int
2416 mac_lomac_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
2417 struct label *label)
2418 {
2419 struct mac_lomac *subj, *obj;
2420
2421 if (!mac_lomac_enabled)
2422 return (0);
2423
2424 subj = SLOT(&cred->cr_label);
2425 obj = SLOT(label);
2426
2427 if (!mac_lomac_subject_dominate(subj, obj))
2428 return (EACCES);
2429
2430 return (0);
2431 }
2432
2433 static int
2434 mac_lomac_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
2435 struct label *label, acl_type_t type, struct acl *acl)
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(label);
2444
2445 if (!mac_lomac_subject_dominate(subj, obj))
2446 return (EACCES);
2447
2448 return (0);
2449 }
2450
2451 static int
2452 mac_lomac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2453 struct label *vnodelabel, int attrnamespace, const char *name,
2454 struct uio *uio)
2455 {
2456 struct mac_lomac *subj, *obj;
2457
2458 if (!mac_lomac_enabled)
2459 return (0);
2460
2461 subj = SLOT(&cred->cr_label);
2462 obj = SLOT(vnodelabel);
2463
2464 if (!mac_lomac_subject_dominate(subj, obj))
2465 return (EACCES);
2466
2467 /* XXX: protect the MAC EA in a special way? */
2468
2469 return (0);
2470 }
2471
2472 static int
2473 mac_lomac_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2474 struct label *vnodelabel, u_long flags)
2475 {
2476 struct mac_lomac *subj, *obj;
2477
2478 if (!mac_lomac_enabled)
2479 return (0);
2480
2481 subj = SLOT(&cred->cr_label);
2482 obj = SLOT(vnodelabel);
2483
2484 if (!mac_lomac_subject_dominate(subj, obj))
2485 return (EACCES);
2486
2487 return (0);
2488 }
2489
2490 static int
2491 mac_lomac_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2492 struct label *vnodelabel, mode_t mode)
2493 {
2494 struct mac_lomac *subj, *obj;
2495
2496 if (!mac_lomac_enabled)
2497 return (0);
2498
2499 subj = SLOT(&cred->cr_label);
2500 obj = SLOT(vnodelabel);
2501
2502 if (!mac_lomac_subject_dominate(subj, obj))
2503 return (EACCES);
2504
2505 return (0);
2506 }
2507
2508 static int
2509 mac_lomac_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2510 struct label *vnodelabel, uid_t uid, gid_t gid)
2511 {
2512 struct mac_lomac *subj, *obj;
2513
2514 if (!mac_lomac_enabled)
2515 return (0);
2516
2517 subj = SLOT(&cred->cr_label);
2518 obj = SLOT(vnodelabel);
2519
2520 if (!mac_lomac_subject_dominate(subj, obj))
2521 return (EACCES);
2522
2523 return (0);
2524 }
2525
2526 static int
2527 mac_lomac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2528 struct label *vnodelabel, struct timespec atime, struct timespec mtime)
2529 {
2530 struct mac_lomac *subj, *obj;
2531
2532 if (!mac_lomac_enabled)
2533 return (0);
2534
2535 subj = SLOT(&cred->cr_label);
2536 obj = SLOT(vnodelabel);
2537
2538 if (!mac_lomac_subject_dominate(subj, obj))
2539 return (EACCES);
2540
2541 return (0);
2542 }
2543
2544 static int
2545 mac_lomac_check_vnode_write(struct ucred *active_cred,
2546 struct ucred *file_cred, struct vnode *vp, struct label *label)
2547 {
2548 struct mac_lomac *subj, *obj;
2549
2550 if (!mac_lomac_enabled || !revocation_enabled)
2551 return (0);
2552
2553 subj = SLOT(&active_cred->cr_label);
2554 obj = SLOT(label);
2555
2556 if (!mac_lomac_subject_dominate(subj, obj))
2557 return (EACCES);
2558
2559 return (0);
2560 }
2561
2562 static void
2563 mac_lomac_thread_userret(struct thread *td)
2564 {
2565 struct proc *p = td->td_proc;
2566 struct mac_lomac_proc *subj = PSLOT(&p->p_label);
2567 struct ucred *newcred, *oldcred;
2568 int dodrop;
2569
2570 mtx_lock(&subj->mtx);
2571 if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) {
2572 dodrop = 0;
2573 mtx_unlock(&subj->mtx);
2574 newcred = crget();
2575 /*
2576 * Prevent a lock order reversal in
2577 * mac_cred_mmapped_drop_perms; ideally, the other
2578 * user of subj->mtx wouldn't be holding Giant.
2579 */
2580 mtx_lock(&Giant);
2581 PROC_LOCK(p);
2582 mtx_lock(&subj->mtx);
2583 /*
2584 * Check if we lost the race while allocating the cred.
2585 */
2586 if ((subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) == 0) {
2587 crfree(newcred);
2588 goto out;
2589 }
2590 oldcred = p->p_ucred;
2591 crcopy(newcred, oldcred);
2592 crhold(newcred);
2593 mac_lomac_copy(&subj->mac_lomac, SLOT(&newcred->cr_label));
2594 p->p_ucred = newcred;
2595 crfree(oldcred);
2596 dodrop = 1;
2597 out:
2598 mtx_unlock(&subj->mtx);
2599 PROC_UNLOCK(p);
2600 if (dodrop)
2601 mac_cred_mmapped_drop_perms(curthread, newcred);
2602 mtx_unlock(&Giant);
2603 } else {
2604 mtx_unlock(&subj->mtx);
2605 }
2606 }
2607
2608 static struct mac_policy_ops mac_lomac_ops =
2609 {
2610 .mpo_destroy = mac_lomac_destroy,
2611 .mpo_init = mac_lomac_init,
2612 .mpo_init_bpfdesc_label = mac_lomac_init_label,
2613 .mpo_init_cred_label = mac_lomac_init_label,
2614 .mpo_init_devfsdirent_label = mac_lomac_init_label,
2615 .mpo_init_ifnet_label = mac_lomac_init_label,
2616 .mpo_init_ipq_label = mac_lomac_init_label,
2617 .mpo_init_mbuf_label = mac_lomac_init_label_waitcheck,
2618 .mpo_init_mount_label = mac_lomac_init_label,
2619 .mpo_init_mount_fs_label = mac_lomac_init_label,
2620 .mpo_init_pipe_label = mac_lomac_init_label,
2621 .mpo_init_proc_label = mac_lomac_init_proc_label,
2622 .mpo_init_socket_label = mac_lomac_init_label_waitcheck,
2623 .mpo_init_socket_peer_label = mac_lomac_init_label_waitcheck,
2624 .mpo_init_vnode_label = mac_lomac_init_label,
2625 .mpo_destroy_bpfdesc_label = mac_lomac_destroy_label,
2626 .mpo_destroy_cred_label = mac_lomac_destroy_label,
2627 .mpo_destroy_devfsdirent_label = mac_lomac_destroy_label,
2628 .mpo_destroy_ifnet_label = mac_lomac_destroy_label,
2629 .mpo_destroy_ipq_label = mac_lomac_destroy_label,
2630 .mpo_destroy_mbuf_label = mac_lomac_destroy_label,
2631 .mpo_destroy_mount_label = mac_lomac_destroy_label,
2632 .mpo_destroy_mount_fs_label = mac_lomac_destroy_label,
2633 .mpo_destroy_pipe_label = mac_lomac_destroy_label,
2634 .mpo_destroy_proc_label = mac_lomac_destroy_proc_label,
2635 .mpo_destroy_socket_label = mac_lomac_destroy_label,
2636 .mpo_destroy_socket_peer_label = mac_lomac_destroy_label,
2637 .mpo_destroy_vnode_label = mac_lomac_destroy_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, &mac_lomac_slot);
Cache object: a262e1dc2fcd1c3d3b4a32aaa2a35974
|