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 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
517 void
mac_vnode_notify_open(vfs_context_t ctx,struct vnode * vp,int acc_flags)518 mac_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
537 void
mac_vnode_notify_link(vfs_context_t ctx,struct vnode * vp,struct vnode * dvp,struct componentname * cnp)538 mac_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
558 void
mac_vnode_notify_deleteextattr(vfs_context_t ctx,struct vnode * vp,const char * name)559 mac_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
578 void
mac_vnode_notify_setacl(vfs_context_t ctx,struct vnode * vp,struct kauth_acl * acl)579 mac_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
598 void
mac_vnode_notify_setattrlist(vfs_context_t ctx,struct vnode * vp,struct attrlist * alist)599 mac_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
618 void
mac_vnode_notify_setextattr(vfs_context_t ctx,struct vnode * vp,const char * name,struct uio * uio)619 mac_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
638 void
mac_vnode_notify_setflags(vfs_context_t ctx,struct vnode * vp,u_long flags)639 mac_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
658 void
mac_vnode_notify_setmode(vfs_context_t ctx,struct vnode * vp,mode_t mode)659 mac_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
678 void
mac_vnode_notify_setowner(vfs_context_t ctx,struct vnode * vp,uid_t uid,gid_t gid)679 mac_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
698 void
mac_vnode_notify_setutimes(vfs_context_t ctx,struct vnode * vp,struct timespec atime,struct timespec mtime)699 mac_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
718 void
mac_vnode_notify_truncate(vfs_context_t ctx,kauth_cred_t file_cred,struct vnode * vp)719 mac_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 */
743 void
mac_vnode_label_update_extattr(struct mount * mp,struct vnode * vp,const char * name)744 mac_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
773 static int
mac_vnode_label_store(vfs_context_t ctx,struct vnode * vp,struct label * intlabel)774 mac_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
801 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)802 mac_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(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, mpc->mpc_name, &spawnattrlen);
847
848 error = mac_error_select(hook(cred, new, vfs_context_proc(ctx), vp, offset, scriptvp,
849 mac_vnode_label(vp), scriptvnodelabel, execl, csflags, spawnattr, spawnattrlen, disjoint),
850 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, mpc->mpc_name, &spawnattrlen);
866
867 error = mac_error_select(hook(cred, new, vfs_context_proc(ctx), vp, offset, scriptvp,
868 mac_vnode_label(vp), scriptvnodelabel, execl, csflags, spawnattr, spawnattrlen, disjoint),
869 error);
870 }
871 mac_policy_list_unbusy();
872 }
873 }
874 *labelupdateerror = error;
875 VFS_KERNEL_DEBUG_END1(27, vp);
876 }
877
878 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)879 mac_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, mpc->mpc_name, &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, mpc->mpc_name, &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
946 int
mac_vnode_check_access(vfs_context_t ctx,struct vnode * vp,int acc_mode)947 mac_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
972 int
mac_vnode_check_chdir(vfs_context_t ctx,struct vnode * dvp)973 mac_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
994 int
mac_vnode_check_chroot(vfs_context_t ctx,struct vnode * dvp,struct componentname * cnp)995 mac_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
1017 int
mac_vnode_check_clone(vfs_context_t ctx,struct vnode * dvp,struct vnode * vp,struct componentname * cnp)1018 mac_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 }
1040 int
mac_vnode_check_create(vfs_context_t ctx,struct vnode * dvp,struct componentname * cnp,struct vnode_attr * vap)1041 mac_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
1063 int
mac_vnode_check_unlink(vfs_context_t ctx,struct vnode * dvp,struct vnode * vp,struct componentname * cnp)1064 mac_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
1087 int
1088 mac_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
1111 int
mac_vnode_check_deleteextattr(vfs_context_t ctx,struct vnode * vp,const char * name)1112 mac_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 }
1133 int
mac_vnode_check_exchangedata(vfs_context_t ctx,struct vnode * v1,struct vnode * v2)1134 mac_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
1159 int
1160 mac_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
1182 int
mac_vnode_check_getattr(vfs_context_t ctx,struct ucred * file_cred,struct vnode * vp,struct vnode_attr * va)1183 mac_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
1205 int
mac_vnode_check_getattrlist(vfs_context_t ctx,struct vnode * vp,struct attrlist * alist,uint64_t options)1206 mac_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
1230 int
mac_vnode_check_exec(vfs_context_t ctx,struct vnode * vp,struct image_params * imgp)1231 mac_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(&imgp->ip_px_smpx, mpc->mpc_name, &spawnattrlen);
1269
1270 error = mac_error_select(
1271 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), 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(&imgp->ip_px_smpx, mpc->mpc_name, &spawnattrlen);
1290
1291 error = mac_error_select(
1292 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), error);
1296 }
1297 mac_policy_list_unbusy();
1298 }
1299 }
1300 VFS_KERNEL_DEBUG_END1(41, vp);
1301
1302 return error;
1303 }
1304
1305 int
mac_vnode_check_fsgetpath(vfs_context_t ctx,struct vnode * vp)1306 mac_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
1327 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)1328 mac_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(ZV_NAMEI);
1361 if (vn_getpath(vp, vn_path, (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(reason, kcdata_estimate_required_buffer_size
1404 (1, (uint32_t)fatal_failure_desc_len))) == 0 &&
1405 (kcdata_error = kcdata_get_memory_addr(&reason->osr_kcd_descriptor,
1406 EXIT_REASON_USER_DESC, (uint32_t)fatal_failure_desc_len,
1407 &data_addr)) == KERN_SUCCESS) {
1408 kern_return_t mc_error = kcdata_memcpy(&reason->osr_kcd_descriptor, (mach_vm_address_t)data_addr,
1409 fatal_failure_desc, (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
1424 out:
1425 if (vn_path) {
1426 zfree(ZV_NAMEI, vn_path);
1427 }
1428
1429 if (fatal_failure_desc_len > 0 && fatal_failure_desc != NULL) {
1430 kheap_free(KHEAP_DEFAULT, fatal_failure_desc, fatal_failure_desc_len);
1431 }
1432
1433 return error;
1434 }
1435
1436 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)1437 mac_vnode_check_supplemental_signature(struct vnode *vp,
1438 struct cs_blob *cs_blob, struct vnode *linked_vp,
1439 struct cs_blob *linked_cs_blob, unsigned int *signer_type)
1440 {
1441 int error;
1442
1443 #if SECURITY_MAC_CHECK_ENFORCE
1444 /* 21167099 - only check if we allow write */
1445 if (!mac_proc_enforce || !mac_vnode_enforce) {
1446 return 0;
1447 }
1448 #endif
1449 VFS_KERNEL_DEBUG_START1(93, vp);
1450 MAC_CHECK(vnode_check_supplemental_signature, vp, mac_vnode_label(vp), cs_blob, linked_vp, linked_cs_blob,
1451 signer_type);
1452 VFS_KERNEL_DEBUG_END1(93, vp);
1453
1454 return error;
1455 }
1456
1457 #if 0
1458 int
1459 mac_vnode_check_getacl(vfs_context_t ctx, struct vnode *vp, acl_type_t type)
1460 {
1461 kauth_cred_t cred;
1462 int error;
1463
1464 #if SECURITY_MAC_CHECK_ENFORCE
1465 /* 21167099 - only check if we allow write */
1466 if (!mac_vnode_enforce) {
1467 return 0;
1468 }
1469 #endif
1470 cred = vfs_context_ucred(ctx);
1471 if (!mac_cred_check_enforce(cred)) {
1472 return 0;
1473 }
1474 VFS_KERNEL_DEBUG_START1(44, vp);
1475 MAC_CHECK(vnode_check_getacl, cred, vp, mac_vnode_label(vp), type);
1476 VFS_KERNEL_DEBUG_END1(44, vp);
1477 return error;
1478 }
1479 #endif
1480
1481 int
mac_vnode_check_getextattr(vfs_context_t ctx,struct vnode * vp,const char * name,struct uio * uio)1482 mac_vnode_check_getextattr(vfs_context_t ctx, struct vnode *vp,
1483 const char *name, struct uio *uio)
1484 {
1485 kauth_cred_t cred;
1486 int error;
1487
1488 #if SECURITY_MAC_CHECK_ENFORCE
1489 /* 21167099 - only check if we allow write */
1490 if (!mac_vnode_enforce) {
1491 return 0;
1492 }
1493 #endif
1494 cred = vfs_context_ucred(ctx);
1495 if (!mac_cred_check_enforce(cred)) {
1496 return 0;
1497 }
1498 VFS_KERNEL_DEBUG_START1(45, vp);
1499 MAC_CHECK(vnode_check_getextattr, cred, vp, mac_vnode_label(vp),
1500 name, uio);
1501 VFS_KERNEL_DEBUG_END1(45, vp);
1502 return error;
1503 }
1504
1505 int
mac_vnode_check_ioctl(vfs_context_t ctx,struct vnode * vp,u_long cmd)1506 mac_vnode_check_ioctl(vfs_context_t ctx, struct vnode *vp, u_long cmd)
1507 {
1508 kauth_cred_t cred;
1509 int error;
1510
1511 #if SECURITY_MAC_CHECK_ENFORCE
1512 /* 21167099 - only check if we allow write */
1513 if (!mac_vnode_enforce) {
1514 return 0;
1515 }
1516 #endif
1517 cred = vfs_context_ucred(ctx);
1518 if (!mac_cred_check_enforce(cred)) {
1519 return 0;
1520 }
1521 VFS_KERNEL_DEBUG_START1(46, vp);
1522 MAC_CHECK(vnode_check_ioctl, cred, vp, mac_vnode_label(vp), cmd);
1523 VFS_KERNEL_DEBUG_END1(46, vp);
1524 return error;
1525 }
1526
1527 int
mac_vnode_check_kqfilter(vfs_context_t ctx,kauth_cred_t file_cred,struct knote * kn,struct vnode * vp)1528 mac_vnode_check_kqfilter(vfs_context_t ctx, kauth_cred_t file_cred,
1529 struct knote *kn, struct vnode *vp)
1530 {
1531 kauth_cred_t cred;
1532 int error;
1533
1534 #if SECURITY_MAC_CHECK_ENFORCE
1535 /* 21167099 - only check if we allow write */
1536 if (!mac_vnode_enforce) {
1537 return 0;
1538 }
1539 #endif
1540 cred = vfs_context_ucred(ctx);
1541 if (!mac_cred_check_enforce(cred)) {
1542 return 0;
1543 }
1544 VFS_KERNEL_DEBUG_START1(47, vp);
1545 MAC_CHECK(vnode_check_kqfilter, cred, file_cred, kn, vp,
1546 mac_vnode_label(vp));
1547 VFS_KERNEL_DEBUG_END1(47, vp);
1548
1549 return error;
1550 }
1551
1552 int
mac_vnode_check_link(vfs_context_t ctx,struct vnode * dvp,struct vnode * vp,struct componentname * cnp)1553 mac_vnode_check_link(vfs_context_t ctx, struct vnode *dvp,
1554 struct vnode *vp, struct componentname *cnp)
1555 {
1556 kauth_cred_t cred;
1557 int error;
1558
1559 #if SECURITY_MAC_CHECK_ENFORCE
1560 /* 21167099 - only check if we allow write */
1561 if (!mac_vnode_enforce) {
1562 return 0;
1563 }
1564 #endif
1565 cred = vfs_context_ucred(ctx);
1566 if (!mac_cred_check_enforce(cred)) {
1567 return 0;
1568 }
1569 VFS_KERNEL_DEBUG_START1(48, vp);
1570 MAC_CHECK(vnode_check_link, cred, dvp, mac_vnode_label(dvp), vp,
1571 mac_vnode_label(vp), cnp);
1572 VFS_KERNEL_DEBUG_END1(48, vp);
1573 return error;
1574 }
1575
1576 int
mac_vnode_check_listextattr(vfs_context_t ctx,struct vnode * vp)1577 mac_vnode_check_listextattr(vfs_context_t ctx, struct vnode *vp)
1578 {
1579 kauth_cred_t cred;
1580 int error;
1581
1582 #if SECURITY_MAC_CHECK_ENFORCE
1583 /* 21167099 - only check if we allow write */
1584 if (!mac_vnode_enforce) {
1585 return 0;
1586 }
1587 #endif
1588 cred = vfs_context_ucred(ctx);
1589 if (!mac_cred_check_enforce(cred)) {
1590 return 0;
1591 }
1592 VFS_KERNEL_DEBUG_START1(49, vp);
1593 MAC_CHECK(vnode_check_listextattr, cred, vp, mac_vnode_label(vp));
1594 VFS_KERNEL_DEBUG_END1(49, vp);
1595 return error;
1596 }
1597
1598 int
mac_vnode_check_lookup_preflight(vfs_context_t ctx,struct vnode * dvp,const char * path,size_t pathlen)1599 mac_vnode_check_lookup_preflight(vfs_context_t ctx, struct vnode *dvp,
1600 const char *path, size_t pathlen)
1601 {
1602 kauth_cred_t cred;
1603 int error;
1604
1605 #if SECURITY_MAC_CHECK_ENFORCE
1606 /* 21167099 - only check if we allow write */
1607 if (!mac_vnode_enforce) {
1608 return 0;
1609 }
1610 #endif
1611 cred = vfs_context_ucred(ctx);
1612 if (!mac_cred_check_enforce(cred)) {
1613 return 0;
1614 }
1615 VFS_KERNEL_DEBUG_START1(50, dvp);
1616 MAC_CHECK(vnode_check_lookup_preflight, cred, dvp, mac_vnode_label(dvp), path, pathlen);
1617 VFS_KERNEL_DEBUG_END1(50, dvp);
1618 return error;
1619 }
1620
1621 int
mac_vnode_check_lookup(vfs_context_t ctx,struct vnode * dvp,struct componentname * cnp)1622 mac_vnode_check_lookup(vfs_context_t ctx, struct vnode *dvp,
1623 struct componentname *cnp)
1624 {
1625 kauth_cred_t cred;
1626 int error;
1627
1628 #if SECURITY_MAC_CHECK_ENFORCE
1629 /* 21167099 - only check if we allow write */
1630 if (!mac_vnode_enforce) {
1631 return 0;
1632 }
1633 #endif
1634 cred = vfs_context_ucred(ctx);
1635 if (!mac_cred_check_enforce(cred)) {
1636 return 0;
1637 }
1638 VFS_KERNEL_DEBUG_START1(51, dvp);
1639 MAC_CHECK(vnode_check_lookup, cred, dvp, mac_vnode_label(dvp), cnp);
1640 VFS_KERNEL_DEBUG_END1(51, dvp);
1641 return error;
1642 }
1643
1644 int
mac_vnode_check_open(vfs_context_t ctx,struct vnode * vp,int acc_mode)1645 mac_vnode_check_open(vfs_context_t ctx, struct vnode *vp, int acc_mode)
1646 {
1647 kauth_cred_t cred;
1648 int error;
1649
1650 #if SECURITY_MAC_CHECK_ENFORCE
1651 /* 21167099 - only check if we allow write */
1652 if (!mac_vnode_enforce) {
1653 return 0;
1654 }
1655 #endif
1656 cred = vfs_context_ucred(ctx);
1657 if (!mac_cred_check_enforce(cred)) {
1658 return 0;
1659 }
1660 VFS_KERNEL_DEBUG_START1(52, vp);
1661 MAC_CHECK(vnode_check_open, cred, vp, mac_vnode_label(vp), acc_mode);
1662 VFS_KERNEL_DEBUG_END1(52, vp);
1663 return error;
1664 }
1665
1666 int
mac_vnode_check_read(vfs_context_t ctx,struct ucred * file_cred,struct vnode * vp)1667 mac_vnode_check_read(vfs_context_t ctx, struct ucred *file_cred,
1668 struct vnode *vp)
1669 {
1670 kauth_cred_t cred;
1671 int error;
1672
1673 #if SECURITY_MAC_CHECK_ENFORCE
1674 /* 21167099 - only check if we allow write */
1675 if (!mac_vnode_enforce) {
1676 return 0;
1677 }
1678 #endif
1679 cred = vfs_context_ucred(ctx);
1680 if (!mac_cred_check_enforce(cred)) {
1681 return 0;
1682 }
1683 VFS_KERNEL_DEBUG_START1(53, vp);
1684 MAC_CHECK(vnode_check_read, cred, file_cred, vp,
1685 mac_vnode_label(vp));
1686 VFS_KERNEL_DEBUG_END1(53, vp);
1687
1688 return error;
1689 }
1690
1691 int
mac_vnode_check_readdir(vfs_context_t ctx,struct vnode * dvp)1692 mac_vnode_check_readdir(vfs_context_t ctx, struct vnode *dvp)
1693 {
1694 kauth_cred_t cred;
1695 int error;
1696
1697 #if SECURITY_MAC_CHECK_ENFORCE
1698 /* 21167099 - only check if we allow write */
1699 if (!mac_vnode_enforce) {
1700 return 0;
1701 }
1702 #endif
1703 cred = vfs_context_ucred(ctx);
1704 if (!mac_cred_check_enforce(cred)) {
1705 return 0;
1706 }
1707 VFS_KERNEL_DEBUG_START1(54, dvp);
1708 MAC_CHECK(vnode_check_readdir, cred, dvp, mac_vnode_label(dvp));
1709 VFS_KERNEL_DEBUG_END1(54, dvp);
1710 return error;
1711 }
1712
1713 int
mac_vnode_check_readlink(vfs_context_t ctx,struct vnode * vp)1714 mac_vnode_check_readlink(vfs_context_t ctx, struct vnode *vp)
1715 {
1716 kauth_cred_t cred;
1717 int error;
1718
1719 #if SECURITY_MAC_CHECK_ENFORCE
1720 /* 21167099 - only check if we allow write */
1721 if (!mac_vnode_enforce) {
1722 return 0;
1723 }
1724 #endif
1725 cred = vfs_context_ucred(ctx);
1726 if (!mac_cred_check_enforce(cred)) {
1727 return 0;
1728 }
1729 VFS_KERNEL_DEBUG_START1(55, vp);
1730 MAC_CHECK(vnode_check_readlink, cred, vp, mac_vnode_label(vp));
1731 VFS_KERNEL_DEBUG_END1(55, vp);
1732 return error;
1733 }
1734
1735 int
mac_vnode_check_label_update(vfs_context_t ctx,struct vnode * vp,struct label * newlabel)1736 mac_vnode_check_label_update(vfs_context_t ctx, struct vnode *vp,
1737 struct label *newlabel)
1738 {
1739 kauth_cred_t cred;
1740 int error;
1741
1742 #if SECURITY_MAC_CHECK_ENFORCE
1743 /* 21167099 - only check if we allow write */
1744 if (!mac_vnode_enforce) {
1745 return 0;
1746 }
1747 #endif
1748 cred = vfs_context_ucred(ctx);
1749 if (!mac_cred_check_enforce(cred)) {
1750 return 0;
1751 }
1752 VFS_KERNEL_DEBUG_START1(56, vp);
1753 MAC_CHECK(vnode_check_label_update, cred, vp, mac_vnode_label(vp), newlabel);
1754 VFS_KERNEL_DEBUG_END1(56, vp);
1755
1756 return error;
1757 }
1758
1759 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)1760 mac_vnode_check_rename(vfs_context_t ctx, struct vnode *dvp,
1761 struct vnode *vp, struct componentname *cnp, struct vnode *tdvp,
1762 struct vnode *tvp, struct componentname *tcnp)
1763 {
1764 kauth_cred_t cred;
1765 int error;
1766
1767 #if SECURITY_MAC_CHECK_ENFORCE
1768 /* 21167099 - only check if we allow write */
1769 if (!mac_vnode_enforce) {
1770 return 0;
1771 }
1772 #endif
1773 cred = vfs_context_ucred(ctx);
1774 if (!mac_cred_check_enforce(cred)) {
1775 return 0;
1776 }
1777
1778 VFS_KERNEL_DEBUG_START1(57, vp);
1779 MAC_CHECK(vnode_check_rename_from, cred, dvp, mac_vnode_label(dvp), vp,
1780 mac_vnode_label(vp), cnp);
1781 if (error) {
1782 VFS_KERNEL_DEBUG_END1(57, vp);
1783 return error;
1784 }
1785
1786 MAC_CHECK(vnode_check_rename_to, cred, tdvp, mac_vnode_label(tdvp), tvp,
1787 tvp != NULL ? mac_vnode_label(tvp) : NULL, dvp == tdvp, tcnp);
1788 if (error) {
1789 VFS_KERNEL_DEBUG_END1(57, vp);
1790 return error;
1791 }
1792
1793 MAC_CHECK(vnode_check_rename, cred, dvp, mac_vnode_label(dvp), vp,
1794 mac_vnode_label(vp), cnp, tdvp, mac_vnode_label(tdvp), tvp,
1795 tvp != NULL ? mac_vnode_label(tvp) : NULL, tcnp);
1796 VFS_KERNEL_DEBUG_END1(57, vp);
1797 return error;
1798 }
1799
1800 int
mac_vnode_check_revoke(vfs_context_t ctx,struct vnode * vp)1801 mac_vnode_check_revoke(vfs_context_t ctx, struct vnode *vp)
1802 {
1803 kauth_cred_t cred;
1804 int error;
1805
1806 #if SECURITY_MAC_CHECK_ENFORCE
1807 /* 21167099 - only check if we allow write */
1808 if (!mac_vnode_enforce) {
1809 return 0;
1810 }
1811 #endif
1812 cred = vfs_context_ucred(ctx);
1813 if (!mac_cred_check_enforce(cred)) {
1814 return 0;
1815 }
1816 VFS_KERNEL_DEBUG_START1(58, vp);
1817 MAC_CHECK(vnode_check_revoke, cred, vp, mac_vnode_label(vp));
1818 VFS_KERNEL_DEBUG_END1(58, vp);
1819 return error;
1820 }
1821
1822 int
mac_vnode_check_searchfs(vfs_context_t ctx,struct vnode * vp,struct attrlist * returnattrs,struct attrlist * searchattrs)1823 mac_vnode_check_searchfs(vfs_context_t ctx, struct vnode *vp, struct attrlist *returnattrs,
1824 struct attrlist *searchattrs)
1825 {
1826 kauth_cred_t cred;
1827 int error;
1828
1829 #if SECURITY_MAC_CHECK_ENFORCE
1830 /* 21167099 - only check if we allow write */
1831 if (!mac_vnode_enforce) {
1832 return 0;
1833 }
1834 #endif
1835 cred = vfs_context_ucred(ctx);
1836 if (!mac_cred_check_enforce(cred)) {
1837 return 0;
1838 }
1839 VFS_KERNEL_DEBUG_START1(59, vp);
1840 MAC_CHECK(vnode_check_searchfs, cred, vp, mac_vnode_label(vp), returnattrs, searchattrs);
1841 VFS_KERNEL_DEBUG_END1(59, vp);
1842 return error;
1843 }
1844
1845 int
mac_vnode_check_select(vfs_context_t ctx,struct vnode * vp,int which)1846 mac_vnode_check_select(vfs_context_t ctx, struct vnode *vp, int which)
1847 {
1848 kauth_cred_t cred;
1849 int error;
1850
1851 #if SECURITY_MAC_CHECK_ENFORCE
1852 /* 21167099 - only check if we allow write */
1853 if (!mac_vnode_enforce) {
1854 return 0;
1855 }
1856 #endif
1857 cred = vfs_context_ucred(ctx);
1858 if (!mac_cred_check_enforce(cred)) {
1859 return 0;
1860 }
1861 VFS_KERNEL_DEBUG_START1(60, vp);
1862 MAC_CHECK(vnode_check_select, cred, vp, mac_vnode_label(vp), which);
1863 VFS_KERNEL_DEBUG_END1(60, vp);
1864 return error;
1865 }
1866
1867 int
mac_vnode_check_setacl(vfs_context_t ctx,struct vnode * vp,struct kauth_acl * acl)1868 mac_vnode_check_setacl(vfs_context_t ctx, struct vnode *vp,
1869 struct kauth_acl *acl)
1870 {
1871 kauth_cred_t cred;
1872 int error;
1873
1874 #if SECURITY_MAC_CHECK_ENFORCE
1875 /* 21167099 - only check if we allow write */
1876 if (!mac_vnode_enforce) {
1877 return 0;
1878 }
1879 #endif
1880 cred = vfs_context_ucred(ctx);
1881 if (!mac_cred_check_enforce(cred)) {
1882 return 0;
1883 }
1884 VFS_KERNEL_DEBUG_START1(61, vp);
1885 MAC_CHECK(vnode_check_setacl, cred, vp, mac_vnode_label(vp), acl);
1886 VFS_KERNEL_DEBUG_END1(61, vp);
1887 return error;
1888 }
1889
1890 int
mac_vnode_check_setattrlist(vfs_context_t ctx,struct vnode * vp,struct attrlist * alist)1891 mac_vnode_check_setattrlist(vfs_context_t ctx, struct vnode *vp,
1892 struct attrlist *alist)
1893 {
1894 kauth_cred_t cred;
1895 int error;
1896
1897 #if SECURITY_MAC_CHECK_ENFORCE
1898 /* 21167099 - only check if we allow write */
1899 if (!mac_vnode_enforce) {
1900 return 0;
1901 }
1902 #endif
1903 cred = vfs_context_ucred(ctx);
1904 if (!mac_cred_check_enforce(cred)) {
1905 return 0;
1906 }
1907 VFS_KERNEL_DEBUG_START1(62, vp);
1908 MAC_CHECK(vnode_check_setattrlist, cred, vp, mac_vnode_label(vp), alist);
1909 VFS_KERNEL_DEBUG_END1(62, vp);
1910 return error;
1911 }
1912
1913 int
mac_vnode_check_setextattr(vfs_context_t ctx,struct vnode * vp,const char * name,struct uio * uio)1914 mac_vnode_check_setextattr(vfs_context_t ctx, struct vnode *vp,
1915 const char *name, struct uio *uio)
1916 {
1917 kauth_cred_t cred;
1918 int error;
1919
1920 #if SECURITY_MAC_CHECK_ENFORCE
1921 /* 21167099 - only check if we allow write */
1922 if (!mac_vnode_enforce) {
1923 return 0;
1924 }
1925 #endif
1926 cred = vfs_context_ucred(ctx);
1927 if (!mac_cred_check_enforce(cred)) {
1928 return 0;
1929 }
1930 VFS_KERNEL_DEBUG_START1(63, vp);
1931 MAC_CHECK(vnode_check_setextattr, cred, vp, mac_vnode_label(vp),
1932 name, uio);
1933 VFS_KERNEL_DEBUG_END1(63, vp);
1934 return error;
1935 }
1936
1937 int
mac_vnode_check_setflags(vfs_context_t ctx,struct vnode * vp,u_long flags)1938 mac_vnode_check_setflags(vfs_context_t ctx, struct vnode *vp, u_long flags)
1939 {
1940 kauth_cred_t cred;
1941 int error;
1942
1943 #if SECURITY_MAC_CHECK_ENFORCE
1944 /* 21167099 - only check if we allow write */
1945 if (!mac_vnode_enforce) {
1946 return 0;
1947 }
1948 #endif
1949 cred = vfs_context_ucred(ctx);
1950 if (!mac_cred_check_enforce(cred)) {
1951 return 0;
1952 }
1953 VFS_KERNEL_DEBUG_START1(64, vp);
1954 MAC_CHECK(vnode_check_setflags, cred, vp, mac_vnode_label(vp), flags);
1955 VFS_KERNEL_DEBUG_END1(64, vp);
1956 return error;
1957 }
1958
1959 int
mac_vnode_check_setmode(vfs_context_t ctx,struct vnode * vp,mode_t mode)1960 mac_vnode_check_setmode(vfs_context_t ctx, struct vnode *vp, mode_t mode)
1961 {
1962 kauth_cred_t cred;
1963 int error;
1964
1965 #if SECURITY_MAC_CHECK_ENFORCE
1966 /* 21167099 - only check if we allow write */
1967 if (!mac_vnode_enforce) {
1968 return 0;
1969 }
1970 #endif
1971 cred = vfs_context_ucred(ctx);
1972 if (!mac_cred_check_enforce(cred)) {
1973 return 0;
1974 }
1975 VFS_KERNEL_DEBUG_START1(65, vp);
1976 MAC_CHECK(vnode_check_setmode, cred, vp, mac_vnode_label(vp), mode);
1977 VFS_KERNEL_DEBUG_END1(65, vp);
1978 return error;
1979 }
1980
1981 int
mac_vnode_check_setowner(vfs_context_t ctx,struct vnode * vp,uid_t uid,gid_t gid)1982 mac_vnode_check_setowner(vfs_context_t ctx, struct vnode *vp, uid_t uid,
1983 gid_t gid)
1984 {
1985 kauth_cred_t cred;
1986 int error;
1987
1988 #if SECURITY_MAC_CHECK_ENFORCE
1989 /* 21167099 - only check if we allow write */
1990 if (!mac_vnode_enforce) {
1991 return 0;
1992 }
1993 #endif
1994 cred = vfs_context_ucred(ctx);
1995 if (!mac_cred_check_enforce(cred)) {
1996 return 0;
1997 }
1998 VFS_KERNEL_DEBUG_START1(66, vp);
1999 MAC_CHECK(vnode_check_setowner, cred, vp, mac_vnode_label(vp), uid, gid);
2000 VFS_KERNEL_DEBUG_END1(66, vp);
2001 return error;
2002 }
2003
2004 int
mac_vnode_check_setutimes(vfs_context_t ctx,struct vnode * vp,struct timespec atime,struct timespec mtime)2005 mac_vnode_check_setutimes(vfs_context_t ctx, struct vnode *vp,
2006 struct timespec atime, struct timespec mtime)
2007 {
2008 kauth_cred_t cred;
2009 int error;
2010
2011 #if SECURITY_MAC_CHECK_ENFORCE
2012 /* 21167099 - only check if we allow write */
2013 if (!mac_vnode_enforce) {
2014 return 0;
2015 }
2016 #endif
2017 cred = vfs_context_ucred(ctx);
2018 if (!mac_cred_check_enforce(cred)) {
2019 return 0;
2020 }
2021 VFS_KERNEL_DEBUG_START1(67, vp);
2022 MAC_CHECK(vnode_check_setutimes, cred, vp, mac_vnode_label(vp), atime,
2023 mtime);
2024 VFS_KERNEL_DEBUG_END1(67, vp);
2025 return error;
2026 }
2027
2028 int
mac_vnode_check_stat(vfs_context_t ctx,struct ucred * file_cred,struct vnode * vp)2029 mac_vnode_check_stat(vfs_context_t ctx, struct ucred *file_cred,
2030 struct vnode *vp)
2031 {
2032 kauth_cred_t cred;
2033 int error;
2034
2035 #if SECURITY_MAC_CHECK_ENFORCE
2036 /* 21167099 - only check if we allow write */
2037 if (!mac_vnode_enforce) {
2038 return 0;
2039 }
2040 #endif
2041 cred = vfs_context_ucred(ctx);
2042 if (!mac_cred_check_enforce(cred)) {
2043 return 0;
2044 }
2045 VFS_KERNEL_DEBUG_START1(68, vp);
2046 MAC_CHECK(vnode_check_stat, cred, file_cred, vp,
2047 mac_vnode_label(vp));
2048 VFS_KERNEL_DEBUG_END1(68, vp);
2049 return error;
2050 }
2051
2052 int
mac_vnode_check_trigger_resolve(vfs_context_t ctx,struct vnode * dvp,struct componentname * cnp)2053 mac_vnode_check_trigger_resolve(vfs_context_t ctx, struct vnode *dvp,
2054 struct componentname *cnp)
2055 {
2056 kauth_cred_t cred;
2057 int error;
2058
2059 #if SECURITY_MAC_CHECK_ENFORCE
2060 /* 21167099 - only check if we allow write */
2061 if (!mac_vnode_enforce) {
2062 return 0;
2063 }
2064 #endif
2065 cred = vfs_context_ucred(ctx);
2066 if (!mac_cred_check_enforce(cred)) {
2067 return 0;
2068 }
2069 VFS_KERNEL_DEBUG_START1(69, dvp);
2070 MAC_CHECK(vnode_check_trigger_resolve, cred, dvp, mac_vnode_label(dvp), cnp);
2071 VFS_KERNEL_DEBUG_END1(69, dvp);
2072 return error;
2073 }
2074
2075 int
mac_vnode_check_truncate(vfs_context_t ctx,struct ucred * file_cred,struct vnode * vp)2076 mac_vnode_check_truncate(vfs_context_t ctx, struct ucred *file_cred,
2077 struct vnode *vp)
2078 {
2079 kauth_cred_t cred;
2080 int error;
2081
2082 #if SECURITY_MAC_CHECK_ENFORCE
2083 /* 21167099 - only check if we allow write */
2084 if (!mac_vnode_enforce) {
2085 return 0;
2086 }
2087 #endif
2088 cred = vfs_context_ucred(ctx);
2089 if (!mac_cred_check_enforce(cred)) {
2090 return 0;
2091 }
2092 VFS_KERNEL_DEBUG_START1(70, vp);
2093 MAC_CHECK(vnode_check_truncate, cred, file_cred, vp,
2094 mac_vnode_label(vp));
2095 VFS_KERNEL_DEBUG_END1(70, vp);
2096
2097 return error;
2098 }
2099
2100 int
mac_vnode_check_write(vfs_context_t ctx,struct ucred * file_cred,struct vnode * vp)2101 mac_vnode_check_write(vfs_context_t ctx, struct ucred *file_cred,
2102 struct vnode *vp)
2103 {
2104 kauth_cred_t cred;
2105 int error;
2106
2107 #if SECURITY_MAC_CHECK_ENFORCE
2108 /* 21167099 - only check if we allow write */
2109 if (!mac_vnode_enforce) {
2110 return 0;
2111 }
2112 #endif
2113 cred = vfs_context_ucred(ctx);
2114 if (!mac_cred_check_enforce(cred)) {
2115 return 0;
2116 }
2117 VFS_KERNEL_DEBUG_START1(71, vp);
2118 MAC_CHECK(vnode_check_write, cred, file_cred, vp, mac_vnode_label(vp));
2119 VFS_KERNEL_DEBUG_END1(71, vp);
2120
2121 return error;
2122 }
2123
2124 int
mac_vnode_check_uipc_bind(vfs_context_t ctx,struct vnode * dvp,struct componentname * cnp,struct vnode_attr * vap)2125 mac_vnode_check_uipc_bind(vfs_context_t ctx, struct vnode *dvp,
2126 struct componentname *cnp, struct vnode_attr *vap)
2127 {
2128 kauth_cred_t cred;
2129 int error;
2130
2131 #if SECURITY_MAC_CHECK_ENFORCE
2132 /* 21167099 - only check if we allow write */
2133 if (!mac_vnode_enforce) {
2134 return 0;
2135 }
2136 #endif
2137 cred = vfs_context_ucred(ctx);
2138 if (!mac_cred_check_enforce(cred)) {
2139 return 0;
2140 }
2141 VFS_KERNEL_DEBUG_START1(72, dvp);
2142 MAC_CHECK(vnode_check_uipc_bind, cred, dvp, mac_vnode_label(dvp), cnp, vap);
2143 VFS_KERNEL_DEBUG_END1(72, dvp);
2144 return error;
2145 }
2146
2147 int
mac_vnode_check_uipc_connect(vfs_context_t ctx,struct vnode * vp,struct socket * so)2148 mac_vnode_check_uipc_connect(vfs_context_t ctx, struct vnode *vp, struct socket *so)
2149 {
2150 kauth_cred_t cred;
2151 int error;
2152
2153 #if SECURITY_MAC_CHECK_ENFORCE
2154 /* 21167099 - only check if we allow write */
2155 if (!mac_vnode_enforce) {
2156 return 0;
2157 }
2158 #endif
2159 cred = vfs_context_ucred(ctx);
2160 if (!mac_cred_check_enforce(cred)) {
2161 return 0;
2162 }
2163 VFS_KERNEL_DEBUG_START1(73, vp);
2164 MAC_CHECK(vnode_check_uipc_connect, cred, vp, mac_vnode_label(vp), (socket_t) so);
2165 VFS_KERNEL_DEBUG_END1(73, vp);
2166 return error;
2167 }
2168
2169 void
mac_vnode_label_update(vfs_context_t ctx,struct vnode * vp,struct label * newlabel)2170 mac_vnode_label_update(vfs_context_t ctx, struct vnode *vp, struct label *newlabel)
2171 {
2172 kauth_cred_t cred = vfs_context_ucred(ctx);
2173 struct label *tmpl = NULL;
2174
2175 if (mac_vnode_label(vp) == NULL) {
2176 tmpl = mac_vnode_label_alloc(vp);
2177 }
2178
2179 vnode_lock(vp);
2180
2181 /*
2182 * Recheck under lock. We allocate labels for vnodes lazily, so
2183 * somebody else might have already got here first.
2184 */
2185 if (mac_vnode_label(vp) == NULL) {
2186 vp->v_label = tmpl;
2187 tmpl = NULL;
2188 }
2189
2190 VFS_KERNEL_DEBUG_START1(74, vp);
2191 MAC_PERFORM(vnode_label_update, cred, vp, mac_vnode_label(vp), newlabel);
2192 VFS_KERNEL_DEBUG_END1(74, vp);
2193 vnode_unlock(vp);
2194
2195 if (tmpl != NULL) {
2196 mac_vnode_label_free(tmpl);
2197 }
2198 }
2199
2200 int
mac_vnode_find_sigs(struct proc * p,struct vnode * vp,off_t offset)2201 mac_vnode_find_sigs(struct proc *p, struct vnode *vp, off_t offset)
2202 {
2203 int error;
2204
2205 #if SECURITY_MAC_CHECK_ENFORCE
2206 /* 21167099 - only check if we allow write */
2207 if (!mac_proc_enforce || !mac_vnode_enforce) {
2208 return 0;
2209 }
2210 #endif
2211
2212 VFS_KERNEL_DEBUG_START1(75, vp);
2213 MAC_CHECK(vnode_find_sigs, p, vp, offset, mac_vnode_label(vp));
2214 VFS_KERNEL_DEBUG_END1(75, vp);
2215
2216 return error;
2217 }
2218
2219 void
mac_mount_label_associate(vfs_context_t ctx,struct mount * mp)2220 mac_mount_label_associate(vfs_context_t ctx, struct mount *mp)
2221 {
2222 kauth_cred_t cred = vfs_context_ucred(ctx);
2223
2224 /* XXX: eventually this logic may be handled by the policy? */
2225
2226 /* We desire MULTILABEL for the root filesystem. */
2227 if ((mp->mnt_flag & MNT_ROOTFS) &&
2228 (strcmp(mp->mnt_vfsstat.f_fstypename, "hfs") == 0)) {
2229 mp->mnt_flag |= MNT_MULTILABEL;
2230 }
2231
2232 /* MULTILABEL on DEVFS. */
2233 if (strcmp(mp->mnt_vfsstat.f_fstypename, "devfs") == 0) {
2234 mp->mnt_flag |= MNT_MULTILABEL;
2235 }
2236
2237 /* MULTILABEL on FDESC pseudo-filesystem. */
2238 if (strcmp(mp->mnt_vfsstat.f_fstypename, "fdesc") == 0) {
2239 mp->mnt_flag |= MNT_MULTILABEL;
2240 }
2241
2242 /* MULTILABEL on all NFS filesystems. */
2243 if (strcmp(mp->mnt_vfsstat.f_fstypename, "nfs") == 0) {
2244 mp->mnt_flag |= MNT_MULTILABEL;
2245 }
2246
2247 /* MULTILABEL on all AFP filesystems. */
2248 if (strcmp(mp->mnt_vfsstat.f_fstypename, "afpfs") == 0) {
2249 mp->mnt_flag |= MNT_MULTILABEL;
2250 }
2251
2252 if (mp->mnt_vtable != NULL) {
2253 /* Any filesystem that supports native XATTRs. */
2254 if ((mp->mnt_vtable->vfc_vfsflags & VFC_VFSNATIVEXATTR)) {
2255 mp->mnt_flag |= MNT_MULTILABEL;
2256 }
2257
2258 /* Filesystem does not support multilabel. */
2259 if ((mp->mnt_vtable->vfc_vfsflags & VFC_VFSNOMACLABEL) &&
2260 (mp->mnt_flag & MNT_MULTILABEL)) {
2261 mp->mnt_flag &= ~MNT_MULTILABEL;
2262 }
2263 }
2264
2265 VFS_KERNEL_DEBUG_START1(76, mp);
2266 MAC_PERFORM(mount_label_associate, cred, mp, mac_mount_label(mp));
2267 VFS_KERNEL_DEBUG_END1(76, mp);
2268 #if DEBUG
2269 printf("MAC Framework enabling %s support: %s -> %s (%s)\n",
2270 mp->mnt_flag & MNT_MULTILABEL ? "multilabel" : "singlelabel",
2271 mp->mnt_vfsstat.f_mntfromname,
2272 mp->mnt_vfsstat.f_mntonname,
2273 mp->mnt_vfsstat.f_fstypename);
2274 #endif
2275 }
2276
2277 int
mac_mount_check_mount(vfs_context_t ctx,struct vnode * vp,struct componentname * cnp,const char * vfc_name)2278 mac_mount_check_mount(vfs_context_t ctx, struct vnode *vp,
2279 struct componentname *cnp, const char *vfc_name)
2280 {
2281 kauth_cred_t cred;
2282 int error;
2283
2284 #if SECURITY_MAC_CHECK_ENFORCE
2285 /* 21167099 - only check if we allow write */
2286 if (!mac_vnode_enforce) {
2287 return 0;
2288 }
2289 #endif
2290 cred = vfs_context_ucred(ctx);
2291 if (!mac_cred_check_enforce(cred)) {
2292 return 0;
2293 }
2294 VFS_KERNEL_DEBUG_START1(77, vp);
2295 MAC_CHECK(mount_check_mount, cred, vp, mac_vnode_label(vp), cnp, vfc_name);
2296 VFS_KERNEL_DEBUG_END1(77, vp);
2297
2298 return error;
2299 }
2300
2301 int
mac_mount_check_mount_late(vfs_context_t ctx,struct mount * mp)2302 mac_mount_check_mount_late(vfs_context_t ctx, struct mount *mp)
2303 {
2304 kauth_cred_t cred;
2305 int error;
2306
2307 #if SECURITY_MAC_CHECK_ENFORCE
2308 /* 21167099 - only check if we allow write */
2309 if (!mac_vnode_enforce) {
2310 return 0;
2311 }
2312 #endif
2313 cred = vfs_context_ucred(ctx);
2314 if (!mac_cred_check_enforce(cred)) {
2315 return 0;
2316 }
2317 VFS_KERNEL_DEBUG_START1(78, mp);
2318 MAC_CHECK(mount_check_mount_late, cred, mp);
2319 VFS_KERNEL_DEBUG_END1(78, mp);
2320
2321 return error;
2322 }
2323
2324 int
mac_mount_check_snapshot_create(vfs_context_t ctx,struct mount * mp,const char * name)2325 mac_mount_check_snapshot_create(vfs_context_t ctx, struct mount *mp,
2326 const char *name)
2327 {
2328 kauth_cred_t cred;
2329 int error;
2330
2331 #if SECURITY_MAC_CHECK_ENFORCE
2332 /* 21167099 - only check if we allow write */
2333 if (!mac_vnode_enforce) {
2334 return 0;
2335 }
2336 #endif
2337 cred = vfs_context_ucred(ctx);
2338 if (!mac_cred_check_enforce(cred)) {
2339 return 0;
2340 }
2341 VFS_KERNEL_DEBUG_START1(79, mp);
2342 MAC_CHECK(mount_check_snapshot_create, cred, mp, name);
2343 VFS_KERNEL_DEBUG_END1(79, mp);
2344 return error;
2345 }
2346
2347 int
mac_mount_check_snapshot_delete(vfs_context_t ctx,struct mount * mp,const char * name)2348 mac_mount_check_snapshot_delete(vfs_context_t ctx, struct mount *mp,
2349 const char *name)
2350 {
2351 kauth_cred_t cred;
2352 int error;
2353
2354 #if SECURITY_MAC_CHECK_ENFORCE
2355 /* 21167099 - only check if we allow write */
2356 if (!mac_vnode_enforce) {
2357 return 0;
2358 }
2359 #endif
2360 cred = vfs_context_ucred(ctx);
2361 if (!mac_cred_check_enforce(cred)) {
2362 return 0;
2363 }
2364 VFS_KERNEL_DEBUG_START1(80, mp);
2365 MAC_CHECK(mount_check_snapshot_delete, cred, mp, name);
2366 VFS_KERNEL_DEBUG_END1(80, mp);
2367 return error;
2368 }
2369
2370 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)2371 mac_mount_check_snapshot_mount(vfs_context_t ctx, struct vnode *rvp, struct vnode *vp, struct componentname *cnp,
2372 const char *name, const char *vfc_name)
2373 {
2374 kauth_cred_t cred;
2375 int error;
2376
2377 #if SECURITY_MAC_CHECK_ENFORCE
2378 /* 21167099 - only check if we allow write */
2379 if (!mac_vnode_enforce) {
2380 return 0;
2381 }
2382 #endif
2383 cred = vfs_context_ucred(ctx);
2384 if (!mac_cred_check_enforce(cred)) {
2385 return 0;
2386 }
2387 VFS_KERNEL_DEBUG_START1(92, vp);
2388 MAC_CHECK(mount_check_snapshot_mount, cred, rvp, vp, cnp, name, vfc_name);
2389 VFS_KERNEL_DEBUG_END1(92, vp);
2390 return error;
2391 }
2392
2393 int
mac_mount_check_snapshot_revert(vfs_context_t ctx,struct mount * mp,const char * name)2394 mac_mount_check_snapshot_revert(vfs_context_t ctx, struct mount *mp,
2395 const char *name)
2396 {
2397 kauth_cred_t cred;
2398 int error;
2399
2400 #if SECURITY_MAC_CHECK_ENFORCE
2401 /* 21167099 - only check if we allow write */
2402 if (!mac_vnode_enforce) {
2403 return 0;
2404 }
2405 #endif
2406 cred = vfs_context_ucred(ctx);
2407 if (!mac_cred_check_enforce(cred)) {
2408 return 0;
2409 }
2410 VFS_KERNEL_DEBUG_START1(81, mp);
2411 MAC_CHECK(mount_check_snapshot_revert, cred, mp, name);
2412 VFS_KERNEL_DEBUG_END1(81, mp);
2413 return error;
2414 }
2415
2416 int
mac_mount_check_remount(vfs_context_t ctx,struct mount * mp)2417 mac_mount_check_remount(vfs_context_t ctx, struct mount *mp)
2418 {
2419 kauth_cred_t cred;
2420 int error;
2421
2422 #if SECURITY_MAC_CHECK_ENFORCE
2423 /* 21167099 - only check if we allow write */
2424 if (!mac_vnode_enforce) {
2425 return 0;
2426 }
2427 #endif
2428 cred = vfs_context_ucred(ctx);
2429 if (!mac_cred_check_enforce(cred)) {
2430 return 0;
2431 }
2432 VFS_KERNEL_DEBUG_START1(82, mp);
2433 MAC_CHECK(mount_check_remount, cred, mp, mac_mount_label(mp));
2434 VFS_KERNEL_DEBUG_END1(82, mp);
2435
2436 return error;
2437 }
2438
2439 int
mac_mount_check_umount(vfs_context_t ctx,struct mount * mp)2440 mac_mount_check_umount(vfs_context_t ctx, struct mount *mp)
2441 {
2442 kauth_cred_t cred;
2443 int error;
2444
2445 #if SECURITY_MAC_CHECK_ENFORCE
2446 /* 21167099 - only check if we allow write */
2447 if (!mac_vnode_enforce) {
2448 return 0;
2449 }
2450 #endif
2451 cred = vfs_context_ucred(ctx);
2452 if (!mac_cred_check_enforce(cred)) {
2453 return 0;
2454 }
2455 VFS_KERNEL_DEBUG_START1(83, mp);
2456 MAC_CHECK(mount_check_umount, cred, mp, mac_mount_label(mp));
2457 VFS_KERNEL_DEBUG_END1(83, mp);
2458
2459 return error;
2460 }
2461
2462 int
mac_mount_check_getattr(vfs_context_t ctx,struct mount * mp,struct vfs_attr * vfa)2463 mac_mount_check_getattr(vfs_context_t ctx, struct mount *mp,
2464 struct vfs_attr *vfa)
2465 {
2466 kauth_cred_t cred;
2467 int error;
2468
2469 #if SECURITY_MAC_CHECK_ENFORCE
2470 /* 21167099 - only check if we allow write */
2471 if (!mac_vnode_enforce) {
2472 return 0;
2473 }
2474 #endif
2475 cred = vfs_context_ucred(ctx);
2476 if (!mac_cred_check_enforce(cred)) {
2477 return 0;
2478 }
2479 VFS_KERNEL_DEBUG_START1(84, mp);
2480 MAC_CHECK(mount_check_getattr, cred, mp, mac_mount_label(mp), vfa);
2481 VFS_KERNEL_DEBUG_END1(84, mp);
2482 return error;
2483 }
2484
2485 int
mac_mount_check_setattr(vfs_context_t ctx,struct mount * mp,struct vfs_attr * vfa)2486 mac_mount_check_setattr(vfs_context_t ctx, struct mount *mp,
2487 struct vfs_attr *vfa)
2488 {
2489 kauth_cred_t cred;
2490 int error;
2491
2492 #if SECURITY_MAC_CHECK_ENFORCE
2493 /* 21167099 - only check if we allow write */
2494 if (!mac_vnode_enforce) {
2495 return 0;
2496 }
2497 #endif
2498 cred = vfs_context_ucred(ctx);
2499 if (!mac_cred_check_enforce(cred)) {
2500 return 0;
2501 }
2502 VFS_KERNEL_DEBUG_START1(85, mp);
2503 MAC_CHECK(mount_check_setattr, cred, mp, mac_mount_label(mp), vfa);
2504 VFS_KERNEL_DEBUG_END1(85, mp);
2505 return error;
2506 }
2507
2508 int
mac_mount_check_stat(vfs_context_t ctx,struct mount * mount)2509 mac_mount_check_stat(vfs_context_t ctx, struct mount *mount)
2510 {
2511 kauth_cred_t cred;
2512 int error;
2513
2514 #if SECURITY_MAC_CHECK_ENFORCE
2515 /* 21167099 - only check if we allow write */
2516 if (!mac_vnode_enforce) {
2517 return 0;
2518 }
2519 #endif
2520 cred = vfs_context_ucred(ctx);
2521 if (!mac_cred_check_enforce(cred)) {
2522 return 0;
2523 }
2524 VFS_KERNEL_DEBUG_START1(86, mount);
2525 MAC_CHECK(mount_check_stat, cred, mount, mac_mount_label(mount));
2526 VFS_KERNEL_DEBUG_END1(86, mount);
2527
2528 return error;
2529 }
2530
2531 int
mac_mount_check_label_update(vfs_context_t ctx,struct mount * mount)2532 mac_mount_check_label_update(vfs_context_t ctx, struct mount *mount)
2533 {
2534 kauth_cred_t cred;
2535 int error;
2536
2537 #if SECURITY_MAC_CHECK_ENFORCE
2538 /* 21167099 - only check if we allow write */
2539 if (!mac_vnode_enforce) {
2540 return 0;
2541 }
2542 #endif
2543 cred = vfs_context_ucred(ctx);
2544 if (!mac_cred_check_enforce(cred)) {
2545 return 0;
2546 }
2547 VFS_KERNEL_DEBUG_START1(87, mount);
2548 MAC_CHECK(mount_check_label_update, cred, mount, mac_mount_label(mount));
2549 VFS_KERNEL_DEBUG_END1(87, mount);
2550
2551 return error;
2552 }
2553
2554 int
mac_mount_check_fsctl(vfs_context_t ctx,struct mount * mp,u_long cmd)2555 mac_mount_check_fsctl(vfs_context_t ctx, struct mount *mp, u_long cmd)
2556 {
2557 kauth_cred_t cred;
2558 int error;
2559
2560 #if SECURITY_MAC_CHECK_ENFORCE
2561 /* 21167099 - only check if we allow write */
2562 if (!mac_vnode_enforce) {
2563 return 0;
2564 }
2565 #endif
2566 cred = vfs_context_ucred(ctx);
2567 if (!mac_cred_check_enforce(cred)) {
2568 return 0;
2569 }
2570 VFS_KERNEL_DEBUG_START1(88, mp);
2571 MAC_CHECK(mount_check_fsctl, cred, mp, mac_mount_label(mp), cmd);
2572 VFS_KERNEL_DEBUG_END1(88, mp);
2573
2574 return error;
2575 }
2576
2577 void
mac_devfs_label_associate_device(dev_t dev,struct devnode * de,const char * fullpath)2578 mac_devfs_label_associate_device(dev_t dev, struct devnode *de,
2579 const char *fullpath)
2580 {
2581 #if SECURITY_MAC_CHECK_ENFORCE
2582 /* 21167099 - only check if we allow write */
2583 if (!mac_device_enforce) {
2584 return;
2585 }
2586 #endif
2587
2588 VFS_KERNEL_DEBUG_START1(89, de);
2589 MAC_PERFORM(devfs_label_associate_device, dev, de, mac_devfs_label(de),
2590 fullpath);
2591 VFS_KERNEL_DEBUG_END1(89, de);
2592 }
2593
2594 void
mac_devfs_label_associate_directory(const char * dirname,int dirnamelen,struct devnode * de,const char * fullpath)2595 mac_devfs_label_associate_directory(const char *dirname, int dirnamelen,
2596 struct devnode *de, const char *fullpath)
2597 {
2598 #if SECURITY_MAC_CHECK_ENFORCE
2599 /* 21167099 - only check if we allow write */
2600 if (!mac_device_enforce) {
2601 return;
2602 }
2603 #endif
2604
2605 VFS_KERNEL_DEBUG_START1(90, de);
2606 MAC_PERFORM(devfs_label_associate_directory, dirname, dirnamelen, de,
2607 mac_devfs_label(de), fullpath);
2608 VFS_KERNEL_DEBUG_END1(90, de);
2609 }
2610
2611 int
vn_setlabel(struct vnode * vp,struct label * intlabel,vfs_context_t context)2612 vn_setlabel(struct vnode *vp, struct label *intlabel, vfs_context_t context)
2613 {
2614 int error;
2615
2616 #if SECURITY_MAC_CHECK_ENFORCE
2617 /* 21167099 - only check if we allow write */
2618 if (!mac_vnode_enforce) {
2619 return 0;
2620 }
2621 #endif
2622 if (!mac_label_vnodes) {
2623 return 0;
2624 }
2625
2626 if (vp->v_mount == NULL) {
2627 printf("vn_setlabel: null v_mount\n");
2628 if (vp->v_type != VNON) {
2629 printf("vn_setlabel: null v_mount with non-VNON\n");
2630 }
2631 return EBADF;
2632 }
2633
2634 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
2635 return ENOTSUP;
2636 }
2637
2638 /*
2639 * Multi-phase commit. First check the policies to confirm the
2640 * change is OK. Then commit via the filesystem. Finally,
2641 * update the actual vnode label. Question: maybe the filesystem
2642 * should update the vnode at the end as part of VNOP_SETLABEL()?
2643 */
2644 error = mac_vnode_check_label_update(context, vp, intlabel);
2645 if (error) {
2646 return error;
2647 }
2648
2649 error = VNOP_SETLABEL(vp, intlabel, context);
2650 if (error == ENOTSUP) {
2651 error = mac_vnode_label_store(context, vp,
2652 intlabel);
2653 if (error) {
2654 printf("%s: mac_vnode_label_store failed %d\n",
2655 __func__, error);
2656 return error;
2657 }
2658 mac_vnode_label_update(context, vp, intlabel);
2659 } else if (error) {
2660 printf("vn_setlabel: vop setlabel failed %d\n", error);
2661 return error;
2662 }
2663
2664 return 0;
2665 }
2666
2667 int
mac_vnode_label_associate_fdesc(struct mount * mp,struct fdescnode * fnp,struct vnode * vp,vfs_context_t ctx)2668 mac_vnode_label_associate_fdesc(struct mount *mp, struct fdescnode *fnp,
2669 struct vnode *vp, vfs_context_t ctx)
2670 {
2671 struct fileproc *fp;
2672 #if CONFIG_MACF_SOCKET_SUBSET
2673 struct socket *so;
2674 #endif
2675 struct pipe *cpipe;
2676 struct vnode *fvp;
2677 struct proc *p;
2678 int error;
2679
2680 error = 0;
2681
2682 VFS_KERNEL_DEBUG_START1(91, vp);
2683 /*
2684 * If no backing file, let the policy choose which label to use.
2685 */
2686 if (fnp->fd_fd == -1) {
2687 MAC_PERFORM(vnode_label_associate_file, vfs_context_ucred(ctx),
2688 mp, mac_mount_label(mp), NULL, NULL, vp, mac_vnode_label(vp));
2689 VFS_KERNEL_DEBUG_END1(91, vp);
2690 return 0;
2691 }
2692
2693 p = vfs_context_proc(ctx);
2694 error = fp_lookup(p, fnp->fd_fd, &fp, 0);
2695 if (error) {
2696 VFS_KERNEL_DEBUG_END1(91, vp);
2697 return error;
2698 }
2699
2700 if (fp->fp_glob == NULL) {
2701 error = EBADF;
2702 goto out;
2703 }
2704
2705 switch (FILEGLOB_DTYPE(fp->fp_glob)) {
2706 case DTYPE_VNODE:
2707 fvp = (struct vnode *)fp_get_data(fp);
2708 if ((error = vnode_getwithref(fvp))) {
2709 goto out;
2710 }
2711 if (mac_vnode_label(fvp) != NULL) {
2712 if (mac_label_vnodes != 0 && mac_vnode_label(vp) == NULL) {
2713 mac_vnode_label_init(vp); /* init dst label */
2714 }
2715 MAC_PERFORM(vnode_label_copy, mac_vnode_label(fvp), mac_vnode_label(vp));
2716 }
2717 (void)vnode_put(fvp);
2718 break;
2719 #if CONFIG_MACF_SOCKET_SUBSET
2720 case DTYPE_SOCKET:
2721 so = (struct socket *)fp_get_data(fp);
2722 socket_lock(so, 1);
2723 MAC_PERFORM(vnode_label_associate_socket,
2724 vfs_context_ucred(ctx), (socket_t)so, NULL,
2725 vp, mac_vnode_label(vp));
2726 socket_unlock(so, 1);
2727 break;
2728 #endif
2729 case DTYPE_PSXSHM:
2730 pshm_label_associate(fp, vp, ctx);
2731 break;
2732 case DTYPE_PSXSEM:
2733 psem_label_associate(fp, vp, ctx);
2734 break;
2735 case DTYPE_PIPE:
2736 cpipe = (struct pipe *)fp_get_data(fp);
2737 /* kern/sys_pipe.c:pipe_select() suggests this test. */
2738 if (cpipe == (struct pipe *)-1) {
2739 error = EINVAL;
2740 goto out;
2741 }
2742 PIPE_LOCK(cpipe);
2743 MAC_PERFORM(vnode_label_associate_pipe, vfs_context_ucred(ctx),
2744 cpipe, mac_pipe_label(cpipe), vp, mac_vnode_label(vp));
2745 PIPE_UNLOCK(cpipe);
2746 break;
2747 case DTYPE_KQUEUE:
2748 case DTYPE_FSEVENTS:
2749 case DTYPE_ATALK:
2750 case DTYPE_NETPOLICY:
2751 case DTYPE_CHANNEL:
2752 case DTYPE_NEXUS:
2753 default:
2754 MAC_PERFORM(vnode_label_associate_file, vfs_context_ucred(ctx),
2755 mp, mac_mount_label(mp), fp->fp_glob, NULL,
2756 vp, mac_vnode_label(vp));
2757 break;
2758 }
2759 out:
2760 VFS_KERNEL_DEBUG_END1(91, vp);
2761 fp_drop(p, fnp->fd_fd, fp, 0);
2762 return error;
2763 }
2764
2765 intptr_t
mac_vnode_label_get(struct vnode * vp,int slot,intptr_t sentinel)2766 mac_vnode_label_get(struct vnode *vp, int slot, intptr_t sentinel)
2767 {
2768 struct label *l;
2769
2770 KASSERT(vp != NULL, ("mac_vnode_label_get: NULL vnode"));
2771 l = mac_vnode_label(vp);
2772 if (l != NULL) {
2773 return mac_label_get(l, slot);
2774 } else {
2775 return sentinel;
2776 }
2777 }
2778
2779 void
mac_vnode_label_set(struct vnode * vp,int slot,intptr_t v)2780 mac_vnode_label_set(struct vnode *vp, int slot, intptr_t v)
2781 {
2782 struct label *l;
2783 KASSERT(vp != NULL, ("mac_vnode_label_set: NULL vnode"));
2784 l = mac_vnode_label(vp);
2785 if (l == NULL) {
2786 mac_vnode_label_init(vp);
2787 l = mac_vnode_label(vp);
2788 }
2789 mac_label_set(l, slot, v);
2790 }
2791
2792 void
mac_vnode_notify_reclaim(struct vnode * vp)2793 mac_vnode_notify_reclaim(struct vnode *vp)
2794 {
2795 VFS_KERNEL_DEBUG_START1(94, vp);
2796 MAC_PERFORM(vnode_notify_reclaim, vp);
2797 VFS_KERNEL_DEBUG_END1(94, vp);
2798 }
2799
2800 int
mac_mount_check_quotactl(vfs_context_t ctx,struct mount * mp,int cmd,int id)2801 mac_mount_check_quotactl(vfs_context_t ctx, struct mount *mp, int cmd, int id)
2802 {
2803 kauth_cred_t cred;
2804 int error;
2805
2806 #if SECURITY_MAC_CHECK_ENFORCE
2807 /* 21167099 - only check if we allow write */
2808 if (!mac_vnode_enforce) {
2809 return 0;
2810 }
2811 #endif
2812 cred = vfs_context_ucred(ctx);
2813 if (!mac_cred_check_enforce(cred)) {
2814 return 0;
2815 }
2816 VFS_KERNEL_DEBUG_START1(95, mp);
2817 MAC_CHECK(mount_check_quotactl, cred, mp, cmd, id);
2818 VFS_KERNEL_DEBUG_END1(95, mp);
2819
2820 return error;
2821 }
2822
2823 int
mac_vnode_check_getattrlistbulk(vfs_context_t ctx,struct vnode * vp,struct attrlist * alist,uint64_t options)2824 mac_vnode_check_getattrlistbulk(vfs_context_t ctx, struct vnode *vp, struct attrlist *alist, uint64_t options)
2825 {
2826 kauth_cred_t cred;
2827 int error;
2828
2829 #if SECURITY_MAC_CHECK_ENFORCE
2830 /* 21167099 - only check if we allow write */
2831 if (!mac_vnode_enforce) {
2832 return 0;
2833 }
2834 #endif
2835 cred = vfs_context_ucred(ctx);
2836 if (!mac_cred_check_enforce(cred)) {
2837 return 0;
2838 }
2839 VFS_KERNEL_DEBUG_START1(96, mp);
2840 MAC_CHECK(vnode_check_getattrlistbulk, cred, vp, alist, options);
2841 VFS_KERNEL_DEBUG_END1(96, mp);
2842
2843 return error;
2844 }
2845
2846 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)2847 mac_vnode_check_copyfile(vfs_context_t ctx, struct vnode *dvp,
2848 struct vnode *tvp, struct vnode *fvp, struct componentname *cnp,
2849 mode_t mode, int flags)
2850 {
2851 kauth_cred_t cred;
2852 int error;
2853
2854 #if SECURITY_MAC_CHECK_ENFORCE
2855 /* 21167099 - only check if we allow write */
2856 if (!mac_vnode_enforce) {
2857 return 0;
2858 }
2859 #endif
2860 cred = vfs_context_ucred(ctx);
2861 if (!mac_cred_check_enforce(cred)) {
2862 return 0;
2863 }
2864 VFS_KERNEL_DEBUG_START1(97, dvp);
2865 MAC_CHECK(vnode_check_copyfile, cred, dvp, mac_vnode_label(dvp),
2866 tvp, tvp ? mac_vnode_label(tvp) : NULL, fvp, mac_vnode_label(fvp), cnp, mode, flags);
2867 VFS_KERNEL_DEBUG_END1(97, dvp);
2868 return error;
2869 }
2870