1 /*-
2 * Copyright (c) 1999-2002, 2007 Robert N. M. Watson
3 * Copyright (c) 2001-2005 Networks Associates Technology, Inc.
4 * All rights reserved.
5 *
6 * This software was developed by Robert Watson for the TrustedBSD Project.
7 *
8 * This software was developed for the FreeBSD Project in part by NAI Labs,
9 * the Security Research Division of Network Associates, Inc. under
10 * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA
11 * CHATS research program.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 * $FreeBSD$
35 */
36
37 /*
38 * Developed by the TrustedBSD Project.
39 *
40 * Low-watermark floating label mandatory integrity policy.
41 */
42
43 #include <sys/types.h>
44 #include <sys/param.h>
45 #include <sys/acl.h>
46 #include <sys/conf.h>
47 #include <sys/extattr.h>
48 #include <sys/kernel.h>
49 #include <sys/malloc.h>
50 #include <sys/mman.h>
51 #include <sys/mount.h>
52 #include <sys/priv.h>
53 #include <sys/proc.h>
54 #include <sys/sbuf.h>
55 #include <sys/systm.h>
56 #include <sys/sysproto.h>
57 #include <sys/sysent.h>
58 #include <sys/systm.h>
59 #include <sys/vnode.h>
60 #include <sys/file.h>
61 #include <sys/socket.h>
62 #include <sys/socketvar.h>
63 #include <sys/sx.h>
64 #include <sys/pipe.h>
65 #include <sys/sysctl.h>
66 #include <sys/syslog.h>
67
68 #include <fs/devfs/devfs.h>
69
70 #include <net/bpfdesc.h>
71 #include <net/if.h>
72 #include <net/if_types.h>
73 #include <net/if_var.h>
74
75 #include <netinet/in.h>
76 #include <netinet/in_pcb.h>
77 #include <netinet/ip_var.h>
78
79 #include <vm/vm.h>
80
81 #include <security/mac/mac_policy.h>
82 #include <security/mac/mac_framework.h>
83 #include <security/mac_lomac/mac_lomac.h>
84
85 struct mac_lomac_proc {
86 struct mac_lomac mac_lomac;
87 struct mtx mtx;
88 };
89
90 SYSCTL_DECL(_security_mac);
91
92 SYSCTL_NODE(_security_mac, OID_AUTO, lomac, CTLFLAG_RW, 0,
93 "TrustedBSD mac_lomac policy controls");
94
95 static int mac_lomac_label_size = sizeof(struct mac_lomac);
96 SYSCTL_INT(_security_mac_lomac, OID_AUTO, label_size, CTLFLAG_RD,
97 &mac_lomac_label_size, 0, "Size of struct mac_lomac");
98
99 static int mac_lomac_enabled = 1;
100 SYSCTL_INT(_security_mac_lomac, OID_AUTO, enabled, CTLFLAG_RW,
101 &mac_lomac_enabled, 0, "Enforce MAC/LOMAC policy");
102 TUNABLE_INT("security.mac.lomac.enabled", &mac_lomac_enabled);
103
104 static int destroyed_not_inited;
105 SYSCTL_INT(_security_mac_lomac, OID_AUTO, destroyed_not_inited, CTLFLAG_RD,
106 &destroyed_not_inited, 0, "Count of labels destroyed but not inited");
107
108 static int trust_all_interfaces = 0;
109 SYSCTL_INT(_security_mac_lomac, OID_AUTO, trust_all_interfaces, CTLFLAG_RD,
110 &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/LOMAC");
111 TUNABLE_INT("security.mac.lomac.trust_all_interfaces", &trust_all_interfaces);
112
113 static char trusted_interfaces[128];
114 SYSCTL_STRING(_security_mac_lomac, OID_AUTO, trusted_interfaces, CTLFLAG_RD,
115 trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/LOMAC");
116 TUNABLE_STR("security.mac.lomac.trusted_interfaces", trusted_interfaces,
117 sizeof(trusted_interfaces));
118
119 static int ptys_equal = 0;
120 SYSCTL_INT(_security_mac_lomac, OID_AUTO, ptys_equal, CTLFLAG_RW,
121 &ptys_equal, 0, "Label pty devices as lomac/equal on create");
122 TUNABLE_INT("security.mac.lomac.ptys_equal", &ptys_equal);
123
124 static int revocation_enabled = 1;
125 SYSCTL_INT(_security_mac_lomac, OID_AUTO, revocation_enabled, CTLFLAG_RW,
126 &revocation_enabled, 0, "Revoke access to objects on relabel");
127 TUNABLE_INT("security.mac.lomac.revocation_enabled", &revocation_enabled);
128
129 static int mac_lomac_slot;
130 #define SLOT(l) ((struct mac_lomac *)mac_label_get((l), mac_lomac_slot))
131 #define SLOT_SET(l, val) mac_label_set((l), mac_lomac_slot, (uintptr_t)(val))
132 #define PSLOT(l) ((struct mac_lomac_proc *) \
133 mac_label_get((l), mac_lomac_slot))
134 #define PSLOT_SET(l, val) mac_label_set((l), mac_lomac_slot, (uintptr_t)(val))
135
136 MALLOC_DEFINE(M_MACLOMAC, "mac_lomac_label", "MAC/LOMAC labels");
137
138 static struct mac_lomac *
139 lomac_alloc(int flag)
140 {
141 struct mac_lomac *mac_lomac;
142
143 mac_lomac = malloc(sizeof(struct mac_lomac), M_MACLOMAC, M_ZERO | flag);
144
145 return (mac_lomac);
146 }
147
148 static void
149 lomac_free(struct mac_lomac *mac_lomac)
150 {
151
152 if (mac_lomac != NULL)
153 free(mac_lomac, M_MACLOMAC);
154 else
155 atomic_add_int(&destroyed_not_inited, 1);
156 }
157
158 static int
159 lomac_atmostflags(struct mac_lomac *mac_lomac, int flags)
160 {
161
162 if ((mac_lomac->ml_flags & flags) != mac_lomac->ml_flags)
163 return (EINVAL);
164 return (0);
165 }
166
167 static int
168 mac_lomac_dominate_element(struct mac_lomac_element *a,
169 struct mac_lomac_element *b)
170 {
171
172 switch (a->mle_type) {
173 case MAC_LOMAC_TYPE_EQUAL:
174 case MAC_LOMAC_TYPE_HIGH:
175 return (1);
176
177 case MAC_LOMAC_TYPE_LOW:
178 switch (b->mle_type) {
179 case MAC_LOMAC_TYPE_GRADE:
180 case MAC_LOMAC_TYPE_HIGH:
181 return (0);
182
183 case MAC_LOMAC_TYPE_EQUAL:
184 case MAC_LOMAC_TYPE_LOW:
185 return (1);
186
187 default:
188 panic("mac_lomac_dominate_element: b->mle_type invalid");
189 }
190
191 case MAC_LOMAC_TYPE_GRADE:
192 switch (b->mle_type) {
193 case MAC_LOMAC_TYPE_EQUAL:
194 case MAC_LOMAC_TYPE_LOW:
195 return (1);
196
197 case MAC_LOMAC_TYPE_HIGH:
198 return (0);
199
200 case MAC_LOMAC_TYPE_GRADE:
201 return (a->mle_grade >= b->mle_grade);
202
203 default:
204 panic("mac_lomac_dominate_element: b->mle_type invalid");
205 }
206
207 default:
208 panic("mac_lomac_dominate_element: a->mle_type invalid");
209 }
210 }
211
212 static int
213 mac_lomac_range_in_range(struct mac_lomac *rangea, struct mac_lomac *rangeb)
214 {
215
216 return (mac_lomac_dominate_element(&rangeb->ml_rangehigh,
217 &rangea->ml_rangehigh) &&
218 mac_lomac_dominate_element(&rangea->ml_rangelow,
219 &rangeb->ml_rangelow));
220 }
221
222 static int
223 mac_lomac_single_in_range(struct mac_lomac *single, struct mac_lomac *range)
224 {
225
226 KASSERT((single->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
227 ("mac_lomac_single_in_range: a not single"));
228 KASSERT((range->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0,
229 ("mac_lomac_single_in_range: b not range"));
230
231 return (mac_lomac_dominate_element(&range->ml_rangehigh,
232 &single->ml_single) &&
233 mac_lomac_dominate_element(&single->ml_single,
234 &range->ml_rangelow));
235 }
236
237 static int
238 mac_lomac_auxsingle_in_range(struct mac_lomac *single, struct mac_lomac *range)
239 {
240
241 KASSERT((single->ml_flags & MAC_LOMAC_FLAG_AUX) != 0,
242 ("mac_lomac_single_in_range: a not auxsingle"));
243 KASSERT((range->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0,
244 ("mac_lomac_single_in_range: b not range"));
245
246 return (mac_lomac_dominate_element(&range->ml_rangehigh,
247 &single->ml_auxsingle) &&
248 mac_lomac_dominate_element(&single->ml_auxsingle,
249 &range->ml_rangelow));
250 }
251
252 static int
253 mac_lomac_dominate_single(struct mac_lomac *a, struct mac_lomac *b)
254 {
255 KASSERT((a->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
256 ("mac_lomac_dominate_single: a not single"));
257 KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
258 ("mac_lomac_dominate_single: b not single"));
259
260 return (mac_lomac_dominate_element(&a->ml_single, &b->ml_single));
261 }
262
263 static int
264 mac_lomac_subject_dominate(struct mac_lomac *a, struct mac_lomac *b)
265 {
266 KASSERT((~a->ml_flags &
267 (MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_RANGE)) == 0,
268 ("mac_lomac_dominate_single: a not subject"));
269 KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
270 ("mac_lomac_dominate_single: b not single"));
271
272 return (mac_lomac_dominate_element(&a->ml_rangehigh,
273 &b->ml_single));
274 }
275
276 static int
277 mac_lomac_equal_element(struct mac_lomac_element *a, struct mac_lomac_element *b)
278 {
279
280 if (a->mle_type == MAC_LOMAC_TYPE_EQUAL ||
281 b->mle_type == MAC_LOMAC_TYPE_EQUAL)
282 return (1);
283
284 return (a->mle_type == b->mle_type && a->mle_grade == b->mle_grade);
285 }
286
287 static int
288 mac_lomac_equal_single(struct mac_lomac *a, struct mac_lomac *b)
289 {
290
291 KASSERT((a->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
292 ("mac_lomac_equal_single: a not single"));
293 KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
294 ("mac_lomac_equal_single: b not single"));
295
296 return (mac_lomac_equal_element(&a->ml_single, &b->ml_single));
297 }
298
299 static int
300 mac_lomac_contains_equal(struct mac_lomac *mac_lomac)
301 {
302
303 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE)
304 if (mac_lomac->ml_single.mle_type == MAC_LOMAC_TYPE_EQUAL)
305 return (1);
306 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_AUX)
307 if (mac_lomac->ml_auxsingle.mle_type == MAC_LOMAC_TYPE_EQUAL)
308 return (1);
309
310 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_RANGE) {
311 if (mac_lomac->ml_rangelow.mle_type == MAC_LOMAC_TYPE_EQUAL)
312 return (1);
313 if (mac_lomac->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_EQUAL)
314 return (1);
315 }
316
317 return (0);
318 }
319
320 static int
321 mac_lomac_subject_privileged(struct mac_lomac *mac_lomac)
322 {
323
324 KASSERT((mac_lomac->ml_flags & MAC_LOMAC_FLAGS_BOTH) ==
325 MAC_LOMAC_FLAGS_BOTH,
326 ("mac_lomac_subject_privileged: subject doesn't have both labels"));
327
328 /* If the single is EQUAL, it's ok. */
329 if (mac_lomac->ml_single.mle_type == MAC_LOMAC_TYPE_EQUAL)
330 return (0);
331
332 /* If either range endpoint is EQUAL, it's ok. */
333 if (mac_lomac->ml_rangelow.mle_type == MAC_LOMAC_TYPE_EQUAL ||
334 mac_lomac->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_EQUAL)
335 return (0);
336
337 /* If the range is low-high, it's ok. */
338 if (mac_lomac->ml_rangelow.mle_type == MAC_LOMAC_TYPE_LOW &&
339 mac_lomac->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_HIGH)
340 return (0);
341
342 /* It's not ok. */
343 return (EPERM);
344 }
345
346 static int
347 mac_lomac_high_single(struct mac_lomac *mac_lomac)
348 {
349
350 KASSERT((mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
351 ("mac_lomac_high_single: mac_lomac not single"));
352
353 return (mac_lomac->ml_single.mle_type == MAC_LOMAC_TYPE_HIGH);
354 }
355
356 static int
357 mac_lomac_valid(struct mac_lomac *mac_lomac)
358 {
359
360 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
361 switch (mac_lomac->ml_single.mle_type) {
362 case MAC_LOMAC_TYPE_GRADE:
363 case MAC_LOMAC_TYPE_EQUAL:
364 case MAC_LOMAC_TYPE_HIGH:
365 case MAC_LOMAC_TYPE_LOW:
366 break;
367
368 default:
369 return (EINVAL);
370 }
371 } else {
372 if (mac_lomac->ml_single.mle_type != MAC_LOMAC_TYPE_UNDEF)
373 return (EINVAL);
374 }
375
376 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_AUX) {
377 switch (mac_lomac->ml_auxsingle.mle_type) {
378 case MAC_LOMAC_TYPE_GRADE:
379 case MAC_LOMAC_TYPE_EQUAL:
380 case MAC_LOMAC_TYPE_HIGH:
381 case MAC_LOMAC_TYPE_LOW:
382 break;
383
384 default:
385 return (EINVAL);
386 }
387 } else {
388 if (mac_lomac->ml_auxsingle.mle_type != MAC_LOMAC_TYPE_UNDEF)
389 return (EINVAL);
390 }
391
392 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_RANGE) {
393 switch (mac_lomac->ml_rangelow.mle_type) {
394 case MAC_LOMAC_TYPE_GRADE:
395 case MAC_LOMAC_TYPE_EQUAL:
396 case MAC_LOMAC_TYPE_HIGH:
397 case MAC_LOMAC_TYPE_LOW:
398 break;
399
400 default:
401 return (EINVAL);
402 }
403
404 switch (mac_lomac->ml_rangehigh.mle_type) {
405 case MAC_LOMAC_TYPE_GRADE:
406 case MAC_LOMAC_TYPE_EQUAL:
407 case MAC_LOMAC_TYPE_HIGH:
408 case MAC_LOMAC_TYPE_LOW:
409 break;
410
411 default:
412 return (EINVAL);
413 }
414 if (!mac_lomac_dominate_element(&mac_lomac->ml_rangehigh,
415 &mac_lomac->ml_rangelow))
416 return (EINVAL);
417 } else {
418 if (mac_lomac->ml_rangelow.mle_type != MAC_LOMAC_TYPE_UNDEF ||
419 mac_lomac->ml_rangehigh.mle_type != MAC_LOMAC_TYPE_UNDEF)
420 return (EINVAL);
421 }
422
423 return (0);
424 }
425
426 static void
427 mac_lomac_set_range(struct mac_lomac *mac_lomac, u_short typelow,
428 u_short gradelow, u_short typehigh, u_short gradehigh)
429 {
430
431 mac_lomac->ml_rangelow.mle_type = typelow;
432 mac_lomac->ml_rangelow.mle_grade = gradelow;
433 mac_lomac->ml_rangehigh.mle_type = typehigh;
434 mac_lomac->ml_rangehigh.mle_grade = gradehigh;
435 mac_lomac->ml_flags |= MAC_LOMAC_FLAG_RANGE;
436 }
437
438 static void
439 mac_lomac_set_single(struct mac_lomac *mac_lomac, u_short type, u_short grade)
440 {
441
442 mac_lomac->ml_single.mle_type = type;
443 mac_lomac->ml_single.mle_grade = grade;
444 mac_lomac->ml_flags |= MAC_LOMAC_FLAG_SINGLE;
445 }
446
447 static void
448 mac_lomac_copy_range(struct mac_lomac *labelfrom, struct mac_lomac *labelto)
449 {
450
451 KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0,
452 ("mac_lomac_copy_range: labelfrom not range"));
453
454 labelto->ml_rangelow = labelfrom->ml_rangelow;
455 labelto->ml_rangehigh = labelfrom->ml_rangehigh;
456 labelto->ml_flags |= MAC_LOMAC_FLAG_RANGE;
457 }
458
459 static void
460 mac_lomac_copy_single(struct mac_lomac *labelfrom, struct mac_lomac *labelto)
461 {
462
463 KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
464 ("mac_lomac_copy_single: labelfrom not single"));
465
466 labelto->ml_single = labelfrom->ml_single;
467 labelto->ml_flags |= MAC_LOMAC_FLAG_SINGLE;
468 }
469
470 static void
471 mac_lomac_copy_auxsingle(struct mac_lomac *labelfrom, struct mac_lomac *labelto)
472 {
473
474 KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_AUX) != 0,
475 ("mac_lomac_copy_auxsingle: labelfrom not auxsingle"));
476
477 labelto->ml_auxsingle = labelfrom->ml_auxsingle;
478 labelto->ml_flags |= MAC_LOMAC_FLAG_AUX;
479 }
480
481 static void
482 mac_lomac_copy(struct mac_lomac *source, struct mac_lomac *dest)
483 {
484
485 if (source->ml_flags & MAC_LOMAC_FLAG_SINGLE)
486 mac_lomac_copy_single(source, dest);
487 if (source->ml_flags & MAC_LOMAC_FLAG_AUX)
488 mac_lomac_copy_auxsingle(source, dest);
489 if (source->ml_flags & MAC_LOMAC_FLAG_RANGE)
490 mac_lomac_copy_range(source, dest);
491 }
492
493 static int mac_lomac_to_string(struct sbuf *sb,
494 struct mac_lomac *mac_lomac);
495
496 static int
497 maybe_demote(struct mac_lomac *subjlabel, struct mac_lomac *objlabel,
498 const char *actionname, const char *objname, struct vnode *vp)
499 {
500 struct sbuf subjlabel_sb, subjtext_sb, objlabel_sb;
501 char *subjlabeltext, *objlabeltext, *subjtext;
502 struct mac_lomac cached_subjlabel;
503 struct mac_lomac_proc *subj;
504 struct vattr va;
505 struct proc *p;
506 pid_t pgid;
507
508 subj = PSLOT(curthread->td_proc->p_label);
509
510 p = curthread->td_proc;
511 mtx_lock(&subj->mtx);
512 if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) {
513 /*
514 * Check to see if the pending demotion would be more or
515 * less severe than this one, and keep the more severe.
516 * This can only happen for a multi-threaded application.
517 */
518 if (mac_lomac_dominate_single(objlabel, &subj->mac_lomac)) {
519 mtx_unlock(&subj->mtx);
520 return (0);
521 }
522 }
523 bzero(&subj->mac_lomac, sizeof(subj->mac_lomac));
524 /*
525 * Always demote the single label.
526 */
527 mac_lomac_copy_single(objlabel, &subj->mac_lomac);
528 /*
529 * Start with the original range, then minimize each side of
530 * the range to the point of not dominating the object. The
531 * high side will always be demoted, of course.
532 */
533 mac_lomac_copy_range(subjlabel, &subj->mac_lomac);
534 if (!mac_lomac_dominate_element(&objlabel->ml_single,
535 &subj->mac_lomac.ml_rangelow))
536 subj->mac_lomac.ml_rangelow = objlabel->ml_single;
537 subj->mac_lomac.ml_rangehigh = objlabel->ml_single;
538 subj->mac_lomac.ml_flags |= MAC_LOMAC_FLAG_UPDATE;
539 thread_lock(curthread);
540 curthread->td_flags |= TDF_ASTPENDING | TDF_MACPEND;
541 thread_unlock(curthread);
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 (vp != NULL && VOP_GETATTR(vp, &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, vp->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 *de, struct label *delabel)
906 {
907 struct mac_lomac *mac_lomac;
908 int lomac_type;
909
910 mac_lomac = SLOT(delabel);
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 *de, struct label *delabel)
929 {
930 struct mac_lomac *mac_lomac;
931
932 mac_lomac = SLOT(delabel);
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 *mplabel)
952 {
953 struct mac_lomac *source, *dest;
954
955 source = SLOT(cred->cr_label);
956 dest = SLOT(mplabel);
957 mac_lomac_copy_single(source, dest);
958 }
959
960 static void
961 mac_lomac_relabel_vnode(struct ucred *cred, struct vnode *vp,
962 struct label *vplabel, struct label *newlabel)
963 {
964 struct mac_lomac *source, *dest;
965
966 source = SLOT(newlabel);
967 dest = SLOT(vplabel);
968
969 try_relabel(source, dest);
970 }
971
972 static void
973 mac_lomac_update_devfs(struct mount *mp, struct devfs_dirent *de,
974 struct label *delabel, struct vnode *vp, struct label *vplabel)
975 {
976 struct mac_lomac *source, *dest;
977
978 source = SLOT(vplabel);
979 dest = SLOT(delabel);
980
981 mac_lomac_copy(source, dest);
982 }
983
984 static void
985 mac_lomac_associate_vnode_devfs(struct mount *mp, struct label *mplabel,
986 struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
987 struct label *vplabel)
988 {
989 struct mac_lomac *source, *dest;
990
991 source = SLOT(delabel);
992 dest = SLOT(vplabel);
993
994 mac_lomac_copy_single(source, dest);
995 }
996
997 static int
998 mac_lomac_associate_vnode_extattr(struct mount *mp, struct label *mplabel,
999 struct vnode *vp, struct label *vplabel)
1000 {
1001 struct mac_lomac temp, *source, *dest;
1002 int buflen, error;
1003
1004 source = SLOT(mplabel);
1005 dest = SLOT(vplabel);
1006
1007 buflen = sizeof(temp);
1008 bzero(&temp, buflen);
1009
1010 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE,
1011 MAC_LOMAC_EXTATTR_NAME, &buflen, (char *)&temp, curthread);
1012 if (error == ENOATTR || error == EOPNOTSUPP) {
1013 /* Fall back to the mntlabel. */
1014 mac_lomac_copy_single(source, dest);
1015 return (0);
1016 } else if (error)
1017 return (error);
1018
1019 if (buflen != sizeof(temp)) {
1020 if (buflen != sizeof(temp) - sizeof(temp.ml_auxsingle)) {
1021 printf("mac_lomac_associate_vnode_extattr: bad size %d\n",
1022 buflen);
1023 return (EPERM);
1024 }
1025 bzero(&temp.ml_auxsingle, sizeof(temp.ml_auxsingle));
1026 buflen = sizeof(temp);
1027 (void)vn_extattr_set(vp, IO_NODELOCKED,
1028 MAC_LOMAC_EXTATTR_NAMESPACE, MAC_LOMAC_EXTATTR_NAME,
1029 buflen, (char *)&temp, curthread);
1030 }
1031 if (mac_lomac_valid(&temp) != 0) {
1032 printf("mac_lomac_associate_vnode_extattr: invalid\n");
1033 return (EPERM);
1034 }
1035 if ((temp.ml_flags & MAC_LOMAC_FLAGS_BOTH) != MAC_LOMAC_FLAG_SINGLE) {
1036 printf("mac_lomac_associate_vnode_extattr: not single\n");
1037 return (EPERM);
1038 }
1039
1040 mac_lomac_copy_single(&temp, dest);
1041 return (0);
1042 }
1043
1044 static void
1045 mac_lomac_associate_vnode_singlelabel(struct mount *mp,
1046 struct label *mplabel, struct vnode *vp, struct label *vplabel)
1047 {
1048 struct mac_lomac *source, *dest;
1049
1050 source = SLOT(mplabel);
1051 dest = SLOT(vplabel);
1052
1053 mac_lomac_copy_single(source, dest);
1054 }
1055
1056 static int
1057 mac_lomac_create_vnode_extattr(struct ucred *cred, struct mount *mp,
1058 struct label *mplabel, struct vnode *dvp, struct label *dvplabel,
1059 struct vnode *vp, struct label *vplabel, struct componentname *cnp)
1060 {
1061 struct mac_lomac *source, *dest, *dir, temp;
1062 size_t buflen;
1063 int error;
1064
1065 buflen = sizeof(temp);
1066 bzero(&temp, buflen);
1067
1068 source = SLOT(cred->cr_label);
1069 dest = SLOT(vplabel);
1070 dir = SLOT(dvplabel);
1071 if (dir->ml_flags & MAC_LOMAC_FLAG_AUX) {
1072 mac_lomac_copy_auxsingle(dir, &temp);
1073 mac_lomac_set_single(&temp, dir->ml_auxsingle.mle_type,
1074 dir->ml_auxsingle.mle_grade);
1075 } else {
1076 mac_lomac_copy_single(source, &temp);
1077 }
1078
1079 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE,
1080 MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread);
1081 if (error == 0)
1082 mac_lomac_copy(&temp, dest);
1083 return (error);
1084 }
1085
1086 static int
1087 mac_lomac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
1088 struct label *vplabel, struct label *intlabel)
1089 {
1090 struct mac_lomac *source, temp;
1091 size_t buflen;
1092 int error;
1093
1094 buflen = sizeof(temp);
1095 bzero(&temp, buflen);
1096
1097 source = SLOT(intlabel);
1098 if ((source->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0)
1099 return (0);
1100
1101 mac_lomac_copy_single(source, &temp);
1102 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE,
1103 MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread);
1104 return (error);
1105 }
1106
1107 /*
1108 * Labeling event operations: IPC object.
1109 */
1110 static void
1111 mac_lomac_create_inpcb_from_socket(struct socket *so, struct label *solabel,
1112 struct inpcb *inp, struct label *inplabel)
1113 {
1114 struct mac_lomac *source, *dest;
1115
1116 source = SLOT(solabel);
1117 dest = SLOT(inplabel);
1118
1119 mac_lomac_copy_single(source, dest);
1120 }
1121
1122 static void
1123 mac_lomac_create_mbuf_from_socket(struct socket *so, struct label *solabel,
1124 struct mbuf *m, struct label *mlabel)
1125 {
1126 struct mac_lomac *source, *dest;
1127
1128 source = SLOT(solabel);
1129 dest = SLOT(mlabel);
1130
1131 mac_lomac_copy_single(source, dest);
1132 }
1133
1134 static void
1135 mac_lomac_create_socket(struct ucred *cred, struct socket *so,
1136 struct label *solabel)
1137 {
1138 struct mac_lomac *source, *dest;
1139
1140 source = SLOT(cred->cr_label);
1141 dest = SLOT(solabel);
1142
1143 mac_lomac_copy_single(source, dest);
1144 }
1145
1146 static void
1147 mac_lomac_create_pipe(struct ucred *cred, struct pipepair *pp,
1148 struct label *pplabel)
1149 {
1150 struct mac_lomac *source, *dest;
1151
1152 source = SLOT(cred->cr_label);
1153 dest = SLOT(pplabel);
1154
1155 mac_lomac_copy_single(source, dest);
1156 }
1157
1158 static void
1159 mac_lomac_create_socket_from_socket(struct socket *oldso,
1160 struct label *oldsolabel, struct socket *newso, struct label *newsolabel)
1161 {
1162 struct mac_lomac *source, *dest;
1163
1164 source = SLOT(oldsolabel);
1165 dest = SLOT(newsolabel);
1166
1167 mac_lomac_copy_single(source, dest);
1168 }
1169
1170 static void
1171 mac_lomac_relabel_socket(struct ucred *cred, struct socket *so,
1172 struct label *solabel, struct label *newlabel)
1173 {
1174 struct mac_lomac *source, *dest;
1175
1176 source = SLOT(newlabel);
1177 dest = SLOT(solabel);
1178
1179 try_relabel(source, dest);
1180 }
1181
1182 static void
1183 mac_lomac_relabel_pipe(struct ucred *cred, struct pipepair *pp,
1184 struct label *pplabel, struct label *newlabel)
1185 {
1186 struct mac_lomac *source, *dest;
1187
1188 source = SLOT(newlabel);
1189 dest = SLOT(pplabel);
1190
1191 try_relabel(source, dest);
1192 }
1193
1194 static void
1195 mac_lomac_set_socket_peer_from_mbuf(struct mbuf *m, struct label *mlabel,
1196 struct socket *so, struct label *sopeerlabel)
1197 {
1198 struct mac_lomac *source, *dest;
1199
1200 source = SLOT(mlabel);
1201 dest = SLOT(sopeerlabel);
1202
1203 mac_lomac_copy_single(source, dest);
1204 }
1205
1206 /*
1207 * Labeling event operations: network objects.
1208 */
1209 static void
1210 mac_lomac_set_socket_peer_from_socket(struct socket *oldso,
1211 struct label *oldsolabel, struct socket *newso,
1212 struct label *newsopeerlabel)
1213 {
1214 struct mac_lomac *source, *dest;
1215
1216 source = SLOT(oldsolabel);
1217 dest = SLOT(newsopeerlabel);
1218
1219 mac_lomac_copy_single(source, dest);
1220 }
1221
1222 static void
1223 mac_lomac_create_bpfdesc(struct ucred *cred, struct bpf_d *d,
1224 struct label *dlabel)
1225 {
1226 struct mac_lomac *source, *dest;
1227
1228 source = SLOT(cred->cr_label);
1229 dest = SLOT(dlabel);
1230
1231 mac_lomac_copy_single(source, dest);
1232 }
1233
1234 static void
1235 mac_lomac_create_ifnet(struct ifnet *ifp, struct label *ifplabel)
1236 {
1237 char tifname[IFNAMSIZ], *p, *q;
1238 char tiflist[sizeof(trusted_interfaces)];
1239 struct mac_lomac *dest;
1240 int len, grade;
1241
1242 dest = SLOT(ifplabel);
1243
1244 if (ifp->if_type == IFT_LOOP) {
1245 grade = MAC_LOMAC_TYPE_EQUAL;
1246 goto set;
1247 }
1248
1249 if (trust_all_interfaces) {
1250 grade = MAC_LOMAC_TYPE_HIGH;
1251 goto set;
1252 }
1253
1254 grade = MAC_LOMAC_TYPE_LOW;
1255
1256 if (trusted_interfaces[0] == '\0' ||
1257 !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
1258 goto set;
1259
1260 bzero(tiflist, sizeof(tiflist));
1261 for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
1262 if(*p != ' ' && *p != '\t')
1263 *q = *p;
1264
1265 for (p = q = tiflist;; p++) {
1266 if (*p == ',' || *p == '\0') {
1267 len = p - q;
1268 if (len < IFNAMSIZ) {
1269 bzero(tifname, sizeof(tifname));
1270 bcopy(q, tifname, len);
1271 if (strcmp(tifname, ifp->if_xname) == 0) {
1272 grade = MAC_LOMAC_TYPE_HIGH;
1273 break;
1274 }
1275 }
1276 else {
1277 *p = '\0';
1278 printf("MAC/LOMAC warning: interface name "
1279 "\"%s\" is too long (must be < %d)\n",
1280 q, IFNAMSIZ);
1281 }
1282 if (*p == '\0')
1283 break;
1284 q = p + 1;
1285 }
1286 }
1287 set:
1288 mac_lomac_set_single(dest, grade, 0);
1289 mac_lomac_set_range(dest, grade, 0, grade, 0);
1290 }
1291
1292 static void
1293 mac_lomac_create_ipq(struct mbuf *m, struct label *mlabel, struct ipq *ipq,
1294 struct label *ipqlabel)
1295 {
1296 struct mac_lomac *source, *dest;
1297
1298 source = SLOT(mlabel);
1299 dest = SLOT(ipqlabel);
1300
1301 mac_lomac_copy_single(source, dest);
1302 }
1303
1304 static void
1305 mac_lomac_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
1306 struct mbuf *m, struct label *mlabel)
1307 {
1308 struct mac_lomac *source, *dest;
1309
1310 source = SLOT(ipqlabel);
1311 dest = SLOT(mlabel);
1312
1313 /* Just use the head, since we require them all to match. */
1314 mac_lomac_copy_single(source, dest);
1315 }
1316
1317 static void
1318 mac_lomac_create_fragment(struct mbuf *m, struct label *mlabel,
1319 struct mbuf *frag, struct label *fraglabel)
1320 {
1321 struct mac_lomac *source, *dest;
1322
1323 source = SLOT(mlabel);
1324 dest = SLOT(fraglabel);
1325
1326 mac_lomac_copy_single(source, dest);
1327 }
1328
1329 static void
1330 mac_lomac_create_mbuf_from_inpcb(struct inpcb *inp, struct label *inplabel,
1331 struct mbuf *m, struct label *mlabel)
1332 {
1333 struct mac_lomac *source, *dest;
1334
1335 source = SLOT(inplabel);
1336 dest = SLOT(mlabel);
1337
1338 mac_lomac_copy_single(source, dest);
1339 }
1340
1341 static void
1342 mac_lomac_create_mbuf_linklayer(struct ifnet *ifp, struct label *ifplabel,
1343 struct mbuf *m, struct label *mlabel)
1344 {
1345 struct mac_lomac *dest;
1346
1347 dest = SLOT(mlabel);
1348
1349 mac_lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0);
1350 }
1351
1352 static void
1353 mac_lomac_create_mbuf_from_bpfdesc(struct bpf_d *d, struct label *dlabel,
1354 struct mbuf *m, struct label *mlabel)
1355 {
1356 struct mac_lomac *source, *dest;
1357
1358 source = SLOT(dlabel);
1359 dest = SLOT(mlabel);
1360
1361 mac_lomac_copy_single(source, dest);
1362 }
1363
1364 static void
1365 mac_lomac_create_mbuf_from_ifnet(struct ifnet *ifp, struct label *ifplabel,
1366 struct mbuf *m, struct label *mlabel)
1367 {
1368 struct mac_lomac *source, *dest;
1369
1370 source = SLOT(ifplabel);
1371 dest = SLOT(mlabel);
1372
1373 mac_lomac_copy_single(source, dest);
1374 }
1375
1376 static void
1377 mac_lomac_create_mbuf_multicast_encap(struct mbuf *m, struct label *mlabel,
1378 struct ifnet *ifp, struct label *ifplabel, struct mbuf *mnew,
1379 struct label *mnewlabel)
1380 {
1381 struct mac_lomac *source, *dest;
1382
1383 source = SLOT(mlabel);
1384 dest = SLOT(mnewlabel);
1385
1386 mac_lomac_copy_single(source, dest);
1387 }
1388
1389 static void
1390 mac_lomac_create_mbuf_netlayer(struct mbuf *m, struct label *mlabel,
1391 struct mbuf *mnew, struct label *mnewlabel)
1392 {
1393 struct mac_lomac *source, *dest;
1394
1395 source = SLOT(mlabel);
1396 dest = SLOT(mnewlabel);
1397
1398 mac_lomac_copy_single(source, dest);
1399 }
1400
1401 static int
1402 mac_lomac_fragment_match(struct mbuf *m, struct label *mlabel,
1403 struct ipq *ipq, struct label *ipqlabel)
1404 {
1405 struct mac_lomac *a, *b;
1406
1407 a = SLOT(ipqlabel);
1408 b = SLOT(mlabel);
1409
1410 return (mac_lomac_equal_single(a, b));
1411 }
1412
1413 static void
1414 mac_lomac_relabel_ifnet(struct ucred *cred, struct ifnet *ifp,
1415 struct label *ifplabel, struct label *newlabel)
1416 {
1417 struct mac_lomac *source, *dest;
1418
1419 source = SLOT(newlabel);
1420 dest = SLOT(ifplabel);
1421
1422 try_relabel(source, dest);
1423 }
1424
1425 static void
1426 mac_lomac_update_ipq(struct mbuf *m, struct label *mlabel, struct ipq *ipq,
1427 struct label *ipqlabel)
1428 {
1429
1430 /* NOOP: we only accept matching labels, so no need to update */
1431 }
1432
1433 static void
1434 mac_lomac_inpcb_sosetlabel(struct socket *so, struct label *solabel,
1435 struct inpcb *inp, struct label *inplabel)
1436 {
1437 struct mac_lomac *source, *dest;
1438
1439 source = SLOT(solabel);
1440 dest = SLOT(inplabel);
1441
1442 mac_lomac_copy_single(source, dest);
1443 }
1444
1445 static void
1446 mac_lomac_init_syncache_from_inpcb(struct label *label, struct inpcb *inp)
1447 {
1448 struct mac_lomac *source, *dest;
1449
1450 source = SLOT(inp->inp_label);
1451 dest = SLOT(label);
1452 mac_lomac_copy(source, dest);
1453 }
1454
1455 static void
1456 mac_lomac_create_mbuf_from_syncache(struct label *sc_label, struct mbuf *m,
1457 struct label *mlabel)
1458 {
1459 struct mac_lomac *source, *dest;
1460
1461 source = SLOT(sc_label);
1462 dest = SLOT(mlabel);
1463 mac_lomac_copy(source, dest);
1464 }
1465
1466 static void
1467 mac_lomac_create_mbuf_from_firewall(struct mbuf *m, struct label *mlabel)
1468 {
1469 struct mac_lomac *dest;
1470
1471 dest = SLOT(mlabel);
1472
1473 /* XXX: where is the label for the firewall really comming from? */
1474 mac_lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0);
1475 }
1476
1477 /*
1478 * Labeling event operations: processes.
1479 */
1480 static void
1481 mac_lomac_execve_transition(struct ucred *old, struct ucred *new,
1482 struct vnode *vp, struct label *vplabel, struct label *interpvnodelabel,
1483 struct image_params *imgp, struct label *execlabel)
1484 {
1485 struct mac_lomac *source, *dest, *obj, *robj;
1486
1487 source = SLOT(old->cr_label);
1488 dest = SLOT(new->cr_label);
1489 obj = SLOT(vplabel);
1490 robj = interpvnodelabel != NULL ? SLOT(interpvnodelabel) : obj;
1491
1492 mac_lomac_copy(source, dest);
1493 /*
1494 * If there's an auxiliary label on the real object, respect it
1495 * and assume that this level should be assumed immediately if
1496 * a higher level is currently in place.
1497 */
1498 if (robj->ml_flags & MAC_LOMAC_FLAG_AUX &&
1499 !mac_lomac_dominate_element(&robj->ml_auxsingle, &dest->ml_single)
1500 && mac_lomac_auxsingle_in_range(robj, dest))
1501 mac_lomac_set_single(dest, robj->ml_auxsingle.mle_type,
1502 robj->ml_auxsingle.mle_grade);
1503 /*
1504 * Restructuring to use the execve transitioning mechanism
1505 * instead of the normal demotion mechanism here would be
1506 * difficult, so just copy the label over and perform standard
1507 * demotion. This is also non-optimal because it will result
1508 * in the intermediate label "new" being created and immediately
1509 * recycled.
1510 */
1511 if (mac_lomac_enabled && revocation_enabled &&
1512 !mac_lomac_dominate_single(obj, source))
1513 (void)maybe_demote(source, obj, "executing", "file", vp);
1514 }
1515
1516 static int
1517 mac_lomac_execve_will_transition(struct ucred *old, struct vnode *vp,
1518 struct label *vplabel, struct label *interpvnodelabel,
1519 struct image_params *imgp, struct label *execlabel)
1520 {
1521 struct mac_lomac *subj, *obj, *robj;
1522
1523 if (!mac_lomac_enabled || !revocation_enabled)
1524 return (0);
1525
1526 subj = SLOT(old->cr_label);
1527 obj = SLOT(vplabel);
1528 robj = interpvnodelabel != NULL ? SLOT(interpvnodelabel) : obj;
1529
1530 return ((robj->ml_flags & MAC_LOMAC_FLAG_AUX &&
1531 !mac_lomac_dominate_element(&robj->ml_auxsingle, &subj->ml_single)
1532 && mac_lomac_auxsingle_in_range(robj, subj)) ||
1533 !mac_lomac_dominate_single(obj, subj));
1534 }
1535
1536 static void
1537 mac_lomac_create_proc0(struct ucred *cred)
1538 {
1539 struct mac_lomac *dest;
1540
1541 dest = SLOT(cred->cr_label);
1542
1543 mac_lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0);
1544 mac_lomac_set_range(dest, MAC_LOMAC_TYPE_LOW, 0, MAC_LOMAC_TYPE_HIGH,
1545 0);
1546 }
1547
1548 static void
1549 mac_lomac_create_proc1(struct ucred *cred)
1550 {
1551 struct mac_lomac *dest;
1552
1553 dest = SLOT(cred->cr_label);
1554
1555 mac_lomac_set_single(dest, MAC_LOMAC_TYPE_HIGH, 0);
1556 mac_lomac_set_range(dest, MAC_LOMAC_TYPE_LOW, 0, MAC_LOMAC_TYPE_HIGH,
1557 0);
1558 }
1559
1560 static void
1561 mac_lomac_relabel_cred(struct ucred *cred, struct label *newlabel)
1562 {
1563 struct mac_lomac *source, *dest;
1564
1565 source = SLOT(newlabel);
1566 dest = SLOT(cred->cr_label);
1567
1568 try_relabel(source, dest);
1569 }
1570
1571 /*
1572 * Access control checks.
1573 */
1574 static int
1575 mac_lomac_check_bpfdesc_receive(struct bpf_d *d, struct label *dlabel,
1576 struct ifnet *ifp, struct label *ifplabel)
1577 {
1578 struct mac_lomac *a, *b;
1579
1580 if (!mac_lomac_enabled)
1581 return (0);
1582
1583 a = SLOT(dlabel);
1584 b = SLOT(ifplabel);
1585
1586 if (mac_lomac_equal_single(a, b))
1587 return (0);
1588 return (EACCES);
1589 }
1590
1591 static int
1592 mac_lomac_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1593 {
1594 struct mac_lomac *subj, *new;
1595 int error;
1596
1597 subj = SLOT(cred->cr_label);
1598 new = SLOT(newlabel);
1599
1600 /*
1601 * If there is a LOMAC label update for the credential, it may
1602 * be an update of the single, range, or both.
1603 */
1604 error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH);
1605 if (error)
1606 return (error);
1607
1608 /*
1609 * If the LOMAC label is to be changed, authorize as appropriate.
1610 */
1611 if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) {
1612 /*
1613 * Fill in the missing parts from the previous label.
1614 */
1615 if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0)
1616 mac_lomac_copy_single(subj, new);
1617 if ((new->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0)
1618 mac_lomac_copy_range(subj, new);
1619
1620 /*
1621 * To change the LOMAC range on a credential, the new
1622 * range label must be in the current range.
1623 */
1624 if (!mac_lomac_range_in_range(new, subj))
1625 return (EPERM);
1626
1627 /*
1628 * To change the LOMAC single label on a credential, the
1629 * new single label must be in the new range. Implicitly
1630 * from the previous check, the new single is in the old
1631 * range.
1632 */
1633 if (!mac_lomac_single_in_range(new, new))
1634 return (EPERM);
1635
1636 /*
1637 * To have EQUAL in any component of the new credential
1638 * LOMAC label, the subject must already have EQUAL in
1639 * their label.
1640 */
1641 if (mac_lomac_contains_equal(new)) {
1642 error = mac_lomac_subject_privileged(subj);
1643 if (error)
1644 return (error);
1645 }
1646
1647 /*
1648 * XXXMAC: Additional consistency tests regarding the
1649 * single and range of the new label might be performed
1650 * here.
1651 */
1652 }
1653
1654 return (0);
1655 }
1656
1657 static int
1658 mac_lomac_check_cred_visible(struct ucred *cr1, struct ucred *cr2)
1659 {
1660 struct mac_lomac *subj, *obj;
1661
1662 if (!mac_lomac_enabled)
1663 return (0);
1664
1665 subj = SLOT(cr1->cr_label);
1666 obj = SLOT(cr2->cr_label);
1667
1668 /* XXX: range */
1669 if (!mac_lomac_dominate_single(obj, subj))
1670 return (ESRCH);
1671
1672 return (0);
1673 }
1674
1675 static int
1676 mac_lomac_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifp,
1677 struct label *ifplabel, struct label *newlabel)
1678 {
1679 struct mac_lomac *subj, *new;
1680 int error;
1681
1682 subj = SLOT(cred->cr_label);
1683 new = SLOT(newlabel);
1684
1685 /*
1686 * If there is a LOMAC label update for the interface, it may
1687 * be an update of the single, range, or both.
1688 */
1689 error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH);
1690 if (error)
1691 return (error);
1692
1693 /*
1694 * Relabling network interfaces requires LOMAC privilege.
1695 */
1696 error = mac_lomac_subject_privileged(subj);
1697 if (error)
1698 return (error);
1699
1700 /*
1701 * If the LOMAC label is to be changed, authorize as appropriate.
1702 */
1703 if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) {
1704 /*
1705 * Fill in the missing parts from the previous label.
1706 */
1707 if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0)
1708 mac_lomac_copy_single(subj, new);
1709 if ((new->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0)
1710 mac_lomac_copy_range(subj, new);
1711
1712 /*
1713 * Rely on the traditional superuser status for the LOMAC
1714 * interface relabel requirements. XXXMAC: This will go
1715 * away.
1716 *
1717 * XXXRW: This is also redundant to a higher layer check.
1718 */
1719 error = priv_check_cred(cred, PRIV_NET_SETIFMAC, 0);
1720 if (error)
1721 return (EPERM);
1722
1723 /*
1724 * XXXMAC: Additional consistency tests regarding the single
1725 * and the range of the new label might be performed here.
1726 */
1727 }
1728
1729 return (0);
1730 }
1731
1732 static int
1733 mac_lomac_check_ifnet_transmit(struct ifnet *ifp, struct label *ifplabel,
1734 struct mbuf *m, struct label *mlabel)
1735 {
1736 struct mac_lomac *p, *i;
1737
1738 if (!mac_lomac_enabled)
1739 return (0);
1740
1741 p = SLOT(mlabel);
1742 i = SLOT(ifplabel);
1743
1744 return (mac_lomac_single_in_range(p, i) ? 0 : EACCES);
1745 }
1746
1747 static int
1748 mac_lomac_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel,
1749 struct mbuf *m, struct label *mlabel)
1750 {
1751 struct mac_lomac *p, *i;
1752
1753 if (!mac_lomac_enabled)
1754 return (0);
1755
1756 p = SLOT(mlabel);
1757 i = SLOT(inplabel);
1758
1759 return (mac_lomac_equal_single(p, i) ? 0 : EACCES);
1760 }
1761
1762 static int
1763 mac_lomac_check_kld_load(struct ucred *cred, struct vnode *vp,
1764 struct label *vplabel)
1765 {
1766 struct mac_lomac *subj, *obj;
1767
1768 if (!mac_lomac_enabled)
1769 return (0);
1770
1771 subj = SLOT(cred->cr_label);
1772 obj = SLOT(vplabel);
1773
1774 if (mac_lomac_subject_privileged(subj))
1775 return (EPERM);
1776
1777 if (!mac_lomac_high_single(obj))
1778 return (EACCES);
1779
1780 return (0);
1781 }
1782
1783 static int
1784 mac_lomac_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp,
1785 struct label *pplabel, unsigned long cmd, void /* caddr_t */ *data)
1786 {
1787
1788 if (!mac_lomac_enabled)
1789 return (0);
1790
1791 /* XXX: This will be implemented soon... */
1792
1793 return (0);
1794 }
1795
1796 static int
1797 mac_lomac_check_pipe_read(struct ucred *cred, struct pipepair *pp,
1798 struct label *pplabel)
1799 {
1800 struct mac_lomac *subj, *obj;
1801
1802 if (!mac_lomac_enabled)
1803 return (0);
1804
1805 subj = SLOT(cred->cr_label);
1806 obj = SLOT(pplabel);
1807
1808 if (!mac_lomac_dominate_single(obj, subj))
1809 return (maybe_demote(subj, obj, "reading", "pipe", NULL));
1810
1811 return (0);
1812 }
1813
1814 static int
1815 mac_lomac_check_pipe_relabel(struct ucred *cred, struct pipepair *pp,
1816 struct label *pplabel, struct label *newlabel)
1817 {
1818 struct mac_lomac *subj, *obj, *new;
1819 int error;
1820
1821 new = SLOT(newlabel);
1822 subj = SLOT(cred->cr_label);
1823 obj = SLOT(pplabel);
1824
1825 /*
1826 * If there is a LOMAC label update for a pipe, it must be a
1827 * single update.
1828 */
1829 error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE);
1830 if (error)
1831 return (error);
1832
1833 /*
1834 * To perform a relabel of a pipe (LOMAC label or not), LOMAC must
1835 * authorize the relabel.
1836 */
1837 if (!mac_lomac_single_in_range(obj, subj))
1838 return (EPERM);
1839
1840 /*
1841 * If the LOMAC label is to be changed, authorize as appropriate.
1842 */
1843 if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
1844 /*
1845 * To change the LOMAC label on a pipe, the new pipe label
1846 * must be in the subject range.
1847 */
1848 if (!mac_lomac_single_in_range(new, subj))
1849 return (EPERM);
1850
1851 /*
1852 * To change the LOMAC label on a pipe to be EQUAL, the
1853 * subject must have appropriate privilege.
1854 */
1855 if (mac_lomac_contains_equal(new)) {
1856 error = mac_lomac_subject_privileged(subj);
1857 if (error)
1858 return (error);
1859 }
1860 }
1861
1862 return (0);
1863 }
1864
1865 static int
1866 mac_lomac_check_pipe_write(struct ucred *cred, struct pipepair *pp,
1867 struct label *pplabel)
1868 {
1869 struct mac_lomac *subj, *obj;
1870
1871 if (!mac_lomac_enabled)
1872 return (0);
1873
1874 subj = SLOT(cred->cr_label);
1875 obj = SLOT(pplabel);
1876
1877 if (!mac_lomac_subject_dominate(subj, obj))
1878 return (EACCES);
1879
1880 return (0);
1881 }
1882
1883 static int
1884 mac_lomac_check_proc_debug(struct ucred *cred, struct proc *p)
1885 {
1886 struct mac_lomac *subj, *obj;
1887
1888 if (!mac_lomac_enabled)
1889 return (0);
1890
1891 subj = SLOT(cred->cr_label);
1892 obj = SLOT(p->p_ucred->cr_label);
1893
1894 /* XXX: range checks */
1895 if (!mac_lomac_dominate_single(obj, subj))
1896 return (ESRCH);
1897 if (!mac_lomac_subject_dominate(subj, obj))
1898 return (EACCES);
1899
1900 return (0);
1901 }
1902
1903 static int
1904 mac_lomac_check_proc_sched(struct ucred *cred, struct proc *p)
1905 {
1906 struct mac_lomac *subj, *obj;
1907
1908 if (!mac_lomac_enabled)
1909 return (0);
1910
1911 subj = SLOT(cred->cr_label);
1912 obj = SLOT(p->p_ucred->cr_label);
1913
1914 /* XXX: range checks */
1915 if (!mac_lomac_dominate_single(obj, subj))
1916 return (ESRCH);
1917 if (!mac_lomac_subject_dominate(subj, obj))
1918 return (EACCES);
1919
1920 return (0);
1921 }
1922
1923 static int
1924 mac_lomac_check_proc_signal(struct ucred *cred, struct proc *p, int signum)
1925 {
1926 struct mac_lomac *subj, *obj;
1927
1928 if (!mac_lomac_enabled)
1929 return (0);
1930
1931 subj = SLOT(cred->cr_label);
1932 obj = SLOT(p->p_ucred->cr_label);
1933
1934 /* XXX: range checks */
1935 if (!mac_lomac_dominate_single(obj, subj))
1936 return (ESRCH);
1937 if (!mac_lomac_subject_dominate(subj, obj))
1938 return (EACCES);
1939
1940 return (0);
1941 }
1942
1943 static int
1944 mac_lomac_check_socket_deliver(struct socket *so, struct label *solabel,
1945 struct mbuf *m, struct label *mlabel)
1946 {
1947 struct mac_lomac *p, *s;
1948
1949 if (!mac_lomac_enabled)
1950 return (0);
1951
1952 p = SLOT(mlabel);
1953 s = SLOT(solabel);
1954
1955 return (mac_lomac_equal_single(p, s) ? 0 : EACCES);
1956 }
1957
1958 static int
1959 mac_lomac_check_socket_relabel(struct ucred *cred, struct socket *so,
1960 struct label *solabel, struct label *newlabel)
1961 {
1962 struct mac_lomac *subj, *obj, *new;
1963 int error;
1964
1965 new = SLOT(newlabel);
1966 subj = SLOT(cred->cr_label);
1967 obj = SLOT(solabel);
1968
1969 /*
1970 * If there is a LOMAC label update for the socket, it may be
1971 * an update of single.
1972 */
1973 error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE);
1974 if (error)
1975 return (error);
1976
1977 /*
1978 * To relabel a socket, the old socket single must be in the subject
1979 * range.
1980 */
1981 if (!mac_lomac_single_in_range(obj, subj))
1982 return (EPERM);
1983
1984 /*
1985 * If the LOMAC label is to be changed, authorize as appropriate.
1986 */
1987 if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
1988 /*
1989 * To relabel a socket, the new socket single must be in
1990 * the subject range.
1991 */
1992 if (!mac_lomac_single_in_range(new, subj))
1993 return (EPERM);
1994
1995 /*
1996 * To change the LOMAC label on the socket to contain EQUAL,
1997 * the subject must have appropriate privilege.
1998 */
1999 if (mac_lomac_contains_equal(new)) {
2000 error = mac_lomac_subject_privileged(subj);
2001 if (error)
2002 return (error);
2003 }
2004 }
2005
2006 return (0);
2007 }
2008
2009 static int
2010 mac_lomac_check_socket_visible(struct ucred *cred, struct socket *so,
2011 struct label *solabel)
2012 {
2013 struct mac_lomac *subj, *obj;
2014
2015 if (!mac_lomac_enabled)
2016 return (0);
2017
2018 subj = SLOT(cred->cr_label);
2019 obj = SLOT(solabel);
2020
2021 if (!mac_lomac_dominate_single(obj, subj))
2022 return (ENOENT);
2023
2024 return (0);
2025 }
2026
2027 /*
2028 * Some system privileges are allowed regardless of integrity grade; others
2029 * are allowed only when running with privilege with respect to the LOMAC
2030 * policy as they might otherwise allow bypassing of the integrity policy.
2031 */
2032 static int
2033 mac_lomac_priv_check(struct ucred *cred, int priv)
2034 {
2035 struct mac_lomac *subj;
2036 int error;
2037
2038 if (!mac_lomac_enabled)
2039 return (0);
2040
2041 /*
2042 * Exempt only specific privileges from the LOMAC integrity policy.
2043 */
2044 switch (priv) {
2045 case PRIV_KTRACE:
2046 case PRIV_MSGBUF:
2047
2048 /*
2049 * Allow processes to manipulate basic process audit properties, and
2050 * to submit audit records.
2051 */
2052 case PRIV_AUDIT_GETAUDIT:
2053 case PRIV_AUDIT_SETAUDIT:
2054 case PRIV_AUDIT_SUBMIT:
2055
2056 /*
2057 * Allow processes to manipulate their regular UNIX credentials.
2058 */
2059 case PRIV_CRED_SETUID:
2060 case PRIV_CRED_SETEUID:
2061 case PRIV_CRED_SETGID:
2062 case PRIV_CRED_SETEGID:
2063 case PRIV_CRED_SETGROUPS:
2064 case PRIV_CRED_SETREUID:
2065 case PRIV_CRED_SETREGID:
2066 case PRIV_CRED_SETRESUID:
2067 case PRIV_CRED_SETRESGID:
2068
2069 /*
2070 * Allow processes to perform system monitoring.
2071 */
2072 case PRIV_SEEOTHERGIDS:
2073 case PRIV_SEEOTHERUIDS:
2074 break;
2075
2076 /*
2077 * Allow access to general process debugging facilities. We
2078 * separately control debugging based on MAC label.
2079 */
2080 case PRIV_DEBUG_DIFFCRED:
2081 case PRIV_DEBUG_SUGID:
2082 case PRIV_DEBUG_UNPRIV:
2083
2084 /*
2085 * Allow manipulating jails.
2086 */
2087 case PRIV_JAIL_ATTACH:
2088
2089 /*
2090 * Allow privilege with respect to the Partition policy, but not the
2091 * Privs policy.
2092 */
2093 case PRIV_MAC_PARTITION:
2094
2095 /*
2096 * Allow privilege with respect to process resource limits and login
2097 * context.
2098 */
2099 case PRIV_PROC_LIMIT:
2100 case PRIV_PROC_SETLOGIN:
2101 case PRIV_PROC_SETRLIMIT:
2102
2103 /*
2104 * Allow System V and POSIX IPC privileges.
2105 */
2106 case PRIV_IPC_READ:
2107 case PRIV_IPC_WRITE:
2108 case PRIV_IPC_ADMIN:
2109 case PRIV_IPC_MSGSIZE:
2110 case PRIV_MQ_ADMIN:
2111
2112 /*
2113 * Allow certain scheduler manipulations -- possibly this should be
2114 * controlled by more fine-grained policy, as potentially low
2115 * integrity processes can deny CPU to higher integrity ones.
2116 */
2117 case PRIV_SCHED_DIFFCRED:
2118 case PRIV_SCHED_SETPRIORITY:
2119 case PRIV_SCHED_RTPRIO:
2120 case PRIV_SCHED_SETPOLICY:
2121 case PRIV_SCHED_SET:
2122 case PRIV_SCHED_SETPARAM:
2123
2124 /*
2125 * More IPC privileges.
2126 */
2127 case PRIV_SEM_WRITE:
2128
2129 /*
2130 * Allow signaling privileges subject to integrity policy.
2131 */
2132 case PRIV_SIGNAL_DIFFCRED:
2133 case PRIV_SIGNAL_SUGID:
2134
2135 /*
2136 * Allow access to only limited sysctls from lower integrity levels;
2137 * piggy-back on the Jail definition.
2138 */
2139 case PRIV_SYSCTL_WRITEJAIL:
2140
2141 /*
2142 * Allow TTY-based privileges, subject to general device access using
2143 * labels on TTY device nodes, but not console privilege.
2144 */
2145 case PRIV_TTY_DRAINWAIT:
2146 case PRIV_TTY_DTRWAIT:
2147 case PRIV_TTY_EXCLUSIVE:
2148 case PRIV_TTY_PRISON:
2149 case PRIV_TTY_STI:
2150 case PRIV_TTY_SETA:
2151
2152 /*
2153 * Grant most VFS privileges, as almost all are in practice bounded
2154 * by more specific checks using labels.
2155 */
2156 case PRIV_VFS_READ:
2157 case PRIV_VFS_WRITE:
2158 case PRIV_VFS_ADMIN:
2159 case PRIV_VFS_EXEC:
2160 case PRIV_VFS_LOOKUP:
2161 case PRIV_VFS_CHFLAGS_DEV:
2162 case PRIV_VFS_CHOWN:
2163 case PRIV_VFS_CHROOT:
2164 case PRIV_VFS_RETAINSUGID:
2165 case PRIV_VFS_EXCEEDQUOTA:
2166 case PRIV_VFS_FCHROOT:
2167 case PRIV_VFS_FHOPEN:
2168 case PRIV_VFS_FHSTATFS:
2169 case PRIV_VFS_GENERATION:
2170 case PRIV_VFS_GETFH:
2171 case PRIV_VFS_GETQUOTA:
2172 case PRIV_VFS_LINK:
2173 case PRIV_VFS_MOUNT:
2174 case PRIV_VFS_MOUNT_OWNER:
2175 case PRIV_VFS_MOUNT_PERM:
2176 case PRIV_VFS_MOUNT_SUIDDIR:
2177 case PRIV_VFS_MOUNT_NONUSER:
2178 case PRIV_VFS_SETGID:
2179 case PRIV_VFS_STICKYFILE:
2180 case PRIV_VFS_SYSFLAGS:
2181 case PRIV_VFS_UNMOUNT:
2182
2183 /*
2184 * Allow VM privileges; it would be nice if these were subject to
2185 * resource limits.
2186 */
2187 case PRIV_VM_MADV_PROTECT:
2188 case PRIV_VM_MLOCK:
2189 case PRIV_VM_MUNLOCK:
2190
2191 /*
2192 * Allow some but not all network privileges. In general, dont allow
2193 * reconfiguring the network stack, just normal use.
2194 */
2195 case PRIV_NETATALK_RESERVEDPORT:
2196 case PRIV_NETINET_RESERVEDPORT:
2197 case PRIV_NETINET_RAW:
2198 case PRIV_NETINET_REUSEPORT:
2199 case PRIV_NETIPX_RESERVEDPORT:
2200 case PRIV_NETIPX_RAW:
2201 break;
2202
2203 /*
2204 * All remaining system privileges are allow only if the process
2205 * holds privilege with respect to the LOMAC policy.
2206 */
2207 default:
2208 subj = SLOT(cred->cr_label);
2209 error = mac_lomac_subject_privileged(subj);
2210 if (error)
2211 return (error);
2212 }
2213 return (0);
2214 }
2215
2216
2217 static int
2218 mac_lomac_check_system_acct(struct ucred *cred, struct vnode *vp,
2219 struct label *vplabel)
2220 {
2221 struct mac_lomac *subj, *obj;
2222
2223 if (!mac_lomac_enabled)
2224 return (0);
2225
2226 subj = SLOT(cred->cr_label);
2227 obj = SLOT(vplabel);
2228
2229 if (mac_lomac_subject_privileged(subj))
2230 return (EPERM);
2231
2232 if (!mac_lomac_high_single(obj))
2233 return (EACCES);
2234
2235 return (0);
2236 }
2237
2238 static int
2239 mac_lomac_check_system_auditctl(struct ucred *cred, struct vnode *vp,
2240 struct label *vplabel)
2241 {
2242 struct mac_lomac *subj, *obj;
2243
2244 if (!mac_lomac_enabled)
2245 return (0);
2246
2247 subj = SLOT(cred->cr_label);
2248 obj = SLOT(vplabel);
2249
2250 if (mac_lomac_subject_privileged(subj))
2251 return (EPERM);
2252
2253 if (!mac_lomac_high_single(obj))
2254 return (EACCES);
2255
2256 return (0);
2257 }
2258
2259 static int
2260 mac_lomac_check_system_swapoff(struct ucred *cred, struct vnode *vp,
2261 struct label *vplabel)
2262 {
2263 struct mac_lomac *subj;
2264
2265 if (!mac_lomac_enabled)
2266 return (0);
2267
2268 subj = SLOT(cred->cr_label);
2269
2270 if (mac_lomac_subject_privileged(subj))
2271 return (EPERM);
2272
2273 return (0);
2274 }
2275
2276 static int
2277 mac_lomac_check_system_swapon(struct ucred *cred, struct vnode *vp,
2278 struct label *vplabel)
2279 {
2280 struct mac_lomac *subj, *obj;
2281
2282 if (!mac_lomac_enabled)
2283 return (0);
2284
2285 subj = SLOT(cred->cr_label);
2286 obj = SLOT(vplabel);
2287
2288 if (mac_lomac_subject_privileged(subj))
2289 return (EPERM);
2290
2291 if (!mac_lomac_high_single(obj))
2292 return (EACCES);
2293
2294 return (0);
2295 }
2296
2297 static int
2298 mac_lomac_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp,
2299 void *arg1, int arg2, struct sysctl_req *req)
2300 {
2301 struct mac_lomac *subj;
2302
2303 if (!mac_lomac_enabled)
2304 return (0);
2305
2306 subj = SLOT(cred->cr_label);
2307
2308 /*
2309 * Treat sysctl variables without CTLFLAG_ANYBODY flag as
2310 * lomac/high, but also require privilege to change them.
2311 */
2312 if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) {
2313 #ifdef notdef
2314 if (!mac_lomac_subject_dominate_high(subj))
2315 return (EACCES);
2316 #endif
2317
2318 if (mac_lomac_subject_privileged(subj))
2319 return (EPERM);
2320 }
2321
2322 return (0);
2323 }
2324
2325 static int
2326 mac_lomac_check_vnode_create(struct ucred *cred, struct vnode *dvp,
2327 struct label *dvplabel, struct componentname *cnp, struct vattr *vap)
2328 {
2329 struct mac_lomac *subj, *obj;
2330
2331 if (!mac_lomac_enabled)
2332 return (0);
2333
2334 subj = SLOT(cred->cr_label);
2335 obj = SLOT(dvplabel);
2336
2337 if (!mac_lomac_subject_dominate(subj, obj))
2338 return (EACCES);
2339 if (obj->ml_flags & MAC_LOMAC_FLAG_AUX &&
2340 !mac_lomac_dominate_element(&subj->ml_single, &obj->ml_auxsingle))
2341 return (EACCES);
2342
2343 return (0);
2344 }
2345
2346 static int
2347 mac_lomac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
2348 struct label *vplabel, acl_type_t type)
2349 {
2350 struct mac_lomac *subj, *obj;
2351
2352 if (!mac_lomac_enabled)
2353 return (0);
2354
2355 subj = SLOT(cred->cr_label);
2356 obj = SLOT(vplabel);
2357
2358 if (!mac_lomac_subject_dominate(subj, obj))
2359 return (EACCES);
2360
2361 return (0);
2362 }
2363
2364 static int
2365 mac_lomac_check_vnode_link(struct ucred *cred, struct vnode *dvp,
2366 struct label *dvplabel, struct vnode *vp, struct label *vplabel,
2367 struct componentname *cnp)
2368 {
2369 struct mac_lomac *subj, *obj;
2370
2371 if (!mac_lomac_enabled)
2372 return (0);
2373
2374 subj = SLOT(cred->cr_label);
2375 obj = SLOT(dvplabel);
2376
2377 if (!mac_lomac_subject_dominate(subj, obj))
2378 return (EACCES);
2379
2380 obj = SLOT(vplabel);
2381
2382 if (!mac_lomac_subject_dominate(subj, obj))
2383 return (EACCES);
2384
2385 return (0);
2386 }
2387
2388 static int
2389 mac_lomac_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
2390 struct label *vplabel, int prot, int flags)
2391 {
2392 struct mac_lomac *subj, *obj;
2393
2394 /*
2395 * Rely on the use of open()-time protections to handle
2396 * non-revocation cases.
2397 */
2398 if (!mac_lomac_enabled)
2399 return (0);
2400
2401 subj = SLOT(cred->cr_label);
2402 obj = SLOT(vplabel);
2403
2404 if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) {
2405 if (!mac_lomac_subject_dominate(subj, obj))
2406 return (EACCES);
2407 }
2408 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2409 if (!mac_lomac_dominate_single(obj, subj))
2410 return (maybe_demote(subj, obj, "mapping", "file", vp));
2411 }
2412
2413 return (0);
2414 }
2415
2416 static void
2417 mac_lomac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp,
2418 struct label *vplabel, /* XXX vm_prot_t */ int *prot)
2419 {
2420 struct mac_lomac *subj, *obj;
2421
2422 /*
2423 * Rely on the use of open()-time protections to handle
2424 * non-revocation cases.
2425 */
2426 if (!mac_lomac_enabled || !revocation_enabled)
2427 return;
2428
2429 subj = SLOT(cred->cr_label);
2430 obj = SLOT(vplabel);
2431
2432 if (!mac_lomac_subject_dominate(subj, obj))
2433 *prot &= ~VM_PROT_WRITE;
2434 }
2435
2436 static int
2437 mac_lomac_check_vnode_open(struct ucred *cred, struct vnode *vp,
2438 struct label *vplabel, int acc_mode)
2439 {
2440 struct mac_lomac *subj, *obj;
2441
2442 if (!mac_lomac_enabled)
2443 return (0);
2444
2445 subj = SLOT(cred->cr_label);
2446 obj = SLOT(vplabel);
2447
2448 /* XXX privilege override for admin? */
2449 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2450 if (!mac_lomac_subject_dominate(subj, obj))
2451 return (EACCES);
2452 }
2453
2454 return (0);
2455 }
2456
2457 static int
2458 mac_lomac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2459 struct vnode *vp, struct label *vplabel)
2460 {
2461 struct mac_lomac *subj, *obj;
2462
2463 if (!mac_lomac_enabled || !revocation_enabled)
2464 return (0);
2465
2466 subj = SLOT(active_cred->cr_label);
2467 obj = SLOT(vplabel);
2468
2469 if (!mac_lomac_dominate_single(obj, subj))
2470 return (maybe_demote(subj, obj, "reading", "file", vp));
2471
2472 return (0);
2473 }
2474
2475 static int
2476 mac_lomac_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2477 struct label *vplabel, struct label *newlabel)
2478 {
2479 struct mac_lomac *old, *new, *subj;
2480 int error;
2481
2482 old = SLOT(vplabel);
2483 new = SLOT(newlabel);
2484 subj = SLOT(cred->cr_label);
2485
2486 /*
2487 * If there is a LOMAC label update for the vnode, it must be a
2488 * single label, with an optional explicit auxiliary single.
2489 */
2490 error = lomac_atmostflags(new,
2491 MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_AUX);
2492 if (error)
2493 return (error);
2494
2495 /*
2496 * To perform a relabel of the vnode (LOMAC label or not), LOMAC must
2497 * authorize the relabel.
2498 */
2499 if (!mac_lomac_single_in_range(old, subj))
2500 return (EPERM);
2501
2502 /*
2503 * If the LOMAC label is to be changed, authorize as appropriate.
2504 */
2505 if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
2506 /*
2507 * To change the LOMAC label on a vnode, the new vnode label
2508 * must be in the subject range.
2509 */
2510 if (!mac_lomac_single_in_range(new, subj))
2511 return (EPERM);
2512
2513 /*
2514 * To change the LOMAC label on the vnode to be EQUAL,
2515 * the subject must have appropriate privilege.
2516 */
2517 if (mac_lomac_contains_equal(new)) {
2518 error = mac_lomac_subject_privileged(subj);
2519 if (error)
2520 return (error);
2521 }
2522 }
2523 if (new->ml_flags & MAC_LOMAC_FLAG_AUX) {
2524 /*
2525 * Fill in the missing parts from the previous label.
2526 */
2527 if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0)
2528 mac_lomac_copy_single(subj, new);
2529
2530 /*
2531 * To change the auxiliary LOMAC label on a vnode, the new
2532 * vnode label must be in the subject range.
2533 */
2534 if (!mac_lomac_auxsingle_in_range(new, subj))
2535 return (EPERM);
2536
2537 /*
2538 * To change the auxiliary LOMAC label on the vnode to be
2539 * EQUAL, the subject must have appropriate privilege.
2540 */
2541 if (mac_lomac_contains_equal(new)) {
2542 error = mac_lomac_subject_privileged(subj);
2543 if (error)
2544 return (error);
2545 }
2546 }
2547
2548 return (0);
2549 }
2550
2551 static int
2552 mac_lomac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2553 struct label *dvplabel, struct vnode *vp, struct label *vplabel,
2554 struct componentname *cnp)
2555 {
2556 struct mac_lomac *subj, *obj;
2557
2558 if (!mac_lomac_enabled)
2559 return (0);
2560
2561 subj = SLOT(cred->cr_label);
2562 obj = SLOT(dvplabel);
2563
2564 if (!mac_lomac_subject_dominate(subj, obj))
2565 return (EACCES);
2566
2567 obj = SLOT(vplabel);
2568
2569 if (!mac_lomac_subject_dominate(subj, obj))
2570 return (EACCES);
2571
2572 return (0);
2573 }
2574
2575 static int
2576 mac_lomac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2577 struct label *dvplabel, struct vnode *vp, struct label *vplabel,
2578 int samedir, struct componentname *cnp)
2579 {
2580 struct mac_lomac *subj, *obj;
2581
2582 if (!mac_lomac_enabled)
2583 return (0);
2584
2585 subj = SLOT(cred->cr_label);
2586 obj = SLOT(dvplabel);
2587
2588 if (!mac_lomac_subject_dominate(subj, obj))
2589 return (EACCES);
2590
2591 if (vp != NULL) {
2592 obj = SLOT(vplabel);
2593
2594 if (!mac_lomac_subject_dominate(subj, obj))
2595 return (EACCES);
2596 }
2597
2598 return (0);
2599 }
2600
2601 static int
2602 mac_lomac_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
2603 struct label *vplabel)
2604 {
2605 struct mac_lomac *subj, *obj;
2606
2607 if (!mac_lomac_enabled)
2608 return (0);
2609
2610 subj = SLOT(cred->cr_label);
2611 obj = SLOT(vplabel);
2612
2613 if (!mac_lomac_subject_dominate(subj, obj))
2614 return (EACCES);
2615
2616 return (0);
2617 }
2618
2619 static int
2620 mac_lomac_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
2621 struct label *vplabel, acl_type_t type, struct acl *acl)
2622 {
2623 struct mac_lomac *subj, *obj;
2624
2625 if (!mac_lomac_enabled)
2626 return (0);
2627
2628 subj = SLOT(cred->cr_label);
2629 obj = SLOT(vplabel);
2630
2631 if (!mac_lomac_subject_dominate(subj, obj))
2632 return (EACCES);
2633
2634 return (0);
2635 }
2636
2637 static int
2638 mac_lomac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2639 struct label *vplabel, int attrnamespace, const char *name,
2640 struct uio *uio)
2641 {
2642 struct mac_lomac *subj, *obj;
2643
2644 if (!mac_lomac_enabled)
2645 return (0);
2646
2647 subj = SLOT(cred->cr_label);
2648 obj = SLOT(vplabel);
2649
2650 if (!mac_lomac_subject_dominate(subj, obj))
2651 return (EACCES);
2652
2653 /* XXX: protect the MAC EA in a special way? */
2654
2655 return (0);
2656 }
2657
2658 static int
2659 mac_lomac_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2660 struct label *vplabel, u_long flags)
2661 {
2662 struct mac_lomac *subj, *obj;
2663
2664 if (!mac_lomac_enabled)
2665 return (0);
2666
2667 subj = SLOT(cred->cr_label);
2668 obj = SLOT(vplabel);
2669
2670 if (!mac_lomac_subject_dominate(subj, obj))
2671 return (EACCES);
2672
2673 return (0);
2674 }
2675
2676 static int
2677 mac_lomac_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2678 struct label *vplabel, mode_t mode)
2679 {
2680 struct mac_lomac *subj, *obj;
2681
2682 if (!mac_lomac_enabled)
2683 return (0);
2684
2685 subj = SLOT(cred->cr_label);
2686 obj = SLOT(vplabel);
2687
2688 if (!mac_lomac_subject_dominate(subj, obj))
2689 return (EACCES);
2690
2691 return (0);
2692 }
2693
2694 static int
2695 mac_lomac_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2696 struct label *vplabel, uid_t uid, gid_t gid)
2697 {
2698 struct mac_lomac *subj, *obj;
2699
2700 if (!mac_lomac_enabled)
2701 return (0);
2702
2703 subj = SLOT(cred->cr_label);
2704 obj = SLOT(vplabel);
2705
2706 if (!mac_lomac_subject_dominate(subj, obj))
2707 return (EACCES);
2708
2709 return (0);
2710 }
2711
2712 static int
2713 mac_lomac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2714 struct label *vplabel, struct timespec atime, struct timespec mtime)
2715 {
2716 struct mac_lomac *subj, *obj;
2717
2718 if (!mac_lomac_enabled)
2719 return (0);
2720
2721 subj = SLOT(cred->cr_label);
2722 obj = SLOT(vplabel);
2723
2724 if (!mac_lomac_subject_dominate(subj, obj))
2725 return (EACCES);
2726
2727 return (0);
2728 }
2729
2730 static int
2731 mac_lomac_check_vnode_unlink(struct ucred *cred, struct vnode *dvp,
2732 struct label *dvplabel, struct vnode *vp, struct label *vplabel,
2733 struct componentname *cnp)
2734 {
2735 struct mac_lomac *subj, *obj;
2736
2737 if (!mac_lomac_enabled)
2738 return (0);
2739
2740 subj = SLOT(cred->cr_label);
2741 obj = SLOT(dvplabel);
2742
2743 if (!mac_lomac_subject_dominate(subj, obj))
2744 return (EACCES);
2745
2746 obj = SLOT(vplabel);
2747
2748 if (!mac_lomac_subject_dominate(subj, obj))
2749 return (EACCES);
2750
2751 return (0);
2752 }
2753
2754 static int
2755 mac_lomac_check_vnode_write(struct ucred *active_cred,
2756 struct ucred *file_cred, struct vnode *vp, struct label *vplabel)
2757 {
2758 struct mac_lomac *subj, *obj;
2759
2760 if (!mac_lomac_enabled || !revocation_enabled)
2761 return (0);
2762
2763 subj = SLOT(active_cred->cr_label);
2764 obj = SLOT(vplabel);
2765
2766 if (!mac_lomac_subject_dominate(subj, obj))
2767 return (EACCES);
2768
2769 return (0);
2770 }
2771
2772 static void
2773 mac_lomac_thread_userret(struct thread *td)
2774 {
2775 struct proc *p = td->td_proc;
2776 struct mac_lomac_proc *subj = PSLOT(p->p_label);
2777 struct ucred *newcred, *oldcred;
2778 int dodrop;
2779
2780 mtx_lock(&subj->mtx);
2781 if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) {
2782 dodrop = 0;
2783 mtx_unlock(&subj->mtx);
2784 newcred = crget();
2785 /*
2786 * Prevent a lock order reversal in
2787 * mac_cred_mmapped_drop_perms; ideally, the other
2788 * user of subj->mtx wouldn't be holding Giant.
2789 */
2790 mtx_lock(&Giant);
2791 PROC_LOCK(p);
2792 mtx_lock(&subj->mtx);
2793 /*
2794 * Check if we lost the race while allocating the cred.
2795 */
2796 if ((subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) == 0) {
2797 crfree(newcred);
2798 goto out;
2799 }
2800 oldcred = p->p_ucred;
2801 crcopy(newcred, oldcred);
2802 crhold(newcred);
2803 mac_lomac_copy(&subj->mac_lomac, SLOT(newcred->cr_label));
2804 p->p_ucred = newcred;
2805 crfree(oldcred);
2806 dodrop = 1;
2807 out:
2808 mtx_unlock(&subj->mtx);
2809 PROC_UNLOCK(p);
2810 if (dodrop)
2811 mac_cred_mmapped_drop_perms(curthread, newcred);
2812 mtx_unlock(&Giant);
2813 } else {
2814 mtx_unlock(&subj->mtx);
2815 }
2816 }
2817
2818 static struct mac_policy_ops mac_lomac_ops =
2819 {
2820 .mpo_init = mac_lomac_init,
2821 .mpo_init_bpfdesc_label = mac_lomac_init_label,
2822 .mpo_init_cred_label = mac_lomac_init_label,
2823 .mpo_init_devfs_label = mac_lomac_init_label,
2824 .mpo_init_ifnet_label = mac_lomac_init_label,
2825 .mpo_init_syncache_label = mac_lomac_init_label_waitcheck,
2826 .mpo_init_inpcb_label = mac_lomac_init_label_waitcheck,
2827 .mpo_init_ipq_label = mac_lomac_init_label_waitcheck,
2828 .mpo_init_mbuf_label = mac_lomac_init_label_waitcheck,
2829 .mpo_init_mount_label = mac_lomac_init_label,
2830 .mpo_init_pipe_label = mac_lomac_init_label,
2831 .mpo_init_proc_label = mac_lomac_init_proc_label,
2832 .mpo_init_socket_label = mac_lomac_init_label_waitcheck,
2833 .mpo_init_socket_peer_label = mac_lomac_init_label_waitcheck,
2834 .mpo_init_vnode_label = mac_lomac_init_label,
2835 .mpo_init_syncache_from_inpcb = mac_lomac_init_syncache_from_inpcb,
2836 .mpo_destroy_bpfdesc_label = mac_lomac_destroy_label,
2837 .mpo_destroy_cred_label = mac_lomac_destroy_label,
2838 .mpo_destroy_devfs_label = mac_lomac_destroy_label,
2839 .mpo_destroy_ifnet_label = mac_lomac_destroy_label,
2840 .mpo_destroy_inpcb_label = mac_lomac_destroy_label,
2841 .mpo_destroy_ipq_label = mac_lomac_destroy_label,
2842 .mpo_destroy_mbuf_label = mac_lomac_destroy_label,
2843 .mpo_destroy_mount_label = mac_lomac_destroy_label,
2844 .mpo_destroy_pipe_label = mac_lomac_destroy_label,
2845 .mpo_destroy_proc_label = mac_lomac_destroy_proc_label,
2846 .mpo_destroy_syncache_label = mac_lomac_destroy_label,
2847 .mpo_destroy_socket_label = mac_lomac_destroy_label,
2848 .mpo_destroy_socket_peer_label = mac_lomac_destroy_label,
2849 .mpo_destroy_vnode_label = mac_lomac_destroy_label,
2850 .mpo_copy_cred_label = mac_lomac_copy_label,
2851 .mpo_copy_ifnet_label = mac_lomac_copy_label,
2852 .mpo_copy_mbuf_label = mac_lomac_copy_label,
2853 .mpo_copy_pipe_label = mac_lomac_copy_label,
2854 .mpo_copy_socket_label = mac_lomac_copy_label,
2855 .mpo_copy_vnode_label = mac_lomac_copy_label,
2856 .mpo_externalize_cred_label = mac_lomac_externalize_label,
2857 .mpo_externalize_ifnet_label = mac_lomac_externalize_label,
2858 .mpo_externalize_pipe_label = mac_lomac_externalize_label,
2859 .mpo_externalize_socket_label = mac_lomac_externalize_label,
2860 .mpo_externalize_socket_peer_label = mac_lomac_externalize_label,
2861 .mpo_externalize_vnode_label = mac_lomac_externalize_label,
2862 .mpo_internalize_cred_label = mac_lomac_internalize_label,
2863 .mpo_internalize_ifnet_label = mac_lomac_internalize_label,
2864 .mpo_internalize_pipe_label = mac_lomac_internalize_label,
2865 .mpo_internalize_socket_label = mac_lomac_internalize_label,
2866 .mpo_internalize_vnode_label = mac_lomac_internalize_label,
2867 .mpo_create_devfs_device = mac_lomac_create_devfs_device,
2868 .mpo_create_devfs_directory = mac_lomac_create_devfs_directory,
2869 .mpo_create_devfs_symlink = mac_lomac_create_devfs_symlink,
2870 .mpo_create_mount = mac_lomac_create_mount,
2871 .mpo_relabel_vnode = mac_lomac_relabel_vnode,
2872 .mpo_update_devfs = mac_lomac_update_devfs,
2873 .mpo_associate_vnode_devfs = mac_lomac_associate_vnode_devfs,
2874 .mpo_associate_vnode_extattr = mac_lomac_associate_vnode_extattr,
2875 .mpo_associate_vnode_singlelabel =
2876 mac_lomac_associate_vnode_singlelabel,
2877 .mpo_create_vnode_extattr = mac_lomac_create_vnode_extattr,
2878 .mpo_setlabel_vnode_extattr = mac_lomac_setlabel_vnode_extattr,
2879 .mpo_create_mbuf_from_socket = mac_lomac_create_mbuf_from_socket,
2880 .mpo_create_mbuf_from_syncache = mac_lomac_create_mbuf_from_syncache,
2881 .mpo_create_pipe = mac_lomac_create_pipe,
2882 .mpo_create_socket = mac_lomac_create_socket,
2883 .mpo_create_socket_from_socket = mac_lomac_create_socket_from_socket,
2884 .mpo_relabel_pipe = mac_lomac_relabel_pipe,
2885 .mpo_relabel_socket = mac_lomac_relabel_socket,
2886 .mpo_set_socket_peer_from_mbuf = mac_lomac_set_socket_peer_from_mbuf,
2887 .mpo_set_socket_peer_from_socket =
2888 mac_lomac_set_socket_peer_from_socket,
2889 .mpo_create_bpfdesc = mac_lomac_create_bpfdesc,
2890 .mpo_create_datagram_from_ipq = mac_lomac_create_datagram_from_ipq,
2891 .mpo_create_fragment = mac_lomac_create_fragment,
2892 .mpo_create_ifnet = mac_lomac_create_ifnet,
2893 .mpo_create_inpcb_from_socket = mac_lomac_create_inpcb_from_socket,
2894 .mpo_create_ipq = mac_lomac_create_ipq,
2895 .mpo_create_mbuf_from_inpcb = mac_lomac_create_mbuf_from_inpcb,
2896 .mpo_create_mbuf_linklayer = mac_lomac_create_mbuf_linklayer,
2897 .mpo_create_mbuf_from_bpfdesc = mac_lomac_create_mbuf_from_bpfdesc,
2898 .mpo_create_mbuf_from_ifnet = mac_lomac_create_mbuf_from_ifnet,
2899 .mpo_create_mbuf_multicast_encap =
2900 mac_lomac_create_mbuf_multicast_encap,
2901 .mpo_create_mbuf_netlayer = mac_lomac_create_mbuf_netlayer,
2902 .mpo_fragment_match = mac_lomac_fragment_match,
2903 .mpo_relabel_ifnet = mac_lomac_relabel_ifnet,
2904 .mpo_update_ipq = mac_lomac_update_ipq,
2905 .mpo_inpcb_sosetlabel = mac_lomac_inpcb_sosetlabel,
2906 .mpo_execve_transition = mac_lomac_execve_transition,
2907 .mpo_execve_will_transition = mac_lomac_execve_will_transition,
2908 .mpo_create_proc0 = mac_lomac_create_proc0,
2909 .mpo_create_proc1 = mac_lomac_create_proc1,
2910 .mpo_relabel_cred = mac_lomac_relabel_cred,
2911 .mpo_check_bpfdesc_receive = mac_lomac_check_bpfdesc_receive,
2912 .mpo_check_cred_relabel = mac_lomac_check_cred_relabel,
2913 .mpo_check_cred_visible = mac_lomac_check_cred_visible,
2914 .mpo_check_ifnet_relabel = mac_lomac_check_ifnet_relabel,
2915 .mpo_check_ifnet_transmit = mac_lomac_check_ifnet_transmit,
2916 .mpo_check_inpcb_deliver = mac_lomac_check_inpcb_deliver,
2917 .mpo_check_kld_load = mac_lomac_check_kld_load,
2918 .mpo_check_pipe_ioctl = mac_lomac_check_pipe_ioctl,
2919 .mpo_check_pipe_read = mac_lomac_check_pipe_read,
2920 .mpo_check_pipe_relabel = mac_lomac_check_pipe_relabel,
2921 .mpo_check_pipe_write = mac_lomac_check_pipe_write,
2922 .mpo_check_proc_debug = mac_lomac_check_proc_debug,
2923 .mpo_check_proc_sched = mac_lomac_check_proc_sched,
2924 .mpo_check_proc_signal = mac_lomac_check_proc_signal,
2925 .mpo_check_socket_deliver = mac_lomac_check_socket_deliver,
2926 .mpo_check_socket_relabel = mac_lomac_check_socket_relabel,
2927 .mpo_check_socket_visible = mac_lomac_check_socket_visible,
2928 .mpo_check_system_acct = mac_lomac_check_system_acct,
2929 .mpo_check_system_auditctl = mac_lomac_check_system_auditctl,
2930 .mpo_check_system_swapoff = mac_lomac_check_system_swapoff,
2931 .mpo_check_system_swapon = mac_lomac_check_system_swapon,
2932 .mpo_check_system_sysctl = mac_lomac_check_system_sysctl,
2933 .mpo_check_vnode_access = mac_lomac_check_vnode_open,
2934 .mpo_check_vnode_create = mac_lomac_check_vnode_create,
2935 .mpo_check_vnode_deleteacl = mac_lomac_check_vnode_deleteacl,
2936 .mpo_check_vnode_link = mac_lomac_check_vnode_link,
2937 .mpo_check_vnode_mmap = mac_lomac_check_vnode_mmap,
2938 .mpo_check_vnode_mmap_downgrade = mac_lomac_check_vnode_mmap_downgrade,
2939 .mpo_check_vnode_open = mac_lomac_check_vnode_open,
2940 .mpo_check_vnode_read = mac_lomac_check_vnode_read,
2941 .mpo_check_vnode_relabel = mac_lomac_check_vnode_relabel,
2942 .mpo_check_vnode_rename_from = mac_lomac_check_vnode_rename_from,
2943 .mpo_check_vnode_rename_to = mac_lomac_check_vnode_rename_to,
2944 .mpo_check_vnode_revoke = mac_lomac_check_vnode_revoke,
2945 .mpo_check_vnode_setacl = mac_lomac_check_vnode_setacl,
2946 .mpo_check_vnode_setextattr = mac_lomac_check_vnode_setextattr,
2947 .mpo_check_vnode_setflags = mac_lomac_check_vnode_setflags,
2948 .mpo_check_vnode_setmode = mac_lomac_check_vnode_setmode,
2949 .mpo_check_vnode_setowner = mac_lomac_check_vnode_setowner,
2950 .mpo_check_vnode_setutimes = mac_lomac_check_vnode_setutimes,
2951 .mpo_check_vnode_unlink = mac_lomac_check_vnode_unlink,
2952 .mpo_check_vnode_write = mac_lomac_check_vnode_write,
2953 .mpo_thread_userret = mac_lomac_thread_userret,
2954 .mpo_create_mbuf_from_firewall = mac_lomac_create_mbuf_from_firewall,
2955 .mpo_priv_check = mac_lomac_priv_check,
2956 };
2957
2958 MAC_POLICY_SET(&mac_lomac_ops, mac_lomac, "TrustedBSD MAC/LOMAC",
2959 MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS,
2960 &mac_lomac_slot);
Cache object: de8f68679b78473756184dfeb8186c62
|