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