]> git.saurik.com Git - apple/xnu.git/blame - security/mac_vfs.c
xnu-1699.22.73.tar.gz
[apple/xnu.git] / security / mac_vfs.c
CommitLineData
2d21ac55
A
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>
b0d623f7 82#include <miscfs/devfs/fdesc.h>
2d21ac55
A
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
89static struct label *
90mac_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
101void
102mac_devfs_label_init(struct devnode *de)
103{
104
105 de->dn_label = mac_devfsdirent_label_alloc();
106}
107
108static struct label *
109mac_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
120void
121mac_mount_label_init(struct mount *mp)
122{
123
124 mp->mnt_mntlabel = mac_mount_label_alloc();
125}
126
127struct label *
128mac_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
139void
140mac_vnode_label_init(vnode_t vp)
141{
2d21ac55
A
142 vp->v_label = mac_vnode_label_alloc();
143}
144
b0d623f7
A
145int
146mac_vnode_label_init_needed(vnode_t vp)
147{
148 return (mac_label_vnodes != 0 && vp->v_label == NULL);
149}
150
2d21ac55
A
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*/
156void
157mac_vnode_label_recycle(vnode_t vp)
158{
159
160 MAC_PERFORM(vnode_label_recycle, vp->v_label);
161}
162
163static void
164mac_devfs_label_free(struct label *label)
165{
166 MAC_PERFORM(devfs_label_destroy, label);
167 mac_labelzone_free(label);
168}
169
170void
171mac_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
179static void
180mac_mount_label_free(struct label *label)
181{
182
183 MAC_PERFORM(mount_label_destroy, label);
184 mac_labelzone_free(label);
185}
186
187void
188mac_mount_label_destroy(struct mount *mp)
189{
2d21ac55
A
190 if (mp->mnt_mntlabel != NULL) {
191 mac_mount_label_free(mp->mnt_mntlabel);
192 mp->mnt_mntlabel = NULL;
193 }
194}
195
196void
197mac_vnode_label_free(struct label *label)
198{
2d21ac55
A
199 MAC_PERFORM(vnode_label_destroy, label);
200 mac_labelzone_free(label);
201}
202
203#ifndef __APPLE__
204void
205mac_vnode_label_destroy(struct vnode *vp)
206{
b0d623f7
A
207 if (vp->v_label != NULL) {
208 mac_vnode_label_free(vp->v_label);
209 vp->v_label = NULL;
210 }
2d21ac55
A
211}
212#endif
213
214void
215mac_vnode_label_copy(struct label *src, struct label *dest)
216{
b0d623f7
A
217 if (src == NULL) {
218 MAC_PERFORM(vnode_label_init, dest);
219 } else {
220 MAC_PERFORM(vnode_label_copy, src, dest);
221 }
2d21ac55
A
222}
223
224int
225mac_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
236int
237mac_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
247int
248mac_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
257int
258mac_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
267int
268mac_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
278void
279mac_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
287void
288mac_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
299int
300mac_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
327void
328mac_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
340int
341mac_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
351void
352mac_vnode_label_associate_singlelabel(struct mount *mp, struct vnode *vp)
353{
354
b0d623f7 355 if (!mac_vnode_enforce || !mac_label_vnodes)
2d21ac55
A
356 return;
357
358 MAC_PERFORM(vnode_label_associate_singlelabel, mp,
359 mp ? mp->mnt_mntlabel : NULL, vp, vp->v_label);
360}
361
362int
363mac_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
6d2010ae
A
380void
381mac_vnode_notify_rename(vfs_context_t ctx, struct vnode *vp,
382 struct vnode *dvp, struct componentname *cnp)
383{
384 kauth_cred_t cred;
385
386 if (!mac_vnode_enforce ||
387 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
388 return;
389
390 cred = vfs_context_ucred(ctx);
391 MAC_PERFORM(vnode_notify_rename, cred, vp, vp->v_label,
392 dvp, dvp->v_label, cnp);
393}
394
2d21ac55
A
395/*
396 * Extended attribute 'name' was updated via
397 * vn_setxattr() or vn_removexattr(). Allow the
398 * policy to update the vnode label.
399 */
400void
401mac_vnode_label_update_extattr(struct mount *mp, struct vnode *vp,
402 const char *name)
403{
404 int error = 0;
405
b0d623f7 406 if (!mac_vnode_enforce || !mac_label_vnodes)
2d21ac55
A
407 return;
408
409 MAC_PERFORM(vnode_label_update_extattr, mp, mp->mnt_mntlabel, vp,
410 vp->v_label, name);
411 if (error == 0)
412 return;
413
414 vnode_lock(vp);
415 vnode_relabel(vp);
416 vnode_unlock(vp);
417 return;
418}
419
420static int
421mac_vnode_label_store(vfs_context_t ctx, struct vnode *vp,
422 struct label *intlabel)
423{
424 kauth_cred_t cred;
425 int error;
426
b0d623f7 427 if (!mac_vnode_enforce || !mac_label_vnodes ||
2d21ac55
A
428 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
429 return 0;
430
431 cred = vfs_context_ucred(ctx);
432 MAC_CHECK(vnode_label_store, cred, vp, vp->v_label, intlabel);
433
434 return (error);
435}
436
c910b4d9 437int
2d21ac55
A
438mac_cred_label_update_execve(vfs_context_t ctx, kauth_cred_t new, struct vnode *vp,
439 struct label *scriptvnodelabel, struct label *execl)
440{
441 kauth_cred_t cred;
c910b4d9 442 int disjoint = 0;
6d2010ae 443 posix_cred_t pcred = posix_cred_get(new);
2d21ac55
A
444
445 if (!mac_proc_enforce && !mac_vnode_enforce)
c910b4d9 446 return disjoint;
2d21ac55
A
447
448 /* mark the new cred to indicate "matching" includes the label */
6d2010ae 449 pcred->cr_flags |= CRF_MAC_ENFORCE;
2d21ac55
A
450
451 cred = vfs_context_ucred(ctx);
452 MAC_PERFORM(cred_label_update_execve, cred, new, vp, vp->v_label,
c910b4d9
A
453 scriptvnodelabel, execl, &disjoint);
454
455 return (disjoint);
2d21ac55
A
456}
457
458int
459mac_cred_check_label_update_execve(vfs_context_t ctx, struct vnode *vp,
460 struct label *scriptvnodelabel, struct label *execlabel, struct proc *p)
461{
462 kauth_cred_t cred;
463 int result = 0;
464
465 if (!mac_proc_enforce && !mac_vnode_enforce)
466 return result;
467
468 cred = vfs_context_ucred(ctx);
469 MAC_BOOLEAN(cred_check_label_update_execve, ||, cred, vp, vp->v_label,
470 scriptvnodelabel, execlabel, p);
471
472 return (result);
473}
474
475int
476mac_vnode_check_access(vfs_context_t ctx, struct vnode *vp,
477 int acc_mode)
478{
479 kauth_cred_t cred;
480 int error;
481 int mask;
482
483 if (!mac_vnode_enforce ||
484 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
485 return 0;
486
487 cred = vfs_context_ucred(ctx);
488 /* Convert {R,W,X}_OK values to V{READ,WRITE,EXEC} for entry points */
489 mask = ACCESS_MODE_TO_VNODE_MASK(acc_mode);
490 MAC_CHECK(vnode_check_access, cred, vp, vp->v_label, mask);
491 return (error);
492 }
493
494int
495mac_vnode_check_chdir(vfs_context_t ctx, struct vnode *dvp)
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_chdir, cred, dvp, dvp->v_label);
506 return (error);
507}
508
509int
510mac_vnode_check_chroot(vfs_context_t ctx, struct vnode *dvp,
511 struct componentname *cnp)
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_chroot, cred, dvp, dvp->v_label, cnp);
522 return (error);
523}
524
525int
526mac_vnode_check_create(vfs_context_t ctx, struct vnode *dvp,
527 struct componentname *cnp, struct vnode_attr *vap)
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_create, cred, dvp, dvp->v_label, cnp, vap);
538 return (error);
539}
540
541int
542mac_vnode_check_unlink(vfs_context_t ctx, struct vnode *dvp, struct vnode *vp,
543 struct componentname *cnp)
544{
545 kauth_cred_t cred;
546 int error;
547
548 if (!mac_vnode_enforce ||
549 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
550 return (0);
551
552 cred = vfs_context_ucred(ctx);
553 MAC_CHECK(vnode_check_unlink, cred, dvp, dvp->v_label, vp,
554 vp->v_label, cnp);
555 return (error);
556}
557#if 0
558int
559mac_vnode_check_deleteacl(vfs_context_t ctx, struct vnode *vp,
560 acl_type_t type)
561{
562 kauth_cred_t cred;
563 int error;
564
565 if (!mac_vnode_enforce ||
566 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
567 return (0);
568
569 cred = vfs_context_ucred(ctx);
570 MAC_CHECK(vnode_check_deleteacl, cred, vp, vp->v_label, type);
571 return (error);
572}
573#endif
574
575int
576mac_vnode_check_deleteextattr(vfs_context_t ctx, struct vnode *vp,
577 const char *name)
578{
579 kauth_cred_t cred;
580 int error;
581
582 if (!mac_vnode_enforce ||
583 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
584 return (0);
585
586 cred = vfs_context_ucred(ctx);
587 MAC_CHECK(vnode_check_deleteextattr, cred, vp, vp->v_label, name);
588 return (error);
589}
590int
591mac_vnode_check_exchangedata(vfs_context_t ctx,
592 struct vnode *v1, struct vnode *v2)
593{
594 kauth_cred_t cred;
595 int error;
596
597 if (!mac_vnode_enforce ||
598 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
599 return (0);
600
601 cred = vfs_context_ucred(ctx);
602 MAC_CHECK(vnode_check_exchangedata, cred, v1, v1->v_label,
603 v2, v2->v_label);
604
605 return (error);
606}
607
608#if 0
609int
610mac_vnode_check_getacl(vfs_context_t ctx, struct vnode *vp, acl_type_t type)
611{
612 kauth_cred_t cred;
613 int error;
614
615 if (!mac_vnode_enforce ||
616 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
617 return (0);
618
619 cred = vfs_context_ucred(ctx);
620 MAC_CHECK(vnode_check_getacl, cred, vp, vp->v_label, type);
621 return (error);
622}
623#endif
624
625int
626mac_vnode_check_getattrlist(vfs_context_t ctx, struct vnode *vp,
627 struct attrlist *alist)
628{
629 kauth_cred_t cred;
630 int error;
631
632 if (!mac_vnode_enforce ||
633 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
634 return (0);
635
636 cred = vfs_context_ucred(ctx);
637 MAC_CHECK(vnode_check_getattrlist, cred, vp, vp->v_label, alist);
638
639 /* Falsify results instead of returning error? */
640 return (error);
641}
642
643int
644mac_vnode_check_exec(vfs_context_t ctx, struct vnode *vp,
645 struct image_params *imgp)
646{
647 kauth_cred_t cred;
648 int error;
649
650 if (!mac_vnode_enforce || !mac_proc_enforce)
651 return (0);
652
653 cred = vfs_context_ucred(ctx);
654 MAC_CHECK(vnode_check_exec, cred, vp, vp->v_label,
655 (imgp != NULL) ? imgp->ip_execlabelp : NULL,
656 (imgp != NULL) ? &imgp->ip_ndp->ni_cnd : NULL,
657 (imgp != NULL) ? &imgp->ip_csflags : NULL);
658 return (error);
659}
660
6d2010ae
A
661int
662mac_vnode_check_fsgetpath(vfs_context_t ctx, struct vnode *vp)
663{
664 kauth_cred_t cred;
665 int error;
666
667 if (!mac_vnode_enforce ||
668 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
669 return (0);
670
671 cred = vfs_context_ucred(ctx);
672 MAC_CHECK(vnode_check_fsgetpath, cred, vp, vp->v_label);
673 return (error);
674}
675
593a1d5f
A
676int
677mac_vnode_check_signature(struct vnode *vp, unsigned char *sha1,
678 void * signature, size_t size)
679{
680 int error;
681
682 if (!mac_vnode_enforce || !mac_proc_enforce)
683 return (0);
684
685 MAC_CHECK(vnode_check_signature, vp, vp->v_label, sha1, signature, size);
686 return (error);
687}
688
2d21ac55
A
689#if 0
690int
691mac_vnode_check_getacl(vfs_context_t ctx, struct vnode *vp, acl_type_t type)
692{
693 kauth_cred_t cred;
694 int error;
695
696 if (!mac_vnode_enforce ||
697 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
698 return (0);
699
700 cred = vfs_context_ucred(ctx);
701 MAC_CHECK(vnode_check_getacl, cred, vp, vp->v_label, type);
702 return (error);
703}
704#endif
705
706int
707mac_vnode_check_getextattr(vfs_context_t ctx, struct vnode *vp,
708 const char *name, struct uio *uio)
709{
710 kauth_cred_t cred;
711 int error;
712
713 if (!mac_vnode_enforce ||
714 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
715 return (0);
716
717 cred = vfs_context_ucred(ctx);
718 MAC_CHECK(vnode_check_getextattr, cred, vp, vp->v_label,
719 name, uio);
720 return (error);
721}
722
723int
724mac_vnode_check_ioctl(vfs_context_t ctx, struct vnode *vp, u_int cmd)
725{
726 kauth_cred_t cred;
727 int error;
728
729 if (!mac_vnode_enforce ||
730 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
731 return (0);
732
733 cred = vfs_context_ucred(ctx);
734 MAC_CHECK(vnode_check_ioctl, cred, vp, vp->v_label, cmd);
735 return (error);
736}
737
738int
739mac_vnode_check_kqfilter(vfs_context_t ctx, kauth_cred_t file_cred,
740 struct knote *kn, struct vnode *vp)
741{
742 kauth_cred_t cred;
743 int error;
744
745 if (!mac_vnode_enforce ||
746 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
747 return (0);
748
749 cred = vfs_context_ucred(ctx);
750 MAC_CHECK(vnode_check_kqfilter, cred, file_cred, kn, vp,
751 vp->v_label);
752
753 return (error);
754}
755
756int
757mac_vnode_check_link(vfs_context_t ctx, struct vnode *dvp,
758 struct vnode *vp, struct componentname *cnp)
759{
760 kauth_cred_t cred;
761 int error;
762
763 if (!mac_vnode_enforce ||
764 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
765 return (0);
766
767 cred = vfs_context_ucred(ctx);
768 MAC_CHECK(vnode_check_link, cred, dvp, dvp->v_label, vp,
769 vp->v_label, cnp);
770 return (error);
771}
772
773int
774mac_vnode_check_listextattr(vfs_context_t ctx, struct vnode *vp)
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_listextattr, cred, vp, vp->v_label);
785 return (error);
786}
787
788int
789mac_vnode_check_lookup(vfs_context_t ctx, struct vnode *dvp,
790 struct componentname *cnp)
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_lookup, cred, dvp, dvp->v_label, cnp);
801 return (error);
802}
803
804int
805mac_vnode_check_open(vfs_context_t ctx, struct vnode *vp, int acc_mode)
806{
807 kauth_cred_t cred;
808 int error;
809
810 if (!mac_vnode_enforce ||
811 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
812 return (0);
813
814 cred = vfs_context_ucred(ctx);
815 MAC_CHECK(vnode_check_open, cred, vp, vp->v_label, acc_mode);
816 return (error);
817}
818
819int
820mac_vnode_check_read(vfs_context_t ctx, struct ucred *file_cred,
821 struct vnode *vp)
822{
823 kauth_cred_t cred;
824 int error;
825
826 if (!mac_vnode_enforce ||
827 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
828 return (0);
829
830 cred = vfs_context_ucred(ctx);
831 MAC_CHECK(vnode_check_read, cred, file_cred, vp,
832 vp->v_label);
833
834 return (error);
835}
836
837int
838mac_vnode_check_readdir(vfs_context_t ctx, struct vnode *dvp)
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_readdir, cred, dvp, dvp->v_label);
849 return (error);
850}
851
852int
853mac_vnode_check_readlink(vfs_context_t ctx, struct vnode *vp)
854{
855 kauth_cred_t cred;
856 int error;
857
858 if (!mac_vnode_enforce ||
859 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
860 return (0);
861
862 cred = vfs_context_ucred(ctx);
863 MAC_CHECK(vnode_check_readlink, cred, vp, vp->v_label);
864 return (error);
865}
866
867int
868mac_vnode_check_label_update(vfs_context_t ctx, struct vnode *vp,
869 struct label *newlabel)
870{
871 kauth_cred_t cred;
872 int error;
873
874 if (!mac_vnode_enforce ||
875 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
876 return (0);
877
878 cred = vfs_context_ucred(ctx);
879 MAC_CHECK(vnode_check_label_update, cred, vp, vp->v_label, newlabel);
880
881 return (error);
882}
883
884int
885mac_vnode_check_rename_from(vfs_context_t ctx, struct vnode *dvp,
886 struct vnode *vp, struct componentname *cnp)
887{
888 kauth_cred_t cred;
889 int error;
890
891 if (!mac_vnode_enforce ||
892 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
893 return (0);
894
895 cred = vfs_context_ucred(ctx);
896 MAC_CHECK(vnode_check_rename_from, cred, dvp, dvp->v_label, vp,
897 vp->v_label, cnp);
898 return (error);
899}
900
901int
902mac_vnode_check_rename_to(vfs_context_t ctx, struct vnode *dvp,
903 struct vnode *vp, int samedir, struct componentname *cnp)
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_rename_to, cred, dvp, dvp->v_label, vp,
914 vp != NULL ? vp->v_label : NULL, samedir, cnp);
915 return (error);
916}
917
918int
919mac_vnode_check_revoke(vfs_context_t ctx, struct vnode *vp)
920{
921 kauth_cred_t cred;
922 int error;
923
924 if (!mac_vnode_enforce ||
925 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
926 return (0);
927
928 cred = vfs_context_ucred(ctx);
929 MAC_CHECK(vnode_check_revoke, cred, vp, vp->v_label);
930 return (error);
931}
932
6d2010ae
A
933int
934mac_vnode_check_searchfs(vfs_context_t ctx, struct vnode *vp, struct attrlist *alist)
935{
936 kauth_cred_t cred;
937 int error;
938
939 if (!mac_vnode_enforce ||
940 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
941 return (0);
942
943 cred = vfs_context_ucred(ctx);
944 MAC_CHECK(vnode_check_searchfs, cred, vp, vp->v_label, alist);
945 return (error);
946}
947
2d21ac55
A
948int
949mac_vnode_check_select(vfs_context_t ctx, struct vnode *vp, int which)
950{
951 kauth_cred_t cred;
952 int error;
953
954 if (!mac_vnode_enforce ||
955 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
956 return (0);
957
958 cred = vfs_context_ucred(ctx);
959 MAC_CHECK(vnode_check_select, cred, vp, vp->v_label, which);
960 return (error);
961}
962
963#if 0
964int
965mac_vnode_check_setacl(vfs_context_t ctx, struct vnode *vp, acl_type_t type,
966 struct acl *acl)
967{
968 kauth_cred_t cred;
969 int error;
970
971 if (!mac_vnode_enforce ||
972 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
973 return (0);
974
975 cred = vfs_context_ucred(ctx);
976 MAC_CHECK(vnode_check_setacl, cred, vp, vp->v_label, type, acl);
977 return (error);
978}
979#endif
980
981int
982mac_vnode_check_setattrlist(vfs_context_t ctx, struct vnode *vp,
983 struct attrlist *alist)
984{
985 kauth_cred_t cred;
986 int error;
987
988 if (!mac_vnode_enforce ||
989 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
990 return (0);
991
992 cred = vfs_context_ucred(ctx);
993 MAC_CHECK(vnode_check_setattrlist, cred, vp, vp->v_label, alist);
994 return (error);
995}
996
997int
998mac_vnode_check_setextattr(vfs_context_t ctx, struct vnode *vp,
999 const char *name, struct uio *uio)
1000{
1001 kauth_cred_t cred;
1002 int error;
1003
1004 if (!mac_vnode_enforce ||
1005 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1006 return (0);
1007
1008 cred = vfs_context_ucred(ctx);
1009 MAC_CHECK(vnode_check_setextattr, cred, vp, vp->v_label,
1010 name, uio);
1011 return (error);
1012}
1013
1014int
1015mac_vnode_check_setflags(vfs_context_t ctx, struct vnode *vp, u_long flags)
1016{
1017 kauth_cred_t cred;
1018 int error;
1019
1020 if (!mac_vnode_enforce ||
1021 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1022 return (0);
1023
1024 cred = vfs_context_ucred(ctx);
1025 MAC_CHECK(vnode_check_setflags, cred, vp, vp->v_label, flags);
1026 return (error);
1027}
1028
1029int
1030mac_vnode_check_setmode(vfs_context_t ctx, struct vnode *vp, mode_t mode)
1031{
1032 kauth_cred_t cred;
1033 int error;
1034
1035 if (!mac_vnode_enforce ||
1036 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1037 return (0);
1038
1039 cred = vfs_context_ucred(ctx);
1040 MAC_CHECK(vnode_check_setmode, cred, vp, vp->v_label, mode);
1041 return (error);
1042}
1043
1044int
1045mac_vnode_check_setowner(vfs_context_t ctx, struct vnode *vp, uid_t uid,
1046 gid_t gid)
1047{
1048 kauth_cred_t cred;
1049 int error;
1050
1051 if (!mac_vnode_enforce ||
1052 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1053 return (0);
1054
1055 cred = vfs_context_ucred(ctx);
1056 MAC_CHECK(vnode_check_setowner, cred, vp, vp->v_label, uid, gid);
1057 return (error);
1058}
1059
1060int
1061mac_vnode_check_setutimes(vfs_context_t ctx, struct vnode *vp,
1062 struct timespec atime, struct timespec mtime)
1063{
1064 kauth_cred_t cred;
1065 int error;
1066
1067 if (!mac_vnode_enforce ||
1068 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1069 return (0);
1070
1071 cred = vfs_context_ucred(ctx);
1072 MAC_CHECK(vnode_check_setutimes, cred, vp, vp->v_label, atime,
1073 mtime);
1074 return (error);
1075}
1076
1077int
1078mac_vnode_check_stat(vfs_context_t ctx, struct ucred *file_cred,
1079 struct vnode *vp)
1080{
1081 kauth_cred_t cred;
1082 int error;
1083
1084 if (!mac_vnode_enforce ||
1085 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1086 return (0);
1087
1088 cred = vfs_context_ucred(ctx);
1089 MAC_CHECK(vnode_check_stat, cred, file_cred, vp,
1090 vp->v_label);
1091 return (error);
1092}
1093
1094int
1095mac_vnode_check_truncate(vfs_context_t ctx, struct ucred *file_cred,
1096 struct vnode *vp)
1097{
1098 kauth_cred_t cred;
1099 int error;
1100
1101 if (!mac_vnode_enforce ||
1102 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1103 return (0);
1104
1105 cred = vfs_context_ucred(ctx);
1106 MAC_CHECK(vnode_check_truncate, cred, file_cred, vp,
1107 vp->v_label);
1108
1109 return (error);
1110}
1111
1112int
1113mac_vnode_check_write(vfs_context_t ctx, struct ucred *file_cred,
1114 struct vnode *vp)
1115{
1116 kauth_cred_t cred;
1117 int error;
1118
1119 if (!mac_vnode_enforce ||
1120 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1121 return (0);
1122
1123 cred = vfs_context_ucred(ctx);
1124 MAC_CHECK(vnode_check_write, cred, file_cred, vp, vp->v_label);
1125
1126 return (error);
1127}
1128
b0d623f7
A
1129int
1130mac_vnode_check_uipc_bind(vfs_context_t ctx, struct vnode *dvp,
1131 struct componentname *cnp, struct vnode_attr *vap)
1132{
1133 kauth_cred_t cred;
1134 int error;
1135
1136 if (!mac_vnode_enforce ||
1137 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1138 return (0);
1139
1140 cred = vfs_context_ucred(ctx);
1141 MAC_CHECK(vnode_check_uipc_bind, cred, dvp, dvp->v_label, cnp, vap);
1142 return (error);
1143}
1144
1145int
1146mac_vnode_check_uipc_connect(vfs_context_t ctx, struct vnode *vp)
1147{
1148 kauth_cred_t cred;
1149 int error;
1150
1151 if (!mac_vnode_enforce ||
1152 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1153 return (0);
1154
1155 cred = vfs_context_ucred(ctx);
1156 MAC_CHECK(vnode_check_uipc_connect, cred, vp, vp->v_label);
1157 return (error);
1158}
1159
2d21ac55
A
1160void
1161mac_vnode_label_update(vfs_context_t ctx, struct vnode *vp, struct label *newlabel)
1162{
1163 kauth_cred_t cred = vfs_context_ucred(ctx);
b0d623f7
A
1164 struct label *tmpl = NULL;
1165
1166 if (vp->v_label == NULL)
1167 tmpl = mac_vnode_label_alloc();
2d21ac55
A
1168
1169 vnode_lock(vp);
b0d623f7
A
1170
1171 /* recheck after lock */
1172 if (vp->v_label == NULL) {
1173 vp->v_label = tmpl;
1174 tmpl = NULL;
1175 }
1176
2d21ac55
A
1177 MAC_PERFORM(vnode_label_update, cred, vp, vp->v_label, newlabel);
1178 vnode_unlock(vp);
b0d623f7
A
1179
1180 if (tmpl != NULL)
1181 mac_vnode_label_free(tmpl);
2d21ac55
A
1182}
1183
1184void
1185mac_mount_label_associate(vfs_context_t ctx, struct mount *mp)
1186{
1187 kauth_cred_t cred = vfs_context_ucred(ctx);
1188
1189 /* XXX: eventually this logic may be handled by the policy? */
1190
1191 /* We desire MULTILABEL for the root filesystem. */
1192 if ((mp->mnt_flag & MNT_ROOTFS) &&
1193 (strcmp(mp->mnt_vfsstat.f_fstypename, "hfs") == 0))
1194 mp->mnt_flag |= MNT_MULTILABEL;
1195
1196 /* MULTILABEL on DEVFS. */
1197 if (strcmp(mp->mnt_vfsstat.f_fstypename, "devfs") == 0)
1198 mp->mnt_flag |= MNT_MULTILABEL;
1199
1200 /* MULTILABEL on FDESC pseudo-filesystem. */
1201 if (strcmp(mp->mnt_vfsstat.f_fstypename, "fdesc") == 0)
1202 mp->mnt_flag |= MNT_MULTILABEL;
1203
1204 /* MULTILABEL on all NFS filesystems. */
1205 if (strcmp(mp->mnt_vfsstat.f_fstypename, "nfs") == 0)
1206 mp->mnt_flag |= MNT_MULTILABEL;
1207
1208 /* MULTILABEL on all AFP filesystems. */
1209 if (strcmp(mp->mnt_vfsstat.f_fstypename, "afpfs") == 0)
1210 mp->mnt_flag |= MNT_MULTILABEL;
1211
1212 if (mp->mnt_vtable != NULL) {
1213 /* Any filesystem that supports native XATTRs. */
1214 if ((mp->mnt_vtable->vfc_vfsflags & VFC_VFSNATIVEXATTR))
1215 mp->mnt_flag |= MNT_MULTILABEL;
1216
1217 /* Filesystem does not support multilabel. */
1218 if ((mp->mnt_vtable->vfc_vfsflags & VFC_VFSNOMACLABEL) &&
1219 (mp->mnt_flag & MNT_MULTILABEL))
1220 mp->mnt_flag &= ~MNT_MULTILABEL;
1221 }
1222
1223 MAC_PERFORM(mount_label_associate, cred, mp, mp->mnt_mntlabel);
1224#if MAC_DEBUG
1225 printf("MAC Framework enabling %s support: %s -> %s (%s)\n",
1226 mp->mnt_flag & MNT_MULTILABEL ? "multilabel" : "singlelabel",
1227 mp->mnt_vfsstat.f_mntfromname,
1228 mp->mnt_vfsstat.f_mntonname,
1229 mp->mnt_vfsstat.f_fstypename);
1230#endif
1231}
1232
1233int
1234mac_mount_check_mount(vfs_context_t ctx, struct vnode *vp,
1235 struct componentname *cnp, const char *vfc_name)
1236{
1237 kauth_cred_t cred;
1238 int error;
1239
1240 if (!mac_vnode_enforce ||
1241 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1242 return (0);
1243
1244 cred = vfs_context_ucred(ctx);
1245 MAC_CHECK(mount_check_mount, cred, vp, vp->v_label, cnp, vfc_name);
1246
1247 return (error);
1248}
1249
1250int
1251mac_mount_check_remount(vfs_context_t ctx, struct mount *mp)
1252{
1253 kauth_cred_t cred;
1254 int error;
1255
1256 if (!mac_vnode_enforce ||
1257 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1258 return (0);
1259
1260 cred = vfs_context_ucred(ctx);
1261 MAC_CHECK(mount_check_remount, cred, mp, mp->mnt_mntlabel);
1262
1263 return (error);
1264}
1265
1266int
1267mac_mount_check_umount(vfs_context_t ctx, struct mount *mp)
1268{
1269 kauth_cred_t cred;
1270 int error;
1271
1272 if (!mac_vnode_enforce ||
1273 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1274 return (0);
1275
1276 cred = vfs_context_ucred(ctx);
1277 MAC_CHECK(mount_check_umount, cred, mp, mp->mnt_mntlabel);
1278
1279 return (error);
1280}
1281
1282int
1283mac_mount_check_getattr(vfs_context_t ctx, struct mount *mp,
1284 struct vfs_attr *vfa)
1285{
1286 kauth_cred_t cred;
1287 int error;
1288
1289 if (!mac_vnode_enforce ||
1290 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1291 return (0);
1292
1293 cred = vfs_context_ucred(ctx);
1294 MAC_CHECK(mount_check_getattr, cred, mp, mp->mnt_mntlabel, vfa);
1295 return (error);
1296}
1297
1298int
1299mac_mount_check_setattr(vfs_context_t ctx, struct mount *mp,
1300 struct vfs_attr *vfa)
1301{
1302 kauth_cred_t cred;
1303 int error;
1304
1305 if (!mac_vnode_enforce ||
1306 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1307 return (0);
1308
1309 cred = vfs_context_ucred(ctx);
1310 MAC_CHECK(mount_check_setattr, cred, mp, mp->mnt_mntlabel, vfa);
1311 return (error);
1312}
1313
1314int
1315mac_mount_check_stat(vfs_context_t ctx, struct mount *mount)
1316{
1317 kauth_cred_t cred;
1318 int error;
1319
1320 if (!mac_vnode_enforce ||
1321 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1322 return (0);
1323
1324 cred = vfs_context_ucred(ctx);
1325 MAC_CHECK(mount_check_stat, cred, mount, mount->mnt_mntlabel);
1326
1327 return (error);
1328}
1329
1330int
1331mac_mount_check_label_update(vfs_context_t ctx, struct mount *mount)
1332{
1333 kauth_cred_t cred;
1334 int error;
1335
1336 if (!mac_vnode_enforce ||
1337 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1338 return (0);
1339
1340 cred = vfs_context_ucred(ctx);
1341 MAC_CHECK(mount_check_label_update, cred, mount, mount->mnt_mntlabel);
1342
1343 return (error);
1344}
1345
1346int
1347mac_mount_check_fsctl(vfs_context_t ctx, struct mount *mp, u_int cmd)
1348{
1349 kauth_cred_t cred;
1350 int error;
1351
1352 if (!mac_vnode_enforce ||
1353 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1354 return (0);
1355
1356 cred = vfs_context_ucred(ctx);
1357 MAC_CHECK(mount_check_fsctl, cred, mp, mp->mnt_mntlabel, cmd);
1358
1359 return (error);
1360}
1361
1362void
1363mac_devfs_label_associate_device(dev_t dev, struct devnode *de,
1364 const char *fullpath)
1365{
1366 if (!mac_device_enforce)
1367 return;
1368
1369 MAC_PERFORM(devfs_label_associate_device, dev, de, de->dn_label,
1370 fullpath);
1371}
1372
1373void
1374mac_devfs_label_associate_directory(const char *dirname, int dirnamelen,
1375 struct devnode *de, const char *fullpath)
1376{
1377 if (!mac_device_enforce)
1378 return;
1379
1380 MAC_PERFORM(devfs_label_associate_directory, dirname, dirnamelen, de,
1381 de->dn_label, fullpath);
1382}
1383
1384int
1385vn_setlabel(struct vnode *vp, struct label *intlabel, vfs_context_t context)
1386{
1387 int error;
1388
b0d623f7 1389 if (!mac_vnode_enforce || !mac_label_vnodes)
2d21ac55
A
1390 return (0);
1391
1392 if (vp->v_mount == NULL) {
1393 printf("vn_setlabel: null v_mount\n");
1394 if (vp->v_type != VNON)
1395 printf("vn_setlabel: null v_mount with non-VNON\n");
1396 return (EBADF);
1397 }
1398
1399 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
1400 return (ENOTSUP);
1401
1402 /*
1403 * Multi-phase commit. First check the policies to confirm the
1404 * change is OK. Then commit via the filesystem. Finally,
1405 * update the actual vnode label. Question: maybe the filesystem
1406 * should update the vnode at the end as part of VNOP_SETLABEL()?
1407 */
1408 error = mac_vnode_check_label_update(context, vp, intlabel);
1409 if (error)
1410 return (error);
1411
1412 error = VNOP_SETLABEL(vp, intlabel, context);
1413 if (error == ENOTSUP) {
1414 error = mac_vnode_label_store(context, vp,
1415 intlabel);
1416 if (error) {
1417 printf("%s: mac_vnode_label_store failed %d\n",
1418 __func__, error);
1419 return (error);
1420 }
1421 mac_vnode_label_update(context, vp, intlabel);
1422 } else
1423 if (error) {
1424 printf("vn_setlabel: vop setlabel failed %d\n", error);
1425 return (error);
1426 }
1427
1428 return (0);
1429}
1430
1431int
1432mac_vnode_label_associate_fdesc(struct mount *mp, struct fdescnode *fnp,
1433 struct vnode *vp, vfs_context_t ctx)
1434{
1435 struct fileproc *fp;
1436 struct socket *so;
1437 struct pipe *cpipe;
1438 struct vnode *fvp;
1439 struct proc *p;
1440 int error;
1441
1442 error = 0;
1443
1444 /*
1445 * If no backing file, let the policy choose which label to use.
1446 */
1447 if (fnp->fd_fd == -1) {
1448 MAC_PERFORM(vnode_label_associate_file, vfs_context_ucred(ctx),
1449 mp, mp->mnt_mntlabel, NULL, NULL, vp, vp->v_label);
1450 return (0);
1451 }
1452
1453 p = vfs_context_proc(ctx);
1454 error = fp_lookup(p, fnp->fd_fd, &fp, 0);
1455 if (error)
1456 return (error);
1457
1458 if (fp->f_fglob == NULL) {
1459 error = EBADF;
1460 goto out;
1461 }
1462
1463 switch (fp->f_fglob->fg_type) {
1464 case DTYPE_VNODE:
1465 fvp = (struct vnode *)fp->f_fglob->fg_data;
1466 if ((error = vnode_getwithref(fvp)))
1467 goto out;
1468 MAC_PERFORM(vnode_label_copy, fvp->v_label, vp->v_label);
1469 (void)vnode_put(fvp);
1470 break;
1471 case DTYPE_SOCKET:
1472 so = (struct socket *)fp->f_fglob->fg_data;
1473 socket_lock(so, 1);
1474 MAC_PERFORM(vnode_label_associate_socket,
1475 vfs_context_ucred(ctx), (socket_t)so, so->so_label,
1476 vp, vp->v_label);
1477 socket_unlock(so, 1);
1478 break;
1479 case DTYPE_PSXSHM:
1480 pshm_label_associate(fp, vp, ctx);
1481 break;
1482 case DTYPE_PSXSEM:
1483 psem_label_associate(fp, vp, ctx);
1484 break;
1485 case DTYPE_PIPE:
1486 cpipe = (struct pipe *)fp->f_fglob->fg_data;
1487 /* kern/sys_pipe.c:pipe_select() suggests this test. */
1488 if (cpipe == (struct pipe *)-1) {
1489 error = EINVAL;
1490 goto out;
1491 }
1492 PIPE_LOCK(cpipe);
1493 MAC_PERFORM(vnode_label_associate_pipe, vfs_context_ucred(ctx),
1494 cpipe, cpipe->pipe_label, vp, vp->v_label);
1495 PIPE_UNLOCK(cpipe);
1496 break;
1497 case DTYPE_KQUEUE:
1498 case DTYPE_FSEVENTS:
1499 default:
1500 MAC_PERFORM(vnode_label_associate_file, vfs_context_ucred(ctx),
1501 mp, mp->mnt_mntlabel, fp->f_fglob, fp->f_fglob->fg_label,
1502 vp, vp->v_label);
1503 break;
1504 }
1505out:
1506 fp_drop(p, fnp->fd_fd, fp, 0);
1507 return (error);
1508}