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