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