]> git.saurik.com Git - apple/xnu.git/blame - security/mac_vfs.c
xnu-3248.50.21.tar.gz
[apple/xnu.git] / security / mac_vfs.c
CommitLineData
2d21ac55
A
1/*
2 * Copyright (c) 2007 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28/*-
29 * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
30 * Copyright (c) 2001 Ilmar S. Habibulin
31 * Copyright (c) 2001, 2002, 2003, 2004 Networks Associates Technology, Inc.
32 * Copyright (c) 2005 SPARTA, Inc.
33 *
34 * This software was developed by Robert Watson and Ilmar Habibulin for the
35 * TrustedBSD Project.
36 *
37 * This software was developed for the FreeBSD Project in part by Network
38 * Associates Laboratories, the Security Research Division of Network
39 * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
40 * as part of the DARPA CHATS research program.
41 *
42 * Redistribution and use in source and binary forms, with or without
43 * modification, are permitted provided that the following conditions
44 * are met:
45 * 1. Redistributions of source code must retain the above copyright
46 * notice, this list of conditions and the following disclaimer.
47 * 2. Redistributions in binary form must reproduce the above copyright
48 * notice, this list of conditions and the following disclaimer in the
49 * documentation and/or other materials provided with the distribution.
50 *
51 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
52 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
53 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
54 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
55 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
57 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
59 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
60 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
61 * SUCH DAMAGE.
62 *
63 */
64
65#include <sys/param.h>
66#include <sys/systm.h>
67#include <sys/kernel.h>
68#include <sys/proc.h>
69#include <sys/kauth.h>
70
71#include <sys/file_internal.h>
72#include <sys/imgact.h>
73#include <sys/namei.h>
74#include <sys/mount_internal.h>
75#include <sys/pipe.h>
76#include <sys/posix_sem.h>
77#include <sys/posix_shm.h>
78#include <sys/uio_internal.h>
79#include <sys/vnode_internal.h>
80
81#include <miscfs/devfs/devfsdefs.h>
b0d623f7 82#include <miscfs/devfs/fdesc.h>
2d21ac55
A
83
84#include <security/mac_internal.h>
85
86/* convert {R,W,X}_OK values to V{READ,WRITE,EXEC} */
87#define ACCESS_MODE_TO_VNODE_MASK(m) (m << 6)
88
89static struct label *
90mac_devfsdirent_label_alloc(void)
91{
92 struct label *label;
93
94 label = mac_labelzone_alloc(MAC_WAITOK);
95 if (label == NULL)
96 return (NULL);
97 MAC_PERFORM(devfs_label_init, label);
98 return (label);
99}
100
101void
102mac_devfs_label_init(struct devnode *de)
103{
104
105 de->dn_label = mac_devfsdirent_label_alloc();
106}
107
108static struct label *
109mac_mount_label_alloc(void)
110{
111 struct label *label;
112
113 label = mac_labelzone_alloc(MAC_WAITOK);
114 if (label == NULL)
115 return (NULL);
116 MAC_PERFORM(mount_label_init, label);
117 return (label);
118}
119
120void
121mac_mount_label_init(struct mount *mp)
122{
123
124 mp->mnt_mntlabel = mac_mount_label_alloc();
125}
126
127struct label *
128mac_vnode_label_alloc(void)
129{
130 struct label *label;
131
132 label = mac_labelzone_alloc(MAC_WAITOK);
133 if (label == NULL)
134 return (NULL);
135 MAC_PERFORM(vnode_label_init, label);
136 return (label);
137}
138
139void
140mac_vnode_label_init(vnode_t vp)
141{
2d21ac55
A
142 vp->v_label = mac_vnode_label_alloc();
143}
144
b0d623f7
A
145int
146mac_vnode_label_init_needed(vnode_t vp)
147{
148 return (mac_label_vnodes != 0 && vp->v_label == NULL);
149}
150
2d21ac55
A
151/*
152 * vnode labels are allocated at the same time as vnodes, but vnodes are never
153 * freed. Instead, we want to remove any sensitive information before putting
154 * them on the free list for reuse.
155*/
156void
157mac_vnode_label_recycle(vnode_t vp)
158{
159
160 MAC_PERFORM(vnode_label_recycle, vp->v_label);
161}
162
163static void
164mac_devfs_label_free(struct label *label)
165{
166 MAC_PERFORM(devfs_label_destroy, label);
167 mac_labelzone_free(label);
168}
169
170void
171mac_devfs_label_destroy(struct devnode *de)
172{
173 if (de->dn_label != NULL) {
174 mac_devfs_label_free(de->dn_label);
175 de->dn_label = NULL;
176 }
177}
178
179static void
180mac_mount_label_free(struct label *label)
181{
182
183 MAC_PERFORM(mount_label_destroy, label);
184 mac_labelzone_free(label);
185}
186
187void
188mac_mount_label_destroy(struct mount *mp)
189{
2d21ac55
A
190 if (mp->mnt_mntlabel != NULL) {
191 mac_mount_label_free(mp->mnt_mntlabel);
192 mp->mnt_mntlabel = NULL;
193 }
194}
195
196void
197mac_vnode_label_free(struct label *label)
198{
2d21ac55
A
199 MAC_PERFORM(vnode_label_destroy, label);
200 mac_labelzone_free(label);
201}
202
203#ifndef __APPLE__
204void
205mac_vnode_label_destroy(struct vnode *vp)
206{
b0d623f7
A
207 if (vp->v_label != NULL) {
208 mac_vnode_label_free(vp->v_label);
209 vp->v_label = NULL;
210 }
2d21ac55
A
211}
212#endif
213
214void
215mac_vnode_label_copy(struct label *src, struct label *dest)
216{
b0d623f7
A
217 if (src == NULL) {
218 MAC_PERFORM(vnode_label_init, dest);
219 } else {
220 MAC_PERFORM(vnode_label_copy, src, dest);
221 }
2d21ac55
A
222}
223
224int
225mac_vnode_label_externalize_audit(struct vnode *vp, struct mac *mac)
226{
227 int error;
228
229 /* It is assumed that any necessary vnode locking is done on entry */
230 error = MAC_EXTERNALIZE_AUDIT(vnode, vp->v_label,
231 mac->m_string, mac->m_buflen);
232
233 return (error);
234}
235
236int
237mac_vnode_label_externalize(struct label *label, char *elements,
238 char *outbuf, size_t outbuflen, int flags __unused)
239{
240 int error;
241
242 error = MAC_EXTERNALIZE(vnode, label, elements, outbuf, outbuflen);
243
244 return (error);
245}
246
247int
248mac_vnode_label_internalize(struct label *label, char *string)
249{
250 int error;
251
252 error = MAC_INTERNALIZE(vnode, label, string);
253
254 return (error);
255}
256
257int
258mac_mount_label_internalize(struct label *label, char *string)
259{
260 int error;
261
262 error = MAC_INTERNALIZE(mount, label, string);
263
264 return (error);
265}
266
267int
268mac_mount_label_externalize(struct label *label, char *elements,
269 char *outbuf, size_t outbuflen)
270{
271 int error;
272
273 error = MAC_EXTERNALIZE(mount, label, elements, outbuf, outbuflen);
274
275 return (error);
276}
277
278void
279mac_devfs_label_copy(struct label *src, struct label *dest)
280{
3e170ce0
A
281#if SECURITY_MAC_CHECK_ENFORCE
282 /* 21167099 - only check if we allow write */
283 if (!mac_device_enforce)
284 return;
285#endif
2d21ac55
A
286
287 MAC_PERFORM(devfs_label_copy, src, dest);
288}
289
290void
291mac_devfs_label_update(struct mount *mp, struct devnode *de,
292 struct vnode *vp)
293{
3e170ce0
A
294#if SECURITY_MAC_CHECK_ENFORCE
295 /* 21167099 - only check if we allow write */
296 if (!mac_device_enforce)
297 return;
298#endif
2d21ac55
A
299
300 MAC_PERFORM(devfs_label_update, mp, de, de->dn_label, vp,
301 vp->v_label);
302}
303
304int
305mac_vnode_label_associate(struct mount *mp, struct vnode *vp, vfs_context_t ctx)
306{
307 struct devnode *dnp;
308 struct fdescnode *fnp;
309 int error = 0;
310
3e170ce0
A
311#if SECURITY_MAC_CHECK_ENFORCE
312 /* 21167099 - only check if we allow write */
313 if (!mac_vnode_enforce)
314 return (error);
315#endif
2d21ac55
A
316
317 /* XXX: should not inspect v_tag in kernel! */
318 switch (vp->v_tag) {
319 case VT_DEVFS:
320 dnp = VTODN(vp);
321 mac_vnode_label_associate_devfs(mp, dnp, vp);
322 break;
323 case VT_FDESC:
324 fnp = VTOFDESC(vp);
325 error = mac_vnode_label_associate_fdesc(mp, fnp, vp, ctx);
326 break;
327 default:
328 error = mac_vnode_label_associate_extattr(mp, vp);
329 break;
330 }
331
332 return (error);
333}
334
335void
336mac_vnode_label_associate_devfs(struct mount *mp, struct devnode *de,
337 struct vnode *vp)
338{
3e170ce0
A
339#if SECURITY_MAC_CHECK_ENFORCE
340 /* 21167099 - only check if we allow write */
341 if (!mac_device_enforce)
342 return;
343#endif
2d21ac55
A
344
345 MAC_PERFORM(vnode_label_associate_devfs,
346 mp, mp ? mp->mnt_mntlabel : NULL,
347 de, de->dn_label,
348 vp, vp->v_label);
349}
350
351int
352mac_vnode_label_associate_extattr(struct mount *mp, struct vnode *vp)
353{
354 int error;
355
356 MAC_CHECK(vnode_label_associate_extattr, mp, mp->mnt_mntlabel, vp,
357 vp->v_label);
358
359 return (error);
360}
361
362void
363mac_vnode_label_associate_singlelabel(struct mount *mp, struct vnode *vp)
364{
3e170ce0
A
365#if SECURITY_MAC_CHECK_ENFORCE
366 /* 21167099 - only check if we allow write */
367 if (!mac_vnode_enforce)
368 return;
369#endif
370 if (!mac_label_vnodes)
2d21ac55
A
371 return;
372
373 MAC_PERFORM(vnode_label_associate_singlelabel, mp,
374 mp ? mp->mnt_mntlabel : NULL, vp, vp->v_label);
375}
376
377int
378mac_vnode_notify_create(vfs_context_t ctx, struct mount *mp,
379 struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
380{
381 kauth_cred_t cred;
382 int error;
383
3e170ce0
A
384#if SECURITY_MAC_CHECK_ENFORCE
385 /* 21167099 - only check if we allow write */
386 if (!mac_vnode_enforce)
387 return (0);
388#endif
389 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
2d21ac55
A
390 return (0);
391
392 cred = vfs_context_ucred(ctx);
393 MAC_CHECK(vnode_notify_create, cred, mp, mp->mnt_mntlabel,
394 dvp, dvp->v_label, vp, vp->v_label, cnp);
395
396 return (error);
397}
398
6d2010ae
A
399void
400mac_vnode_notify_rename(vfs_context_t ctx, struct vnode *vp,
401 struct vnode *dvp, struct componentname *cnp)
402{
403 kauth_cred_t cred;
404
3e170ce0
A
405#if SECURITY_MAC_CHECK_ENFORCE
406 /* 21167099 - only check if we allow write */
407 if (!mac_vnode_enforce)
408 return;
409#endif
410 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
411 return;
6d2010ae
A
412
413 cred = vfs_context_ucred(ctx);
414 MAC_PERFORM(vnode_notify_rename, cred, vp, vp->v_label,
415 dvp, dvp->v_label, cnp);
416}
417
4b17d6b6
A
418void
419mac_vnode_notify_open(vfs_context_t ctx, struct vnode *vp, int acc_flags)
420{
421 kauth_cred_t cred;
422
3e170ce0
A
423#if SECURITY_MAC_CHECK_ENFORCE
424 /* 21167099 - only check if we allow write */
425 if (!mac_vnode_enforce)
426 return;
427#endif
428 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
429 return;
4b17d6b6
A
430
431 cred = vfs_context_ucred(ctx);
432 MAC_PERFORM(vnode_notify_open, cred, vp, vp->v_label, acc_flags);
433}
434
39236c6e
A
435void
436mac_vnode_notify_link(vfs_context_t ctx, struct vnode *vp,
437 struct vnode *dvp, struct componentname *cnp)
438{
439 kauth_cred_t cred;
440
3e170ce0
A
441#if SECURITY_MAC_CHECK_ENFORCE
442 /* 21167099 - only check if we allow write */
443 if (!mac_vnode_enforce)
444 return;
445#endif
446 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
447 return;
39236c6e
A
448
449 cred = vfs_context_ucred(ctx);
450 MAC_PERFORM(vnode_notify_link, cred, dvp, dvp->v_label, vp, vp->v_label, cnp);
451}
452
2d21ac55
A
453/*
454 * Extended attribute 'name' was updated via
455 * vn_setxattr() or vn_removexattr(). Allow the
456 * policy to update the vnode label.
457 */
458void
459mac_vnode_label_update_extattr(struct mount *mp, struct vnode *vp,
460 const char *name)
461{
462 int error = 0;
463
3e170ce0
A
464#if SECURITY_MAC_CHECK_ENFORCE
465 /* 21167099 - only check if we allow write */
466 if (!mac_vnode_enforce)
467 return;
468#endif
469 if (!mac_label_vnodes)
2d21ac55
A
470 return;
471
472 MAC_PERFORM(vnode_label_update_extattr, mp, mp->mnt_mntlabel, vp,
473 vp->v_label, name);
474 if (error == 0)
475 return;
476
477 vnode_lock(vp);
478 vnode_relabel(vp);
479 vnode_unlock(vp);
480 return;
481}
482
483static int
484mac_vnode_label_store(vfs_context_t ctx, struct vnode *vp,
485 struct label *intlabel)
486{
487 kauth_cred_t cred;
488 int error;
489
3e170ce0
A
490#if SECURITY_MAC_CHECK_ENFORCE
491 /* 21167099 - only check if we allow write */
492 if (!mac_vnode_enforce)
493 return 0;
494#endif
495 if (!mac_label_vnodes ||
2d21ac55
A
496 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
497 return 0;
498
499 cred = vfs_context_ucred(ctx);
500 MAC_CHECK(vnode_label_store, cred, vp, vp->v_label, intlabel);
501
502 return (error);
503}
504
fe8ab488
A
505void
506mac_cred_label_update_execve(vfs_context_t ctx, kauth_cred_t new, struct vnode *vp, off_t offset,
507 struct vnode *scriptvp, struct label *scriptvnodelabel, struct label *execl, u_int *csflags,
508 void *macextensions, int *disjoint, int *labelupdateerror)
2d21ac55
A
509{
510 kauth_cred_t cred;
fe8ab488
A
511 *disjoint = 0;
512 int error;
6d2010ae 513 posix_cred_t pcred = posix_cred_get(new);
2d21ac55 514
3e170ce0
A
515#if SECURITY_MAC_CHECK_ENFORCE
516 /* 21167099 - only check if we allow write */
517 if (!mac_proc_enforce || !mac_vnode_enforce)
518 return;
519#endif
2d21ac55
A
520
521 /* mark the new cred to indicate "matching" includes the label */
6d2010ae 522 pcred->cr_flags |= CRF_MAC_ENFORCE;
2d21ac55
A
523
524 cred = vfs_context_ucred(ctx);
39236c6e
A
525
526 /*
fe8ab488 527 * NB: Cannot use MAC_CHECK macro because we need a sequence point after
39236c6e
A
528 * calling exec_spawnattr_getmacpolicyinfo() and before passing the
529 * spawnattrlen as an argument to the hook.
530 */
531 {
532 struct mac_policy_conf *mpc;
533 u_int i;
534
fe8ab488 535 error = 0;
39236c6e
A
536 for (i = 0; i< mac_policy_list.staticmax; i++) {
537 mpc = mac_policy_list.entries[i].mpc;
538 if (mpc == NULL)
539 continue;
540
541 mpo_cred_label_update_execve_t *hook = mpc->mpc_ops->mpo_cred_label_update_execve;
542 if (hook == NULL)
543 continue;
544
545 size_t spawnattrlen = 0;
546 void *spawnattr = exec_spawnattr_getmacpolicyinfo(macextensions, mpc->mpc_name, &spawnattrlen);
547
fe8ab488
A
548 error = mac_error_select(hook(cred, new, vfs_context_proc(ctx), vp, offset, scriptvp,
549 vp->v_label, scriptvnodelabel, execl, csflags, spawnattr, spawnattrlen, disjoint),
550 error);
39236c6e
A
551 }
552 if (mac_policy_list_conditional_busy() != 0) {
553 for (; i <= mac_policy_list.maxindex; i++) {
554 mpc = mac_policy_list.entries[i].mpc;
555 if (mpc == NULL)
556 continue;
557
558 mpo_cred_label_update_execve_t *hook = mpc->mpc_ops->mpo_cred_label_update_execve;
559 if (hook == NULL)
560 continue;
561
562 size_t spawnattrlen = 0;
563 void *spawnattr = exec_spawnattr_getmacpolicyinfo(macextensions, mpc->mpc_name, &spawnattrlen);
564
fe8ab488
A
565 error = mac_error_select(hook(cred, new, vfs_context_proc(ctx), vp, offset, scriptvp,
566 vp->v_label, scriptvnodelabel, execl, csflags, spawnattr, spawnattrlen, disjoint),
567 error);
39236c6e
A
568 }
569 mac_policy_list_unbusy();
570 }
571 }
fe8ab488 572 *labelupdateerror = error;
2d21ac55
A
573}
574
575int
fe8ab488 576mac_cred_check_label_update_execve(vfs_context_t ctx, struct vnode *vp, off_t offset,
39236c6e
A
577 struct vnode *scriptvp, struct label *scriptvnodelabel, struct label *execlabel,
578 struct proc *p, void *macextensions)
2d21ac55
A
579{
580 kauth_cred_t cred;
581 int result = 0;
582
3e170ce0
A
583#if SECURITY_MAC_CHECK_ENFORCE
584 /* 21167099 - only check if we allow write */
585 if (!mac_proc_enforce || !mac_vnode_enforce)
586 return result;
587#endif
2d21ac55
A
588
589 cred = vfs_context_ucred(ctx);
39236c6e
A
590
591 /*
592 * NB: Cannot use MAC_BOOLEAN macro because we need a sequence point after
593 * calling exec_spawnattr_getmacpolicyinfo() and before passing the
594 * spawnattrlen as an argument to the hook.
595 */
596 {
597 struct mac_policy_conf *mpc;
598 u_int i;
599
600 for (i = 0; i< mac_policy_list.staticmax; i++) {
601 mpc = mac_policy_list.entries[i].mpc;
602 if (mpc == NULL)
603 continue;
604
605 mpo_cred_check_label_update_execve_t *hook = mpc->mpc_ops->mpo_cred_check_label_update_execve;
606 if (hook == NULL)
607 continue;
608
609 size_t spawnattrlen = 0;
610 void *spawnattr = exec_spawnattr_getmacpolicyinfo(macextensions, mpc->mpc_name, &spawnattrlen);
611
fe8ab488 612 result = result || hook(cred, vp, offset, scriptvp, vp->v_label, scriptvnodelabel, execlabel, p, spawnattr, spawnattrlen);
39236c6e
A
613 }
614 if (mac_policy_list_conditional_busy() != 0) {
615 for (; i <= mac_policy_list.maxindex; i++) {
616 mpc = mac_policy_list.entries[i].mpc;
617 if (mpc == NULL)
618 continue;
619
620 mpo_cred_check_label_update_execve_t *hook = mpc->mpc_ops->mpo_cred_check_label_update_execve;
621 if (hook == NULL)
622 continue;
623
624 size_t spawnattrlen = 0;
625 void *spawnattr = exec_spawnattr_getmacpolicyinfo(macextensions, mpc->mpc_name, &spawnattrlen);
626
fe8ab488 627 result = result || hook(cred, vp, offset, scriptvp, vp->v_label, scriptvnodelabel, execlabel, p, spawnattr, spawnattrlen);
39236c6e
A
628 }
629 mac_policy_list_unbusy();
630 }
631 }
2d21ac55
A
632
633 return (result);
634}
635
636int
637mac_vnode_check_access(vfs_context_t ctx, struct vnode *vp,
638 int acc_mode)
639{
640 kauth_cred_t cred;
641 int error;
642 int mask;
643
3e170ce0
A
644#if SECURITY_MAC_CHECK_ENFORCE
645 /* 21167099 - only check if we allow write */
646 if (!mac_vnode_enforce)
647 return 0;
648#endif
649 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
2d21ac55
A
650 return 0;
651
652 cred = vfs_context_ucred(ctx);
653 /* Convert {R,W,X}_OK values to V{READ,WRITE,EXEC} for entry points */
654 mask = ACCESS_MODE_TO_VNODE_MASK(acc_mode);
655 MAC_CHECK(vnode_check_access, cred, vp, vp->v_label, mask);
656 return (error);
657 }
658
659int
660mac_vnode_check_chdir(vfs_context_t ctx, struct vnode *dvp)
661{
662 kauth_cred_t cred;
663 int error;
664
3e170ce0
A
665#if SECURITY_MAC_CHECK_ENFORCE
666 /* 21167099 - only check if we allow write */
667 if (!mac_vnode_enforce)
668 return 0;
669#endif
670 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
671 return 0;
2d21ac55
A
672
673 cred = vfs_context_ucred(ctx);
674 MAC_CHECK(vnode_check_chdir, cred, dvp, dvp->v_label);
675 return (error);
676}
677
678int
679mac_vnode_check_chroot(vfs_context_t ctx, struct vnode *dvp,
680 struct componentname *cnp)
681{
682 kauth_cred_t cred;
683 int error;
684
3e170ce0
A
685#if SECURITY_MAC_CHECK_ENFORCE
686 /* 21167099 - only check if we allow write */
687 if (!mac_vnode_enforce)
688 return 0;
689#endif
690 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
691 return 0;
2d21ac55
A
692
693 cred = vfs_context_ucred(ctx);
694 MAC_CHECK(vnode_check_chroot, cred, dvp, dvp->v_label, cnp);
695 return (error);
696}
697
698int
699mac_vnode_check_create(vfs_context_t ctx, struct vnode *dvp,
700 struct componentname *cnp, struct vnode_attr *vap)
701{
702 kauth_cred_t cred;
703 int error;
704
3e170ce0
A
705#if SECURITY_MAC_CHECK_ENFORCE
706 /* 21167099 - only check if we allow write */
707 if (!mac_vnode_enforce)
708 return 0;
709#endif
710 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
711 return 0;
2d21ac55
A
712
713 cred = vfs_context_ucred(ctx);
714 MAC_CHECK(vnode_check_create, cred, dvp, dvp->v_label, cnp, vap);
715 return (error);
716}
717
718int
719mac_vnode_check_unlink(vfs_context_t ctx, struct vnode *dvp, struct vnode *vp,
720 struct componentname *cnp)
721{
722 kauth_cred_t cred;
723 int error;
724
3e170ce0
A
725#if SECURITY_MAC_CHECK_ENFORCE
726 /* 21167099 - only check if we allow write */
727 if (!mac_vnode_enforce)
728 return 0;
729#endif
730 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
731 return 0;
2d21ac55
A
732
733 cred = vfs_context_ucred(ctx);
734 MAC_CHECK(vnode_check_unlink, cred, dvp, dvp->v_label, vp,
735 vp->v_label, cnp);
736 return (error);
737}
738#if 0
739int
740mac_vnode_check_deleteacl(vfs_context_t ctx, struct vnode *vp,
741 acl_type_t type)
742{
743 kauth_cred_t cred;
744 int error;
745
3e170ce0
A
746#if SECURITY_MAC_CHECK_ENFORCE
747 /* 21167099 - only check if we allow write */
748 if (!mac_vnode_enforce)
749 return 0;
750#endif
751 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
752 return 0;
2d21ac55
A
753
754 cred = vfs_context_ucred(ctx);
755 MAC_CHECK(vnode_check_deleteacl, cred, vp, vp->v_label, type);
756 return (error);
757}
758#endif
759
760int
761mac_vnode_check_deleteextattr(vfs_context_t ctx, struct vnode *vp,
762 const char *name)
763{
764 kauth_cred_t cred;
765 int error;
766
3e170ce0
A
767#if SECURITY_MAC_CHECK_ENFORCE
768 /* 21167099 - only check if we allow write */
769 if (!mac_vnode_enforce)
770 return 0;
771#endif
772 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
773 return 0;
2d21ac55
A
774
775 cred = vfs_context_ucred(ctx);
776 MAC_CHECK(vnode_check_deleteextattr, cred, vp, vp->v_label, name);
777 return (error);
778}
779int
780mac_vnode_check_exchangedata(vfs_context_t ctx,
781 struct vnode *v1, struct vnode *v2)
782{
783 kauth_cred_t cred;
784 int error;
785
3e170ce0
A
786#if SECURITY_MAC_CHECK_ENFORCE
787 /* 21167099 - only check if we allow write */
788 if (!mac_vnode_enforce)
789 return 0;
790#endif
791 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
792 return 0;
2d21ac55
A
793
794 cred = vfs_context_ucred(ctx);
795 MAC_CHECK(vnode_check_exchangedata, cred, v1, v1->v_label,
796 v2, v2->v_label);
797
798 return (error);
799}
800
801#if 0
802int
803mac_vnode_check_getacl(vfs_context_t ctx, struct vnode *vp, acl_type_t type)
804{
805 kauth_cred_t cred;
806 int error;
807
3e170ce0
A
808#if SECURITY_MAC_CHECK_ENFORCE
809 /* 21167099 - only check if we allow write */
810 if (!mac_vnode_enforce)
811 return 0;
812#endif
813 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
814 return 0;
2d21ac55
A
815
816 cred = vfs_context_ucred(ctx);
817 MAC_CHECK(vnode_check_getacl, cred, vp, vp->v_label, type);
818 return (error);
819}
820#endif
821
822int
823mac_vnode_check_getattrlist(vfs_context_t ctx, struct vnode *vp,
824 struct attrlist *alist)
825{
826 kauth_cred_t cred;
827 int error;
828
3e170ce0
A
829#if SECURITY_MAC_CHECK_ENFORCE
830 /* 21167099 - only check if we allow write */
831 if (!mac_vnode_enforce)
832 return 0;
833#endif
834 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
835 return 0;
2d21ac55
A
836
837 cred = vfs_context_ucred(ctx);
838 MAC_CHECK(vnode_check_getattrlist, cred, vp, vp->v_label, alist);
839
840 /* Falsify results instead of returning error? */
841 return (error);
842}
843
844int
845mac_vnode_check_exec(vfs_context_t ctx, struct vnode *vp,
846 struct image_params *imgp)
847{
848 kauth_cred_t cred;
39236c6e 849 int error = 0;
2d21ac55 850
3e170ce0
A
851#if SECURITY_MAC_CHECK_ENFORCE
852 /* 21167099 - only check if we allow write */
853 if (!mac_proc_enforce || !mac_vnode_enforce)
854 return 0;
855#endif
2d21ac55
A
856
857 cred = vfs_context_ucred(ctx);
39236c6e
A
858
859 /*
860 * NB: Cannot use MAC_CHECK macro because we need a sequence point after
861 * calling exec_spawnattr_getmacpolicyinfo() and before passing the
862 * spawnattrlen as an argument to the hook.
863 */
864 {
865 struct mac_policy_conf *mpc;
866 u_int i;
867
868 for (i = 0; i< mac_policy_list.staticmax; i++) {
869 mpc = mac_policy_list.entries[i].mpc;
870 if (mpc == NULL)
871 continue;
872
873 mpo_vnode_check_exec_t *hook = mpc->mpc_ops->mpo_vnode_check_exec;
874 if (hook == NULL)
875 continue;
876
877 size_t spawnattrlen = 0;
fe8ab488 878 void *spawnattr = exec_spawnattr_getmacpolicyinfo(imgp->ip_px_smpx, mpc->mpc_name, &spawnattrlen);
39236c6e
A
879
880 error = mac_error_select(
fe8ab488
A
881 hook(cred,
882 vp, imgp->ip_scriptvp, vp->v_label, imgp->ip_scriptlabelp,
883 imgp->ip_execlabelp, &imgp->ip_ndp->ni_cnd, &imgp->ip_csflags,
39236c6e
A
884 spawnattr, spawnattrlen), error);
885 }
886 if (mac_policy_list_conditional_busy() != 0) {
887 for (; i <= mac_policy_list.maxindex; i++) {
888 mpc = mac_policy_list.entries[i].mpc;
889 if (mpc == NULL)
890 continue;
891
892 mpo_vnode_check_exec_t *hook = mpc->mpc_ops->mpo_vnode_check_exec;
893 if (hook == NULL)
894 continue;
895
896 size_t spawnattrlen = 0;
fe8ab488 897 void *spawnattr = exec_spawnattr_getmacpolicyinfo(imgp->ip_px_smpx, mpc->mpc_name, &spawnattrlen);
39236c6e
A
898
899 error = mac_error_select(
fe8ab488
A
900 hook(cred,
901 vp, imgp->ip_scriptvp, vp->v_label, imgp->ip_scriptlabelp,
902 imgp->ip_execlabelp, &imgp->ip_ndp->ni_cnd, &imgp->ip_csflags,
39236c6e
A
903 spawnattr, spawnattrlen), error);
904 }
905 mac_policy_list_unbusy();
906 }
907 }
908
2d21ac55
A
909 return (error);
910}
911
6d2010ae
A
912int
913mac_vnode_check_fsgetpath(vfs_context_t ctx, struct vnode *vp)
914{
915 kauth_cred_t cred;
916 int error;
917
3e170ce0
A
918#if SECURITY_MAC_CHECK_ENFORCE
919 /* 21167099 - only check if we allow write */
920 if (!mac_vnode_enforce)
921 return 0;
922#endif
923 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
924 return 0;
6d2010ae
A
925
926 cred = vfs_context_ucred(ctx);
927 MAC_CHECK(vnode_check_fsgetpath, cred, vp, vp->v_label);
928 return (error);
929}
930
593a1d5f 931int
39236c6e
A
932mac_vnode_check_signature(struct vnode *vp, off_t macho_offset,
933 unsigned char *sha1,
fe8ab488 934 const void *signature, size_t size,
c18c124e 935 int flags, int *is_platform_binary)
593a1d5f
A
936{
937 int error;
938
3e170ce0
A
939#if SECURITY_MAC_CHECK_ENFORCE
940 /* 21167099 - only check if we allow write */
941 if (!mac_proc_enforce || !mac_vnode_enforce)
942 return 0;
943#endif
593a1d5f 944
fe8ab488 945 MAC_CHECK(vnode_check_signature, vp, vp->v_label, macho_offset, sha1,
c18c124e
A
946 signature, size,
947 flags, is_platform_binary);
593a1d5f
A
948 return (error);
949}
950
2d21ac55
A
951#if 0
952int
953mac_vnode_check_getacl(vfs_context_t ctx, struct vnode *vp, acl_type_t type)
954{
955 kauth_cred_t cred;
956 int error;
957
3e170ce0
A
958#if SECURITY_MAC_CHECK_ENFORCE
959 /* 21167099 - only check if we allow write */
960 if (!mac_vnode_enforce)
961 return 0;
962#endif
963 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
964 return 0;
2d21ac55
A
965
966 cred = vfs_context_ucred(ctx);
967 MAC_CHECK(vnode_check_getacl, cred, vp, vp->v_label, type);
968 return (error);
969}
970#endif
971
972int
973mac_vnode_check_getextattr(vfs_context_t ctx, struct vnode *vp,
974 const char *name, struct uio *uio)
975{
976 kauth_cred_t cred;
977 int error;
978
3e170ce0
A
979#if SECURITY_MAC_CHECK_ENFORCE
980 /* 21167099 - only check if we allow write */
981 if (!mac_vnode_enforce)
982 return 0;
983#endif
984 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
985 return 0;
2d21ac55
A
986
987 cred = vfs_context_ucred(ctx);
988 MAC_CHECK(vnode_check_getextattr, cred, vp, vp->v_label,
989 name, uio);
990 return (error);
991}
992
993int
994mac_vnode_check_ioctl(vfs_context_t ctx, struct vnode *vp, u_int cmd)
995{
996 kauth_cred_t cred;
997 int error;
998
3e170ce0
A
999#if SECURITY_MAC_CHECK_ENFORCE
1000 /* 21167099 - only check if we allow write */
1001 if (!mac_vnode_enforce)
1002 return 0;
1003#endif
1004 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1005 return 0;
2d21ac55
A
1006
1007 cred = vfs_context_ucred(ctx);
1008 MAC_CHECK(vnode_check_ioctl, cred, vp, vp->v_label, cmd);
1009 return (error);
1010}
1011
1012int
1013mac_vnode_check_kqfilter(vfs_context_t ctx, kauth_cred_t file_cred,
1014 struct knote *kn, struct vnode *vp)
1015{
1016 kauth_cred_t cred;
1017 int error;
1018
3e170ce0
A
1019#if SECURITY_MAC_CHECK_ENFORCE
1020 /* 21167099 - only check if we allow write */
1021 if (!mac_vnode_enforce)
1022 return 0;
1023#endif
1024 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1025 return 0;
2d21ac55
A
1026
1027 cred = vfs_context_ucred(ctx);
1028 MAC_CHECK(vnode_check_kqfilter, cred, file_cred, kn, vp,
1029 vp->v_label);
1030
1031 return (error);
1032}
1033
1034int
1035mac_vnode_check_link(vfs_context_t ctx, struct vnode *dvp,
1036 struct vnode *vp, struct componentname *cnp)
1037{
1038 kauth_cred_t cred;
1039 int error;
1040
3e170ce0
A
1041#if SECURITY_MAC_CHECK_ENFORCE
1042 /* 21167099 - only check if we allow write */
1043 if (!mac_vnode_enforce)
1044 return 0;
1045#endif
1046 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1047 return 0;
2d21ac55
A
1048
1049 cred = vfs_context_ucred(ctx);
1050 MAC_CHECK(vnode_check_link, cred, dvp, dvp->v_label, vp,
1051 vp->v_label, cnp);
1052 return (error);
1053}
1054
1055int
1056mac_vnode_check_listextattr(vfs_context_t ctx, struct vnode *vp)
1057{
1058 kauth_cred_t cred;
1059 int error;
1060
3e170ce0
A
1061#if SECURITY_MAC_CHECK_ENFORCE
1062 /* 21167099 - only check if we allow write */
1063 if (!mac_vnode_enforce)
1064 return 0;
1065#endif
1066 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1067 return 0;
2d21ac55
A
1068
1069 cred = vfs_context_ucred(ctx);
1070 MAC_CHECK(vnode_check_listextattr, cred, vp, vp->v_label);
1071 return (error);
1072}
1073
1074int
1075mac_vnode_check_lookup(vfs_context_t ctx, struct vnode *dvp,
1076 struct componentname *cnp)
1077{
1078 kauth_cred_t cred;
1079 int error;
1080
3e170ce0
A
1081#if SECURITY_MAC_CHECK_ENFORCE
1082 /* 21167099 - only check if we allow write */
1083 if (!mac_vnode_enforce)
1084 return 0;
1085#endif
1086 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1087 return 0;
2d21ac55
A
1088
1089 cred = vfs_context_ucred(ctx);
1090 MAC_CHECK(vnode_check_lookup, cred, dvp, dvp->v_label, cnp);
1091 return (error);
1092}
1093
1094int
1095mac_vnode_check_open(vfs_context_t ctx, struct vnode *vp, int acc_mode)
1096{
1097 kauth_cred_t cred;
1098 int error;
1099
3e170ce0
A
1100#if SECURITY_MAC_CHECK_ENFORCE
1101 /* 21167099 - only check if we allow write */
1102 if (!mac_vnode_enforce)
1103 return 0;
1104#endif
1105 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1106 return 0;
2d21ac55
A
1107
1108 cred = vfs_context_ucred(ctx);
1109 MAC_CHECK(vnode_check_open, cred, vp, vp->v_label, acc_mode);
1110 return (error);
1111}
1112
1113int
1114mac_vnode_check_read(vfs_context_t ctx, struct ucred *file_cred,
1115 struct vnode *vp)
1116{
1117 kauth_cred_t cred;
1118 int error;
1119
3e170ce0
A
1120#if SECURITY_MAC_CHECK_ENFORCE
1121 /* 21167099 - only check if we allow write */
1122 if (!mac_vnode_enforce)
1123 return 0;
1124#endif
1125 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1126 return 0;
2d21ac55
A
1127
1128 cred = vfs_context_ucred(ctx);
1129 MAC_CHECK(vnode_check_read, cred, file_cred, vp,
1130 vp->v_label);
1131
1132 return (error);
1133}
1134
1135int
1136mac_vnode_check_readdir(vfs_context_t ctx, struct vnode *dvp)
1137{
1138 kauth_cred_t cred;
1139 int error;
1140
3e170ce0
A
1141#if SECURITY_MAC_CHECK_ENFORCE
1142 /* 21167099 - only check if we allow write */
1143 if (!mac_vnode_enforce)
1144 return 0;
1145#endif
1146 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1147 return 0;
2d21ac55
A
1148
1149 cred = vfs_context_ucred(ctx);
1150 MAC_CHECK(vnode_check_readdir, cred, dvp, dvp->v_label);
1151 return (error);
1152}
1153
1154int
1155mac_vnode_check_readlink(vfs_context_t ctx, struct vnode *vp)
1156{
1157 kauth_cred_t cred;
1158 int error;
1159
3e170ce0
A
1160#if SECURITY_MAC_CHECK_ENFORCE
1161 /* 21167099 - only check if we allow write */
1162 if (!mac_vnode_enforce)
1163 return 0;
1164#endif
1165 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1166 return 0;
2d21ac55
A
1167
1168 cred = vfs_context_ucred(ctx);
1169 MAC_CHECK(vnode_check_readlink, cred, vp, vp->v_label);
1170 return (error);
1171}
1172
1173int
1174mac_vnode_check_label_update(vfs_context_t ctx, struct vnode *vp,
1175 struct label *newlabel)
1176{
1177 kauth_cred_t cred;
1178 int error;
1179
3e170ce0
A
1180#if SECURITY_MAC_CHECK_ENFORCE
1181 /* 21167099 - only check if we allow write */
1182 if (!mac_vnode_enforce)
1183 return 0;
1184#endif
1185 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1186 return 0;
2d21ac55
A
1187
1188 cred = vfs_context_ucred(ctx);
1189 MAC_CHECK(vnode_check_label_update, cred, vp, vp->v_label, newlabel);
1190
1191 return (error);
1192}
1193
1194int
fe8ab488
A
1195mac_vnode_check_rename(vfs_context_t ctx, struct vnode *dvp,
1196 struct vnode *vp, struct componentname *cnp, struct vnode *tdvp,
1197 struct vnode *tvp, struct componentname *tcnp)
2d21ac55
A
1198{
1199 kauth_cred_t cred;
1200 int error;
1201
3e170ce0
A
1202#if SECURITY_MAC_CHECK_ENFORCE
1203 /* 21167099 - only check if we allow write */
1204 if (!mac_vnode_enforce)
1205 return 0;
1206#endif
1207 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1208 return 0;
2d21ac55
A
1209
1210 cred = vfs_context_ucred(ctx);
fe8ab488 1211
2d21ac55
A
1212 MAC_CHECK(vnode_check_rename_from, cred, dvp, dvp->v_label, vp,
1213 vp->v_label, cnp);
fe8ab488
A
1214 if (error)
1215 return (error);
2d21ac55 1216
fe8ab488
A
1217 MAC_CHECK(vnode_check_rename_to, cred, tdvp, tdvp->v_label, tvp,
1218 tvp != NULL ? tvp->v_label : NULL, dvp == tdvp, tcnp);
1219 if (error)
1220 return (error);
2d21ac55 1221
fe8ab488
A
1222 MAC_CHECK(vnode_check_rename, cred, dvp, dvp->v_label, vp,
1223 vp->v_label, cnp, tdvp, tdvp->v_label, tvp,
1224 tvp != NULL ? tvp->v_label : NULL, tcnp);
2d21ac55
A
1225 return (error);
1226}
1227
1228int
1229mac_vnode_check_revoke(vfs_context_t ctx, struct vnode *vp)
1230{
1231 kauth_cred_t cred;
1232 int error;
1233
3e170ce0
A
1234#if SECURITY_MAC_CHECK_ENFORCE
1235 /* 21167099 - only check if we allow write */
1236 if (!mac_vnode_enforce)
1237 return 0;
1238#endif
1239 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1240 return 0;
2d21ac55
A
1241
1242 cred = vfs_context_ucred(ctx);
1243 MAC_CHECK(vnode_check_revoke, cred, vp, vp->v_label);
1244 return (error);
1245}
1246
6d2010ae
A
1247int
1248mac_vnode_check_searchfs(vfs_context_t ctx, struct vnode *vp, struct attrlist *alist)
1249{
1250 kauth_cred_t cred;
1251 int error;
1252
3e170ce0
A
1253#if SECURITY_MAC_CHECK_ENFORCE
1254 /* 21167099 - only check if we allow write */
1255 if (!mac_vnode_enforce)
1256 return 0;
1257#endif
1258 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1259 return 0;
6d2010ae
A
1260
1261 cred = vfs_context_ucred(ctx);
1262 MAC_CHECK(vnode_check_searchfs, cred, vp, vp->v_label, alist);
1263 return (error);
1264}
1265
2d21ac55
A
1266int
1267mac_vnode_check_select(vfs_context_t ctx, struct vnode *vp, int which)
1268{
1269 kauth_cred_t cred;
1270 int error;
1271
3e170ce0
A
1272#if SECURITY_MAC_CHECK_ENFORCE
1273 /* 21167099 - only check if we allow write */
1274 if (!mac_vnode_enforce)
1275 return 0;
1276#endif
1277 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1278 return 0;
2d21ac55
A
1279
1280 cred = vfs_context_ucred(ctx);
1281 MAC_CHECK(vnode_check_select, cred, vp, vp->v_label, which);
1282 return (error);
1283}
1284
1285#if 0
1286int
1287mac_vnode_check_setacl(vfs_context_t ctx, struct vnode *vp, acl_type_t type,
1288 struct acl *acl)
1289{
1290 kauth_cred_t cred;
1291 int error;
1292
3e170ce0
A
1293#if SECURITY_MAC_CHECK_ENFORCE
1294 /* 21167099 - only check if we allow write */
1295 if (!mac_vnode_enforce)
1296 return 0;
1297#endif
1298 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1299 return 0;
2d21ac55
A
1300
1301 cred = vfs_context_ucred(ctx);
1302 MAC_CHECK(vnode_check_setacl, cred, vp, vp->v_label, type, acl);
1303 return (error);
1304}
1305#endif
1306
1307int
1308mac_vnode_check_setattrlist(vfs_context_t ctx, struct vnode *vp,
1309 struct attrlist *alist)
1310{
1311 kauth_cred_t cred;
1312 int error;
1313
3e170ce0
A
1314#if SECURITY_MAC_CHECK_ENFORCE
1315 /* 21167099 - only check if we allow write */
1316 if (!mac_vnode_enforce)
1317 return 0;
1318#endif
1319 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1320 return 0;
2d21ac55
A
1321
1322 cred = vfs_context_ucred(ctx);
1323 MAC_CHECK(vnode_check_setattrlist, cred, vp, vp->v_label, alist);
1324 return (error);
1325}
1326
1327int
1328mac_vnode_check_setextattr(vfs_context_t ctx, struct vnode *vp,
1329 const char *name, struct uio *uio)
1330{
1331 kauth_cred_t cred;
1332 int error;
1333
3e170ce0
A
1334#if SECURITY_MAC_CHECK_ENFORCE
1335 /* 21167099 - only check if we allow write */
1336 if (!mac_vnode_enforce)
1337 return 0;
1338#endif
1339 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1340 return 0;
2d21ac55
A
1341
1342 cred = vfs_context_ucred(ctx);
1343 MAC_CHECK(vnode_check_setextattr, cred, vp, vp->v_label,
1344 name, uio);
1345 return (error);
1346}
1347
1348int
1349mac_vnode_check_setflags(vfs_context_t ctx, struct vnode *vp, u_long flags)
1350{
1351 kauth_cred_t cred;
1352 int error;
1353
3e170ce0
A
1354#if SECURITY_MAC_CHECK_ENFORCE
1355 /* 21167099 - only check if we allow write */
1356 if (!mac_vnode_enforce)
1357 return 0;
1358#endif
1359 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1360 return 0;
2d21ac55
A
1361
1362 cred = vfs_context_ucred(ctx);
1363 MAC_CHECK(vnode_check_setflags, cred, vp, vp->v_label, flags);
1364 return (error);
1365}
1366
1367int
1368mac_vnode_check_setmode(vfs_context_t ctx, struct vnode *vp, mode_t mode)
1369{
1370 kauth_cred_t cred;
1371 int error;
1372
3e170ce0
A
1373#if SECURITY_MAC_CHECK_ENFORCE
1374 /* 21167099 - only check if we allow write */
1375 if (!mac_vnode_enforce)
1376 return 0;
1377#endif
1378 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1379 return 0;
2d21ac55
A
1380
1381 cred = vfs_context_ucred(ctx);
1382 MAC_CHECK(vnode_check_setmode, cred, vp, vp->v_label, mode);
1383 return (error);
1384}
1385
1386int
1387mac_vnode_check_setowner(vfs_context_t ctx, struct vnode *vp, uid_t uid,
1388 gid_t gid)
1389{
1390 kauth_cred_t cred;
1391 int error;
1392
3e170ce0
A
1393#if SECURITY_MAC_CHECK_ENFORCE
1394 /* 21167099 - only check if we allow write */
1395 if (!mac_vnode_enforce)
1396 return 0;
1397#endif
1398 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1399 return 0;
2d21ac55
A
1400
1401 cred = vfs_context_ucred(ctx);
1402 MAC_CHECK(vnode_check_setowner, cred, vp, vp->v_label, uid, gid);
1403 return (error);
1404}
1405
1406int
1407mac_vnode_check_setutimes(vfs_context_t ctx, struct vnode *vp,
1408 struct timespec atime, struct timespec mtime)
1409{
1410 kauth_cred_t cred;
1411 int error;
1412
3e170ce0
A
1413#if SECURITY_MAC_CHECK_ENFORCE
1414 /* 21167099 - only check if we allow write */
1415 if (!mac_vnode_enforce)
1416 return 0;
1417#endif
1418 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1419 return 0;
2d21ac55
A
1420
1421 cred = vfs_context_ucred(ctx);
1422 MAC_CHECK(vnode_check_setutimes, cred, vp, vp->v_label, atime,
1423 mtime);
1424 return (error);
1425}
1426
1427int
1428mac_vnode_check_stat(vfs_context_t ctx, struct ucred *file_cred,
1429 struct vnode *vp)
1430{
1431 kauth_cred_t cred;
1432 int error;
1433
3e170ce0
A
1434#if SECURITY_MAC_CHECK_ENFORCE
1435 /* 21167099 - only check if we allow write */
1436 if (!mac_vnode_enforce)
1437 return 0;
1438#endif
1439 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1440 return 0;
2d21ac55
A
1441
1442 cred = vfs_context_ucred(ctx);
1443 MAC_CHECK(vnode_check_stat, cred, file_cred, vp,
1444 vp->v_label);
1445 return (error);
1446}
1447
1448int
1449mac_vnode_check_truncate(vfs_context_t ctx, struct ucred *file_cred,
1450 struct vnode *vp)
1451{
1452 kauth_cred_t cred;
1453 int error;
1454
3e170ce0
A
1455#if SECURITY_MAC_CHECK_ENFORCE
1456 /* 21167099 - only check if we allow write */
1457 if (!mac_vnode_enforce)
1458 return 0;
1459#endif
1460 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1461 return 0;
2d21ac55
A
1462
1463 cred = vfs_context_ucred(ctx);
1464 MAC_CHECK(vnode_check_truncate, cred, file_cred, vp,
1465 vp->v_label);
1466
1467 return (error);
1468}
1469
1470int
1471mac_vnode_check_write(vfs_context_t ctx, struct ucred *file_cred,
1472 struct vnode *vp)
1473{
1474 kauth_cred_t cred;
1475 int error;
1476
3e170ce0
A
1477#if SECURITY_MAC_CHECK_ENFORCE
1478 /* 21167099 - only check if we allow write */
1479 if (!mac_vnode_enforce)
1480 return 0;
1481#endif
1482 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1483 return 0;
2d21ac55
A
1484
1485 cred = vfs_context_ucred(ctx);
1486 MAC_CHECK(vnode_check_write, cred, file_cred, vp, vp->v_label);
1487
1488 return (error);
1489}
1490
b0d623f7
A
1491int
1492mac_vnode_check_uipc_bind(vfs_context_t ctx, struct vnode *dvp,
1493 struct componentname *cnp, struct vnode_attr *vap)
1494{
1495 kauth_cred_t cred;
1496 int error;
1497
3e170ce0
A
1498#if SECURITY_MAC_CHECK_ENFORCE
1499 /* 21167099 - only check if we allow write */
1500 if (!mac_vnode_enforce)
1501 return 0;
1502#endif
1503 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1504 return 0;
b0d623f7
A
1505
1506 cred = vfs_context_ucred(ctx);
1507 MAC_CHECK(vnode_check_uipc_bind, cred, dvp, dvp->v_label, cnp, vap);
1508 return (error);
1509}
1510
1511int
1512mac_vnode_check_uipc_connect(vfs_context_t ctx, struct vnode *vp)
1513{
1514 kauth_cred_t cred;
1515 int error;
1516
3e170ce0
A
1517#if SECURITY_MAC_CHECK_ENFORCE
1518 /* 21167099 - only check if we allow write */
1519 if (!mac_vnode_enforce)
1520 return 0;
1521#endif
1522 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1523 return 0;
b0d623f7
A
1524
1525 cred = vfs_context_ucred(ctx);
1526 MAC_CHECK(vnode_check_uipc_connect, cred, vp, vp->v_label);
1527 return (error);
1528}
1529
2d21ac55
A
1530void
1531mac_vnode_label_update(vfs_context_t ctx, struct vnode *vp, struct label *newlabel)
1532{
1533 kauth_cred_t cred = vfs_context_ucred(ctx);
b0d623f7
A
1534 struct label *tmpl = NULL;
1535
1536 if (vp->v_label == NULL)
1537 tmpl = mac_vnode_label_alloc();
2d21ac55
A
1538
1539 vnode_lock(vp);
b0d623f7
A
1540
1541 /* recheck after lock */
1542 if (vp->v_label == NULL) {
1543 vp->v_label = tmpl;
1544 tmpl = NULL;
1545 }
1546
2d21ac55
A
1547 MAC_PERFORM(vnode_label_update, cred, vp, vp->v_label, newlabel);
1548 vnode_unlock(vp);
b0d623f7
A
1549
1550 if (tmpl != NULL)
1551 mac_vnode_label_free(tmpl);
2d21ac55
A
1552}
1553
39236c6e
A
1554int
1555mac_vnode_find_sigs(struct proc *p, struct vnode *vp, off_t offset)
1556{
1557 int error;
1558
3e170ce0
A
1559#if SECURITY_MAC_CHECK_ENFORCE
1560 /* 21167099 - only check if we allow write */
1561 if (!mac_proc_enforce || !mac_vnode_enforce)
1562 return 0;
1563#endif
39236c6e
A
1564
1565 MAC_CHECK(vnode_find_sigs, p, vp, offset, vp->v_label);
1566
1567 return (error);
1568}
1569
2d21ac55
A
1570void
1571mac_mount_label_associate(vfs_context_t ctx, struct mount *mp)
1572{
1573 kauth_cred_t cred = vfs_context_ucred(ctx);
1574
1575 /* XXX: eventually this logic may be handled by the policy? */
1576
1577 /* We desire MULTILABEL for the root filesystem. */
1578 if ((mp->mnt_flag & MNT_ROOTFS) &&
1579 (strcmp(mp->mnt_vfsstat.f_fstypename, "hfs") == 0))
1580 mp->mnt_flag |= MNT_MULTILABEL;
1581
1582 /* MULTILABEL on DEVFS. */
1583 if (strcmp(mp->mnt_vfsstat.f_fstypename, "devfs") == 0)
1584 mp->mnt_flag |= MNT_MULTILABEL;
1585
1586 /* MULTILABEL on FDESC pseudo-filesystem. */
1587 if (strcmp(mp->mnt_vfsstat.f_fstypename, "fdesc") == 0)
1588 mp->mnt_flag |= MNT_MULTILABEL;
1589
1590 /* MULTILABEL on all NFS filesystems. */
1591 if (strcmp(mp->mnt_vfsstat.f_fstypename, "nfs") == 0)
1592 mp->mnt_flag |= MNT_MULTILABEL;
1593
1594 /* MULTILABEL on all AFP filesystems. */
1595 if (strcmp(mp->mnt_vfsstat.f_fstypename, "afpfs") == 0)
1596 mp->mnt_flag |= MNT_MULTILABEL;
1597
1598 if (mp->mnt_vtable != NULL) {
1599 /* Any filesystem that supports native XATTRs. */
1600 if ((mp->mnt_vtable->vfc_vfsflags & VFC_VFSNATIVEXATTR))
1601 mp->mnt_flag |= MNT_MULTILABEL;
1602
1603 /* Filesystem does not support multilabel. */
1604 if ((mp->mnt_vtable->vfc_vfsflags & VFC_VFSNOMACLABEL) &&
1605 (mp->mnt_flag & MNT_MULTILABEL))
1606 mp->mnt_flag &= ~MNT_MULTILABEL;
1607 }
1608
1609 MAC_PERFORM(mount_label_associate, cred, mp, mp->mnt_mntlabel);
316670eb 1610#if DEBUG
2d21ac55
A
1611 printf("MAC Framework enabling %s support: %s -> %s (%s)\n",
1612 mp->mnt_flag & MNT_MULTILABEL ? "multilabel" : "singlelabel",
1613 mp->mnt_vfsstat.f_mntfromname,
1614 mp->mnt_vfsstat.f_mntonname,
1615 mp->mnt_vfsstat.f_fstypename);
1616#endif
1617}
1618
1619int
1620mac_mount_check_mount(vfs_context_t ctx, struct vnode *vp,
1621 struct componentname *cnp, const char *vfc_name)
1622{
1623 kauth_cred_t cred;
1624 int error;
1625
3e170ce0
A
1626#if SECURITY_MAC_CHECK_ENFORCE
1627 /* 21167099 - only check if we allow write */
1628 if (!mac_vnode_enforce)
1629 return 0;
1630#endif
1631 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1632 return 0;
2d21ac55
A
1633
1634 cred = vfs_context_ucred(ctx);
1635 MAC_CHECK(mount_check_mount, cred, vp, vp->v_label, cnp, vfc_name);
1636
1637 return (error);
1638}
1639
1640int
1641mac_mount_check_remount(vfs_context_t ctx, struct mount *mp)
1642{
1643 kauth_cred_t cred;
1644 int error;
1645
3e170ce0
A
1646#if SECURITY_MAC_CHECK_ENFORCE
1647 /* 21167099 - only check if we allow write */
1648 if (!mac_vnode_enforce)
1649 return 0;
1650#endif
1651 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1652 return 0;
2d21ac55
A
1653
1654 cred = vfs_context_ucred(ctx);
1655 MAC_CHECK(mount_check_remount, cred, mp, mp->mnt_mntlabel);
1656
1657 return (error);
1658}
1659
1660int
1661mac_mount_check_umount(vfs_context_t ctx, struct mount *mp)
1662{
1663 kauth_cred_t cred;
1664 int error;
1665
3e170ce0
A
1666#if SECURITY_MAC_CHECK_ENFORCE
1667 /* 21167099 - only check if we allow write */
1668 if (!mac_vnode_enforce)
1669 return 0;
1670#endif
1671 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1672 return 0;
2d21ac55
A
1673
1674 cred = vfs_context_ucred(ctx);
1675 MAC_CHECK(mount_check_umount, cred, mp, mp->mnt_mntlabel);
1676
1677 return (error);
1678}
1679
1680int
1681mac_mount_check_getattr(vfs_context_t ctx, struct mount *mp,
1682 struct vfs_attr *vfa)
1683{
1684 kauth_cred_t cred;
1685 int error;
1686
3e170ce0
A
1687#if SECURITY_MAC_CHECK_ENFORCE
1688 /* 21167099 - only check if we allow write */
1689 if (!mac_vnode_enforce)
1690 return 0;
1691#endif
1692 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1693 return 0;
2d21ac55
A
1694
1695 cred = vfs_context_ucred(ctx);
1696 MAC_CHECK(mount_check_getattr, cred, mp, mp->mnt_mntlabel, vfa);
1697 return (error);
1698}
1699
1700int
1701mac_mount_check_setattr(vfs_context_t ctx, struct mount *mp,
1702 struct vfs_attr *vfa)
1703{
1704 kauth_cred_t cred;
1705 int error;
1706
3e170ce0
A
1707#if SECURITY_MAC_CHECK_ENFORCE
1708 /* 21167099 - only check if we allow write */
1709 if (!mac_vnode_enforce)
1710 return 0;
1711#endif
1712 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1713 return 0;
2d21ac55
A
1714
1715 cred = vfs_context_ucred(ctx);
1716 MAC_CHECK(mount_check_setattr, cred, mp, mp->mnt_mntlabel, vfa);
1717 return (error);
1718}
1719
1720int
1721mac_mount_check_stat(vfs_context_t ctx, struct mount *mount)
1722{
1723 kauth_cred_t cred;
1724 int error;
1725
3e170ce0
A
1726#if SECURITY_MAC_CHECK_ENFORCE
1727 /* 21167099 - only check if we allow write */
1728 if (!mac_vnode_enforce)
1729 return 0;
1730#endif
1731 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1732 return 0;
2d21ac55
A
1733
1734 cred = vfs_context_ucred(ctx);
1735 MAC_CHECK(mount_check_stat, cred, mount, mount->mnt_mntlabel);
1736
1737 return (error);
1738}
1739
1740int
1741mac_mount_check_label_update(vfs_context_t ctx, struct mount *mount)
1742{
1743 kauth_cred_t cred;
1744 int error;
1745
3e170ce0
A
1746#if SECURITY_MAC_CHECK_ENFORCE
1747 /* 21167099 - only check if we allow write */
1748 if (!mac_vnode_enforce)
1749 return 0;
1750#endif
1751 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1752 return 0;
2d21ac55
A
1753
1754 cred = vfs_context_ucred(ctx);
1755 MAC_CHECK(mount_check_label_update, cred, mount, mount->mnt_mntlabel);
1756
1757 return (error);
1758}
1759
1760int
1761mac_mount_check_fsctl(vfs_context_t ctx, struct mount *mp, u_int cmd)
1762{
1763 kauth_cred_t cred;
1764 int error;
1765
3e170ce0
A
1766#if SECURITY_MAC_CHECK_ENFORCE
1767 /* 21167099 - only check if we allow write */
1768 if (!mac_vnode_enforce)
1769 return 0;
1770#endif
1771 if (!mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
1772 return 0;
2d21ac55
A
1773
1774 cred = vfs_context_ucred(ctx);
1775 MAC_CHECK(mount_check_fsctl, cred, mp, mp->mnt_mntlabel, cmd);
1776
1777 return (error);
1778}
1779
1780void
1781mac_devfs_label_associate_device(dev_t dev, struct devnode *de,
1782 const char *fullpath)
1783{
3e170ce0
A
1784#if SECURITY_MAC_CHECK_ENFORCE
1785 /* 21167099 - only check if we allow write */
1786 if (!mac_device_enforce)
1787 return;
1788#endif
2d21ac55
A
1789
1790 MAC_PERFORM(devfs_label_associate_device, dev, de, de->dn_label,
1791 fullpath);
1792}
1793
1794void
1795mac_devfs_label_associate_directory(const char *dirname, int dirnamelen,
1796 struct devnode *de, const char *fullpath)
1797{
3e170ce0
A
1798#if SECURITY_MAC_CHECK_ENFORCE
1799 /* 21167099 - only check if we allow write */
1800 if (!mac_device_enforce)
1801 return;
1802#endif
2d21ac55
A
1803
1804 MAC_PERFORM(devfs_label_associate_directory, dirname, dirnamelen, de,
1805 de->dn_label, fullpath);
1806}
1807
1808int
1809vn_setlabel(struct vnode *vp, struct label *intlabel, vfs_context_t context)
1810{
1811 int error;
1812
3e170ce0
A
1813#if SECURITY_MAC_CHECK_ENFORCE
1814 /* 21167099 - only check if we allow write */
1815 if (!mac_vnode_enforce)
1816 return 0;
1817#endif
1818 if (!mac_label_vnodes)
2d21ac55
A
1819 return (0);
1820
1821 if (vp->v_mount == NULL) {
1822 printf("vn_setlabel: null v_mount\n");
1823 if (vp->v_type != VNON)
1824 printf("vn_setlabel: null v_mount with non-VNON\n");
1825 return (EBADF);
1826 }
1827
1828 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
1829 return (ENOTSUP);
1830
1831 /*
1832 * Multi-phase commit. First check the policies to confirm the
1833 * change is OK. Then commit via the filesystem. Finally,
1834 * update the actual vnode label. Question: maybe the filesystem
1835 * should update the vnode at the end as part of VNOP_SETLABEL()?
1836 */
1837 error = mac_vnode_check_label_update(context, vp, intlabel);
1838 if (error)
1839 return (error);
1840
1841 error = VNOP_SETLABEL(vp, intlabel, context);
1842 if (error == ENOTSUP) {
1843 error = mac_vnode_label_store(context, vp,
1844 intlabel);
1845 if (error) {
1846 printf("%s: mac_vnode_label_store failed %d\n",
1847 __func__, error);
1848 return (error);
1849 }
1850 mac_vnode_label_update(context, vp, intlabel);
1851 } else
1852 if (error) {
1853 printf("vn_setlabel: vop setlabel failed %d\n", error);
1854 return (error);
1855 }
1856
1857 return (0);
1858}
1859
1860int
1861mac_vnode_label_associate_fdesc(struct mount *mp, struct fdescnode *fnp,
1862 struct vnode *vp, vfs_context_t ctx)
1863{
1864 struct fileproc *fp;
39236c6e 1865#if CONFIG_MACF_SOCKET_SUBSET
2d21ac55 1866 struct socket *so;
39236c6e 1867#endif
2d21ac55
A
1868 struct pipe *cpipe;
1869 struct vnode *fvp;
1870 struct proc *p;
1871 int error;
1872
1873 error = 0;
1874
1875 /*
1876 * If no backing file, let the policy choose which label to use.
1877 */
1878 if (fnp->fd_fd == -1) {
1879 MAC_PERFORM(vnode_label_associate_file, vfs_context_ucred(ctx),
1880 mp, mp->mnt_mntlabel, NULL, NULL, vp, vp->v_label);
1881 return (0);
1882 }
1883
1884 p = vfs_context_proc(ctx);
1885 error = fp_lookup(p, fnp->fd_fd, &fp, 0);
1886 if (error)
1887 return (error);
1888
1889 if (fp->f_fglob == NULL) {
1890 error = EBADF;
1891 goto out;
1892 }
1893
39236c6e 1894 switch (FILEGLOB_DTYPE(fp->f_fglob)) {
2d21ac55
A
1895 case DTYPE_VNODE:
1896 fvp = (struct vnode *)fp->f_fglob->fg_data;
1897 if ((error = vnode_getwithref(fvp)))
1898 goto out;
1899 MAC_PERFORM(vnode_label_copy, fvp->v_label, vp->v_label);
1900 (void)vnode_put(fvp);
1901 break;
39236c6e 1902#if CONFIG_MACF_SOCKET_SUBSET
2d21ac55
A
1903 case DTYPE_SOCKET:
1904 so = (struct socket *)fp->f_fglob->fg_data;
1905 socket_lock(so, 1);
1906 MAC_PERFORM(vnode_label_associate_socket,
1907 vfs_context_ucred(ctx), (socket_t)so, so->so_label,
1908 vp, vp->v_label);
1909 socket_unlock(so, 1);
1910 break;
39236c6e 1911#endif
2d21ac55
A
1912 case DTYPE_PSXSHM:
1913 pshm_label_associate(fp, vp, ctx);
1914 break;
1915 case DTYPE_PSXSEM:
1916 psem_label_associate(fp, vp, ctx);
1917 break;
1918 case DTYPE_PIPE:
1919 cpipe = (struct pipe *)fp->f_fglob->fg_data;
1920 /* kern/sys_pipe.c:pipe_select() suggests this test. */
1921 if (cpipe == (struct pipe *)-1) {
1922 error = EINVAL;
1923 goto out;
1924 }
1925 PIPE_LOCK(cpipe);
1926 MAC_PERFORM(vnode_label_associate_pipe, vfs_context_ucred(ctx),
1927 cpipe, cpipe->pipe_label, vp, vp->v_label);
1928 PIPE_UNLOCK(cpipe);
1929 break;
1930 case DTYPE_KQUEUE:
1931 case DTYPE_FSEVENTS:
1932 default:
1933 MAC_PERFORM(vnode_label_associate_file, vfs_context_ucred(ctx),
1934 mp, mp->mnt_mntlabel, fp->f_fglob, fp->f_fglob->fg_label,
1935 vp, vp->v_label);
1936 break;
1937 }
1938out:
1939 fp_drop(p, fnp->fd_fd, fp, 0);
1940 return (error);
1941}