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