]> git.saurik.com Git - apple/xnu.git/blob - security/mac_vfs.c
xnu-1486.2.11.tar.gz
[apple/xnu.git] / security / mac_vfs.c
1 /*
2 * Copyright (c) 2007 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28 /*-
29 * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
30 * Copyright (c) 2001 Ilmar S. Habibulin
31 * Copyright (c) 2001, 2002, 2003, 2004 Networks Associates Technology, Inc.
32 * Copyright (c) 2005 SPARTA, Inc.
33 *
34 * This software was developed by Robert Watson and Ilmar Habibulin for the
35 * TrustedBSD Project.
36 *
37 * This software was developed for the FreeBSD Project in part by Network
38 * Associates Laboratories, the Security Research Division of Network
39 * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
40 * as part of the DARPA CHATS research program.
41 *
42 * Redistribution and use in source and binary forms, with or without
43 * modification, are permitted provided that the following conditions
44 * are met:
45 * 1. Redistributions of source code must retain the above copyright
46 * notice, this list of conditions and the following disclaimer.
47 * 2. Redistributions in binary form must reproduce the above copyright
48 * notice, this list of conditions and the following disclaimer in the
49 * documentation and/or other materials provided with the distribution.
50 *
51 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
52 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
53 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
54 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
55 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
57 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
59 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
60 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
61 * SUCH DAMAGE.
62 *
63 */
64
65 #include <sys/param.h>
66 #include <sys/systm.h>
67 #include <sys/kernel.h>
68 #include <sys/proc.h>
69 #include <sys/kauth.h>
70
71 #include <sys/file_internal.h>
72 #include <sys/imgact.h>
73 #include <sys/namei.h>
74 #include <sys/mount_internal.h>
75 #include <sys/pipe.h>
76 #include <sys/posix_sem.h>
77 #include <sys/posix_shm.h>
78 #include <sys/uio_internal.h>
79 #include <sys/vnode_internal.h>
80
81 #include <miscfs/devfs/devfsdefs.h>
82 #include <miscfs/devfs/fdesc.h>
83
84 #include <security/mac_internal.h>
85
86 /* convert {R,W,X}_OK values to V{READ,WRITE,EXEC} */
87 #define ACCESS_MODE_TO_VNODE_MASK(m) (m << 6)
88
89 static struct label *
90 mac_devfsdirent_label_alloc(void)
91 {
92 struct label *label;
93
94 label = mac_labelzone_alloc(MAC_WAITOK);
95 if (label == NULL)
96 return (NULL);
97 MAC_PERFORM(devfs_label_init, label);
98 return (label);
99 }
100
101 void
102 mac_devfs_label_init(struct devnode *de)
103 {
104
105 de->dn_label = mac_devfsdirent_label_alloc();
106 }
107
108 static struct label *
109 mac_mount_label_alloc(void)
110 {
111 struct label *label;
112
113 label = mac_labelzone_alloc(MAC_WAITOK);
114 if (label == NULL)
115 return (NULL);
116 MAC_PERFORM(mount_label_init, label);
117 return (label);
118 }
119
120 void
121 mac_mount_label_init(struct mount *mp)
122 {
123
124 mp->mnt_mntlabel = mac_mount_label_alloc();
125 }
126
127 struct label *
128 mac_vnode_label_alloc(void)
129 {
130 struct label *label;
131
132 label = mac_labelzone_alloc(MAC_WAITOK);
133 if (label == NULL)
134 return (NULL);
135 MAC_PERFORM(vnode_label_init, label);
136 return (label);
137 }
138
139 void
140 mac_vnode_label_init(vnode_t vp)
141 {
142 vp->v_label = mac_vnode_label_alloc();
143 }
144
145 int
146 mac_vnode_label_init_needed(vnode_t vp)
147 {
148 return (mac_label_vnodes != 0 && vp->v_label == NULL);
149 }
150
151 /*
152 * vnode labels are allocated at the same time as vnodes, but vnodes are never
153 * freed. Instead, we want to remove any sensitive information before putting
154 * them on the free list for reuse.
155 */
156 void
157 mac_vnode_label_recycle(vnode_t vp)
158 {
159
160 MAC_PERFORM(vnode_label_recycle, vp->v_label);
161 }
162
163 static void
164 mac_devfs_label_free(struct label *label)
165 {
166 MAC_PERFORM(devfs_label_destroy, label);
167 mac_labelzone_free(label);
168 }
169
170 void
171 mac_devfs_label_destroy(struct devnode *de)
172 {
173 if (de->dn_label != NULL) {
174 mac_devfs_label_free(de->dn_label);
175 de->dn_label = NULL;
176 }
177 }
178
179 static void
180 mac_mount_label_free(struct label *label)
181 {
182
183 MAC_PERFORM(mount_label_destroy, label);
184 mac_labelzone_free(label);
185 }
186
187 void
188 mac_mount_label_destroy(struct mount *mp)
189 {
190 if (mp->mnt_mntlabel != NULL) {
191 mac_mount_label_free(mp->mnt_mntlabel);
192 mp->mnt_mntlabel = NULL;
193 }
194 }
195
196 void
197 mac_vnode_label_free(struct label *label)
198 {
199 MAC_PERFORM(vnode_label_destroy, label);
200 mac_labelzone_free(label);
201 }
202
203 #ifndef __APPLE__
204 void
205 mac_vnode_label_destroy(struct vnode *vp)
206 {
207 if (vp->v_label != NULL) {
208 mac_vnode_label_free(vp->v_label);
209 vp->v_label = NULL;
210 }
211 }
212 #endif
213
214 void
215 mac_vnode_label_copy(struct label *src, struct label *dest)
216 {
217 if (src == NULL) {
218 MAC_PERFORM(vnode_label_init, dest);
219 } else {
220 MAC_PERFORM(vnode_label_copy, src, dest);
221 }
222 }
223
224 int
225 mac_vnode_label_externalize_audit(struct vnode *vp, struct mac *mac)
226 {
227 int error;
228
229 /* It is assumed that any necessary vnode locking is done on entry */
230 error = MAC_EXTERNALIZE_AUDIT(vnode, vp->v_label,
231 mac->m_string, mac->m_buflen);
232
233 return (error);
234 }
235
236 int
237 mac_vnode_label_externalize(struct label *label, char *elements,
238 char *outbuf, size_t outbuflen, int flags __unused)
239 {
240 int error;
241
242 error = MAC_EXTERNALIZE(vnode, label, elements, outbuf, outbuflen);
243
244 return (error);
245 }
246
247 int
248 mac_vnode_label_internalize(struct label *label, char *string)
249 {
250 int error;
251
252 error = MAC_INTERNALIZE(vnode, label, string);
253
254 return (error);
255 }
256
257 int
258 mac_mount_label_internalize(struct label *label, char *string)
259 {
260 int error;
261
262 error = MAC_INTERNALIZE(mount, label, string);
263
264 return (error);
265 }
266
267 int
268 mac_mount_label_externalize(struct label *label, char *elements,
269 char *outbuf, size_t outbuflen)
270 {
271 int error;
272
273 error = MAC_EXTERNALIZE(mount, label, elements, outbuf, outbuflen);
274
275 return (error);
276 }
277
278 void
279 mac_devfs_label_copy(struct label *src, struct label *dest)
280 {
281 if (!mac_device_enforce)
282 return;
283
284 MAC_PERFORM(devfs_label_copy, src, dest);
285 }
286
287 void
288 mac_devfs_label_update(struct mount *mp, struct devnode *de,
289 struct vnode *vp)
290 {
291
292 if (!mac_device_enforce)
293 return;
294
295 MAC_PERFORM(devfs_label_update, mp, de, de->dn_label, vp,
296 vp->v_label);
297 }
298
299 int
300 mac_vnode_label_associate(struct mount *mp, struct vnode *vp, vfs_context_t ctx)
301 {
302 struct devnode *dnp;
303 struct fdescnode *fnp;
304 int error = 0;
305
306 if (!mac_vnode_enforce)
307 return (error);
308
309 /* XXX: should not inspect v_tag in kernel! */
310 switch (vp->v_tag) {
311 case VT_DEVFS:
312 dnp = VTODN(vp);
313 mac_vnode_label_associate_devfs(mp, dnp, vp);
314 break;
315 case VT_FDESC:
316 fnp = VTOFDESC(vp);
317 error = mac_vnode_label_associate_fdesc(mp, fnp, vp, ctx);
318 break;
319 default:
320 error = mac_vnode_label_associate_extattr(mp, vp);
321 break;
322 }
323
324 return (error);
325 }
326
327 void
328 mac_vnode_label_associate_devfs(struct mount *mp, struct devnode *de,
329 struct vnode *vp)
330 {
331 if (!mac_device_enforce)
332 return;
333
334 MAC_PERFORM(vnode_label_associate_devfs,
335 mp, mp ? mp->mnt_mntlabel : NULL,
336 de, de->dn_label,
337 vp, vp->v_label);
338 }
339
340 int
341 mac_vnode_label_associate_extattr(struct mount *mp, struct vnode *vp)
342 {
343 int error;
344
345 MAC_CHECK(vnode_label_associate_extattr, mp, mp->mnt_mntlabel, vp,
346 vp->v_label);
347
348 return (error);
349 }
350
351 void
352 mac_vnode_label_associate_singlelabel(struct mount *mp, struct vnode *vp)
353 {
354
355 if (!mac_vnode_enforce || !mac_label_vnodes)
356 return;
357
358 MAC_PERFORM(vnode_label_associate_singlelabel, mp,
359 mp ? mp->mnt_mntlabel : NULL, vp, vp->v_label);
360 }
361
362 int
363 mac_vnode_notify_create(vfs_context_t ctx, struct mount *mp,
364 struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
365 {
366 kauth_cred_t cred;
367 int error;
368
369 if (!mac_vnode_enforce ||
370 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
371 return (0);
372
373 cred = vfs_context_ucred(ctx);
374 MAC_CHECK(vnode_notify_create, cred, mp, mp->mnt_mntlabel,
375 dvp, dvp->v_label, vp, vp->v_label, cnp);
376
377 return (error);
378 }
379
380 /*
381 * Extended attribute 'name' was updated via
382 * vn_setxattr() or vn_removexattr(). Allow the
383 * policy to update the vnode label.
384 */
385 void
386 mac_vnode_label_update_extattr(struct mount *mp, struct vnode *vp,
387 const char *name)
388 {
389 int error = 0;
390
391 if (!mac_vnode_enforce || !mac_label_vnodes)
392 return;
393
394 MAC_PERFORM(vnode_label_update_extattr, mp, mp->mnt_mntlabel, vp,
395 vp->v_label, name);
396 if (error == 0)
397 return;
398
399 vnode_lock(vp);
400 vnode_relabel(vp);
401 vnode_unlock(vp);
402 return;
403 }
404
405 static int
406 mac_vnode_label_store(vfs_context_t ctx, struct vnode *vp,
407 struct label *intlabel)
408 {
409 kauth_cred_t cred;
410 int error;
411
412 if (!mac_vnode_enforce || !mac_label_vnodes ||
413 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
414 return 0;
415
416 cred = vfs_context_ucred(ctx);
417 MAC_CHECK(vnode_label_store, cred, vp, vp->v_label, intlabel);
418
419 return (error);
420 }
421
422 int
423 mac_cred_label_update_execve(vfs_context_t ctx, kauth_cred_t new, struct vnode *vp,
424 struct label *scriptvnodelabel, struct label *execl)
425 {
426 kauth_cred_t cred;
427 int disjoint = 0;
428
429 if (!mac_proc_enforce && !mac_vnode_enforce)
430 return disjoint;
431
432 /* mark the new cred to indicate "matching" includes the label */
433 new->cr_flags |= CRF_MAC_ENFORCE;
434
435 cred = vfs_context_ucred(ctx);
436 MAC_PERFORM(cred_label_update_execve, cred, new, vp, vp->v_label,
437 scriptvnodelabel, execl, &disjoint);
438
439 return (disjoint);
440 }
441
442 int
443 mac_cred_check_label_update_execve(vfs_context_t ctx, struct vnode *vp,
444 struct label *scriptvnodelabel, struct label *execlabel, struct proc *p)
445 {
446 kauth_cred_t cred;
447 int result = 0;
448
449 if (!mac_proc_enforce && !mac_vnode_enforce)
450 return result;
451
452 cred = vfs_context_ucred(ctx);
453 MAC_BOOLEAN(cred_check_label_update_execve, ||, cred, vp, vp->v_label,
454 scriptvnodelabel, execlabel, p);
455
456 return (result);
457 }
458
459 int
460 mac_vnode_check_access(vfs_context_t ctx, struct vnode *vp,
461 int acc_mode)
462 {
463 kauth_cred_t cred;
464 int error;
465 int mask;
466
467 if (!mac_vnode_enforce ||
468 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
469 return 0;
470
471 cred = vfs_context_ucred(ctx);
472 /* Convert {R,W,X}_OK values to V{READ,WRITE,EXEC} for entry points */
473 mask = ACCESS_MODE_TO_VNODE_MASK(acc_mode);
474 MAC_CHECK(vnode_check_access, cred, vp, vp->v_label, mask);
475 return (error);
476 }
477
478 int
479 mac_vnode_check_chdir(vfs_context_t ctx, struct vnode *dvp)
480 {
481 kauth_cred_t cred;
482 int error;
483
484 if (!mac_vnode_enforce ||
485 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
486 return (0);
487
488 cred = vfs_context_ucred(ctx);
489 MAC_CHECK(vnode_check_chdir, cred, dvp, dvp->v_label);
490 return (error);
491 }
492
493 int
494 mac_vnode_check_chroot(vfs_context_t ctx, struct vnode *dvp,
495 struct componentname *cnp)
496 {
497 kauth_cred_t cred;
498 int error;
499
500 if (!mac_vnode_enforce ||
501 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
502 return (0);
503
504 cred = vfs_context_ucred(ctx);
505 MAC_CHECK(vnode_check_chroot, cred, dvp, dvp->v_label, cnp);
506 return (error);
507 }
508
509 int
510 mac_vnode_check_create(vfs_context_t ctx, struct vnode *dvp,
511 struct componentname *cnp, struct vnode_attr *vap)
512 {
513 kauth_cred_t cred;
514 int error;
515
516 if (!mac_vnode_enforce ||
517 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
518 return (0);
519
520 cred = vfs_context_ucred(ctx);
521 MAC_CHECK(vnode_check_create, cred, dvp, dvp->v_label, cnp, vap);
522 return (error);
523 }
524
525 int
526 mac_vnode_check_unlink(vfs_context_t ctx, struct vnode *dvp, struct vnode *vp,
527 struct componentname *cnp)
528 {
529 kauth_cred_t cred;
530 int error;
531
532 if (!mac_vnode_enforce ||
533 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
534 return (0);
535
536 cred = vfs_context_ucred(ctx);
537 MAC_CHECK(vnode_check_unlink, cred, dvp, dvp->v_label, vp,
538 vp->v_label, cnp);
539 return (error);
540 }
541 #if 0
542 int
543 mac_vnode_check_deleteacl(vfs_context_t ctx, struct vnode *vp,
544 acl_type_t type)
545 {
546 kauth_cred_t cred;
547 int error;
548
549 if (!mac_vnode_enforce ||
550 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
551 return (0);
552
553 cred = vfs_context_ucred(ctx);
554 MAC_CHECK(vnode_check_deleteacl, cred, vp, vp->v_label, type);
555 return (error);
556 }
557 #endif
558
559 int
560 mac_vnode_check_deleteextattr(vfs_context_t ctx, struct vnode *vp,
561 const char *name)
562 {
563 kauth_cred_t cred;
564 int error;
565
566 if (!mac_vnode_enforce ||
567 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
568 return (0);
569
570 cred = vfs_context_ucred(ctx);
571 MAC_CHECK(vnode_check_deleteextattr, cred, vp, vp->v_label, name);
572 return (error);
573 }
574 int
575 mac_vnode_check_exchangedata(vfs_context_t ctx,
576 struct vnode *v1, struct vnode *v2)
577 {
578 kauth_cred_t cred;
579 int error;
580
581 if (!mac_vnode_enforce ||
582 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
583 return (0);
584
585 cred = vfs_context_ucred(ctx);
586 MAC_CHECK(vnode_check_exchangedata, cred, v1, v1->v_label,
587 v2, v2->v_label);
588
589 return (error);
590 }
591
592 #if 0
593 int
594 mac_vnode_check_getacl(vfs_context_t ctx, struct vnode *vp, acl_type_t type)
595 {
596 kauth_cred_t cred;
597 int error;
598
599 if (!mac_vnode_enforce ||
600 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
601 return (0);
602
603 cred = vfs_context_ucred(ctx);
604 MAC_CHECK(vnode_check_getacl, cred, vp, vp->v_label, type);
605 return (error);
606 }
607 #endif
608
609 int
610 mac_vnode_check_getattrlist(vfs_context_t ctx, struct vnode *vp,
611 struct attrlist *alist)
612 {
613 kauth_cred_t cred;
614 int error;
615
616 if (!mac_vnode_enforce ||
617 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
618 return (0);
619
620 cred = vfs_context_ucred(ctx);
621 MAC_CHECK(vnode_check_getattrlist, cred, vp, vp->v_label, alist);
622
623 /* Falsify results instead of returning error? */
624 return (error);
625 }
626
627 int
628 mac_vnode_check_exec(vfs_context_t ctx, struct vnode *vp,
629 struct image_params *imgp)
630 {
631 kauth_cred_t cred;
632 int error;
633
634 if (!mac_vnode_enforce || !mac_proc_enforce)
635 return (0);
636
637 cred = vfs_context_ucred(ctx);
638 MAC_CHECK(vnode_check_exec, cred, vp, vp->v_label,
639 (imgp != NULL) ? imgp->ip_execlabelp : NULL,
640 (imgp != NULL) ? &imgp->ip_ndp->ni_cnd : NULL,
641 (imgp != NULL) ? &imgp->ip_csflags : NULL);
642 return (error);
643 }
644
645 int
646 mac_vnode_check_signature(struct vnode *vp, unsigned char *sha1,
647 void * signature, size_t size)
648 {
649 int error;
650
651 if (!mac_vnode_enforce || !mac_proc_enforce)
652 return (0);
653
654 MAC_CHECK(vnode_check_signature, vp, vp->v_label, sha1, signature, size);
655 return (error);
656 }
657
658 #if 0
659 int
660 mac_vnode_check_getacl(vfs_context_t ctx, struct vnode *vp, acl_type_t type)
661 {
662 kauth_cred_t cred;
663 int error;
664
665 if (!mac_vnode_enforce ||
666 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
667 return (0);
668
669 cred = vfs_context_ucred(ctx);
670 MAC_CHECK(vnode_check_getacl, cred, vp, vp->v_label, type);
671 return (error);
672 }
673 #endif
674
675 int
676 mac_vnode_check_getextattr(vfs_context_t ctx, struct vnode *vp,
677 const char *name, struct uio *uio)
678 {
679 kauth_cred_t cred;
680 int error;
681
682 if (!mac_vnode_enforce ||
683 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
684 return (0);
685
686 cred = vfs_context_ucred(ctx);
687 MAC_CHECK(vnode_check_getextattr, cred, vp, vp->v_label,
688 name, uio);
689 return (error);
690 }
691
692 int
693 mac_vnode_check_ioctl(vfs_context_t ctx, struct vnode *vp, u_int cmd)
694 {
695 kauth_cred_t cred;
696 int error;
697
698 if (!mac_vnode_enforce ||
699 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
700 return (0);
701
702 cred = vfs_context_ucred(ctx);
703 MAC_CHECK(vnode_check_ioctl, cred, vp, vp->v_label, cmd);
704 return (error);
705 }
706
707 int
708 mac_vnode_check_kqfilter(vfs_context_t ctx, kauth_cred_t file_cred,
709 struct knote *kn, struct vnode *vp)
710 {
711 kauth_cred_t cred;
712 int error;
713
714 if (!mac_vnode_enforce ||
715 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
716 return (0);
717
718 cred = vfs_context_ucred(ctx);
719 MAC_CHECK(vnode_check_kqfilter, cred, file_cred, kn, vp,
720 vp->v_label);
721
722 return (error);
723 }
724
725 int
726 mac_vnode_check_link(vfs_context_t ctx, struct vnode *dvp,
727 struct vnode *vp, struct componentname *cnp)
728 {
729 kauth_cred_t cred;
730 int error;
731
732 if (!mac_vnode_enforce ||
733 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
734 return (0);
735
736 cred = vfs_context_ucred(ctx);
737 MAC_CHECK(vnode_check_link, cred, dvp, dvp->v_label, vp,
738 vp->v_label, cnp);
739 return (error);
740 }
741
742 int
743 mac_vnode_check_listextattr(vfs_context_t ctx, struct vnode *vp)
744 {
745 kauth_cred_t cred;
746 int error;
747
748 if (!mac_vnode_enforce ||
749 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
750 return (0);
751
752 cred = vfs_context_ucred(ctx);
753 MAC_CHECK(vnode_check_listextattr, cred, vp, vp->v_label);
754 return (error);
755 }
756
757 int
758 mac_vnode_check_lookup(vfs_context_t ctx, struct vnode *dvp,
759 struct componentname *cnp)
760 {
761 kauth_cred_t cred;
762 int error;
763
764 if (!mac_vnode_enforce ||
765 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
766 return (0);
767
768 cred = vfs_context_ucred(ctx);
769 MAC_CHECK(vnode_check_lookup, cred, dvp, dvp->v_label, cnp);
770 return (error);
771 }
772
773 int
774 mac_vnode_check_open(vfs_context_t ctx, struct vnode *vp, int acc_mode)
775 {
776 kauth_cred_t cred;
777 int error;
778
779 if (!mac_vnode_enforce ||
780 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
781 return (0);
782
783 cred = vfs_context_ucred(ctx);
784 MAC_CHECK(vnode_check_open, cred, vp, vp->v_label, acc_mode);
785 return (error);
786 }
787
788 int
789 mac_vnode_check_read(vfs_context_t ctx, struct ucred *file_cred,
790 struct vnode *vp)
791 {
792 kauth_cred_t cred;
793 int error;
794
795 if (!mac_vnode_enforce ||
796 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
797 return (0);
798
799 cred = vfs_context_ucred(ctx);
800 MAC_CHECK(vnode_check_read, cred, file_cred, vp,
801 vp->v_label);
802
803 return (error);
804 }
805
806 int
807 mac_vnode_check_readdir(vfs_context_t ctx, struct vnode *dvp)
808 {
809 kauth_cred_t cred;
810 int error;
811
812 if (!mac_vnode_enforce ||
813 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
814 return (0);
815
816 cred = vfs_context_ucred(ctx);
817 MAC_CHECK(vnode_check_readdir, cred, dvp, dvp->v_label);
818 return (error);
819 }
820
821 int
822 mac_vnode_check_readlink(vfs_context_t ctx, struct vnode *vp)
823 {
824 kauth_cred_t cred;
825 int error;
826
827 if (!mac_vnode_enforce ||
828 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
829 return (0);
830
831 cred = vfs_context_ucred(ctx);
832 MAC_CHECK(vnode_check_readlink, cred, vp, vp->v_label);
833 return (error);
834 }
835
836 int
837 mac_vnode_check_label_update(vfs_context_t ctx, struct vnode *vp,
838 struct label *newlabel)
839 {
840 kauth_cred_t cred;
841 int error;
842
843 if (!mac_vnode_enforce ||
844 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
845 return (0);
846
847 cred = vfs_context_ucred(ctx);
848 MAC_CHECK(vnode_check_label_update, cred, vp, vp->v_label, newlabel);
849
850 return (error);
851 }
852
853 int
854 mac_vnode_check_rename_from(vfs_context_t ctx, struct vnode *dvp,
855 struct vnode *vp, struct componentname *cnp)
856 {
857 kauth_cred_t cred;
858 int error;
859
860 if (!mac_vnode_enforce ||
861 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
862 return (0);
863
864 cred = vfs_context_ucred(ctx);
865 MAC_CHECK(vnode_check_rename_from, cred, dvp, dvp->v_label, vp,
866 vp->v_label, cnp);
867 return (error);
868 }
869
870 int
871 mac_vnode_check_rename_to(vfs_context_t ctx, struct vnode *dvp,
872 struct vnode *vp, int samedir, struct componentname *cnp)
873 {
874 kauth_cred_t cred;
875 int error;
876
877 if (!mac_vnode_enforce ||
878 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
879 return (0);
880
881 cred = vfs_context_ucred(ctx);
882 MAC_CHECK(vnode_check_rename_to, cred, dvp, dvp->v_label, vp,
883 vp != NULL ? vp->v_label : NULL, samedir, cnp);
884 return (error);
885 }
886
887 int
888 mac_vnode_check_revoke(vfs_context_t ctx, struct vnode *vp)
889 {
890 kauth_cred_t cred;
891 int error;
892
893 if (!mac_vnode_enforce ||
894 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
895 return (0);
896
897 cred = vfs_context_ucred(ctx);
898 MAC_CHECK(vnode_check_revoke, cred, vp, vp->v_label);
899 return (error);
900 }
901
902 int
903 mac_vnode_check_select(vfs_context_t ctx, struct vnode *vp, int which)
904 {
905 kauth_cred_t cred;
906 int error;
907
908 if (!mac_vnode_enforce ||
909 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
910 return (0);
911
912 cred = vfs_context_ucred(ctx);
913 MAC_CHECK(vnode_check_select, cred, vp, vp->v_label, which);
914 return (error);
915 }
916
917 #if 0
918 int
919 mac_vnode_check_setacl(vfs_context_t ctx, struct vnode *vp, acl_type_t type,
920 struct acl *acl)
921 {
922 kauth_cred_t cred;
923 int error;
924
925 if (!mac_vnode_enforce ||
926 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
927 return (0);
928
929 cred = vfs_context_ucred(ctx);
930 MAC_CHECK(vnode_check_setacl, cred, vp, vp->v_label, type, acl);
931 return (error);
932 }
933 #endif
934
935 int
936 mac_vnode_check_setattrlist(vfs_context_t ctx, struct vnode *vp,
937 struct attrlist *alist)
938 {
939 kauth_cred_t cred;
940 int error;
941
942 if (!mac_vnode_enforce ||
943 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
944 return (0);
945
946 cred = vfs_context_ucred(ctx);
947 MAC_CHECK(vnode_check_setattrlist, cred, vp, vp->v_label, alist);
948 return (error);
949 }
950
951 int
952 mac_vnode_check_setextattr(vfs_context_t ctx, struct vnode *vp,
953 const char *name, struct uio *uio)
954 {
955 kauth_cred_t cred;
956 int error;
957
958 if (!mac_vnode_enforce ||
959 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
960 return (0);
961
962 cred = vfs_context_ucred(ctx);
963 MAC_CHECK(vnode_check_setextattr, cred, vp, vp->v_label,
964 name, uio);
965 return (error);
966 }
967
968 int
969 mac_vnode_check_setflags(vfs_context_t ctx, struct vnode *vp, u_long flags)
970 {
971 kauth_cred_t cred;
972 int error;
973
974 if (!mac_vnode_enforce ||
975 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
976 return (0);
977
978 cred = vfs_context_ucred(ctx);
979 MAC_CHECK(vnode_check_setflags, cred, vp, vp->v_label, flags);
980 return (error);
981 }
982
983 int
984 mac_vnode_check_setmode(vfs_context_t ctx, struct vnode *vp, mode_t mode)
985 {
986 kauth_cred_t cred;
987 int error;
988
989 if (!mac_vnode_enforce ||
990 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
991 return (0);
992
993 cred = vfs_context_ucred(ctx);
994 MAC_CHECK(vnode_check_setmode, cred, vp, vp->v_label, mode);
995 return (error);
996 }
997
998 int
999 mac_vnode_check_setowner(vfs_context_t ctx, struct vnode *vp, uid_t uid,
1000 gid_t gid)
1001 {
1002 kauth_cred_t cred;
1003 int error;
1004
1005 if (!mac_vnode_enforce ||
1006 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1007 return (0);
1008
1009 cred = vfs_context_ucred(ctx);
1010 MAC_CHECK(vnode_check_setowner, cred, vp, vp->v_label, uid, gid);
1011 return (error);
1012 }
1013
1014 int
1015 mac_vnode_check_setutimes(vfs_context_t ctx, struct vnode *vp,
1016 struct timespec atime, struct timespec mtime)
1017 {
1018 kauth_cred_t cred;
1019 int error;
1020
1021 if (!mac_vnode_enforce ||
1022 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1023 return (0);
1024
1025 cred = vfs_context_ucred(ctx);
1026 MAC_CHECK(vnode_check_setutimes, cred, vp, vp->v_label, atime,
1027 mtime);
1028 return (error);
1029 }
1030
1031 int
1032 mac_vnode_check_stat(vfs_context_t ctx, struct ucred *file_cred,
1033 struct vnode *vp)
1034 {
1035 kauth_cred_t cred;
1036 int error;
1037
1038 if (!mac_vnode_enforce ||
1039 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1040 return (0);
1041
1042 cred = vfs_context_ucred(ctx);
1043 MAC_CHECK(vnode_check_stat, cred, file_cred, vp,
1044 vp->v_label);
1045 return (error);
1046 }
1047
1048 int
1049 mac_vnode_check_truncate(vfs_context_t ctx, struct ucred *file_cred,
1050 struct vnode *vp)
1051 {
1052 kauth_cred_t cred;
1053 int error;
1054
1055 if (!mac_vnode_enforce ||
1056 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1057 return (0);
1058
1059 cred = vfs_context_ucred(ctx);
1060 MAC_CHECK(vnode_check_truncate, cred, file_cred, vp,
1061 vp->v_label);
1062
1063 return (error);
1064 }
1065
1066 int
1067 mac_vnode_check_write(vfs_context_t ctx, struct ucred *file_cred,
1068 struct vnode *vp)
1069 {
1070 kauth_cred_t cred;
1071 int error;
1072
1073 if (!mac_vnode_enforce ||
1074 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1075 return (0);
1076
1077 cred = vfs_context_ucred(ctx);
1078 MAC_CHECK(vnode_check_write, cred, file_cred, vp, vp->v_label);
1079
1080 return (error);
1081 }
1082
1083 int
1084 mac_vnode_check_uipc_bind(vfs_context_t ctx, struct vnode *dvp,
1085 struct componentname *cnp, struct vnode_attr *vap)
1086 {
1087 kauth_cred_t cred;
1088 int error;
1089
1090 if (!mac_vnode_enforce ||
1091 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1092 return (0);
1093
1094 cred = vfs_context_ucred(ctx);
1095 MAC_CHECK(vnode_check_uipc_bind, cred, dvp, dvp->v_label, cnp, vap);
1096 return (error);
1097 }
1098
1099 int
1100 mac_vnode_check_uipc_connect(vfs_context_t ctx, struct vnode *vp)
1101 {
1102 kauth_cred_t cred;
1103 int error;
1104
1105 if (!mac_vnode_enforce ||
1106 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1107 return (0);
1108
1109 cred = vfs_context_ucred(ctx);
1110 MAC_CHECK(vnode_check_uipc_connect, cred, vp, vp->v_label);
1111 return (error);
1112 }
1113
1114 void
1115 mac_vnode_label_update(vfs_context_t ctx, struct vnode *vp, struct label *newlabel)
1116 {
1117 kauth_cred_t cred = vfs_context_ucred(ctx);
1118 struct label *tmpl = NULL;
1119
1120 if (vp->v_label == NULL)
1121 tmpl = mac_vnode_label_alloc();
1122
1123 vnode_lock(vp);
1124
1125 /* recheck after lock */
1126 if (vp->v_label == NULL) {
1127 vp->v_label = tmpl;
1128 tmpl = NULL;
1129 }
1130
1131 MAC_PERFORM(vnode_label_update, cred, vp, vp->v_label, newlabel);
1132 vnode_unlock(vp);
1133
1134 if (tmpl != NULL)
1135 mac_vnode_label_free(tmpl);
1136 }
1137
1138 void
1139 mac_mount_label_associate(vfs_context_t ctx, struct mount *mp)
1140 {
1141 kauth_cred_t cred = vfs_context_ucred(ctx);
1142
1143 /* XXX: eventually this logic may be handled by the policy? */
1144
1145 /* We desire MULTILABEL for the root filesystem. */
1146 if ((mp->mnt_flag & MNT_ROOTFS) &&
1147 (strcmp(mp->mnt_vfsstat.f_fstypename, "hfs") == 0))
1148 mp->mnt_flag |= MNT_MULTILABEL;
1149
1150 /* MULTILABEL on DEVFS. */
1151 if (strcmp(mp->mnt_vfsstat.f_fstypename, "devfs") == 0)
1152 mp->mnt_flag |= MNT_MULTILABEL;
1153
1154 /* MULTILABEL on FDESC pseudo-filesystem. */
1155 if (strcmp(mp->mnt_vfsstat.f_fstypename, "fdesc") == 0)
1156 mp->mnt_flag |= MNT_MULTILABEL;
1157
1158 /* MULTILABEL on all NFS filesystems. */
1159 if (strcmp(mp->mnt_vfsstat.f_fstypename, "nfs") == 0)
1160 mp->mnt_flag |= MNT_MULTILABEL;
1161
1162 /* MULTILABEL on all AFP filesystems. */
1163 if (strcmp(mp->mnt_vfsstat.f_fstypename, "afpfs") == 0)
1164 mp->mnt_flag |= MNT_MULTILABEL;
1165
1166 if (mp->mnt_vtable != NULL) {
1167 /* Any filesystem that supports native XATTRs. */
1168 if ((mp->mnt_vtable->vfc_vfsflags & VFC_VFSNATIVEXATTR))
1169 mp->mnt_flag |= MNT_MULTILABEL;
1170
1171 /* Filesystem does not support multilabel. */
1172 if ((mp->mnt_vtable->vfc_vfsflags & VFC_VFSNOMACLABEL) &&
1173 (mp->mnt_flag & MNT_MULTILABEL))
1174 mp->mnt_flag &= ~MNT_MULTILABEL;
1175 }
1176
1177 MAC_PERFORM(mount_label_associate, cred, mp, mp->mnt_mntlabel);
1178 #if MAC_DEBUG
1179 printf("MAC Framework enabling %s support: %s -> %s (%s)\n",
1180 mp->mnt_flag & MNT_MULTILABEL ? "multilabel" : "singlelabel",
1181 mp->mnt_vfsstat.f_mntfromname,
1182 mp->mnt_vfsstat.f_mntonname,
1183 mp->mnt_vfsstat.f_fstypename);
1184 #endif
1185 }
1186
1187 int
1188 mac_mount_check_mount(vfs_context_t ctx, struct vnode *vp,
1189 struct componentname *cnp, const char *vfc_name)
1190 {
1191 kauth_cred_t cred;
1192 int error;
1193
1194 if (!mac_vnode_enforce ||
1195 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1196 return (0);
1197
1198 cred = vfs_context_ucred(ctx);
1199 MAC_CHECK(mount_check_mount, cred, vp, vp->v_label, cnp, vfc_name);
1200
1201 return (error);
1202 }
1203
1204 int
1205 mac_mount_check_remount(vfs_context_t ctx, struct mount *mp)
1206 {
1207 kauth_cred_t cred;
1208 int error;
1209
1210 if (!mac_vnode_enforce ||
1211 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1212 return (0);
1213
1214 cred = vfs_context_ucred(ctx);
1215 MAC_CHECK(mount_check_remount, cred, mp, mp->mnt_mntlabel);
1216
1217 return (error);
1218 }
1219
1220 int
1221 mac_mount_check_umount(vfs_context_t ctx, struct mount *mp)
1222 {
1223 kauth_cred_t cred;
1224 int error;
1225
1226 if (!mac_vnode_enforce ||
1227 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1228 return (0);
1229
1230 cred = vfs_context_ucred(ctx);
1231 MAC_CHECK(mount_check_umount, cred, mp, mp->mnt_mntlabel);
1232
1233 return (error);
1234 }
1235
1236 int
1237 mac_mount_check_getattr(vfs_context_t ctx, struct mount *mp,
1238 struct vfs_attr *vfa)
1239 {
1240 kauth_cred_t cred;
1241 int error;
1242
1243 if (!mac_vnode_enforce ||
1244 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1245 return (0);
1246
1247 cred = vfs_context_ucred(ctx);
1248 MAC_CHECK(mount_check_getattr, cred, mp, mp->mnt_mntlabel, vfa);
1249 return (error);
1250 }
1251
1252 int
1253 mac_mount_check_setattr(vfs_context_t ctx, struct mount *mp,
1254 struct vfs_attr *vfa)
1255 {
1256 kauth_cred_t cred;
1257 int error;
1258
1259 if (!mac_vnode_enforce ||
1260 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1261 return (0);
1262
1263 cred = vfs_context_ucred(ctx);
1264 MAC_CHECK(mount_check_setattr, cred, mp, mp->mnt_mntlabel, vfa);
1265 return (error);
1266 }
1267
1268 int
1269 mac_mount_check_stat(vfs_context_t ctx, struct mount *mount)
1270 {
1271 kauth_cred_t cred;
1272 int error;
1273
1274 if (!mac_vnode_enforce ||
1275 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1276 return (0);
1277
1278 cred = vfs_context_ucred(ctx);
1279 MAC_CHECK(mount_check_stat, cred, mount, mount->mnt_mntlabel);
1280
1281 return (error);
1282 }
1283
1284 int
1285 mac_mount_check_label_update(vfs_context_t ctx, struct mount *mount)
1286 {
1287 kauth_cred_t cred;
1288 int error;
1289
1290 if (!mac_vnode_enforce ||
1291 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1292 return (0);
1293
1294 cred = vfs_context_ucred(ctx);
1295 MAC_CHECK(mount_check_label_update, cred, mount, mount->mnt_mntlabel);
1296
1297 return (error);
1298 }
1299
1300 int
1301 mac_mount_check_fsctl(vfs_context_t ctx, struct mount *mp, u_int cmd)
1302 {
1303 kauth_cred_t cred;
1304 int error;
1305
1306 if (!mac_vnode_enforce ||
1307 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1308 return (0);
1309
1310 cred = vfs_context_ucred(ctx);
1311 MAC_CHECK(mount_check_fsctl, cred, mp, mp->mnt_mntlabel, cmd);
1312
1313 return (error);
1314 }
1315
1316 void
1317 mac_devfs_label_associate_device(dev_t dev, struct devnode *de,
1318 const char *fullpath)
1319 {
1320 if (!mac_device_enforce)
1321 return;
1322
1323 MAC_PERFORM(devfs_label_associate_device, dev, de, de->dn_label,
1324 fullpath);
1325 }
1326
1327 void
1328 mac_devfs_label_associate_directory(const char *dirname, int dirnamelen,
1329 struct devnode *de, const char *fullpath)
1330 {
1331 if (!mac_device_enforce)
1332 return;
1333
1334 MAC_PERFORM(devfs_label_associate_directory, dirname, dirnamelen, de,
1335 de->dn_label, fullpath);
1336 }
1337
1338 int
1339 vn_setlabel(struct vnode *vp, struct label *intlabel, vfs_context_t context)
1340 {
1341 int error;
1342
1343 if (!mac_vnode_enforce || !mac_label_vnodes)
1344 return (0);
1345
1346 if (vp->v_mount == NULL) {
1347 printf("vn_setlabel: null v_mount\n");
1348 if (vp->v_type != VNON)
1349 printf("vn_setlabel: null v_mount with non-VNON\n");
1350 return (EBADF);
1351 }
1352
1353 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
1354 return (ENOTSUP);
1355
1356 /*
1357 * Multi-phase commit. First check the policies to confirm the
1358 * change is OK. Then commit via the filesystem. Finally,
1359 * update the actual vnode label. Question: maybe the filesystem
1360 * should update the vnode at the end as part of VNOP_SETLABEL()?
1361 */
1362 error = mac_vnode_check_label_update(context, vp, intlabel);
1363 if (error)
1364 return (error);
1365
1366 error = VNOP_SETLABEL(vp, intlabel, context);
1367 if (error == ENOTSUP) {
1368 error = mac_vnode_label_store(context, vp,
1369 intlabel);
1370 if (error) {
1371 printf("%s: mac_vnode_label_store failed %d\n",
1372 __func__, error);
1373 return (error);
1374 }
1375 mac_vnode_label_update(context, vp, intlabel);
1376 } else
1377 if (error) {
1378 printf("vn_setlabel: vop setlabel failed %d\n", error);
1379 return (error);
1380 }
1381
1382 return (0);
1383 }
1384
1385 int
1386 mac_vnode_label_associate_fdesc(struct mount *mp, struct fdescnode *fnp,
1387 struct vnode *vp, vfs_context_t ctx)
1388 {
1389 struct fileproc *fp;
1390 struct socket *so;
1391 struct pipe *cpipe;
1392 struct vnode *fvp;
1393 struct proc *p;
1394 int error;
1395
1396 error = 0;
1397
1398 /*
1399 * If no backing file, let the policy choose which label to use.
1400 */
1401 if (fnp->fd_fd == -1) {
1402 MAC_PERFORM(vnode_label_associate_file, vfs_context_ucred(ctx),
1403 mp, mp->mnt_mntlabel, NULL, NULL, vp, vp->v_label);
1404 return (0);
1405 }
1406
1407 p = vfs_context_proc(ctx);
1408 error = fp_lookup(p, fnp->fd_fd, &fp, 0);
1409 if (error)
1410 return (error);
1411
1412 if (fp->f_fglob == NULL) {
1413 error = EBADF;
1414 goto out;
1415 }
1416
1417 switch (fp->f_fglob->fg_type) {
1418 case DTYPE_VNODE:
1419 fvp = (struct vnode *)fp->f_fglob->fg_data;
1420 if ((error = vnode_getwithref(fvp)))
1421 goto out;
1422 MAC_PERFORM(vnode_label_copy, fvp->v_label, vp->v_label);
1423 (void)vnode_put(fvp);
1424 break;
1425 case DTYPE_SOCKET:
1426 so = (struct socket *)fp->f_fglob->fg_data;
1427 socket_lock(so, 1);
1428 MAC_PERFORM(vnode_label_associate_socket,
1429 vfs_context_ucred(ctx), (socket_t)so, so->so_label,
1430 vp, vp->v_label);
1431 socket_unlock(so, 1);
1432 break;
1433 case DTYPE_PSXSHM:
1434 pshm_label_associate(fp, vp, ctx);
1435 break;
1436 case DTYPE_PSXSEM:
1437 psem_label_associate(fp, vp, ctx);
1438 break;
1439 case DTYPE_PIPE:
1440 cpipe = (struct pipe *)fp->f_fglob->fg_data;
1441 /* kern/sys_pipe.c:pipe_select() suggests this test. */
1442 if (cpipe == (struct pipe *)-1) {
1443 error = EINVAL;
1444 goto out;
1445 }
1446 PIPE_LOCK(cpipe);
1447 MAC_PERFORM(vnode_label_associate_pipe, vfs_context_ucred(ctx),
1448 cpipe, cpipe->pipe_label, vp, vp->v_label);
1449 PIPE_UNLOCK(cpipe);
1450 break;
1451 case DTYPE_KQUEUE:
1452 case DTYPE_FSEVENTS:
1453 default:
1454 MAC_PERFORM(vnode_label_associate_file, vfs_context_ucred(ctx),
1455 mp, mp->mnt_mntlabel, fp->f_fglob, fp->f_fglob->fg_label,
1456 vp, vp->v_label);
1457 break;
1458 }
1459 out:
1460 fp_drop(p, fnp->fd_fd, fp, 0);
1461 return (error);
1462 }