]> git.saurik.com Git - apple/xnu.git/blob - security/mac_vfs.c
xnu-7195.101.1.tar.gz
[apple/xnu.git] / security / mac_vfs.c
1 /*
2 * Copyright (c) 2007-2016 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 <kern/kalloc.h>
66 #include <libkern/OSAtomic.h>
67
68 #include <sys/param.h>
69 #include <sys/systm.h>
70 #include <sys/kernel.h>
71 #include <sys/proc.h>
72 #include <sys/kauth.h>
73
74 #include <sys/file_internal.h>
75 #include <sys/imgact.h>
76 #include <sys/namei.h>
77 #include <sys/mount_internal.h>
78 #include <sys/pipe.h>
79 #include <sys/posix_sem.h>
80 #include <sys/posix_shm.h>
81 #include <sys/reason.h>
82 #include <sys/uio_internal.h>
83 #include <sys/vnode_internal.h>
84 #include <sys/kdebug.h>
85
86
87 #include <miscfs/devfs/devfsdefs.h>
88 #include <miscfs/devfs/fdesc.h>
89
90 #include <security/mac_internal.h>
91
92 /* convert {R,W,X}_OK values to V{READ,WRITE,EXEC} */
93 #define ACCESS_MODE_TO_VNODE_MASK(m) (m << 6)
94
95
96 /*
97 * Optional tracing of policy operations. Define VFS_TRACE_POLICY_OPS to trace the operations.
98 *
99 * Along with DBG_FSYSTEM and DBG_VFS, dcode in the macros below is used to construct
100 * KDBG_EVENTID(DBG_FSYSTEM, DBG_VFS, dcode) global event id, see bsd/sys/kdebug.h.
101 * Note that dcode is multiplied by 4 and ORed as part of the construction. See bsd/kern/trace_codes
102 * for list of system-wide {global event id, name} pairs. Currently DBG_VFS event ids are in range
103 * [0x3130000, 0x3130174].
104 */
105
106 //#define VFS_TRACE_POLICY_OPS
107
108 #ifdef VFS_TRACE_POLICY_OPS
109 #define DBG_VFS_CODE(dcode) FSDBG_CODE(DBG_VFS, dcode)
110 #define VFS_KERNEL_DEBUG_START0(dcode) KERNEL_DEBUG_CONSTANT(DBG_VFS_CODE(dcode) | DBG_FUNC_START, 0, 0, 0, 0, 0)
111 #define VFS_KERNEL_DEBUG_END0(dcode) KERNEL_DEBUG_CONSTANT(DBG_VFS_CODE(dcode) | DBG_FUNC_END, 0, 0, 0, 0, 0)
112 #define VFS_KERNEL_DEBUG_START1(dcode, darg) KERNEL_DEBUG_CONSTANT(DBG_VFS_CODE(dcode) | DBG_FUNC_START, darg, 0, 0, 0, 0)
113 #define VFS_KERNEL_DEBUG_END1(dcode, darg) KERNEL_DEBUG_CONSTANT(DBG_VFS_CODE(dcode) | DBG_FUNC_END, darg, 0, 0, 0, 0)
114 #else
115 #define VFS_KERNEL_DEBUG_START0(dcode) do {} while (0)
116 #define VFS_KERNEL_DEBUG_END0(dcode) do {} while (0)
117 #define VFS_KERNEL_DEBUG_START1(dcode, darg) do {} while (0)
118 #define VFS_KERNEL_DEBUG_END1(dcode, darg) do {} while (0)
119 #endif
120
121 static struct label *
122 mac_devfsdirent_label_alloc(void)
123 {
124 struct label *label;
125
126 label = mac_labelzone_alloc(MAC_WAITOK);
127 if (label == NULL) {
128 return NULL;
129 }
130 VFS_KERNEL_DEBUG_START0(0);
131 MAC_PERFORM(devfs_label_init, label);
132 VFS_KERNEL_DEBUG_END0(0);
133 return label;
134 }
135
136 void
137 mac_devfs_label_init(struct devnode *de)
138 {
139 de->dn_label = mac_devfsdirent_label_alloc();
140 }
141
142 static struct label *
143 mac_mount_label_alloc(void)
144 {
145 struct label *label;
146
147 label = mac_labelzone_alloc(MAC_WAITOK);
148 if (label == NULL) {
149 return NULL;
150 }
151 VFS_KERNEL_DEBUG_START0(1);
152 MAC_PERFORM(mount_label_init, label);
153 VFS_KERNEL_DEBUG_END0(1);
154 return label;
155 }
156
157 void
158 mac_mount_label_init(struct mount *mp)
159 {
160 mp->mnt_mntlabel = mac_mount_label_alloc();
161 }
162
163 struct label *
164 mac_vnode_label_alloc(void)
165 {
166 struct label *label;
167
168 label = mac_labelzone_alloc(MAC_WAITOK);
169 if (label == NULL) {
170 return NULL;
171 }
172 VFS_KERNEL_DEBUG_START0(2);
173 MAC_PERFORM(vnode_label_init, label);
174 VFS_KERNEL_DEBUG_END0(2);
175 OSIncrementAtomic(&mac_vnode_label_count);
176 return label;
177 }
178
179 void
180 mac_vnode_label_init(vnode_t vp)
181 {
182 vp->v_label = mac_vnode_label_alloc();
183 }
184
185 int
186 mac_vnode_label_init_needed(vnode_t vp)
187 {
188 #if CONFIG_MACF_LAZY_VNODE_LABELS
189 (void)vp;
190 return false;
191 #else
192 return mac_label_vnodes != 0 && vp->v_label == NULL;
193 #endif
194 }
195
196 struct label *
197 mac_vnode_label_allocate(vnode_t vp)
198 {
199 if (mac_vnode_label_init_needed(vp)) {
200 vp->v_label = mac_vnode_label_alloc();
201 }
202 return vp->v_label;
203 }
204
205 /*
206 * vnode labels are allocated at the same time as vnodes, but vnodes are never
207 * freed. Instead, we want to remove any sensitive information before putting
208 * them on the free list for reuse.
209 */
210 void
211 mac_vnode_label_recycle(vnode_t vp)
212 {
213 MAC_PERFORM(vnode_label_recycle, vp->v_label);
214 #if CONFIG_MACF_LAZY_VNODE_LABELS
215 if (vp->v_label) {
216 mac_vnode_label_destroy(vp);
217 vp->v_label = NULL;
218 vp->v_lflag &= ~VL_LABELED;
219 }
220 #endif
221 }
222
223 static void
224 mac_devfs_label_free(struct label *label)
225 {
226 VFS_KERNEL_DEBUG_START1(3, label);
227 MAC_PERFORM(devfs_label_destroy, label);
228 VFS_KERNEL_DEBUG_END1(3, label);
229 mac_labelzone_free(label);
230 }
231
232 void
233 mac_devfs_label_destroy(struct devnode *de)
234 {
235 if (de->dn_label != NULL) {
236 mac_devfs_label_free(de->dn_label);
237 de->dn_label = NULL;
238 }
239 }
240
241 static void
242 mac_mount_label_free(struct label *label)
243 {
244 VFS_KERNEL_DEBUG_START1(4, label);
245 MAC_PERFORM(mount_label_destroy, label);
246 VFS_KERNEL_DEBUG_END1(4, label);
247 mac_labelzone_free(label);
248 }
249
250 void
251 mac_mount_label_destroy(struct mount *mp)
252 {
253 if (mp->mnt_mntlabel != NULL) {
254 mac_mount_label_free(mp->mnt_mntlabel);
255 mp->mnt_mntlabel = NULL;
256 }
257 }
258
259 void
260 mac_vnode_label_free(struct label *label)
261 {
262 if (label != NULL) {
263 VFS_KERNEL_DEBUG_START1(5, label);
264 MAC_PERFORM(vnode_label_destroy, label);
265 VFS_KERNEL_DEBUG_END1(5, label);
266 mac_labelzone_free(label);
267 OSDecrementAtomic(&mac_vnode_label_count);
268 }
269 }
270
271 void
272 mac_vnode_label_destroy(struct vnode *vp)
273 {
274 if (vp->v_label != NULL) {
275 mac_vnode_label_free(vp->v_label);
276 vp->v_label = NULL;
277 }
278 }
279
280 void
281 mac_vnode_label_copy(struct label *src, struct label *dest)
282 {
283 VFS_KERNEL_DEBUG_START1(6, src);
284 if (src == NULL) {
285 MAC_PERFORM(vnode_label_init, dest);
286 } else {
287 MAC_PERFORM(vnode_label_copy, src, dest);
288 }
289 VFS_KERNEL_DEBUG_END1(6, src);
290 }
291
292 int
293 mac_vnode_label_externalize_audit(struct vnode *vp, struct mac *mac)
294 {
295 int error;
296
297 /* It is assumed that any necessary vnode locking is done on entry */
298 error = MAC_EXTERNALIZE_AUDIT(vnode, vp->v_label,
299 mac->m_string, mac->m_buflen);
300
301 return error;
302 }
303
304 int
305 mac_vnode_label_externalize(struct label *label, char *elements,
306 char *outbuf, size_t outbuflen, int flags __unused)
307 {
308 int error;
309
310 error = MAC_EXTERNALIZE(vnode, label, elements, outbuf, outbuflen);
311
312 return error;
313 }
314
315 int
316 mac_vnode_label_internalize(struct label *label, char *string)
317 {
318 int error;
319
320 error = MAC_INTERNALIZE(vnode, label, string);
321
322 return error;
323 }
324
325 int
326 mac_mount_label_internalize(struct label *label, char *string)
327 {
328 int error;
329
330 error = MAC_INTERNALIZE(mount, label, string);
331
332 return error;
333 }
334
335 int
336 mac_mount_label_externalize(struct label *label, char *elements,
337 char *outbuf, size_t outbuflen)
338 {
339 int error;
340
341 error = MAC_EXTERNALIZE(mount, label, elements, outbuf, outbuflen);
342
343 return error;
344 }
345
346 void
347 mac_devfs_label_copy(struct label *src, struct label *dest)
348 {
349 #if SECURITY_MAC_CHECK_ENFORCE
350 /* 21167099 - only check if we allow write */
351 if (!mac_device_enforce) {
352 return;
353 }
354 #endif
355
356 VFS_KERNEL_DEBUG_START1(7, src);
357 MAC_PERFORM(devfs_label_copy, src, dest);
358 VFS_KERNEL_DEBUG_END1(7, src);
359 }
360
361 void
362 mac_devfs_label_update(struct mount *mp, struct devnode *de,
363 struct vnode *vp)
364 {
365 #if SECURITY_MAC_CHECK_ENFORCE
366 /* 21167099 - only check if we allow write */
367 if (!mac_device_enforce) {
368 return;
369 }
370 #endif
371
372 VFS_KERNEL_DEBUG_START1(8, vp);
373 MAC_PERFORM(devfs_label_update, mp, de, de->dn_label, vp,
374 vp->v_label);
375 VFS_KERNEL_DEBUG_END1(8, vp);
376 }
377
378 int
379 mac_vnode_label_associate(struct mount *mp, struct vnode *vp, vfs_context_t ctx)
380 {
381 struct devnode *dnp;
382 struct fdescnode *fnp;
383 int error = 0;
384
385 #if SECURITY_MAC_CHECK_ENFORCE
386 /* 21167099 - only check if we allow write */
387 if (!mac_vnode_enforce) {
388 return error;
389 }
390 #endif
391
392 /* XXX: should not inspect v_tag in kernel! */
393 switch (vp->v_tag) {
394 case VT_DEVFS:
395 dnp = VTODN(vp);
396 mac_vnode_label_associate_devfs(mp, dnp, vp);
397 break;
398 case VT_FDESC:
399 fnp = VTOFDESC(vp);
400 error = mac_vnode_label_associate_fdesc(mp, fnp, vp, ctx);
401 break;
402 default:
403 error = mac_vnode_label_associate_extattr(mp, vp);
404 break;
405 }
406
407 return error;
408 }
409
410 void
411 mac_vnode_label_associate_devfs(struct mount *mp, struct devnode *de,
412 struct vnode *vp)
413 {
414 #if SECURITY_MAC_CHECK_ENFORCE
415 /* 21167099 - only check if we allow write */
416 if (!mac_device_enforce) {
417 return;
418 }
419 #endif
420
421 VFS_KERNEL_DEBUG_START1(9, vp);
422 MAC_PERFORM(vnode_label_associate_devfs,
423 mp, mp ? mp->mnt_mntlabel : NULL,
424 de, de->dn_label,
425 vp, vp->v_label);
426 VFS_KERNEL_DEBUG_END1(9, vp);
427 }
428
429 int
430 mac_vnode_label_associate_extattr(struct mount *mp, struct vnode *vp)
431 {
432 int error;
433
434 VFS_KERNEL_DEBUG_START1(10, vp);
435 MAC_CHECK(vnode_label_associate_extattr, mp, mp->mnt_mntlabel, vp,
436 vp->v_label);
437 VFS_KERNEL_DEBUG_END1(10, vp);
438
439 return error;
440 }
441
442 void
443 mac_vnode_label_associate_singlelabel(struct mount *mp, struct vnode *vp)
444 {
445 #if SECURITY_MAC_CHECK_ENFORCE
446 /* 21167099 - only check if we allow write */
447 if (!mac_vnode_enforce) {
448 return;
449 }
450 #endif
451 if (!mac_label_vnodes) {
452 return;
453 }
454
455 VFS_KERNEL_DEBUG_START1(11, vp);
456 MAC_PERFORM(vnode_label_associate_singlelabel, mp,
457 mp ? mp->mnt_mntlabel : NULL, vp, vp->v_label);
458 VFS_KERNEL_DEBUG_END1(11, vp);
459 }
460
461 int
462 mac_vnode_notify_create(vfs_context_t ctx, struct mount *mp,
463 struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
464 {
465 kauth_cred_t cred;
466 int error;
467
468 #if SECURITY_MAC_CHECK_ENFORCE
469 /* 21167099 - only check if we allow write */
470 if (!mac_vnode_enforce) {
471 return 0;
472 }
473 #endif
474 cred = vfs_context_ucred(ctx);
475 if (!mac_cred_check_enforce(cred)) {
476 return 0;
477 }
478 VFS_KERNEL_DEBUG_START1(12, vp);
479 MAC_CHECK(vnode_notify_create, cred, mp, mp->mnt_mntlabel,
480 dvp, dvp->v_label, vp, vp->v_label, cnp);
481 VFS_KERNEL_DEBUG_END1(12, vp);
482
483 return error;
484 }
485
486 void
487 mac_vnode_notify_rename(vfs_context_t ctx, struct vnode *vp,
488 struct vnode *dvp, struct componentname *cnp)
489 {
490 kauth_cred_t cred;
491
492 #if SECURITY_MAC_CHECK_ENFORCE
493 /* 21167099 - only check if we allow write */
494 if (!mac_vnode_enforce) {
495 return;
496 }
497 #endif
498 cred = vfs_context_ucred(ctx);
499 if (!mac_cred_check_enforce(cred)) {
500 return;
501 }
502 VFS_KERNEL_DEBUG_START1(13, vp);
503 MAC_PERFORM(vnode_notify_rename, cred, vp, vp->v_label,
504 dvp, dvp->v_label, cnp);
505 VFS_KERNEL_DEBUG_END1(13, vp);
506 }
507
508 void
509 mac_vnode_notify_open(vfs_context_t ctx, struct vnode *vp, int acc_flags)
510 {
511 kauth_cred_t cred;
512
513 #if SECURITY_MAC_CHECK_ENFORCE
514 /* 21167099 - only check if we allow write */
515 if (!mac_vnode_enforce) {
516 return;
517 }
518 #endif
519 cred = vfs_context_ucred(ctx);
520 if (!mac_cred_check_enforce(cred)) {
521 return;
522 }
523 VFS_KERNEL_DEBUG_START1(14, vp);
524 MAC_PERFORM(vnode_notify_open, cred, vp, vp->v_label, acc_flags);
525 VFS_KERNEL_DEBUG_END1(14, vp);
526 }
527
528 void
529 mac_vnode_notify_link(vfs_context_t ctx, struct vnode *vp,
530 struct vnode *dvp, struct componentname *cnp)
531 {
532 kauth_cred_t cred;
533
534 #if SECURITY_MAC_CHECK_ENFORCE
535 /* 21167099 - only check if we allow write */
536 if (!mac_vnode_enforce) {
537 return;
538 }
539 #endif
540 cred = vfs_context_ucred(ctx);
541 if (!mac_cred_check_enforce(cred)) {
542 return;
543 }
544 VFS_KERNEL_DEBUG_START1(15, vp);
545 MAC_PERFORM(vnode_notify_link, cred, dvp, dvp->v_label, vp, vp->v_label, cnp);
546 VFS_KERNEL_DEBUG_END1(15, vp);
547 }
548
549 void
550 mac_vnode_notify_deleteextattr(vfs_context_t ctx, struct vnode *vp, const char *name)
551 {
552 kauth_cred_t cred;
553
554 #if SECURITY_MAC_CHECK_ENFORCE
555 /* 21167099 - only check if we allow write */
556 if (!mac_vnode_enforce) {
557 return;
558 }
559 #endif
560 cred = vfs_context_ucred(ctx);
561 if (!mac_cred_check_enforce(cred)) {
562 return;
563 }
564 VFS_KERNEL_DEBUG_START1(16, vp);
565 MAC_PERFORM(vnode_notify_deleteextattr, cred, vp, vp->v_label, name);
566 VFS_KERNEL_DEBUG_END1(16, vp);
567 }
568
569 void
570 mac_vnode_notify_setacl(vfs_context_t ctx, struct vnode *vp, struct kauth_acl *acl)
571 {
572 kauth_cred_t cred;
573
574 #if SECURITY_MAC_CHECK_ENFORCE
575 /* 21167099 - only check if we allow write */
576 if (!mac_vnode_enforce) {
577 return;
578 }
579 #endif
580 cred = vfs_context_ucred(ctx);
581 if (!mac_cred_check_enforce(cred)) {
582 return;
583 }
584 VFS_KERNEL_DEBUG_START1(17, vp);
585 MAC_PERFORM(vnode_notify_setacl, cred, vp, vp->v_label, acl);
586 VFS_KERNEL_DEBUG_END1(17, vp);
587 }
588
589 void
590 mac_vnode_notify_setattrlist(vfs_context_t ctx, struct vnode *vp, struct attrlist *alist)
591 {
592 kauth_cred_t cred;
593
594 #if SECURITY_MAC_CHECK_ENFORCE
595 /* 21167099 - only check if we allow write */
596 if (!mac_vnode_enforce) {
597 return;
598 }
599 #endif
600 cred = vfs_context_ucred(ctx);
601 if (!mac_cred_check_enforce(cred)) {
602 return;
603 }
604 VFS_KERNEL_DEBUG_START1(18, vp);
605 MAC_PERFORM(vnode_notify_setattrlist, cred, vp, vp->v_label, alist);
606 VFS_KERNEL_DEBUG_END1(18, vp);
607 }
608
609 void
610 mac_vnode_notify_setextattr(vfs_context_t ctx, struct vnode *vp, const char *name, struct uio *uio)
611 {
612 kauth_cred_t cred;
613
614 #if SECURITY_MAC_CHECK_ENFORCE
615 /* 21167099 - only check if we allow write */
616 if (!mac_vnode_enforce) {
617 return;
618 }
619 #endif
620 cred = vfs_context_ucred(ctx);
621 if (!mac_cred_check_enforce(cred)) {
622 return;
623 }
624 VFS_KERNEL_DEBUG_START1(19, vp);
625 MAC_PERFORM(vnode_notify_setextattr, cred, vp, vp->v_label, name, uio);
626 VFS_KERNEL_DEBUG_END1(19, vp);
627 }
628
629 void
630 mac_vnode_notify_setflags(vfs_context_t ctx, struct vnode *vp, u_long flags)
631 {
632 kauth_cred_t cred;
633
634 #if SECURITY_MAC_CHECK_ENFORCE
635 /* 21167099 - only check if we allow write */
636 if (!mac_vnode_enforce) {
637 return;
638 }
639 #endif
640 cred = vfs_context_ucred(ctx);
641 if (!mac_cred_check_enforce(cred)) {
642 return;
643 }
644 VFS_KERNEL_DEBUG_START1(20, vp);
645 MAC_PERFORM(vnode_notify_setflags, cred, vp, vp->v_label, flags);
646 VFS_KERNEL_DEBUG_END1(20, vp);
647 }
648
649 void
650 mac_vnode_notify_setmode(vfs_context_t ctx, struct vnode *vp, mode_t mode)
651 {
652 kauth_cred_t cred;
653
654 #if SECURITY_MAC_CHECK_ENFORCE
655 /* 21167099 - only check if we allow write */
656 if (!mac_vnode_enforce) {
657 return;
658 }
659 #endif
660 cred = vfs_context_ucred(ctx);
661 if (!mac_cred_check_enforce(cred)) {
662 return;
663 }
664 VFS_KERNEL_DEBUG_START1(21, vp);
665 MAC_PERFORM(vnode_notify_setmode, cred, vp, vp->v_label, mode);
666 VFS_KERNEL_DEBUG_END1(21, vp);
667 }
668
669 void
670 mac_vnode_notify_setowner(vfs_context_t ctx, struct vnode *vp, uid_t uid, gid_t gid)
671 {
672 kauth_cred_t cred;
673
674 #if SECURITY_MAC_CHECK_ENFORCE
675 /* 21167099 - only check if we allow write */
676 if (!mac_vnode_enforce) {
677 return;
678 }
679 #endif
680 cred = vfs_context_ucred(ctx);
681 if (!mac_cred_check_enforce(cred)) {
682 return;
683 }
684 VFS_KERNEL_DEBUG_START1(22, vp);
685 MAC_PERFORM(vnode_notify_setowner, cred, vp, vp->v_label, uid, gid);
686 VFS_KERNEL_DEBUG_END1(22, vp);
687 }
688
689 void
690 mac_vnode_notify_setutimes(vfs_context_t ctx, struct vnode *vp, struct timespec atime, struct timespec mtime)
691 {
692 kauth_cred_t cred;
693
694 #if SECURITY_MAC_CHECK_ENFORCE
695 /* 21167099 - only check if we allow write */
696 if (!mac_vnode_enforce) {
697 return;
698 }
699 #endif
700 cred = vfs_context_ucred(ctx);
701 if (!mac_cred_check_enforce(cred)) {
702 return;
703 }
704 VFS_KERNEL_DEBUG_START1(23, vp);
705 MAC_PERFORM(vnode_notify_setutimes, cred, vp, vp->v_label, atime, mtime);
706 VFS_KERNEL_DEBUG_END1(23, vp);
707 }
708
709 void
710 mac_vnode_notify_truncate(vfs_context_t ctx, kauth_cred_t file_cred, struct vnode *vp)
711 {
712 kauth_cred_t cred;
713
714 #if SECURITY_MAC_CHECK_ENFORCE
715 /* 21167099 - only check if we allow write */
716 if (!mac_vnode_enforce) {
717 return;
718 }
719 #endif
720 cred = vfs_context_ucred(ctx);
721 if (!mac_cred_check_enforce(cred)) {
722 return;
723 }
724 VFS_KERNEL_DEBUG_START1(24, vp);
725 MAC_PERFORM(vnode_notify_truncate, cred, file_cred, vp, vp->v_label);
726 VFS_KERNEL_DEBUG_END1(24, vp);
727 }
728
729 /*
730 * Extended attribute 'name' was updated via
731 * vn_setxattr() or vn_removexattr(). Allow the
732 * policy to update the vnode label.
733 */
734 void
735 mac_vnode_label_update_extattr(struct mount *mp, struct vnode *vp,
736 const char *name)
737 {
738 int error = 0;
739
740 #if SECURITY_MAC_CHECK_ENFORCE
741 /* 21167099 - only check if we allow write */
742 if (!mac_vnode_enforce) {
743 return;
744 }
745 #endif
746 if (!mac_label_vnodes) {
747 return;
748 }
749
750 VFS_KERNEL_DEBUG_START1(25, vp);
751 MAC_PERFORM(vnode_label_update_extattr, mp, mp->mnt_mntlabel, vp,
752 vp->v_label, name);
753 VFS_KERNEL_DEBUG_END1(25, vp);
754 if (error == 0) {
755 return;
756 }
757
758 vnode_lock(vp);
759 vnode_relabel(vp);
760 vnode_unlock(vp);
761 return;
762 }
763
764 static int
765 mac_vnode_label_store(vfs_context_t ctx, struct vnode *vp,
766 struct label *intlabel)
767 {
768 kauth_cred_t cred;
769 int error;
770
771 #if SECURITY_MAC_CHECK_ENFORCE
772 /* 21167099 - only check if we allow write */
773 if (!mac_vnode_enforce) {
774 return 0;
775 }
776 #endif
777 if (!mac_label_vnodes) {
778 return 0;
779 }
780
781 cred = vfs_context_ucred(ctx);
782 if (!mac_cred_check_enforce(cred)) {
783 return 0;
784 }
785 VFS_KERNEL_DEBUG_START1(26, vp);
786 MAC_CHECK(vnode_label_store, cred, vp, vp->v_label, intlabel);
787 VFS_KERNEL_DEBUG_END1(26, vp);
788
789 return error;
790 }
791
792 void
793 mac_cred_label_update_execve(vfs_context_t ctx, kauth_cred_t new, struct vnode *vp, off_t offset,
794 struct vnode *scriptvp, struct label *scriptvnodelabel, struct label *execl, u_int *csflags,
795 void *macextensions, int *disjoint, int *labelupdateerror)
796 {
797 kauth_cred_t cred;
798 *disjoint = 0;
799 int error;
800 posix_cred_t pcred = posix_cred_get(new);
801
802 #if SECURITY_MAC_CHECK_ENFORCE
803 /* 21167099 - only check if we allow write */
804 if (!mac_proc_enforce || !mac_vnode_enforce) {
805 return;
806 }
807 #endif
808
809 /* mark the new cred to indicate "matching" includes the label */
810 pcred->cr_flags |= CRF_MAC_ENFORCE;
811
812 cred = vfs_context_ucred(ctx);
813
814 /*
815 * NB: Cannot use MAC_CHECK macro because we need a sequence point after
816 * calling exec_spawnattr_getmacpolicyinfo() and before passing the
817 * spawnattrlen as an argument to the hook.
818 */
819 VFS_KERNEL_DEBUG_START1(27, vp);
820 {
821 struct mac_policy_conf *mpc;
822 u_int i;
823
824 error = 0;
825 for (i = 0; i < mac_policy_list.staticmax; i++) {
826 mpc = mac_policy_list.entries[i].mpc;
827 if (mpc == NULL) {
828 continue;
829 }
830
831 mpo_cred_label_update_execve_t *hook = mpc->mpc_ops->mpo_cred_label_update_execve;
832 if (hook == NULL) {
833 continue;
834 }
835
836 size_t spawnattrlen = 0;
837 void *spawnattr = exec_spawnattr_getmacpolicyinfo(macextensions, mpc->mpc_name, &spawnattrlen);
838
839 error = mac_error_select(hook(cred, new, vfs_context_proc(ctx), vp, offset, scriptvp,
840 vp->v_label, scriptvnodelabel, execl, csflags, spawnattr, spawnattrlen, disjoint),
841 error);
842 }
843 if (mac_policy_list_conditional_busy() != 0) {
844 for (; i <= mac_policy_list.maxindex; i++) {
845 mpc = mac_policy_list.entries[i].mpc;
846 if (mpc == NULL) {
847 continue;
848 }
849
850 mpo_cred_label_update_execve_t *hook = mpc->mpc_ops->mpo_cred_label_update_execve;
851 if (hook == NULL) {
852 continue;
853 }
854
855 size_t spawnattrlen = 0;
856 void *spawnattr = exec_spawnattr_getmacpolicyinfo(macextensions, mpc->mpc_name, &spawnattrlen);
857
858 error = mac_error_select(hook(cred, new, vfs_context_proc(ctx), vp, offset, scriptvp,
859 vp->v_label, scriptvnodelabel, execl, csflags, spawnattr, spawnattrlen, disjoint),
860 error);
861 }
862 mac_policy_list_unbusy();
863 }
864 }
865 *labelupdateerror = error;
866 VFS_KERNEL_DEBUG_END1(27, vp);
867 }
868
869 int
870 mac_cred_check_label_update_execve(vfs_context_t ctx, struct vnode *vp, off_t offset,
871 struct vnode *scriptvp, struct label *scriptvnodelabel, struct label *execlabel,
872 struct proc *p, void *macextensions)
873 {
874 kauth_cred_t cred;
875 int result = 0;
876
877 #if SECURITY_MAC_CHECK_ENFORCE
878 /* 21167099 - only check if we allow write */
879 if (!mac_proc_enforce || !mac_vnode_enforce) {
880 return result;
881 }
882 #endif
883
884 cred = vfs_context_ucred(ctx);
885
886 VFS_KERNEL_DEBUG_START1(28, vp);
887 /*
888 * NB: Cannot use MAC_BOOLEAN macro because we need a sequence point after
889 * calling exec_spawnattr_getmacpolicyinfo() and before passing the
890 * spawnattrlen as an argument to the hook.
891 */
892 {
893 struct mac_policy_conf *mpc;
894 u_int i;
895
896 for (i = 0; i < mac_policy_list.staticmax; i++) {
897 mpc = mac_policy_list.entries[i].mpc;
898 if (mpc == NULL) {
899 continue;
900 }
901
902 mpo_cred_check_label_update_execve_t *hook = mpc->mpc_ops->mpo_cred_check_label_update_execve;
903 if (hook == NULL) {
904 continue;
905 }
906
907 size_t spawnattrlen = 0;
908 void *spawnattr = exec_spawnattr_getmacpolicyinfo(macextensions, mpc->mpc_name, &spawnattrlen);
909
910 result = result || hook(cred, vp, offset, scriptvp, vp->v_label, scriptvnodelabel, execlabel, p, spawnattr, spawnattrlen);
911 }
912 if (mac_policy_list_conditional_busy() != 0) {
913 for (; i <= mac_policy_list.maxindex; i++) {
914 mpc = mac_policy_list.entries[i].mpc;
915 if (mpc == NULL) {
916 continue;
917 }
918
919 mpo_cred_check_label_update_execve_t *hook = mpc->mpc_ops->mpo_cred_check_label_update_execve;
920 if (hook == NULL) {
921 continue;
922 }
923
924 size_t spawnattrlen = 0;
925 void *spawnattr = exec_spawnattr_getmacpolicyinfo(macextensions, mpc->mpc_name, &spawnattrlen);
926
927 result = result || hook(cred, vp, offset, scriptvp, vp->v_label, scriptvnodelabel, execlabel, p, spawnattr, spawnattrlen);
928 }
929 mac_policy_list_unbusy();
930 }
931 }
932 VFS_KERNEL_DEBUG_END1(28, vp);
933
934 return result;
935 }
936
937 int
938 mac_vnode_check_access(vfs_context_t ctx, struct vnode *vp,
939 int acc_mode)
940 {
941 kauth_cred_t cred;
942 int error;
943 int mask;
944
945 #if SECURITY_MAC_CHECK_ENFORCE
946 /* 21167099 - only check if we allow write */
947 if (!mac_vnode_enforce) {
948 return 0;
949 }
950 #endif
951 cred = vfs_context_ucred(ctx);
952 if (!mac_cred_check_enforce(cred)) {
953 return 0;
954 }
955 /* Convert {R,W,X}_OK values to V{READ,WRITE,EXEC} for entry points */
956 mask = ACCESS_MODE_TO_VNODE_MASK(acc_mode);
957 VFS_KERNEL_DEBUG_START1(29, vp);
958 MAC_CHECK(vnode_check_access, cred, vp, vp->v_label, mask);
959 VFS_KERNEL_DEBUG_END1(29, vp);
960 return error;
961 }
962
963 int
964 mac_vnode_check_chdir(vfs_context_t ctx, struct vnode *dvp)
965 {
966 kauth_cred_t cred;
967 int error;
968
969 #if SECURITY_MAC_CHECK_ENFORCE
970 /* 21167099 - only check if we allow write */
971 if (!mac_vnode_enforce) {
972 return 0;
973 }
974 #endif
975 cred = vfs_context_ucred(ctx);
976 if (!mac_cred_check_enforce(cred)) {
977 return 0;
978 }
979 VFS_KERNEL_DEBUG_START1(30, dvp);
980 MAC_CHECK(vnode_check_chdir, cred, dvp, dvp->v_label);
981 VFS_KERNEL_DEBUG_END1(30, dvp);
982 return error;
983 }
984
985 int
986 mac_vnode_check_chroot(vfs_context_t ctx, struct vnode *dvp,
987 struct componentname *cnp)
988 {
989 kauth_cred_t cred;
990 int error;
991
992 #if SECURITY_MAC_CHECK_ENFORCE
993 /* 21167099 - only check if we allow write */
994 if (!mac_vnode_enforce) {
995 return 0;
996 }
997 #endif
998 cred = vfs_context_ucred(ctx);
999 if (!mac_cred_check_enforce(cred)) {
1000 return 0;
1001 }
1002 VFS_KERNEL_DEBUG_START1(31, dvp);
1003 MAC_CHECK(vnode_check_chroot, cred, dvp, dvp->v_label, cnp);
1004 VFS_KERNEL_DEBUG_END1(31, dvp);
1005 return error;
1006 }
1007
1008 int
1009 mac_vnode_check_clone(vfs_context_t ctx, struct vnode *dvp,
1010 struct vnode *vp, struct componentname *cnp)
1011 {
1012 kauth_cred_t cred;
1013 int error;
1014
1015 #if SECURITY_MAC_CHECK_ENFORCE
1016 /* 21167099 - only check if we allow write */
1017 if (!mac_vnode_enforce) {
1018 return 0;
1019 }
1020 #endif
1021 cred = vfs_context_ucred(ctx);
1022 if (!mac_cred_check_enforce(cred)) {
1023 return 0;
1024 }
1025 VFS_KERNEL_DEBUG_START1(32, dvp);
1026 MAC_CHECK(vnode_check_clone, cred, dvp, dvp->v_label, vp,
1027 vp->v_label, cnp);
1028 VFS_KERNEL_DEBUG_END1(32, dvp);
1029 return error;
1030 }
1031 int
1032 mac_vnode_check_create(vfs_context_t ctx, struct vnode *dvp,
1033 struct componentname *cnp, struct vnode_attr *vap)
1034 {
1035 kauth_cred_t cred;
1036 int error;
1037
1038 #if SECURITY_MAC_CHECK_ENFORCE
1039 /* 21167099 - only check if we allow write */
1040 if (!mac_vnode_enforce) {
1041 return 0;
1042 }
1043 #endif
1044 cred = vfs_context_ucred(ctx);
1045 if (!mac_cred_check_enforce(cred)) {
1046 return 0;
1047 }
1048 VFS_KERNEL_DEBUG_START1(33, dvp);
1049 MAC_CHECK(vnode_check_create, cred, dvp, dvp->v_label, cnp, vap);
1050 VFS_KERNEL_DEBUG_END1(33, dvp);
1051 return error;
1052 }
1053
1054 int
1055 mac_vnode_check_unlink(vfs_context_t ctx, struct vnode *dvp, struct vnode *vp,
1056 struct componentname *cnp)
1057 {
1058 kauth_cred_t cred;
1059 int error;
1060
1061 #if SECURITY_MAC_CHECK_ENFORCE
1062 /* 21167099 - only check if we allow write */
1063 if (!mac_vnode_enforce) {
1064 return 0;
1065 }
1066 #endif
1067 cred = vfs_context_ucred(ctx);
1068 if (!mac_cred_check_enforce(cred)) {
1069 return 0;
1070 }
1071 VFS_KERNEL_DEBUG_START1(34, dvp);
1072 MAC_CHECK(vnode_check_unlink, cred, dvp, dvp->v_label, vp,
1073 vp->v_label, cnp);
1074 VFS_KERNEL_DEBUG_END1(34, dvp);
1075 return error;
1076 }
1077 #if 0
1078 int
1079 mac_vnode_check_deleteacl(vfs_context_t ctx, struct vnode *vp,
1080 acl_type_t type)
1081 {
1082 kauth_cred_t cred;
1083 int error;
1084
1085 #if SECURITY_MAC_CHECK_ENFORCE
1086 /* 21167099 - only check if we allow write */
1087 if (!mac_vnode_enforce) {
1088 return 0;
1089 }
1090 #endif
1091 cred = vfs_context_ucred(ctx);
1092 if (!mac_cred_check_enforce(cred)) {
1093 return 0;
1094 }
1095 VFS_KERNEL_DEBUG_START1(35, dvp);
1096 MAC_CHECK(vnode_check_deleteacl, cred, vp, vp->v_label, type);
1097 VFS_KERNEL_DEBUG_END1(35, dvp);
1098 return error;
1099 }
1100 #endif
1101
1102 int
1103 mac_vnode_check_deleteextattr(vfs_context_t ctx, struct vnode *vp,
1104 const char *name)
1105 {
1106 kauth_cred_t cred;
1107 int error;
1108
1109 #if SECURITY_MAC_CHECK_ENFORCE
1110 /* 21167099 - only check if we allow write */
1111 if (!mac_vnode_enforce) {
1112 return 0;
1113 }
1114 #endif
1115 cred = vfs_context_ucred(ctx);
1116 if (!mac_cred_check_enforce(cred)) {
1117 return 0;
1118 }
1119 VFS_KERNEL_DEBUG_START1(36, vp);
1120 MAC_CHECK(vnode_check_deleteextattr, cred, vp, vp->v_label, name);
1121 VFS_KERNEL_DEBUG_END1(36, vp);
1122 return error;
1123 }
1124 int
1125 mac_vnode_check_exchangedata(vfs_context_t ctx,
1126 struct vnode *v1, struct vnode *v2)
1127 {
1128 kauth_cred_t cred;
1129 int error;
1130
1131 #if SECURITY_MAC_CHECK_ENFORCE
1132 /* 21167099 - only check if we allow write */
1133 if (!mac_vnode_enforce) {
1134 return 0;
1135 }
1136 #endif
1137 cred = vfs_context_ucred(ctx);
1138 if (!mac_cred_check_enforce(cred)) {
1139 return 0;
1140 }
1141 VFS_KERNEL_DEBUG_START1(37, v1);
1142 MAC_CHECK(vnode_check_exchangedata, cred, v1, v1->v_label,
1143 v2, v2->v_label);
1144 VFS_KERNEL_DEBUG_END1(37, v1);
1145
1146 return error;
1147 }
1148
1149 #if 0
1150 int
1151 mac_vnode_check_getacl(vfs_context_t ctx, struct vnode *vp, acl_type_t type)
1152 {
1153 kauth_cred_t cred;
1154 int error;
1155
1156 #if SECURITY_MAC_CHECK_ENFORCE
1157 /* 21167099 - only check if we allow write */
1158 if (!mac_vnode_enforce) {
1159 return 0;
1160 }
1161 #endif
1162 cred = vfs_context_ucred(ctx);
1163 if (!mac_cred_check_enforce(cred)) {
1164 return 0;
1165 }
1166 VFS_KERNEL_DEBUG_START1(38, vp);
1167 MAC_CHECK(vnode_check_getacl, cred, vp, vp->v_label, type);
1168 VFS_KERNEL_DEBUG_END1(38, vp);
1169 return error;
1170 }
1171 #endif
1172
1173 int
1174 mac_vnode_check_getattr(vfs_context_t ctx, struct ucred *file_cred,
1175 struct vnode *vp, struct vnode_attr *va)
1176 {
1177 kauth_cred_t cred;
1178 int error;
1179
1180 #if SECURITY_MAC_CHECK_ENFORCE
1181 /* 21167099 - only check if we allow write */
1182 if (!mac_vnode_enforce) {
1183 return 0;
1184 }
1185 #endif
1186 cred = vfs_context_ucred(ctx);
1187 if (!mac_cred_check_enforce(cred)) {
1188 return 0;
1189 }
1190 VFS_KERNEL_DEBUG_START1(39, vp);
1191 MAC_CHECK(vnode_check_getattr, cred, file_cred, vp, vp->v_label, va);
1192 VFS_KERNEL_DEBUG_END1(39, vp);
1193 return error;
1194 }
1195
1196 int
1197 mac_vnode_check_getattrlist(vfs_context_t ctx, struct vnode *vp,
1198 struct attrlist *alist)
1199 {
1200 kauth_cred_t cred;
1201 int error;
1202
1203 #if SECURITY_MAC_CHECK_ENFORCE
1204 /* 21167099 - only check if we allow write */
1205 if (!mac_vnode_enforce) {
1206 return 0;
1207 }
1208 #endif
1209 cred = vfs_context_ucred(ctx);
1210 if (!mac_cred_check_enforce(cred)) {
1211 return 0;
1212 }
1213 VFS_KERNEL_DEBUG_START1(40, vp);
1214 MAC_CHECK(vnode_check_getattrlist, cred, vp, vp->v_label, alist);
1215 VFS_KERNEL_DEBUG_END1(40, vp);
1216
1217 /* Falsify results instead of returning error? */
1218 return error;
1219 }
1220
1221 int
1222 mac_vnode_check_exec(vfs_context_t ctx, struct vnode *vp,
1223 struct image_params *imgp)
1224 {
1225 kauth_cred_t cred;
1226 int error = 0;
1227
1228 #if SECURITY_MAC_CHECK_ENFORCE
1229 /* 21167099 - only check if we allow write */
1230 if (!mac_proc_enforce || !mac_vnode_enforce) {
1231 return 0;
1232 }
1233 #endif
1234
1235 cred = vfs_context_ucred(ctx);
1236
1237 /*
1238 * NB: Cannot use MAC_CHECK macro because we need a sequence point after
1239 * calling exec_spawnattr_getmacpolicyinfo() and before passing the
1240 * spawnattrlen as an argument to the hook.
1241 */
1242 VFS_KERNEL_DEBUG_START1(41, vp);
1243 {
1244 struct mac_policy_conf *mpc;
1245 u_int i;
1246
1247 for (i = 0; i < mac_policy_list.staticmax; i++) {
1248 mpc = mac_policy_list.entries[i].mpc;
1249 if (mpc == NULL) {
1250 continue;
1251 }
1252
1253 mpo_vnode_check_exec_t *hook = mpc->mpc_ops->mpo_vnode_check_exec;
1254 if (hook == NULL) {
1255 continue;
1256 }
1257
1258 size_t spawnattrlen = 0;
1259 void *spawnattr = exec_spawnattr_getmacpolicyinfo(imgp->ip_px_smpx, mpc->mpc_name, &spawnattrlen);
1260
1261 error = mac_error_select(
1262 hook(cred,
1263 vp, imgp->ip_scriptvp, vp->v_label, imgp->ip_scriptlabelp,
1264 imgp->ip_execlabelp, &imgp->ip_ndp->ni_cnd, &imgp->ip_csflags,
1265 spawnattr, spawnattrlen), error);
1266 }
1267 if (mac_policy_list_conditional_busy() != 0) {
1268 for (; i <= mac_policy_list.maxindex; i++) {
1269 mpc = mac_policy_list.entries[i].mpc;
1270 if (mpc == NULL) {
1271 continue;
1272 }
1273
1274 mpo_vnode_check_exec_t *hook = mpc->mpc_ops->mpo_vnode_check_exec;
1275 if (hook == NULL) {
1276 continue;
1277 }
1278
1279 size_t spawnattrlen = 0;
1280 void *spawnattr = exec_spawnattr_getmacpolicyinfo(imgp->ip_px_smpx, mpc->mpc_name, &spawnattrlen);
1281
1282 error = mac_error_select(
1283 hook(cred,
1284 vp, imgp->ip_scriptvp, vp->v_label, imgp->ip_scriptlabelp,
1285 imgp->ip_execlabelp, &imgp->ip_ndp->ni_cnd, &imgp->ip_csflags,
1286 spawnattr, spawnattrlen), error);
1287 }
1288 mac_policy_list_unbusy();
1289 }
1290 }
1291 VFS_KERNEL_DEBUG_END1(41, vp);
1292
1293 return error;
1294 }
1295
1296 int
1297 mac_vnode_check_fsgetpath(vfs_context_t ctx, struct vnode *vp)
1298 {
1299 kauth_cred_t cred;
1300 int error;
1301
1302 #if SECURITY_MAC_CHECK_ENFORCE
1303 /* 21167099 - only check if we allow write */
1304 if (!mac_vnode_enforce) {
1305 return 0;
1306 }
1307 #endif
1308 cred = vfs_context_ucred(ctx);
1309 if (!mac_cred_check_enforce(cred)) {
1310 return 0;
1311 }
1312 VFS_KERNEL_DEBUG_START1(42, vp);
1313 MAC_CHECK(vnode_check_fsgetpath, cred, vp, vp->v_label);
1314 VFS_KERNEL_DEBUG_END1(42, vp);
1315 return error;
1316 }
1317
1318 int
1319 mac_vnode_check_signature(struct vnode *vp, struct cs_blob *cs_blob,
1320 struct image_params *imgp,
1321 unsigned int *cs_flags, unsigned int *signer_type,
1322 int flags, unsigned int platform)
1323 {
1324 int error;
1325 char *fatal_failure_desc = NULL;
1326 size_t fatal_failure_desc_len = 0;
1327
1328 char *vn_path = NULL;
1329 vm_size_t vn_pathlen = MAXPATHLEN;
1330 cpu_type_t cpu_type = (imgp == NULL) ? CPU_TYPE_ANY : imgp->ip_origcputype;
1331
1332
1333 #if SECURITY_MAC_CHECK_ENFORCE
1334 /* 21167099 - only check if we allow write */
1335 if (!mac_proc_enforce || !mac_vnode_enforce) {
1336 return 0;
1337 }
1338 #endif
1339
1340 VFS_KERNEL_DEBUG_START1(43, vp);
1341 MAC_CHECK(vnode_check_signature, vp, vp->v_label, cpu_type, cs_blob,
1342 cs_flags, signer_type, flags, platform, &fatal_failure_desc, &fatal_failure_desc_len);
1343 VFS_KERNEL_DEBUG_END1(43, vp);
1344
1345 if (fatal_failure_desc_len) {
1346 // A fatal code signature validation failure occured, formulate a crash
1347 // reason.
1348
1349 char const *path = NULL;
1350
1351 vn_path = zalloc(ZV_NAMEI);
1352 if (vn_getpath(vp, vn_path, (int*)&vn_pathlen) == 0) {
1353 path = vn_path;
1354 } else {
1355 path = "(get vnode path failed)";
1356 }
1357
1358 if (error == 0) {
1359 panic("mac_vnode_check_signature: MAC hook returned no error, "
1360 "but status is claimed to be fatal? "
1361 "path: '%s', fatal_failure_desc_len: %ld, fatal_failure_desc:\n%s\n",
1362 path, fatal_failure_desc_len, fatal_failure_desc);
1363 }
1364
1365 printf("mac_vnode_check_signature: %s: code signature validation failed fatally: %s",
1366 path, fatal_failure_desc);
1367
1368 if (imgp == NULL) {
1369 goto out;
1370 }
1371
1372 os_reason_t reason = os_reason_create(OS_REASON_CODESIGNING,
1373 CODESIGNING_EXIT_REASON_TASKGATED_INVALID_SIG);
1374
1375 if (reason == OS_REASON_NULL) {
1376 printf("mac_vnode_check_signature: %s: failure to allocate exit reason for validation failure: %s\n",
1377 path, fatal_failure_desc);
1378 goto out;
1379 }
1380
1381 imgp->ip_cs_error = reason;
1382 reason->osr_flags = (OS_REASON_FLAG_GENERATE_CRASH_REPORT |
1383 OS_REASON_FLAG_CONSISTENT_FAILURE);
1384
1385 if (fatal_failure_desc == NULL) {
1386 // This may happen if allocation for the buffer failed.
1387 printf("mac_vnode_check_signature: %s: fatal failure is missing its description.\n", path);
1388 } else {
1389 mach_vm_address_t data_addr = 0;
1390
1391 int reason_error = 0;
1392 int kcdata_error = 0;
1393
1394 if ((reason_error = os_reason_alloc_buffer_noblock(reason, kcdata_estimate_required_buffer_size
1395 (1, (uint32_t)fatal_failure_desc_len))) == 0 &&
1396 (kcdata_error = kcdata_get_memory_addr(&reason->osr_kcd_descriptor,
1397 EXIT_REASON_USER_DESC, (uint32_t)fatal_failure_desc_len,
1398 &data_addr)) == KERN_SUCCESS) {
1399 kern_return_t mc_error = kcdata_memcpy(&reason->osr_kcd_descriptor, (mach_vm_address_t)data_addr,
1400 fatal_failure_desc, (uint32_t)fatal_failure_desc_len);
1401
1402 if (mc_error != KERN_SUCCESS) {
1403 printf("mac_vnode_check_signature: %s: failed to copy reason string "
1404 "(kcdata_memcpy error: %d, length: %ld)\n",
1405 path, mc_error, fatal_failure_desc_len);
1406 }
1407 } else {
1408 printf("mac_vnode_check_signature: %s: failed to allocate space for reason string "
1409 "(os_reason_alloc_buffer error: %d, kcdata error: %d, length: %ld)\n",
1410 path, reason_error, kcdata_error, fatal_failure_desc_len);
1411 }
1412 }
1413 }
1414
1415 out:
1416 if (vn_path) {
1417 zfree(ZV_NAMEI, vn_path);
1418 }
1419
1420 if (fatal_failure_desc_len > 0 && fatal_failure_desc != NULL) {
1421 /* AMFI uses kalloc() which for kexts is redirected to KHEAP_KEXT */
1422 kheap_free(KHEAP_KEXT, fatal_failure_desc, fatal_failure_desc_len);
1423 }
1424
1425 return error;
1426 }
1427
1428 int
1429 mac_vnode_check_supplemental_signature(struct vnode *vp,
1430 struct cs_blob *cs_blob, struct vnode *linked_vp,
1431 struct cs_blob *linked_cs_blob, unsigned int *signer_type)
1432 {
1433 int error;
1434
1435 #if SECURITY_MAC_CHECK_ENFORCE
1436 /* 21167099 - only check if we allow write */
1437 if (!mac_proc_enforce || !mac_vnode_enforce) {
1438 return 0;
1439 }
1440 #endif
1441 VFS_KERNEL_DEBUG_START1(93, vp);
1442 MAC_CHECK(vnode_check_supplemental_signature, vp, vp->v_label, cs_blob, linked_vp, linked_cs_blob,
1443 signer_type);
1444 VFS_KERNEL_DEBUG_END1(93, vp);
1445
1446 return error;
1447 }
1448
1449 #if 0
1450 int
1451 mac_vnode_check_getacl(vfs_context_t ctx, struct vnode *vp, acl_type_t type)
1452 {
1453 kauth_cred_t cred;
1454 int error;
1455
1456 #if SECURITY_MAC_CHECK_ENFORCE
1457 /* 21167099 - only check if we allow write */
1458 if (!mac_vnode_enforce) {
1459 return 0;
1460 }
1461 #endif
1462 cred = vfs_context_ucred(ctx);
1463 if (!mac_cred_check_enforce(cred)) {
1464 return 0;
1465 }
1466 VFS_KERNEL_DEBUG_START1(44, vp);
1467 MAC_CHECK(vnode_check_getacl, cred, vp, vp->v_label, type);
1468 VFS_KERNEL_DEBUG_END1(44, vp);
1469 return error;
1470 }
1471 #endif
1472
1473 int
1474 mac_vnode_check_getextattr(vfs_context_t ctx, struct vnode *vp,
1475 const char *name, struct uio *uio)
1476 {
1477 kauth_cred_t cred;
1478 int error;
1479
1480 #if SECURITY_MAC_CHECK_ENFORCE
1481 /* 21167099 - only check if we allow write */
1482 if (!mac_vnode_enforce) {
1483 return 0;
1484 }
1485 #endif
1486 cred = vfs_context_ucred(ctx);
1487 if (!mac_cred_check_enforce(cred)) {
1488 return 0;
1489 }
1490 VFS_KERNEL_DEBUG_START1(45, vp);
1491 MAC_CHECK(vnode_check_getextattr, cred, vp, vp->v_label,
1492 name, uio);
1493 VFS_KERNEL_DEBUG_END1(45, vp);
1494 return error;
1495 }
1496
1497 int
1498 mac_vnode_check_ioctl(vfs_context_t ctx, struct vnode *vp, u_long cmd)
1499 {
1500 kauth_cred_t cred;
1501 int error;
1502
1503 #if SECURITY_MAC_CHECK_ENFORCE
1504 /* 21167099 - only check if we allow write */
1505 if (!mac_vnode_enforce) {
1506 return 0;
1507 }
1508 #endif
1509 cred = vfs_context_ucred(ctx);
1510 if (!mac_cred_check_enforce(cred)) {
1511 return 0;
1512 }
1513 VFS_KERNEL_DEBUG_START1(46, vp);
1514 MAC_CHECK(vnode_check_ioctl, cred, vp, vp->v_label, cmd);
1515 VFS_KERNEL_DEBUG_END1(46, vp);
1516 return error;
1517 }
1518
1519 int
1520 mac_vnode_check_kqfilter(vfs_context_t ctx, kauth_cred_t file_cred,
1521 struct knote *kn, struct vnode *vp)
1522 {
1523 kauth_cred_t cred;
1524 int error;
1525
1526 #if SECURITY_MAC_CHECK_ENFORCE
1527 /* 21167099 - only check if we allow write */
1528 if (!mac_vnode_enforce) {
1529 return 0;
1530 }
1531 #endif
1532 cred = vfs_context_ucred(ctx);
1533 if (!mac_cred_check_enforce(cred)) {
1534 return 0;
1535 }
1536 VFS_KERNEL_DEBUG_START1(47, vp);
1537 MAC_CHECK(vnode_check_kqfilter, cred, file_cred, kn, vp,
1538 vp->v_label);
1539 VFS_KERNEL_DEBUG_END1(47, vp);
1540
1541 return error;
1542 }
1543
1544 int
1545 mac_vnode_check_link(vfs_context_t ctx, struct vnode *dvp,
1546 struct vnode *vp, struct componentname *cnp)
1547 {
1548 kauth_cred_t cred;
1549 int error;
1550
1551 #if SECURITY_MAC_CHECK_ENFORCE
1552 /* 21167099 - only check if we allow write */
1553 if (!mac_vnode_enforce) {
1554 return 0;
1555 }
1556 #endif
1557 cred = vfs_context_ucred(ctx);
1558 if (!mac_cred_check_enforce(cred)) {
1559 return 0;
1560 }
1561 VFS_KERNEL_DEBUG_START1(48, vp);
1562 MAC_CHECK(vnode_check_link, cred, dvp, dvp->v_label, vp,
1563 vp->v_label, cnp);
1564 VFS_KERNEL_DEBUG_END1(48, vp);
1565 return error;
1566 }
1567
1568 int
1569 mac_vnode_check_listextattr(vfs_context_t ctx, struct vnode *vp)
1570 {
1571 kauth_cred_t cred;
1572 int error;
1573
1574 #if SECURITY_MAC_CHECK_ENFORCE
1575 /* 21167099 - only check if we allow write */
1576 if (!mac_vnode_enforce) {
1577 return 0;
1578 }
1579 #endif
1580 cred = vfs_context_ucred(ctx);
1581 if (!mac_cred_check_enforce(cred)) {
1582 return 0;
1583 }
1584 VFS_KERNEL_DEBUG_START1(49, vp);
1585 MAC_CHECK(vnode_check_listextattr, cred, vp, vp->v_label);
1586 VFS_KERNEL_DEBUG_END1(49, vp);
1587 return error;
1588 }
1589
1590 int
1591 mac_vnode_check_lookup_preflight(vfs_context_t ctx, struct vnode *dvp,
1592 const char *path, size_t pathlen)
1593 {
1594 kauth_cred_t cred;
1595 int error;
1596
1597 #if SECURITY_MAC_CHECK_ENFORCE
1598 /* 21167099 - only check if we allow write */
1599 if (!mac_vnode_enforce) {
1600 return 0;
1601 }
1602 #endif
1603 cred = vfs_context_ucred(ctx);
1604 if (!mac_cred_check_enforce(cred)) {
1605 return 0;
1606 }
1607 VFS_KERNEL_DEBUG_START1(50, dvp);
1608 MAC_CHECK(vnode_check_lookup_preflight, cred, dvp, dvp->v_label, path, pathlen);
1609 VFS_KERNEL_DEBUG_END1(50, dvp);
1610 return error;
1611 }
1612
1613 int
1614 mac_vnode_check_lookup(vfs_context_t ctx, struct vnode *dvp,
1615 struct componentname *cnp)
1616 {
1617 kauth_cred_t cred;
1618 int error;
1619
1620 #if SECURITY_MAC_CHECK_ENFORCE
1621 /* 21167099 - only check if we allow write */
1622 if (!mac_vnode_enforce) {
1623 return 0;
1624 }
1625 #endif
1626 cred = vfs_context_ucred(ctx);
1627 if (!mac_cred_check_enforce(cred)) {
1628 return 0;
1629 }
1630 VFS_KERNEL_DEBUG_START1(51, dvp);
1631 MAC_CHECK(vnode_check_lookup, cred, dvp, dvp->v_label, cnp);
1632 VFS_KERNEL_DEBUG_END1(51, dvp);
1633 return error;
1634 }
1635
1636 int
1637 mac_vnode_check_open(vfs_context_t ctx, struct vnode *vp, int acc_mode)
1638 {
1639 kauth_cred_t cred;
1640 int error;
1641
1642 #if SECURITY_MAC_CHECK_ENFORCE
1643 /* 21167099 - only check if we allow write */
1644 if (!mac_vnode_enforce) {
1645 return 0;
1646 }
1647 #endif
1648 cred = vfs_context_ucred(ctx);
1649 if (!mac_cred_check_enforce(cred)) {
1650 return 0;
1651 }
1652 VFS_KERNEL_DEBUG_START1(52, vp);
1653 MAC_CHECK(vnode_check_open, cred, vp, vp->v_label, acc_mode);
1654 VFS_KERNEL_DEBUG_END1(52, vp);
1655 return error;
1656 }
1657
1658 int
1659 mac_vnode_check_read(vfs_context_t ctx, struct ucred *file_cred,
1660 struct vnode *vp)
1661 {
1662 kauth_cred_t cred;
1663 int error;
1664
1665 #if SECURITY_MAC_CHECK_ENFORCE
1666 /* 21167099 - only check if we allow write */
1667 if (!mac_vnode_enforce) {
1668 return 0;
1669 }
1670 #endif
1671 cred = vfs_context_ucred(ctx);
1672 if (!mac_cred_check_enforce(cred)) {
1673 return 0;
1674 }
1675 VFS_KERNEL_DEBUG_START1(53, vp);
1676 MAC_CHECK(vnode_check_read, cred, file_cred, vp,
1677 vp->v_label);
1678 VFS_KERNEL_DEBUG_END1(53, vp);
1679
1680 return error;
1681 }
1682
1683 int
1684 mac_vnode_check_readdir(vfs_context_t ctx, struct vnode *dvp)
1685 {
1686 kauth_cred_t cred;
1687 int error;
1688
1689 #if SECURITY_MAC_CHECK_ENFORCE
1690 /* 21167099 - only check if we allow write */
1691 if (!mac_vnode_enforce) {
1692 return 0;
1693 }
1694 #endif
1695 cred = vfs_context_ucred(ctx);
1696 if (!mac_cred_check_enforce(cred)) {
1697 return 0;
1698 }
1699 VFS_KERNEL_DEBUG_START1(54, dvp);
1700 MAC_CHECK(vnode_check_readdir, cred, dvp, dvp->v_label);
1701 VFS_KERNEL_DEBUG_END1(54, dvp);
1702 return error;
1703 }
1704
1705 int
1706 mac_vnode_check_readlink(vfs_context_t ctx, struct vnode *vp)
1707 {
1708 kauth_cred_t cred;
1709 int error;
1710
1711 #if SECURITY_MAC_CHECK_ENFORCE
1712 /* 21167099 - only check if we allow write */
1713 if (!mac_vnode_enforce) {
1714 return 0;
1715 }
1716 #endif
1717 cred = vfs_context_ucred(ctx);
1718 if (!mac_cred_check_enforce(cred)) {
1719 return 0;
1720 }
1721 VFS_KERNEL_DEBUG_START1(55, vp);
1722 MAC_CHECK(vnode_check_readlink, cred, vp, vp->v_label);
1723 VFS_KERNEL_DEBUG_END1(55, vp);
1724 return error;
1725 }
1726
1727 int
1728 mac_vnode_check_label_update(vfs_context_t ctx, struct vnode *vp,
1729 struct label *newlabel)
1730 {
1731 kauth_cred_t cred;
1732 int error;
1733
1734 #if SECURITY_MAC_CHECK_ENFORCE
1735 /* 21167099 - only check if we allow write */
1736 if (!mac_vnode_enforce) {
1737 return 0;
1738 }
1739 #endif
1740 cred = vfs_context_ucred(ctx);
1741 if (!mac_cred_check_enforce(cred)) {
1742 return 0;
1743 }
1744 VFS_KERNEL_DEBUG_START1(56, vp);
1745 MAC_CHECK(vnode_check_label_update, cred, vp, vp->v_label, newlabel);
1746 VFS_KERNEL_DEBUG_END1(56, vp);
1747
1748 return error;
1749 }
1750
1751 int
1752 mac_vnode_check_rename(vfs_context_t ctx, struct vnode *dvp,
1753 struct vnode *vp, struct componentname *cnp, struct vnode *tdvp,
1754 struct vnode *tvp, struct componentname *tcnp)
1755 {
1756 kauth_cred_t cred;
1757 int error;
1758
1759 #if SECURITY_MAC_CHECK_ENFORCE
1760 /* 21167099 - only check if we allow write */
1761 if (!mac_vnode_enforce) {
1762 return 0;
1763 }
1764 #endif
1765 cred = vfs_context_ucred(ctx);
1766 if (!mac_cred_check_enforce(cred)) {
1767 return 0;
1768 }
1769
1770 VFS_KERNEL_DEBUG_START1(57, vp);
1771 MAC_CHECK(vnode_check_rename_from, cred, dvp, dvp->v_label, vp,
1772 vp->v_label, cnp);
1773 if (error) {
1774 VFS_KERNEL_DEBUG_END1(57, vp);
1775 return error;
1776 }
1777
1778 MAC_CHECK(vnode_check_rename_to, cred, tdvp, tdvp->v_label, tvp,
1779 tvp != NULL ? tvp->v_label : NULL, dvp == tdvp, tcnp);
1780 if (error) {
1781 VFS_KERNEL_DEBUG_END1(57, vp);
1782 return error;
1783 }
1784
1785 MAC_CHECK(vnode_check_rename, cred, dvp, dvp->v_label, vp,
1786 vp->v_label, cnp, tdvp, tdvp->v_label, tvp,
1787 tvp != NULL ? tvp->v_label : NULL, tcnp);
1788 VFS_KERNEL_DEBUG_END1(57, vp);
1789 return error;
1790 }
1791
1792 int
1793 mac_vnode_check_revoke(vfs_context_t ctx, struct vnode *vp)
1794 {
1795 kauth_cred_t cred;
1796 int error;
1797
1798 #if SECURITY_MAC_CHECK_ENFORCE
1799 /* 21167099 - only check if we allow write */
1800 if (!mac_vnode_enforce) {
1801 return 0;
1802 }
1803 #endif
1804 cred = vfs_context_ucred(ctx);
1805 if (!mac_cred_check_enforce(cred)) {
1806 return 0;
1807 }
1808 VFS_KERNEL_DEBUG_START1(58, vp);
1809 MAC_CHECK(vnode_check_revoke, cred, vp, vp->v_label);
1810 VFS_KERNEL_DEBUG_END1(58, vp);
1811 return error;
1812 }
1813
1814 int
1815 mac_vnode_check_searchfs(vfs_context_t ctx, struct vnode *vp, struct attrlist *alist)
1816 {
1817 kauth_cred_t cred;
1818 int error;
1819
1820 #if SECURITY_MAC_CHECK_ENFORCE
1821 /* 21167099 - only check if we allow write */
1822 if (!mac_vnode_enforce) {
1823 return 0;
1824 }
1825 #endif
1826 cred = vfs_context_ucred(ctx);
1827 if (!mac_cred_check_enforce(cred)) {
1828 return 0;
1829 }
1830 VFS_KERNEL_DEBUG_START1(59, vp);
1831 MAC_CHECK(vnode_check_searchfs, cred, vp, vp->v_label, alist);
1832 VFS_KERNEL_DEBUG_END1(59, vp);
1833 return error;
1834 }
1835
1836 int
1837 mac_vnode_check_select(vfs_context_t ctx, struct vnode *vp, int which)
1838 {
1839 kauth_cred_t cred;
1840 int error;
1841
1842 #if SECURITY_MAC_CHECK_ENFORCE
1843 /* 21167099 - only check if we allow write */
1844 if (!mac_vnode_enforce) {
1845 return 0;
1846 }
1847 #endif
1848 cred = vfs_context_ucred(ctx);
1849 if (!mac_cred_check_enforce(cred)) {
1850 return 0;
1851 }
1852 VFS_KERNEL_DEBUG_START1(60, vp);
1853 MAC_CHECK(vnode_check_select, cred, vp, vp->v_label, which);
1854 VFS_KERNEL_DEBUG_END1(60, vp);
1855 return error;
1856 }
1857
1858 int
1859 mac_vnode_check_setacl(vfs_context_t ctx, struct vnode *vp,
1860 struct kauth_acl *acl)
1861 {
1862 kauth_cred_t cred;
1863 int error;
1864
1865 #if SECURITY_MAC_CHECK_ENFORCE
1866 /* 21167099 - only check if we allow write */
1867 if (!mac_vnode_enforce) {
1868 return 0;
1869 }
1870 #endif
1871 cred = vfs_context_ucred(ctx);
1872 if (!mac_cred_check_enforce(cred)) {
1873 return 0;
1874 }
1875 VFS_KERNEL_DEBUG_START1(61, vp);
1876 MAC_CHECK(vnode_check_setacl, cred, vp, vp->v_label, acl);
1877 VFS_KERNEL_DEBUG_END1(61, vp);
1878 return error;
1879 }
1880
1881 int
1882 mac_vnode_check_setattrlist(vfs_context_t ctx, struct vnode *vp,
1883 struct attrlist *alist)
1884 {
1885 kauth_cred_t cred;
1886 int error;
1887
1888 #if SECURITY_MAC_CHECK_ENFORCE
1889 /* 21167099 - only check if we allow write */
1890 if (!mac_vnode_enforce) {
1891 return 0;
1892 }
1893 #endif
1894 cred = vfs_context_ucred(ctx);
1895 if (!mac_cred_check_enforce(cred)) {
1896 return 0;
1897 }
1898 VFS_KERNEL_DEBUG_START1(62, vp);
1899 MAC_CHECK(vnode_check_setattrlist, cred, vp, vp->v_label, alist);
1900 VFS_KERNEL_DEBUG_END1(62, vp);
1901 return error;
1902 }
1903
1904 int
1905 mac_vnode_check_setextattr(vfs_context_t ctx, struct vnode *vp,
1906 const char *name, struct uio *uio)
1907 {
1908 kauth_cred_t cred;
1909 int error;
1910
1911 #if SECURITY_MAC_CHECK_ENFORCE
1912 /* 21167099 - only check if we allow write */
1913 if (!mac_vnode_enforce) {
1914 return 0;
1915 }
1916 #endif
1917 cred = vfs_context_ucred(ctx);
1918 if (!mac_cred_check_enforce(cred)) {
1919 return 0;
1920 }
1921 VFS_KERNEL_DEBUG_START1(63, vp);
1922 MAC_CHECK(vnode_check_setextattr, cred, vp, vp->v_label,
1923 name, uio);
1924 VFS_KERNEL_DEBUG_END1(63, vp);
1925 return error;
1926 }
1927
1928 int
1929 mac_vnode_check_setflags(vfs_context_t ctx, struct vnode *vp, u_long flags)
1930 {
1931 kauth_cred_t cred;
1932 int error;
1933
1934 #if SECURITY_MAC_CHECK_ENFORCE
1935 /* 21167099 - only check if we allow write */
1936 if (!mac_vnode_enforce) {
1937 return 0;
1938 }
1939 #endif
1940 cred = vfs_context_ucred(ctx);
1941 if (!mac_cred_check_enforce(cred)) {
1942 return 0;
1943 }
1944 VFS_KERNEL_DEBUG_START1(64, vp);
1945 MAC_CHECK(vnode_check_setflags, cred, vp, vp->v_label, flags);
1946 VFS_KERNEL_DEBUG_END1(64, vp);
1947 return error;
1948 }
1949
1950 int
1951 mac_vnode_check_setmode(vfs_context_t ctx, struct vnode *vp, mode_t mode)
1952 {
1953 kauth_cred_t cred;
1954 int error;
1955
1956 #if SECURITY_MAC_CHECK_ENFORCE
1957 /* 21167099 - only check if we allow write */
1958 if (!mac_vnode_enforce) {
1959 return 0;
1960 }
1961 #endif
1962 cred = vfs_context_ucred(ctx);
1963 if (!mac_cred_check_enforce(cred)) {
1964 return 0;
1965 }
1966 VFS_KERNEL_DEBUG_START1(65, vp);
1967 MAC_CHECK(vnode_check_setmode, cred, vp, vp->v_label, mode);
1968 VFS_KERNEL_DEBUG_END1(65, vp);
1969 return error;
1970 }
1971
1972 int
1973 mac_vnode_check_setowner(vfs_context_t ctx, struct vnode *vp, uid_t uid,
1974 gid_t gid)
1975 {
1976 kauth_cred_t cred;
1977 int error;
1978
1979 #if SECURITY_MAC_CHECK_ENFORCE
1980 /* 21167099 - only check if we allow write */
1981 if (!mac_vnode_enforce) {
1982 return 0;
1983 }
1984 #endif
1985 cred = vfs_context_ucred(ctx);
1986 if (!mac_cred_check_enforce(cred)) {
1987 return 0;
1988 }
1989 VFS_KERNEL_DEBUG_START1(66, vp);
1990 MAC_CHECK(vnode_check_setowner, cred, vp, vp->v_label, uid, gid);
1991 VFS_KERNEL_DEBUG_END1(66, vp);
1992 return error;
1993 }
1994
1995 int
1996 mac_vnode_check_setutimes(vfs_context_t ctx, struct vnode *vp,
1997 struct timespec atime, struct timespec mtime)
1998 {
1999 kauth_cred_t cred;
2000 int error;
2001
2002 #if SECURITY_MAC_CHECK_ENFORCE
2003 /* 21167099 - only check if we allow write */
2004 if (!mac_vnode_enforce) {
2005 return 0;
2006 }
2007 #endif
2008 cred = vfs_context_ucred(ctx);
2009 if (!mac_cred_check_enforce(cred)) {
2010 return 0;
2011 }
2012 VFS_KERNEL_DEBUG_START1(67, vp);
2013 MAC_CHECK(vnode_check_setutimes, cred, vp, vp->v_label, atime,
2014 mtime);
2015 VFS_KERNEL_DEBUG_END1(67, vp);
2016 return error;
2017 }
2018
2019 int
2020 mac_vnode_check_stat(vfs_context_t ctx, struct ucred *file_cred,
2021 struct vnode *vp)
2022 {
2023 kauth_cred_t cred;
2024 int error;
2025
2026 #if SECURITY_MAC_CHECK_ENFORCE
2027 /* 21167099 - only check if we allow write */
2028 if (!mac_vnode_enforce) {
2029 return 0;
2030 }
2031 #endif
2032 cred = vfs_context_ucred(ctx);
2033 if (!mac_cred_check_enforce(cred)) {
2034 return 0;
2035 }
2036 VFS_KERNEL_DEBUG_START1(68, vp);
2037 MAC_CHECK(vnode_check_stat, cred, file_cred, vp,
2038 vp->v_label);
2039 VFS_KERNEL_DEBUG_END1(68, vp);
2040 return error;
2041 }
2042
2043 int
2044 mac_vnode_check_trigger_resolve(vfs_context_t ctx, struct vnode *dvp,
2045 struct componentname *cnp)
2046 {
2047 kauth_cred_t cred;
2048 int error;
2049
2050 #if SECURITY_MAC_CHECK_ENFORCE
2051 /* 21167099 - only check if we allow write */
2052 if (!mac_vnode_enforce) {
2053 return 0;
2054 }
2055 #endif
2056 cred = vfs_context_ucred(ctx);
2057 if (!mac_cred_check_enforce(cred)) {
2058 return 0;
2059 }
2060 VFS_KERNEL_DEBUG_START1(69, dvp);
2061 MAC_CHECK(vnode_check_trigger_resolve, cred, dvp, dvp->v_label, cnp);
2062 VFS_KERNEL_DEBUG_END1(69, dvp);
2063 return error;
2064 }
2065
2066 int
2067 mac_vnode_check_truncate(vfs_context_t ctx, struct ucred *file_cred,
2068 struct vnode *vp)
2069 {
2070 kauth_cred_t cred;
2071 int error;
2072
2073 #if SECURITY_MAC_CHECK_ENFORCE
2074 /* 21167099 - only check if we allow write */
2075 if (!mac_vnode_enforce) {
2076 return 0;
2077 }
2078 #endif
2079 cred = vfs_context_ucred(ctx);
2080 if (!mac_cred_check_enforce(cred)) {
2081 return 0;
2082 }
2083 VFS_KERNEL_DEBUG_START1(70, vp);
2084 MAC_CHECK(vnode_check_truncate, cred, file_cred, vp,
2085 vp->v_label);
2086 VFS_KERNEL_DEBUG_END1(70, vp);
2087
2088 return error;
2089 }
2090
2091 int
2092 mac_vnode_check_write(vfs_context_t ctx, struct ucred *file_cred,
2093 struct vnode *vp)
2094 {
2095 kauth_cred_t cred;
2096 int error;
2097
2098 #if SECURITY_MAC_CHECK_ENFORCE
2099 /* 21167099 - only check if we allow write */
2100 if (!mac_vnode_enforce) {
2101 return 0;
2102 }
2103 #endif
2104 cred = vfs_context_ucred(ctx);
2105 if (!mac_cred_check_enforce(cred)) {
2106 return 0;
2107 }
2108 VFS_KERNEL_DEBUG_START1(71, vp);
2109 MAC_CHECK(vnode_check_write, cred, file_cred, vp, vp->v_label);
2110 VFS_KERNEL_DEBUG_END1(71, vp);
2111
2112 return error;
2113 }
2114
2115 int
2116 mac_vnode_check_uipc_bind(vfs_context_t ctx, struct vnode *dvp,
2117 struct componentname *cnp, struct vnode_attr *vap)
2118 {
2119 kauth_cred_t cred;
2120 int error;
2121
2122 #if SECURITY_MAC_CHECK_ENFORCE
2123 /* 21167099 - only check if we allow write */
2124 if (!mac_vnode_enforce) {
2125 return 0;
2126 }
2127 #endif
2128 cred = vfs_context_ucred(ctx);
2129 if (!mac_cred_check_enforce(cred)) {
2130 return 0;
2131 }
2132 VFS_KERNEL_DEBUG_START1(72, dvp);
2133 MAC_CHECK(vnode_check_uipc_bind, cred, dvp, dvp->v_label, cnp, vap);
2134 VFS_KERNEL_DEBUG_END1(72, dvp);
2135 return error;
2136 }
2137
2138 int
2139 mac_vnode_check_uipc_connect(vfs_context_t ctx, struct vnode *vp, struct socket *so)
2140 {
2141 kauth_cred_t cred;
2142 int error;
2143
2144 #if SECURITY_MAC_CHECK_ENFORCE
2145 /* 21167099 - only check if we allow write */
2146 if (!mac_vnode_enforce) {
2147 return 0;
2148 }
2149 #endif
2150 cred = vfs_context_ucred(ctx);
2151 if (!mac_cred_check_enforce(cred)) {
2152 return 0;
2153 }
2154 VFS_KERNEL_DEBUG_START1(73, vp);
2155 MAC_CHECK(vnode_check_uipc_connect, cred, vp, vp->v_label, (socket_t) so);
2156 VFS_KERNEL_DEBUG_END1(73, vp);
2157 return error;
2158 }
2159
2160 void
2161 mac_vnode_label_update(vfs_context_t ctx, struct vnode *vp, struct label *newlabel)
2162 {
2163 kauth_cred_t cred = vfs_context_ucred(ctx);
2164 struct label *tmpl = NULL;
2165
2166 if (vp->v_label == NULL) {
2167 tmpl = mac_vnode_label_alloc();
2168 }
2169
2170 vnode_lock(vp);
2171
2172 /* recheck after lock */
2173 if (vp->v_label == NULL) {
2174 vp->v_label = tmpl;
2175 tmpl = NULL;
2176 }
2177
2178 VFS_KERNEL_DEBUG_START1(74, vp);
2179 MAC_PERFORM(vnode_label_update, cred, vp, vp->v_label, newlabel);
2180 VFS_KERNEL_DEBUG_END1(74, vp);
2181 vnode_unlock(vp);
2182
2183 if (tmpl != NULL) {
2184 mac_vnode_label_free(tmpl);
2185 }
2186 }
2187
2188 int
2189 mac_vnode_find_sigs(struct proc *p, struct vnode *vp, off_t offset)
2190 {
2191 int error;
2192
2193 #if SECURITY_MAC_CHECK_ENFORCE
2194 /* 21167099 - only check if we allow write */
2195 if (!mac_proc_enforce || !mac_vnode_enforce) {
2196 return 0;
2197 }
2198 #endif
2199
2200 VFS_KERNEL_DEBUG_START1(75, vp);
2201 MAC_CHECK(vnode_find_sigs, p, vp, offset, vp->v_label);
2202 VFS_KERNEL_DEBUG_END1(75, vp);
2203
2204 return error;
2205 }
2206
2207 void
2208 mac_mount_label_associate(vfs_context_t ctx, struct mount *mp)
2209 {
2210 kauth_cred_t cred = vfs_context_ucred(ctx);
2211
2212 /* XXX: eventually this logic may be handled by the policy? */
2213
2214 /* We desire MULTILABEL for the root filesystem. */
2215 if ((mp->mnt_flag & MNT_ROOTFS) &&
2216 (strcmp(mp->mnt_vfsstat.f_fstypename, "hfs") == 0)) {
2217 mp->mnt_flag |= MNT_MULTILABEL;
2218 }
2219
2220 /* MULTILABEL on DEVFS. */
2221 if (strcmp(mp->mnt_vfsstat.f_fstypename, "devfs") == 0) {
2222 mp->mnt_flag |= MNT_MULTILABEL;
2223 }
2224
2225 /* MULTILABEL on FDESC pseudo-filesystem. */
2226 if (strcmp(mp->mnt_vfsstat.f_fstypename, "fdesc") == 0) {
2227 mp->mnt_flag |= MNT_MULTILABEL;
2228 }
2229
2230 /* MULTILABEL on all NFS filesystems. */
2231 if (strcmp(mp->mnt_vfsstat.f_fstypename, "nfs") == 0) {
2232 mp->mnt_flag |= MNT_MULTILABEL;
2233 }
2234
2235 /* MULTILABEL on all AFP filesystems. */
2236 if (strcmp(mp->mnt_vfsstat.f_fstypename, "afpfs") == 0) {
2237 mp->mnt_flag |= MNT_MULTILABEL;
2238 }
2239
2240 if (mp->mnt_vtable != NULL) {
2241 /* Any filesystem that supports native XATTRs. */
2242 if ((mp->mnt_vtable->vfc_vfsflags & VFC_VFSNATIVEXATTR)) {
2243 mp->mnt_flag |= MNT_MULTILABEL;
2244 }
2245
2246 /* Filesystem does not support multilabel. */
2247 if ((mp->mnt_vtable->vfc_vfsflags & VFC_VFSNOMACLABEL) &&
2248 (mp->mnt_flag & MNT_MULTILABEL)) {
2249 mp->mnt_flag &= ~MNT_MULTILABEL;
2250 }
2251 }
2252
2253 VFS_KERNEL_DEBUG_START1(76, mp);
2254 MAC_PERFORM(mount_label_associate, cred, mp, mp->mnt_mntlabel);
2255 VFS_KERNEL_DEBUG_END1(76, mp);
2256 #if DEBUG
2257 printf("MAC Framework enabling %s support: %s -> %s (%s)\n",
2258 mp->mnt_flag & MNT_MULTILABEL ? "multilabel" : "singlelabel",
2259 mp->mnt_vfsstat.f_mntfromname,
2260 mp->mnt_vfsstat.f_mntonname,
2261 mp->mnt_vfsstat.f_fstypename);
2262 #endif
2263 }
2264
2265 int
2266 mac_mount_check_mount(vfs_context_t ctx, struct vnode *vp,
2267 struct componentname *cnp, const char *vfc_name)
2268 {
2269 kauth_cred_t cred;
2270 int error;
2271
2272 #if SECURITY_MAC_CHECK_ENFORCE
2273 /* 21167099 - only check if we allow write */
2274 if (!mac_vnode_enforce) {
2275 return 0;
2276 }
2277 #endif
2278 cred = vfs_context_ucred(ctx);
2279 if (!mac_cred_check_enforce(cred)) {
2280 return 0;
2281 }
2282 VFS_KERNEL_DEBUG_START1(77, vp);
2283 MAC_CHECK(mount_check_mount, cred, vp, vp->v_label, cnp, vfc_name);
2284 VFS_KERNEL_DEBUG_END1(77, vp);
2285
2286 return error;
2287 }
2288
2289 int
2290 mac_mount_check_mount_late(vfs_context_t ctx, struct mount *mp)
2291 {
2292 kauth_cred_t cred;
2293 int error;
2294
2295 #if SECURITY_MAC_CHECK_ENFORCE
2296 /* 21167099 - only check if we allow write */
2297 if (!mac_vnode_enforce) {
2298 return 0;
2299 }
2300 #endif
2301 cred = vfs_context_ucred(ctx);
2302 if (!mac_cred_check_enforce(cred)) {
2303 return 0;
2304 }
2305 VFS_KERNEL_DEBUG_START1(78, mp);
2306 MAC_CHECK(mount_check_mount_late, cred, mp);
2307 VFS_KERNEL_DEBUG_END1(78, mp);
2308
2309 return error;
2310 }
2311
2312 int
2313 mac_mount_check_snapshot_create(vfs_context_t ctx, struct mount *mp,
2314 const char *name)
2315 {
2316 kauth_cred_t cred;
2317 int error;
2318
2319 #if SECURITY_MAC_CHECK_ENFORCE
2320 /* 21167099 - only check if we allow write */
2321 if (!mac_vnode_enforce) {
2322 return 0;
2323 }
2324 #endif
2325 cred = vfs_context_ucred(ctx);
2326 if (!mac_cred_check_enforce(cred)) {
2327 return 0;
2328 }
2329 VFS_KERNEL_DEBUG_START1(79, mp);
2330 MAC_CHECK(mount_check_snapshot_create, cred, mp, name);
2331 VFS_KERNEL_DEBUG_END1(79, mp);
2332 return error;
2333 }
2334
2335 int
2336 mac_mount_check_snapshot_delete(vfs_context_t ctx, struct mount *mp,
2337 const char *name)
2338 {
2339 kauth_cred_t cred;
2340 int error;
2341
2342 #if SECURITY_MAC_CHECK_ENFORCE
2343 /* 21167099 - only check if we allow write */
2344 if (!mac_vnode_enforce) {
2345 return 0;
2346 }
2347 #endif
2348 cred = vfs_context_ucred(ctx);
2349 if (!mac_cred_check_enforce(cred)) {
2350 return 0;
2351 }
2352 VFS_KERNEL_DEBUG_START1(80, mp);
2353 MAC_CHECK(mount_check_snapshot_delete, cred, mp, name);
2354 VFS_KERNEL_DEBUG_END1(80, mp);
2355 return error;
2356 }
2357
2358 int
2359 mac_mount_check_snapshot_mount(vfs_context_t ctx, struct vnode *rvp, struct vnode *vp, struct componentname *cnp,
2360 const char *name, const char *vfc_name)
2361 {
2362 kauth_cred_t cred;
2363 int error;
2364
2365 #if SECURITY_MAC_CHECK_ENFORCE
2366 /* 21167099 - only check if we allow write */
2367 if (!mac_vnode_enforce) {
2368 return 0;
2369 }
2370 #endif
2371 cred = vfs_context_ucred(ctx);
2372 if (!mac_cred_check_enforce(cred)) {
2373 return 0;
2374 }
2375 VFS_KERNEL_DEBUG_START1(92, vp);
2376 MAC_CHECK(mount_check_snapshot_mount, cred, rvp, vp, cnp, name, vfc_name);
2377 VFS_KERNEL_DEBUG_END1(92, vp);
2378 return error;
2379 }
2380
2381 int
2382 mac_mount_check_snapshot_revert(vfs_context_t ctx, struct mount *mp,
2383 const char *name)
2384 {
2385 kauth_cred_t cred;
2386 int error;
2387
2388 #if SECURITY_MAC_CHECK_ENFORCE
2389 /* 21167099 - only check if we allow write */
2390 if (!mac_vnode_enforce) {
2391 return 0;
2392 }
2393 #endif
2394 cred = vfs_context_ucred(ctx);
2395 if (!mac_cred_check_enforce(cred)) {
2396 return 0;
2397 }
2398 VFS_KERNEL_DEBUG_START1(81, mp);
2399 MAC_CHECK(mount_check_snapshot_revert, cred, mp, name);
2400 VFS_KERNEL_DEBUG_END1(81, mp);
2401 return error;
2402 }
2403
2404 int
2405 mac_mount_check_remount(vfs_context_t ctx, struct mount *mp)
2406 {
2407 kauth_cred_t cred;
2408 int error;
2409
2410 #if SECURITY_MAC_CHECK_ENFORCE
2411 /* 21167099 - only check if we allow write */
2412 if (!mac_vnode_enforce) {
2413 return 0;
2414 }
2415 #endif
2416 cred = vfs_context_ucred(ctx);
2417 if (!mac_cred_check_enforce(cred)) {
2418 return 0;
2419 }
2420 VFS_KERNEL_DEBUG_START1(82, mp);
2421 MAC_CHECK(mount_check_remount, cred, mp, mp->mnt_mntlabel);
2422 VFS_KERNEL_DEBUG_END1(82, mp);
2423
2424 return error;
2425 }
2426
2427 int
2428 mac_mount_check_umount(vfs_context_t ctx, struct mount *mp)
2429 {
2430 kauth_cred_t cred;
2431 int error;
2432
2433 #if SECURITY_MAC_CHECK_ENFORCE
2434 /* 21167099 - only check if we allow write */
2435 if (!mac_vnode_enforce) {
2436 return 0;
2437 }
2438 #endif
2439 cred = vfs_context_ucred(ctx);
2440 if (!mac_cred_check_enforce(cred)) {
2441 return 0;
2442 }
2443 VFS_KERNEL_DEBUG_START1(83, mp);
2444 MAC_CHECK(mount_check_umount, cred, mp, mp->mnt_mntlabel);
2445 VFS_KERNEL_DEBUG_END1(83, mp);
2446
2447 return error;
2448 }
2449
2450 int
2451 mac_mount_check_getattr(vfs_context_t ctx, struct mount *mp,
2452 struct vfs_attr *vfa)
2453 {
2454 kauth_cred_t cred;
2455 int error;
2456
2457 #if SECURITY_MAC_CHECK_ENFORCE
2458 /* 21167099 - only check if we allow write */
2459 if (!mac_vnode_enforce) {
2460 return 0;
2461 }
2462 #endif
2463 cred = vfs_context_ucred(ctx);
2464 if (!mac_cred_check_enforce(cred)) {
2465 return 0;
2466 }
2467 VFS_KERNEL_DEBUG_START1(84, mp);
2468 MAC_CHECK(mount_check_getattr, cred, mp, mp->mnt_mntlabel, vfa);
2469 VFS_KERNEL_DEBUG_END1(84, mp);
2470 return error;
2471 }
2472
2473 int
2474 mac_mount_check_setattr(vfs_context_t ctx, struct mount *mp,
2475 struct vfs_attr *vfa)
2476 {
2477 kauth_cred_t cred;
2478 int error;
2479
2480 #if SECURITY_MAC_CHECK_ENFORCE
2481 /* 21167099 - only check if we allow write */
2482 if (!mac_vnode_enforce) {
2483 return 0;
2484 }
2485 #endif
2486 cred = vfs_context_ucred(ctx);
2487 if (!mac_cred_check_enforce(cred)) {
2488 return 0;
2489 }
2490 VFS_KERNEL_DEBUG_START1(85, mp);
2491 MAC_CHECK(mount_check_setattr, cred, mp, mp->mnt_mntlabel, vfa);
2492 VFS_KERNEL_DEBUG_END1(85, mp);
2493 return error;
2494 }
2495
2496 int
2497 mac_mount_check_stat(vfs_context_t ctx, struct mount *mount)
2498 {
2499 kauth_cred_t cred;
2500 int error;
2501
2502 #if SECURITY_MAC_CHECK_ENFORCE
2503 /* 21167099 - only check if we allow write */
2504 if (!mac_vnode_enforce) {
2505 return 0;
2506 }
2507 #endif
2508 cred = vfs_context_ucred(ctx);
2509 if (!mac_cred_check_enforce(cred)) {
2510 return 0;
2511 }
2512 VFS_KERNEL_DEBUG_START1(86, mount);
2513 MAC_CHECK(mount_check_stat, cred, mount, mount->mnt_mntlabel);
2514 VFS_KERNEL_DEBUG_END1(86, mount);
2515
2516 return error;
2517 }
2518
2519 int
2520 mac_mount_check_label_update(vfs_context_t ctx, struct mount *mount)
2521 {
2522 kauth_cred_t cred;
2523 int error;
2524
2525 #if SECURITY_MAC_CHECK_ENFORCE
2526 /* 21167099 - only check if we allow write */
2527 if (!mac_vnode_enforce) {
2528 return 0;
2529 }
2530 #endif
2531 cred = vfs_context_ucred(ctx);
2532 if (!mac_cred_check_enforce(cred)) {
2533 return 0;
2534 }
2535 VFS_KERNEL_DEBUG_START1(87, mount);
2536 MAC_CHECK(mount_check_label_update, cred, mount, mount->mnt_mntlabel);
2537 VFS_KERNEL_DEBUG_END1(87, mount);
2538
2539 return error;
2540 }
2541
2542 int
2543 mac_mount_check_fsctl(vfs_context_t ctx, struct mount *mp, u_long cmd)
2544 {
2545 kauth_cred_t cred;
2546 int error;
2547
2548 #if SECURITY_MAC_CHECK_ENFORCE
2549 /* 21167099 - only check if we allow write */
2550 if (!mac_vnode_enforce) {
2551 return 0;
2552 }
2553 #endif
2554 cred = vfs_context_ucred(ctx);
2555 if (!mac_cred_check_enforce(cred)) {
2556 return 0;
2557 }
2558 VFS_KERNEL_DEBUG_START1(88, mp);
2559 MAC_CHECK(mount_check_fsctl, cred, mp, mp->mnt_mntlabel, cmd);
2560 VFS_KERNEL_DEBUG_END1(88, mp);
2561
2562 return error;
2563 }
2564
2565 void
2566 mac_devfs_label_associate_device(dev_t dev, struct devnode *de,
2567 const char *fullpath)
2568 {
2569 #if SECURITY_MAC_CHECK_ENFORCE
2570 /* 21167099 - only check if we allow write */
2571 if (!mac_device_enforce) {
2572 return;
2573 }
2574 #endif
2575
2576 VFS_KERNEL_DEBUG_START1(89, de);
2577 MAC_PERFORM(devfs_label_associate_device, dev, de, de->dn_label,
2578 fullpath);
2579 VFS_KERNEL_DEBUG_END1(89, de);
2580 }
2581
2582 void
2583 mac_devfs_label_associate_directory(const char *dirname, int dirnamelen,
2584 struct devnode *de, const char *fullpath)
2585 {
2586 #if SECURITY_MAC_CHECK_ENFORCE
2587 /* 21167099 - only check if we allow write */
2588 if (!mac_device_enforce) {
2589 return;
2590 }
2591 #endif
2592
2593 VFS_KERNEL_DEBUG_START1(90, de);
2594 MAC_PERFORM(devfs_label_associate_directory, dirname, dirnamelen, de,
2595 de->dn_label, fullpath);
2596 VFS_KERNEL_DEBUG_END1(90, de);
2597 }
2598
2599 int
2600 vn_setlabel(struct vnode *vp, struct label *intlabel, vfs_context_t context)
2601 {
2602 int error;
2603
2604 #if SECURITY_MAC_CHECK_ENFORCE
2605 /* 21167099 - only check if we allow write */
2606 if (!mac_vnode_enforce) {
2607 return 0;
2608 }
2609 #endif
2610 if (!mac_label_vnodes) {
2611 return 0;
2612 }
2613
2614 if (vp->v_mount == NULL) {
2615 printf("vn_setlabel: null v_mount\n");
2616 if (vp->v_type != VNON) {
2617 printf("vn_setlabel: null v_mount with non-VNON\n");
2618 }
2619 return EBADF;
2620 }
2621
2622 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
2623 return ENOTSUP;
2624 }
2625
2626 /*
2627 * Multi-phase commit. First check the policies to confirm the
2628 * change is OK. Then commit via the filesystem. Finally,
2629 * update the actual vnode label. Question: maybe the filesystem
2630 * should update the vnode at the end as part of VNOP_SETLABEL()?
2631 */
2632 error = mac_vnode_check_label_update(context, vp, intlabel);
2633 if (error) {
2634 return error;
2635 }
2636
2637 error = VNOP_SETLABEL(vp, intlabel, context);
2638 if (error == ENOTSUP) {
2639 error = mac_vnode_label_store(context, vp,
2640 intlabel);
2641 if (error) {
2642 printf("%s: mac_vnode_label_store failed %d\n",
2643 __func__, error);
2644 return error;
2645 }
2646 mac_vnode_label_update(context, vp, intlabel);
2647 } else if (error) {
2648 printf("vn_setlabel: vop setlabel failed %d\n", error);
2649 return error;
2650 }
2651
2652 return 0;
2653 }
2654
2655 int
2656 mac_vnode_label_associate_fdesc(struct mount *mp, struct fdescnode *fnp,
2657 struct vnode *vp, vfs_context_t ctx)
2658 {
2659 struct fileproc *fp;
2660 #if CONFIG_MACF_SOCKET_SUBSET
2661 struct socket *so;
2662 #endif
2663 struct pipe *cpipe;
2664 struct vnode *fvp;
2665 struct proc *p;
2666 int error;
2667
2668 error = 0;
2669
2670 VFS_KERNEL_DEBUG_START1(91, vp);
2671 /*
2672 * If no backing file, let the policy choose which label to use.
2673 */
2674 if (fnp->fd_fd == -1) {
2675 MAC_PERFORM(vnode_label_associate_file, vfs_context_ucred(ctx),
2676 mp, mp->mnt_mntlabel, NULL, NULL, vp, vp->v_label);
2677 VFS_KERNEL_DEBUG_END1(91, vp);
2678 return 0;
2679 }
2680
2681 p = vfs_context_proc(ctx);
2682 error = fp_lookup(p, fnp->fd_fd, &fp, 0);
2683 if (error) {
2684 VFS_KERNEL_DEBUG_END1(91, vp);
2685 return error;
2686 }
2687
2688 if (fp->fp_glob == NULL) {
2689 error = EBADF;
2690 goto out;
2691 }
2692
2693 switch (FILEGLOB_DTYPE(fp->fp_glob)) {
2694 case DTYPE_VNODE:
2695 fvp = (struct vnode *)fp->fp_glob->fg_data;
2696 if ((error = vnode_getwithref(fvp))) {
2697 goto out;
2698 }
2699 if (fvp->v_label != NULL) {
2700 if (mac_label_vnodes != 0 && vp->v_label == NULL) {
2701 mac_vnode_label_init(vp); /* init dst label */
2702 }
2703 MAC_PERFORM(vnode_label_copy, fvp->v_label, vp->v_label);
2704 }
2705 (void)vnode_put(fvp);
2706 break;
2707 #if CONFIG_MACF_SOCKET_SUBSET
2708 case DTYPE_SOCKET:
2709 so = (struct socket *)fp->fp_glob->fg_data;
2710 socket_lock(so, 1);
2711 MAC_PERFORM(vnode_label_associate_socket,
2712 vfs_context_ucred(ctx), (socket_t)so, so->so_label,
2713 vp, vp->v_label);
2714 socket_unlock(so, 1);
2715 break;
2716 #endif
2717 case DTYPE_PSXSHM:
2718 pshm_label_associate(fp, vp, ctx);
2719 break;
2720 case DTYPE_PSXSEM:
2721 psem_label_associate(fp, vp, ctx);
2722 break;
2723 case DTYPE_PIPE:
2724 cpipe = (struct pipe *)fp->fp_glob->fg_data;
2725 /* kern/sys_pipe.c:pipe_select() suggests this test. */
2726 if (cpipe == (struct pipe *)-1) {
2727 error = EINVAL;
2728 goto out;
2729 }
2730 PIPE_LOCK(cpipe);
2731 MAC_PERFORM(vnode_label_associate_pipe, vfs_context_ucred(ctx),
2732 cpipe, cpipe->pipe_label, vp, vp->v_label);
2733 PIPE_UNLOCK(cpipe);
2734 break;
2735 case DTYPE_KQUEUE:
2736 case DTYPE_FSEVENTS:
2737 case DTYPE_ATALK:
2738 case DTYPE_NETPOLICY:
2739 default:
2740 MAC_PERFORM(vnode_label_associate_file, vfs_context_ucred(ctx),
2741 mp, mp->mnt_mntlabel, fp->fp_glob, fp->fp_glob->fg_label,
2742 vp, vp->v_label);
2743 break;
2744 }
2745 out:
2746 VFS_KERNEL_DEBUG_END1(91, vp);
2747 fp_drop(p, fnp->fd_fd, fp, 0);
2748 return error;
2749 }
2750
2751 intptr_t
2752 mac_vnode_label_get(struct vnode *vp, int slot, intptr_t sentinel)
2753 {
2754 struct label *l;
2755
2756 KASSERT(vp != NULL, ("mac_vnode_label_get: NULL vnode"));
2757 l = vp->v_label;
2758 if (l != NULL) {
2759 return mac_label_get(l, slot);
2760 } else {
2761 return sentinel;
2762 }
2763 }
2764
2765 void
2766 mac_vnode_label_set(struct vnode *vp, int slot, intptr_t v)
2767 {
2768 struct label *l;
2769 KASSERT(vp != NULL, ("mac_vnode_label_set: NULL vnode"));
2770 l = vp->v_label;
2771 if (l == NULL) {
2772 mac_vnode_label_init(vp);
2773 l = vp->v_label;
2774 }
2775 mac_label_set(l, slot, v);
2776 }
2777
2778 void
2779 mac_vnode_notify_reclaim(struct vnode *vp)
2780 {
2781 VFS_KERNEL_DEBUG_START1(94, vp);
2782 MAC_PERFORM(vnode_notify_reclaim, vp);
2783 VFS_KERNEL_DEBUG_END1(94, vp);
2784 }