2 * Copyright (c) 2007 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
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-2006 SPARTA, Inc.
34 * This software was developed by Robert Watson and Ilmar Habibulin for the
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.
42 * Redistribution and use in source and binary forms, with or without
43 * modification, are permitted provided that the following conditions
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.
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
66 * Framework for extensible kernel access control. This file contains
67 * Kernel and userland interface to the framework, policy registration
68 * and composition. Per-object interfaces, controls, and labeling may be
69 * found in src/sys/mac/. Sample policies may be found in src/sys/mac*.
74 #include <security/mac_internal.h>
75 #include <security/mac_mach_internal.h>
76 #include <sys/param.h>
77 #include <sys/vnode.h>
78 #include <sys/vnode_internal.h>
79 #include <sys/vfs_context.h>
80 #include <sys/namei.h>
81 #include <bsd/bsm/audit.h>
82 #include <bsd/security/audit/audit.h>
84 #include <sys/file_internal.h>
85 #include <sys/filedesc.h>
87 #include <sys/proc_internal.h>
88 #include <sys/kauth.h>
89 #include <sys/sysproto.h>
91 #include <mach/exception_types.h>
92 #include <mach/vm_types.h>
93 #include <mach/vm_prot.h>
95 #include <kern/zalloc.h>
96 #include <kern/sched_prim.h>
97 #include <osfmk/kern/task.h>
98 #include <osfmk/kern/kalloc.h>
101 #include <security/mac.h>
102 #include <security/mac_policy.h>
103 #include <security/mac_framework.h>
104 #include <security/mac_internal.h>
105 #include <security/mac_mach_internal.h>
110 * define MB_DEBUG to display run-time debugging information
115 #define DPRINTF(x) printf x
122 SYSCTL_NODE(, OID_AUTO
, security
, CTLFLAG_RW
|CTLFLAG_LOCKED
, 0,
123 "Security Controls");
124 SYSCTL_NODE(_security
, OID_AUTO
, mac
, CTLFLAG_RW
|CTLFLAG_LOCKED
, 0,
125 "TrustedBSD MAC policy controls");
128 #define SECURITY_MAC_CTLFLAGS CTLFLAG_RW | CTLFLAG_LOCKED
130 #define SECURITY_MAC_CTLFLAGS CTLFLAG_RD | CTLFLAG_LOCKED
134 * Declare that the kernel provides MAC support, version 1. This permits
135 * modules to refuse to be loaded if the necessary support isn't present,
136 * even if it's pre-boot.
139 MODULE_VERSION(kernel_mac_support
, 1);
142 #if MAC_MAX_SLOTS > 32
143 #error "MAC_MAX_SLOTS too large"
146 static unsigned int mac_max_slots
= MAC_MAX_SLOTS
;
147 static unsigned int mac_slot_offsets_free
= (1 << MAC_MAX_SLOTS
) - 1;
148 SYSCTL_UINT(_security_mac
, OID_AUTO
, max_slots
, CTLFLAG_RD
| CTLFLAG_LOCKED
,
149 &mac_max_slots
, 0, "");
152 * Has the kernel started generating labeled objects yet? All read/write
153 * access to this variable is serialized during the boot process. Following
154 * the end of serialization, we don't update this flag; no locking.
159 * Flag to indicate whether or not we should allocate label storage for
160 * new mbufs. Since most dynamic policies we currently work with don't
161 * rely on mbuf labeling, try to avoid paying the cost of mtag allocation
162 * unless specifically notified of interest. One result of this is
163 * that if a dynamically loaded policy requests mbuf labels, it must
164 * be able to deal with a NULL label being returned on any mbufs that
165 * were already in flight when the policy was loaded. Since the policy
166 * already has to deal with uninitialized labels, this probably won't
167 * be a problem. Note: currently no locking. Will this be a problem?
170 unsigned int mac_label_mbufs
= 1;
171 SYSCTL_UINT(_security_mac
, OID_AUTO
, label_mbufs
, SECURITY_MAC_CTLFLAGS
,
172 &mac_label_mbufs
, 0, "Label all MBUFs");
177 * Flag to indicate whether or not we should allocate label storage for
178 * new vnodes. Since most dynamic policies we currently work with don't
179 * rely on vnode labeling, try to avoid paying the cost of mtag allocation
180 * unless specifically notified of interest. One result of this is
181 * that if a dynamically loaded policy requests vnode labels, it must
182 * be able to deal with a NULL label being returned on any vnodes that
183 * were already in flight when the policy was loaded. Since the policy
184 * already has to deal with uninitialized labels, this probably won't
187 unsigned int mac_label_vnodes
= 0;
188 SYSCTL_UINT(_security_mac
, OID_AUTO
, labelvnodes
, SECURITY_MAC_CTLFLAGS
,
189 &mac_label_vnodes
, 0, "Label all vnodes");
192 unsigned int mac_mmap_revocation
= 0;
193 SYSCTL_UINT(_security_mac
, OID_AUTO
, mmap_revocation
, SECURITY_MAC_CTLFLAGS
,
194 &mac_mmap_revocation
, 0, "Revoke mmap access to files on subject "
197 unsigned int mac_mmap_revocation_via_cow
= 0;
198 SYSCTL_UINT(_security_mac
, OID_AUTO
, mmap_revocation_via_cow
, SECURITY_MAC_CTLFLAGS
,
199 &mac_mmap_revocation_via_cow
, 0, "Revoke mmap access to files via "
200 "copy-on-write semantics, or by removing all write access");
202 unsigned int mac_device_enforce
= 1;
203 SYSCTL_UINT(_security_mac
, OID_AUTO
, device_enforce
, SECURITY_MAC_CTLFLAGS
,
204 &mac_device_enforce
, 0, "Enforce MAC policy on device operations");
206 unsigned int mac_pipe_enforce
= 1;
207 SYSCTL_UINT(_security_mac
, OID_AUTO
, pipe_enforce
, SECURITY_MAC_CTLFLAGS
,
208 &mac_pipe_enforce
, 0, "Enforce MAC policy on pipe operations");
210 unsigned int mac_posixsem_enforce
= 1;
211 SYSCTL_UINT(_security_mac
, OID_AUTO
, posixsem_enforce
, SECURITY_MAC_CTLFLAGS
,
212 &mac_posixsem_enforce
, 0, "Enforce MAC policy on POSIX semaphores");
214 unsigned int mac_posixshm_enforce
= 1;
215 SYSCTL_UINT(_security_mac
, OID_AUTO
, posixshm_enforce
, SECURITY_MAC_CTLFLAGS
,
216 &mac_posixshm_enforce
, 0, "Enforce MAC policy on Posix Shared Memory");
218 unsigned int mac_proc_enforce
= 1;
219 SYSCTL_UINT(_security_mac
, OID_AUTO
, proc_enforce
, SECURITY_MAC_CTLFLAGS
,
220 &mac_proc_enforce
, 0, "Enforce MAC policy on process operations");
222 unsigned int mac_socket_enforce
= 1;
223 SYSCTL_UINT(_security_mac
, OID_AUTO
, socket_enforce
, SECURITY_MAC_CTLFLAGS
,
224 &mac_socket_enforce
, 0, "Enforce MAC policy on socket operations");
226 unsigned int mac_system_enforce
= 1;
227 SYSCTL_UINT(_security_mac
, OID_AUTO
, system_enforce
, SECURITY_MAC_CTLFLAGS
,
228 &mac_system_enforce
, 0, "Enforce MAC policy on system-wide interfaces");
230 unsigned int mac_sysvmsg_enforce
= 1;
231 SYSCTL_UINT(_security_mac
, OID_AUTO
, sysvmsg_enforce
, SECURITY_MAC_CTLFLAGS
,
232 &mac_sysvmsg_enforce
, 0, "Enforce MAC policy on System V IPC message queues");
234 unsigned int mac_sysvsem_enforce
= 1;
235 SYSCTL_UINT(_security_mac
, OID_AUTO
, sysvsem_enforce
, SECURITY_MAC_CTLFLAGS
,
236 &mac_sysvsem_enforce
, 0, "Enforce MAC policy on System V IPC semaphores");
238 unsigned int mac_sysvshm_enforce
= 1;
239 SYSCTL_INT(_security_mac
, OID_AUTO
, sysvshm_enforce
, SECURITY_MAC_CTLFLAGS
,
240 &mac_sysvshm_enforce
, 0, "Enforce MAC policy on System V Shared Memory");
242 unsigned int mac_vm_enforce
= 1;
243 SYSCTL_INT(_security_mac
, OID_AUTO
, vm_enforce
, SECURITY_MAC_CTLFLAGS
,
244 &mac_vm_enforce
, 0, "Enforce MAC policy on VM operations");
246 unsigned int mac_vnode_enforce
= 1;
247 SYSCTL_UINT(_security_mac
, OID_AUTO
, vnode_enforce
, SECURITY_MAC_CTLFLAGS
,
248 &mac_vnode_enforce
, 0, "Enforce MAC policy on vnode operations");
252 * mac_audit_data_zone is the zone used for data pushed into the audit
253 * record by policies. Using a zone simplifies memory management of this
254 * data, and allows tracking of the amount of data in flight.
256 extern zone_t mac_audit_data_zone
;
260 * mac_policy_list holds the list of policy modules. Modules with a
261 * handle lower than staticmax are considered "static" and cannot be
262 * unloaded. Such policies can be invoked without holding the busy count.
264 * Modules with a handle at or above the staticmax high water mark
265 * are considered to be "dynamic" policies. A busy count is maintained
266 * for the list, stored in mac_policy_busy. The busy count is protected
267 * by mac_policy_mtx; the list may be modified only while the busy
268 * count is 0, requiring that the lock be held to prevent new references
269 * to the list from being acquired. For almost all operations,
270 * incrementing the busy count is sufficient to guarantee consistency,
271 * as the list cannot be modified while the busy count is elevated.
272 * For a few special operations involving a change to the list of
273 * active policies, the mtx itself must be held.
275 static lck_mtx_t
*mac_policy_mtx
;
278 * Policy list array allocation chunk size. Trying to set this so that we
279 * allocate a page at a time.
281 #define MAC_POLICY_LIST_CHUNKSIZE 512
283 static int mac_policy_busy
;
285 mac_policy_list_t mac_policy_list
;
288 * mac_label_element_list holds the master list of label namespaces for
289 * all the policies. When a policy is loaded, each of it's label namespace
290 * elements is added to the master list if not already present. When a
291 * policy is unloaded, the namespace elements are removed if no other
292 * policy is interested in that namespace element.
294 struct mac_label_element_list_t mac_label_element_list
;
295 struct mac_label_element_list_t mac_static_label_element_list
;
298 * Journal of label operations that occur before policies are loaded.
300 struct mac_label_journal_list_t mac_label_journal_list
;
303 mac_label_journal_add (struct label
*l
, int type
)
305 struct mac_label_journal
*mlj
;
307 if (mac_label_journal_find(l
))
310 MALLOC(mlj
, struct mac_label_journal
*,
311 sizeof(struct mac_label_journal
), M_MACTEMP
, M_WAITOK
);
314 TAILQ_INSERT_TAIL(&mac_label_journal_list
, mlj
, link
);
320 mac_label_journal_remove (struct label
*l
)
322 struct mac_label_journal
*mlj
;
324 mlj
= mac_label_journal_find(l
);
328 TAILQ_REMOVE(&mac_label_journal_list
, mlj
, link
);
329 FREE(mlj
, M_MACTEMP
);
333 struct mac_label_journal
*
334 mac_label_journal_find (struct label
*l
)
336 struct mac_label_journal
*mlj
;
338 TAILQ_FOREACH(mlj
, &mac_label_journal_list
, link
) {
347 mac_label_journal (struct label
*l
, int op
, ...)
349 struct mac_label_journal
*mlj
;
352 mlj
= mac_label_journal_find(l
);
354 printf("%s(): Label not in list!\n", __func__
);
358 if (op
== MLJ_PORT_OP_UPDATE
) {
360 mlj
->kotype
= va_arg(ap
, int);
369 * The assumption during replay is that the system is totally
370 * serialized and no additional tasks/ports will be created.
373 mac_label_journal_replay (void)
375 struct mac_label_journal
*mlj
;
377 TAILQ_FOREACH(mlj
, &mac_label_journal_list
, link
) {
380 if (mlj
->ops
& MLJ_PORT_OP_INIT
)
381 MAC_PERFORM(port_label_init
, mlj
->l
);
382 if (mlj
->ops
& MLJ_PORT_OP_CREATE_K
)
383 MAC_PERFORM(port_label_associate_kernel
, mlj
->l
, 0);
384 if (mlj
->ops
& MLJ_PORT_OP_UPDATE
)
385 MAC_PERFORM(port_label_update_kobject
, mlj
->l
,
389 if (mlj
->ops
& MLJ_TASK_OP_INIT
)
390 MAC_PERFORM(task_label_init
, mlj
->l
);
392 /* Not enough context to replay. */
393 if (mlj
->ops
& MLJ_TASK_OP_CREATE_K
)
403 while (!TAILQ_EMPTY(&mac_label_journal_list
)) {
404 mlj
= TAILQ_FIRST(&mac_label_journal_list
);
405 TAILQ_REMOVE(&mac_label_journal_list
, mlj
, link
);
406 FREE(mlj
, M_MACTEMP
);
412 mac_policy_grab_exclusive(void)
414 lck_mtx_lock(mac_policy_mtx
);
415 while (mac_policy_busy
!= 0) {
416 lck_mtx_sleep(mac_policy_mtx
, LCK_SLEEP_UNLOCK
,
417 (event_t
)&mac_policy_busy
, THREAD_UNINT
);
418 lck_mtx_lock(mac_policy_mtx
);
423 mac_policy_assert_exclusive(void)
425 lck_mtx_assert(mac_policy_mtx
, LCK_MTX_ASSERT_OWNED
);
426 KASSERT(mac_policy_busy
== 0,
427 ("mac_policy_assert_exclusive(): not exclusive"));
431 mac_policy_release_exclusive(void)
434 KASSERT(mac_policy_busy
== 0,
435 ("mac_policy_release_exclusive(): not exclusive"));
436 lck_mtx_unlock(mac_policy_mtx
);
437 thread_wakeup((event_t
) &mac_policy_busy
);
441 mac_policy_list_busy(void)
443 lck_mtx_lock(mac_policy_mtx
);
445 lck_mtx_unlock(mac_policy_mtx
);
449 mac_policy_list_conditional_busy(void)
453 if (mac_policy_list
.numloaded
<= mac_policy_list
.staticmax
)
456 lck_mtx_lock(mac_policy_mtx
);
457 if (mac_policy_list
.numloaded
> mac_policy_list
.staticmax
) {
462 lck_mtx_unlock(mac_policy_mtx
);
467 mac_policy_list_unbusy(void)
469 lck_mtx_lock(mac_policy_mtx
);
471 KASSERT(mac_policy_busy
>= 0, ("MAC_POLICY_LIST_LOCK"));
472 if (mac_policy_busy
== 0)
473 thread_wakeup(&mac_policy_busy
);
474 lck_mtx_unlock(mac_policy_mtx
);
478 * Early pre-malloc MAC initialization, including appropriate SMP locks.
481 mac_policy_init(void)
483 lck_grp_attr_t
*mac_lck_grp_attr
;
484 lck_attr_t
*mac_lck_attr
;
485 lck_grp_t
*mac_lck_grp
;
487 mac_policy_list
.numloaded
= 0;
488 mac_policy_list
.max
= MAC_POLICY_LIST_CHUNKSIZE
;
489 mac_policy_list
.maxindex
= 0;
490 mac_policy_list
.staticmax
= 0;
491 mac_policy_list
.freehint
= 0;
492 mac_policy_list
.chunks
= 1;
494 mac_policy_list
.entries
= kalloc(sizeof(struct mac_policy_list_element
) * MAC_POLICY_LIST_CHUNKSIZE
);
495 bzero(mac_policy_list
.entries
, sizeof(struct mac_policy_list_element
) * MAC_POLICY_LIST_CHUNKSIZE
);
497 LIST_INIT(&mac_label_element_list
);
498 LIST_INIT(&mac_static_label_element_list
);
499 TAILQ_INIT(&mac_label_journal_list
);
501 mac_lck_grp_attr
= lck_grp_attr_alloc_init();
502 lck_grp_attr_setstat(mac_lck_grp_attr
);
503 mac_lck_grp
= lck_grp_alloc_init("MAC lock", mac_lck_grp_attr
);
504 mac_lck_attr
= lck_attr_alloc_init();
505 lck_attr_setdefault(mac_lck_attr
);
506 mac_policy_mtx
= lck_mtx_alloc_init(mac_lck_grp
, mac_lck_attr
);
507 lck_attr_free(mac_lck_attr
);
508 lck_grp_attr_free(mac_lck_grp_attr
);
509 lck_grp_free(mac_lck_grp
);
511 mac_labelzone_init();
514 /* Function pointer set up for loading security extensions.
515 * It is set to an actual function after OSlibkernInit()
516 * has been called, and is set back to 0 by OSKextRemoveKextBootstrap()
519 void (*load_security_extensions_function
)(void) = 0;
522 * Init after early Mach startup, but before BSD
525 mac_policy_initmach(void)
529 * For the purposes of modules that want to know if they were
530 * loaded "early", set the mac_late flag once we've processed
531 * modules either linked into the kernel, or loaded before the
535 if (load_security_extensions_function
) {
536 load_security_extensions_function();
540 mac_label_journal_replay();
548 mac_policy_initbsd(void)
550 struct mac_policy_conf
*mpc
;
554 mac_audit_data_zone
= zinit(MAC_AUDIT_DATA_LIMIT
,
555 AQ_HIWATER
* MAC_AUDIT_DATA_LIMIT
,
556 8192, "mac_audit_data_zone");
559 printf("MAC Framework successfully initialized\n");
561 /* Call bsd init functions of already loaded policies */
564 * Using the exclusive lock means no other framework entry
565 * points can proceed while initializations are running.
566 * This may not be necessary.
568 mac_policy_grab_exclusive();
570 for (i
= 0; i
<= mac_policy_list
.maxindex
; i
++) {
571 mpc
= mac_get_mpc(i
);
572 if ((mpc
!= NULL
) && (mpc
->mpc_ops
->mpo_policy_initbsd
!= NULL
))
573 (*(mpc
->mpc_ops
->mpo_policy_initbsd
))(mpc
);
576 mac_policy_release_exclusive();
580 * After a policy has been loaded, add the label namespaces managed by the
581 * policy to either the static or non-static label namespace list.
582 * A namespace is added to the the list only if it is not already on one of
586 mac_policy_addto_labellist(mac_policy_handle_t handle
, int static_entry
)
588 struct mac_label_listener
**new_mlls
;
589 struct mac_label_element
*mle
, **new_mles
;
590 struct mac_label_element_list_t
*list
;
591 struct mac_policy_conf
*mpc
;
592 const char *name
, *name2
;
593 u_int idx
, mle_free
, mll_free
;
595 mpc
= mac_get_mpc(handle
);
597 if (mpc
->mpc_labelnames
== NULL
)
600 if (mpc
->mpc_labelname_count
== 0)
604 list
= &mac_static_label_element_list
;
606 list
= &mac_label_element_list
;
609 * Before we grab the policy list lock, allocate enough memory
610 * to contain the potential new elements so we don't have to
611 * give up the lock, or allocate with the lock held.
613 MALLOC(new_mles
, struct mac_label_element
**,
614 sizeof(struct mac_label_element
*) *
615 mpc
->mpc_labelname_count
, M_MACTEMP
, M_WAITOK
| M_ZERO
);
616 for (idx
= 0; idx
< mpc
->mpc_labelname_count
; idx
++)
617 MALLOC(new_mles
[idx
], struct mac_label_element
*,
618 sizeof(struct mac_label_element
),
619 M_MACTEMP
, M_WAITOK
);
621 MALLOC(new_mlls
, struct mac_label_listener
**,
622 sizeof(struct mac_label_listener
*) *
623 mpc
->mpc_labelname_count
, M_MACTEMP
, M_WAITOK
);
624 for (idx
= 0; idx
< mpc
->mpc_labelname_count
; idx
++)
625 MALLOC(new_mlls
[idx
], struct mac_label_listener
*,
626 sizeof(struct mac_label_listener
), M_MACTEMP
, M_WAITOK
);
630 mac_policy_grab_exclusive();
631 for (idx
= 0; idx
< mpc
->mpc_labelname_count
; idx
++) {
633 if (*(name
= mpc
->mpc_labelnames
[idx
]) == '?')
636 * Check both label element lists and add to the
637 * appropriate list only if not already on a list.
639 LIST_FOREACH(mle
, &mac_static_label_element_list
, mle_list
) {
640 if (*(name2
= mle
->mle_name
) == '?')
642 if (strcmp(name
, name2
) == 0)
646 LIST_FOREACH(mle
, &mac_label_element_list
, mle_list
) {
647 if (*(name2
= mle
->mle_name
) == '?')
649 if (strcmp(name
, name2
) == 0)
654 mle
= new_mles
[mle_free
];
655 strlcpy(mle
->mle_name
, mpc
->mpc_labelnames
[idx
],
656 MAC_MAX_LABEL_ELEMENT_NAME
);
657 LIST_INIT(&mle
->mle_listeners
);
658 LIST_INSERT_HEAD(list
, mle
, mle_list
);
661 /* Add policy handler as a listener. */
662 new_mlls
[mll_free
]->mll_handle
= handle
;
663 LIST_INSERT_HEAD(&mle
->mle_listeners
, new_mlls
[mll_free
],
668 mac_policy_release_exclusive();
670 /* Free up any unused label elements and listeners */
671 for (idx
= mle_free
; idx
< mpc
->mpc_labelname_count
; idx
++)
672 FREE(new_mles
[idx
], M_MACTEMP
);
673 FREE(new_mles
, M_MACTEMP
);
674 for (idx
= mll_free
; idx
< mpc
->mpc_labelname_count
; idx
++)
675 FREE(new_mlls
[idx
], M_MACTEMP
);
676 FREE(new_mlls
, M_MACTEMP
);
680 * After a policy has been unloaded, remove the label namespaces that the
681 * the policy manages from the non-static list of namespaces.
682 * The removal only takes place when no other policy is interested in the
685 * Must be called with the policy exclusive lock held.
688 mac_policy_removefrom_labellist(mac_policy_handle_t handle
)
690 struct mac_label_listener
*mll
;
691 struct mac_label_element
*mle
;
692 struct mac_policy_conf
*mpc
;
694 mpc
= mac_get_mpc(handle
);
696 if (mpc
->mpc_labelnames
== NULL
)
699 if (mpc
->mpc_labelname_count
== 0)
703 * Unregister policy as being interested in any label
704 * namespaces. If no other policy is listening, remove
705 * that label element from the list. Note that we only
706 * have to worry about the non-static list.
708 LIST_FOREACH(mle
, &mac_label_element_list
, mle_list
) {
709 LIST_FOREACH(mll
, &mle
->mle_listeners
, mll_list
) {
710 if (mll
->mll_handle
== handle
) {
711 LIST_REMOVE(mll
, mll_list
);
712 FREE(mll
, M_MACTEMP
);
713 if (LIST_EMPTY(&mle
->mle_listeners
)) {
714 LIST_REMOVE(mle
, mle_list
);
715 FREE(mle
, M_MACTEMP
);
724 * After the policy list has changed, walk the list to update any global
728 mac_policy_updateflags(void)
733 mac_policy_fixup_mmd_list(struct mac_module_data
*new)
735 struct mac_module_data
*old
;
736 struct mac_module_data_element
*ele
, *aele
;
737 struct mac_module_data_list
*arr
, *dict
;
738 unsigned int i
, j
, k
;
740 old
= new->base_addr
;
741 DPRINTF(("fixup_mmd: old %p new %p\n", old
, new));
742 for (i
= 0; i
< new->count
; i
++) {
743 ele
= &(new->data
[i
]);
744 DPRINTF(("fixup_mmd: ele %p\n", ele
));
745 DPRINTF((" key %p value %p\n", ele
->key
, ele
->value
));
746 mmd_fixup_ele(old
, new, ele
); /* Fix up key/value ptrs. */
747 DPRINTF((" key %p value %p\n", ele
->key
, ele
->value
));
748 if (ele
->value_type
== MAC_DATA_TYPE_ARRAY
) {
749 arr
= (struct mac_module_data_list
*)ele
->value
;
750 DPRINTF(("fixup_mmd: array @%p\n", arr
));
751 for (j
= 0; j
< arr
->count
; j
++) {
752 aele
= &(arr
->list
[j
]);
753 DPRINTF(("fixup_mmd: aele %p\n", aele
));
754 DPRINTF((" key %p value %p\n", aele
->key
, aele
->value
));
755 mmd_fixup_ele(old
, new, aele
);
756 DPRINTF((" key %p value %p\n", aele
->key
, aele
->value
));
757 if (arr
->type
== MAC_DATA_TYPE_DICT
) {
758 dict
= (struct mac_module_data_list
*)aele
->value
;
759 DPRINTF(("fixup_mmd: dict @%p\n", dict
));
760 for (k
= 0; k
< dict
->count
; k
++)
761 mmd_fixup_ele(old
, new,
767 new->base_addr
= new;
771 mac_policy_register(struct mac_policy_conf
*mpc
, mac_policy_handle_t
*handlep
,
774 struct mac_policy_list_element
*tmac_policy_list_element
;
775 int error
, slot
, static_entry
= 0;
779 * Some preliminary checks to make sure the policy's conf structure
780 * contains the required fields.
782 if (mpc
->mpc_name
== NULL
)
783 panic("policy's name is not set\n");
785 if (mpc
->mpc_fullname
== NULL
)
786 panic("policy's full name is not set\n");
788 if (mpc
->mpc_labelname_count
> MAC_MAX_MANAGED_NAMESPACES
)
789 panic("policy's managed label namespaces exceeds maximum\n");
791 if (mpc
->mpc_ops
== NULL
)
792 panic("policy's OPs field is NULL\n");
797 if (mpc
->mpc_loadtime_flags
& MPC_LOADTIME_FLAG_NOTLATE
) {
798 printf("Module %s does not support late loading.\n",
802 mac_policy_grab_exclusive();
805 if (mac_policy_list
.numloaded
>= mac_policy_list
.max
) {
806 /* allocate new policy list array, zero new chunk */
807 tmac_policy_list_element
=
808 kalloc((sizeof(struct mac_policy_list_element
) *
809 MAC_POLICY_LIST_CHUNKSIZE
) * (mac_policy_list
.chunks
+ 1));
810 bzero(&tmac_policy_list_element
[mac_policy_list
.max
],
811 sizeof(struct mac_policy_list_element
) *
812 MAC_POLICY_LIST_CHUNKSIZE
);
814 /* copy old entries into new list */
815 memcpy(tmac_policy_list_element
, mac_policy_list
.entries
,
816 sizeof(struct mac_policy_list_element
) *
817 MAC_POLICY_LIST_CHUNKSIZE
* mac_policy_list
.chunks
);
820 kfree(mac_policy_list
.entries
,
821 sizeof(struct mac_policy_list_element
) *
822 MAC_POLICY_LIST_CHUNKSIZE
* mac_policy_list
.chunks
);
824 mac_policy_list
.entries
= tmac_policy_list_element
;
826 /* Update maximums, etc */
827 mac_policy_list
.max
+= MAC_POLICY_LIST_CHUNKSIZE
;
828 mac_policy_list
.chunks
++;
831 /* Check for policy with same name already loaded */
832 for (i
= 0; i
<= mac_policy_list
.maxindex
; i
++) {
833 if (mac_policy_list
.entries
[i
].mpc
== NULL
)
836 if (strcmp(mac_policy_list
.entries
[i
].mpc
->mpc_name
,
837 mpc
->mpc_name
) == 0) {
843 if (mpc
->mpc_field_off
!= NULL
) {
844 slot
= ffs(mac_slot_offsets_free
);
850 mac_slot_offsets_free
&= ~(1 << slot
);
851 *mpc
->mpc_field_off
= slot
;
853 mpc
->mpc_runtime_flags
|= MPC_RUNTIME_FLAG_REGISTERED
;
856 struct mac_module_data
*mmd
= xd
; /* module data from plist */
858 /* Make a copy of the data. */
859 mpc
->mpc_data
= (void *)kalloc(mmd
->size
);
860 if (mpc
->mpc_data
!= NULL
) {
861 memcpy(mpc
->mpc_data
, mmd
, mmd
->size
);
863 /* Fix up pointers after copy. */
864 mac_policy_fixup_mmd_list(mpc
->mpc_data
);
868 /* Find the first free handle in the list (using our hint). */
869 for (i
= mac_policy_list
.freehint
; i
< mac_policy_list
.max
; i
++) {
870 if (mac_policy_list
.entries
[i
].mpc
== NULL
) {
872 mac_policy_list
.freehint
= ++i
;
878 * If we are loading a MAC module before the framework has
879 * finished initializing or the module is not unloadable and
880 * we can place its handle adjacent to the last static entry,
881 * bump the static policy high water mark.
882 * Static policies can get by with weaker locking requirements.
885 ((mpc
->mpc_loadtime_flags
& MPC_LOADTIME_FLAG_UNLOADOK
) == 0 &&
886 *handlep
== mac_policy_list
.staticmax
)) {
888 mac_policy_list
.staticmax
++;
891 mac_policy_list
.entries
[*handlep
].mpc
= mpc
;
893 /* Update counters, etc */
894 if (*handlep
> mac_policy_list
.maxindex
)
895 mac_policy_list
.maxindex
= *handlep
;
896 mac_policy_list
.numloaded
++;
898 /* Per-policy initialization. */
899 printf ("calling mpo_policy_init for %s\n", mpc
->mpc_name
);
900 if (mpc
->mpc_ops
->mpo_policy_init
!= NULL
)
901 (*(mpc
->mpc_ops
->mpo_policy_init
))(mpc
);
903 if (mac_late
&& mpc
->mpc_ops
->mpo_policy_initbsd
!= NULL
) {
904 printf ("calling mpo_policy_initbsd for %s\n", mpc
->mpc_name
);
905 (*(mpc
->mpc_ops
->mpo_policy_initbsd
))(mpc
);
908 mac_policy_updateflags();
911 mac_policy_release_exclusive();
913 mac_policy_addto_labellist(*handlep
, static_entry
);
915 printf("Security policy loaded: %s (%s)\n", mpc
->mpc_fullname
,
922 mac_policy_release_exclusive();
928 mac_policy_unregister(mac_policy_handle_t handle
)
930 struct mac_policy_conf
*mpc
;
933 * If we fail the load, we may get a request to unload. Check
934 * to see if we did the run-time registration, and if not,
937 mac_policy_grab_exclusive();
938 mpc
= mac_get_mpc(handle
);
939 if ((mpc
->mpc_runtime_flags
& MPC_RUNTIME_FLAG_REGISTERED
) == 0) {
940 mac_policy_release_exclusive();
946 * Don't allow unloading modules with private data.
948 if (mpc
->mpc_field_off
!= NULL
) {
949 MAC_POLICY_LIST_UNLOCK();
954 * Only allow the unload to proceed if the module is unloadable
955 * by its own definition.
957 if ((mpc
->mpc_loadtime_flags
& MPC_LOADTIME_FLAG_UNLOADOK
) == 0) {
958 mac_policy_release_exclusive();
962 mac_policy_removefrom_labellist(handle
);
964 mac_get_mpc(handle
) = NULL
;
965 if (handle
< mac_policy_list
.freehint
&&
966 handle
>= mac_policy_list
.staticmax
)
967 mac_policy_list
.freehint
= handle
;
969 if (handle
== mac_policy_list
.maxindex
)
970 mac_policy_list
.maxindex
--;
972 mac_policy_list
.numloaded
--;
973 if (mpc
->mpc_field_off
!= NULL
) {
974 mac_slot_offsets_free
|= (1 << *mpc
->mpc_field_off
);
977 if (mpc
->mpc_ops
->mpo_policy_destroy
!= NULL
)
978 (*(mpc
->mpc_ops
->mpo_policy_destroy
))(mpc
);
980 mpc
->mpc_runtime_flags
&= ~MPC_RUNTIME_FLAG_REGISTERED
;
981 mac_policy_updateflags();
983 mac_policy_release_exclusive();
986 struct mac_module_data
*mmd
= mpc
->mpc_data
;
987 kfree(mmd
, mmd
->size
);
988 mpc
->mpc_data
= NULL
;
991 printf("Security policy unload: %s (%s)\n", mpc
->mpc_fullname
,
998 * Define an error value precedence, and given two arguments, selects the
999 * value with the higher precedence.
1002 mac_error_select(int error1
, int error2
)
1005 /* Certain decision-making errors take top priority. */
1006 if (error1
== EDEADLK
|| error2
== EDEADLK
)
1009 /* Invalid arguments should be reported where possible. */
1010 if (error1
== EINVAL
|| error2
== EINVAL
)
1013 /* Precedence goes to "visibility", with both process and file. */
1014 if (error1
== ESRCH
|| error2
== ESRCH
)
1017 if (error1
== ENOENT
|| error2
== ENOENT
)
1020 /* Precedence goes to DAC/MAC protections. */
1021 if (error1
== EACCES
|| error2
== EACCES
)
1024 /* Precedence goes to privilege. */
1025 if (error1
== EPERM
|| error2
== EPERM
)
1028 /* Precedence goes to error over success; otherwise, arbitrary. */
1035 mac_label_init(struct label
*label
)
1038 bzero(label
, sizeof(*label
));
1039 label
->l_flags
= MAC_FLAG_INITIALIZED
;
1043 mac_label_destroy(struct label
*label
)
1046 KASSERT(label
->l_flags
& MAC_FLAG_INITIALIZED
,
1047 ("destroying uninitialized label"));
1049 bzero(label
, sizeof(*label
));
1050 /* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */
1054 mac_port_check_service (struct label
*subj
, struct label
*obj
,
1055 const char *s
, const char *p
)
1059 MAC_CHECK(port_check_service
, subj
, obj
, s
, p
);
1064 mac_port_label_compute(struct label
*subj
, struct label
*obj
,
1065 const char *s
, struct label
*out
)
1069 MAC_CHECK(port_label_compute
, subj
, obj
, s
, out
);
1074 mac_check_structmac_consistent(struct user_mac
*mac
)
1077 if (mac
->m_buflen
> MAC_MAX_LABEL_BUF_LEN
|| mac
->m_buflen
== 0)
1084 * Get the external forms of labels from all policies, for a single
1085 * label namespace or "*" for all namespaces. Returns ENOENT if no policy
1086 * is registered for the namespace, unless the namespace begins with a '?'.
1089 mac_label_externalize(size_t mpo_externalize_off
, struct label
*label
,
1090 const char *element
, struct sbuf
*sb
)
1092 struct mac_policy_conf
*mpc
;
1093 struct mac_label_listener
*mll
;
1094 struct mac_label_element
*mle
;
1095 struct mac_label_element_list_t
*element_list
;
1097 int (*mpo_externalize
)(struct label
*, char *, struct sbuf
*);
1098 int all_labels
= 0, ignorenotfound
= 0, error
= 0, busy
= FALSE
;
1099 unsigned int count
= 0;
1101 if (element
[0] == '?') {
1104 } else if (element
[0] == '*' && element
[1] == '\0')
1107 element_list
= &mac_static_label_element_list
;
1109 LIST_FOREACH(mle
, element_list
, mle_list
) {
1110 name
= mle
->mle_name
;
1117 if (strcmp(name
, element
) != 0)
1120 LIST_FOREACH(mll
, &mle
->mle_listeners
, mll_list
) {
1121 mpc
= mac_policy_list
.entries
[mll
->mll_handle
].mpc
;
1124 mpo_externalize
= *(typeof(mpo_externalize
) *)
1125 ((char *)mpc
->mpc_ops
+ mpo_externalize_off
);
1126 if (mpo_externalize
== NULL
)
1128 error
= sbuf_printf(sb
, "%s/", name
);
1131 error
= mpo_externalize(label
, mle
->mle_name
, sb
);
1133 if (error
!= ENOENT
)
1136 * If a policy doesn't have a label to
1137 * externalize it returns ENOENT. This
1138 * may occur for policies that support
1139 * multiple label elements for some
1140 * (but not all) object types.
1142 sbuf_setpos(sb
, sbuf_len(sb
) -
1143 (strlen(name
) + 1));
1147 error
= sbuf_putc(sb
, ',');
1153 /* If there are dynamic policies present, check their elements too. */
1154 if (!busy
&& mac_policy_list_conditional_busy() == 1) {
1155 element_list
= &mac_label_element_list
;
1161 mac_policy_list_unbusy();
1162 if (!error
&& count
== 0) {
1163 if (!all_labels
&& !ignorenotfound
)
1164 error
= ENOENT
; /* XXX: ENOLABEL? */
1170 * Get the external forms of labels from all policies, for all label
1171 * namespaces contained in a list.
1173 * XXX This may be leaking an sbuf.
1176 mac_externalize(size_t mpo_externalize_off
, struct label
*label
,
1177 const char *elementlist
, char *outbuf
, size_t outbuflen
)
1185 /* allocate a scratch buffer the size of the string */
1186 MALLOC(scratch_base
, char *, strlen(elementlist
)+1, M_MACTEMP
, M_WAITOK
);
1187 if (scratch_base
== NULL
) {
1192 /* copy the elementlist to the scratch buffer */
1193 strlcpy(scratch_base
, elementlist
, strlen(elementlist
)+1);
1196 * set up a temporary pointer that can be used to iterate the
1197 * scratch buffer without losing the allocation address
1199 scratch
= scratch_base
;
1202 if (sbuf_new(&sb
, outbuf
, outbuflen
, SBUF_FIXEDLEN
) == NULL
) {
1203 /* could not allocate interior buffer */
1207 /* iterate the scratch buffer; NOTE: buffer contents modified! */
1208 while ((element
= strsep(&scratch
, ",")) != NULL
) {
1209 error
= mac_label_externalize(mpo_externalize_off
, label
,
1214 if ((len
= sbuf_len(&sb
)) > 0)
1215 sbuf_setpos(&sb
, len
- 1); /* trim trailing comma */
1219 if (scratch_base
!= NULL
)
1220 FREE(scratch_base
, M_MACTEMP
);
1226 * Have all policies set the internal form of a label, for a single
1230 mac_label_internalize(size_t mpo_internalize_off
, struct label
*label
,
1231 char *element_name
, char *element_data
)
1233 struct mac_policy_conf
*mpc
;
1234 struct mac_label_listener
*mll
;
1235 struct mac_label_element
*mle
;
1236 struct mac_label_element_list_t
*element_list
;
1237 int (*mpo_internalize
)(struct label
*, char *, char *);
1238 int error
= 0, busy
= FALSE
;
1239 unsigned int count
= 0;
1242 element_list
= &mac_static_label_element_list
;
1244 LIST_FOREACH(mle
, element_list
, mle_list
) {
1245 if (*(name
= mle
->mle_name
) == '?')
1247 if (strcmp(element_name
, name
) != 0)
1249 LIST_FOREACH(mll
, &mle
->mle_listeners
, mll_list
) {
1250 mpc
= mac_policy_list
.entries
[mll
->mll_handle
].mpc
;
1253 mpo_internalize
= *(typeof(mpo_internalize
) *)
1254 ((char *)mpc
->mpc_ops
+ mpo_internalize_off
);
1255 if (mpo_internalize
== NULL
)
1257 error
= mpo_internalize(label
, element_name
,
1264 /* If there are dynamic policies present, check their elements too. */
1265 if (!busy
&& mac_policy_list_conditional_busy() == 1) {
1266 element_list
= &mac_label_element_list
;
1272 mac_policy_list_unbusy();
1273 if (!error
&& count
== 0)
1279 mac_internalize(size_t mpo_internalize_off
, struct label
*label
,
1282 char *element_name
, *element_data
;
1285 while (!error
&& (element_name
= strsep(&textlabels
, ",")) != NULL
) {
1286 element_data
= strchr(element_name
, '/');
1287 if (element_data
== NULL
) {
1291 *element_data
++ = '\0';
1292 error
= mac_label_internalize(mpo_internalize_off
, label
,
1293 element_name
, element_data
);
1301 __mac_get_pid(struct proc
*p
, struct __mac_get_pid_args
*uap
, int *ret __unused
)
1303 char *elements
, *buffer
;
1304 struct user_mac mac
;
1306 struct ucred
*tcred
;
1310 AUDIT_ARG(pid
, uap
->pid
);
1311 if (IS_64BIT_PROCESS(p
)) {
1312 struct user64_mac mac64
;
1313 error
= copyin(uap
->mac_p
, &mac64
, sizeof(mac64
));
1314 mac
.m_buflen
= mac64
.m_buflen
;
1315 mac
.m_string
= mac64
.m_string
;
1317 struct user32_mac mac32
;
1318 error
= copyin(uap
->mac_p
, &mac32
, sizeof(mac32
));
1319 mac
.m_buflen
= mac32
.m_buflen
;
1320 mac
.m_string
= mac32
.m_string
;
1325 error
= mac_check_structmac_consistent(&mac
);
1329 tproc
= proc_find(uap
->pid
);
1332 tcred
= kauth_cred_proc_ref(tproc
);
1335 MALLOC(elements
, char *, mac
.m_buflen
, M_MACTEMP
, M_WAITOK
);
1336 error
= copyinstr(mac
.m_string
, elements
, mac
.m_buflen
, &ulen
);
1338 FREE(elements
, M_MACTEMP
);
1339 kauth_cred_unref(&tcred
);
1342 AUDIT_ARG(mac_string
, elements
);
1344 MALLOC(buffer
, char *, mac
.m_buflen
, M_MACTEMP
, M_WAITOK
| M_ZERO
);
1345 error
= mac_cred_label_externalize(tcred
->cr_label
, elements
,
1346 buffer
, mac
.m_buflen
, M_WAITOK
);
1348 error
= copyout(buffer
, mac
.m_string
, strlen(buffer
)+1);
1350 FREE(buffer
, M_MACTEMP
);
1351 FREE(elements
, M_MACTEMP
);
1352 kauth_cred_unref(&tcred
);
1357 __mac_get_proc(proc_t p
, struct __mac_get_proc_args
*uap
, int *ret __unused
)
1359 char *elements
, *buffer
;
1360 struct user_mac mac
;
1365 if (IS_64BIT_PROCESS(p
)) {
1366 struct user64_mac mac64
;
1367 error
= copyin(uap
->mac_p
, &mac64
, sizeof(mac64
));
1368 mac
.m_buflen
= mac64
.m_buflen
;
1369 mac
.m_string
= mac64
.m_string
;
1371 struct user32_mac mac32
;
1372 error
= copyin(uap
->mac_p
, &mac32
, sizeof(mac32
));
1373 mac
.m_buflen
= mac32
.m_buflen
;
1374 mac
.m_string
= mac32
.m_string
;
1379 error
= mac_check_structmac_consistent(&mac
);
1383 MALLOC(elements
, char *, mac
.m_buflen
, M_MACTEMP
, M_WAITOK
);
1384 error
= copyinstr(mac
.m_string
, elements
, mac
.m_buflen
, &ulen
);
1386 FREE(elements
, M_MACTEMP
);
1389 AUDIT_ARG(mac_string
, elements
);
1391 cr
= kauth_cred_proc_ref(p
);
1393 MALLOC(buffer
, char *, mac
.m_buflen
, M_MACTEMP
, M_WAITOK
| M_ZERO
);
1394 error
= mac_cred_label_externalize(cr
->cr_label
,
1395 elements
, buffer
, mac
.m_buflen
, M_WAITOK
);
1397 error
= copyout(buffer
, mac
.m_string
, strlen(buffer
)+1);
1399 FREE(buffer
, M_MACTEMP
);
1400 FREE(elements
, M_MACTEMP
);
1401 kauth_cred_unref(&cr
);
1406 __mac_set_proc(proc_t p
, struct __mac_set_proc_args
*uap
, int *ret __unused
)
1408 kauth_cred_t newcred
;
1409 struct label
*intlabel
;
1410 struct user_mac mac
;
1415 if (IS_64BIT_PROCESS(p
)) {
1416 struct user64_mac mac64
;
1417 error
= copyin(uap
->mac_p
, &mac64
, sizeof(mac64
));
1418 mac
.m_buflen
= mac64
.m_buflen
;
1419 mac
.m_string
= mac64
.m_string
;
1421 struct user32_mac mac32
;
1422 error
= copyin(uap
->mac_p
, &mac32
, sizeof(mac32
));
1423 mac
.m_buflen
= mac32
.m_buflen
;
1424 mac
.m_string
= mac32
.m_string
;
1429 error
= mac_check_structmac_consistent(&mac
);
1433 MALLOC(buffer
, char *, mac
.m_buflen
, M_MACTEMP
, M_WAITOK
);
1434 error
= copyinstr(mac
.m_string
, buffer
, mac
.m_buflen
, &ulen
);
1436 FREE(buffer
, M_MACTEMP
);
1439 AUDIT_ARG(mac_string
, buffer
);
1441 intlabel
= mac_cred_label_alloc();
1442 error
= mac_cred_label_internalize(intlabel
, buffer
);
1443 FREE(buffer
, M_MACTEMP
);
1447 error
= mac_cred_check_label_update(kauth_cred_get(), intlabel
);
1452 error
= kauth_proc_label_update(p
, intlabel
);
1456 newcred
= kauth_cred_proc_ref(p
);
1457 mac_task_label_update_cred(newcred
, p
->task
);
1460 if (mac_vm_enforce
) {
1461 mutex_lock(Giant
); /* XXX FUNNEL? */
1462 mac_cred_mmapped_drop_perms(p
, newcred
);
1463 mutex_unlock(Giant
); /* XXX FUNNEL? */
1467 kauth_cred_unref(&newcred
);
1469 mac_cred_label_free(intlabel
);
1476 * Get login context ID. A login context associates a BSD process
1477 * with an instance of a user. For more information see getlcid(2) man page.
1479 * Parameters: p Process requesting the get
1480 * uap User argument descriptor (see below)
1483 * Indirect: uap->lcid login context ID to search
1484 * uap->mac_p.m_buflen MAC info buffer size
1485 * uap->mac_p.m_string MAC info user address
1487 * Returns: 0 Success
1491 __mac_get_lcid(proc_t p
, struct __mac_get_lcid_args
*uap
, int *ret __unused
)
1493 char *elements
, *buffer
;
1494 struct user_mac mac
;
1499 AUDIT_ARG(value32
, uap
->lcid
);
1500 if (IS_64BIT_PROCESS(p
)) {
1501 struct user64_mac mac64
;
1502 error
= copyin(uap
->mac_p
, &mac64
, sizeof(mac64
));
1503 mac
.m_buflen
= mac64
.m_buflen
;
1504 mac
.m_string
= mac64
.m_string
;
1506 struct user32_mac mac32
;
1507 error
= copyin(uap
->mac_p
, &mac32
, sizeof(mac32
));
1508 mac
.m_buflen
= mac32
.m_buflen
;
1509 mac
.m_string
= mac32
.m_string
;
1515 error
= mac_check_structmac_consistent(&mac
);
1519 l
= lcfind(uap
->lcid
);
1523 MALLOC(elements
, char *, mac
.m_buflen
, M_MACTEMP
, M_WAITOK
);
1524 error
= copyinstr(mac
.m_string
, elements
, mac
.m_buflen
, &ulen
);
1527 FREE(elements
, M_MACTEMP
);
1530 AUDIT_ARG(mac_string
, elements
);
1531 MALLOC(buffer
, char *, mac
.m_buflen
, M_MACTEMP
, M_WAITOK
);
1532 error
= mac_lctx_label_externalize(l
->lc_label
, elements
,
1533 buffer
, mac
.m_buflen
);
1535 error
= copyout(buffer
, mac
.m_string
, strlen(buffer
)+1);
1538 FREE(buffer
, M_MACTEMP
);
1539 FREE(elements
, M_MACTEMP
);
1545 * Get login context label. A login context associates a BSD process
1546 * associated with an instance of a user.
1548 * Parameters: p Process requesting the get
1549 * uap User argument descriptor (see below)
1552 * Indirect: uap->lcid login context ID to search
1553 * uap->mac_p MAC info
1555 * Returns: 0 Success
1560 __mac_get_lctx(proc_t p
, struct __mac_get_lctx_args
*uap
, int *ret __unused
)
1562 char *elements
, *buffer
;
1563 struct user_mac mac
;
1567 if (IS_64BIT_PROCESS(p
)) {
1568 struct user64_mac mac64
;
1569 error
= copyin(uap
->mac_p
, &mac64
, sizeof(mac64
));
1570 mac
.m_buflen
= mac64
.m_buflen
;
1571 mac
.m_string
= mac64
.m_string
;
1573 struct user32_mac mac32
;
1574 error
= copyin(uap
->mac_p
, &mac32
, sizeof(mac32
));
1575 mac
.m_buflen
= mac32
.m_buflen
;
1576 mac
.m_string
= mac32
.m_string
;
1582 error
= mac_check_structmac_consistent(&mac
);
1586 MALLOC(elements
, char *, mac
.m_buflen
, M_MACTEMP
, M_WAITOK
);
1587 error
= copyinstr(mac
.m_string
, elements
, mac
.m_buflen
, &ulen
);
1589 FREE(elements
, M_MACTEMP
);
1592 AUDIT_ARG(mac_string
, elements
);
1593 MALLOC(buffer
, char *, mac
.m_buflen
, M_MACTEMP
, M_WAITOK
);
1596 if (p
->p_lctx
== NULL
) {
1602 error
= mac_lctx_label_externalize(p
->p_lctx
->lc_label
,
1603 elements
, buffer
, mac
.m_buflen
);
1606 error
= copyout(buffer
, mac
.m_string
, strlen(buffer
)+1);
1609 FREE(buffer
, M_MACTEMP
);
1610 FREE(elements
, M_MACTEMP
);
1615 __mac_set_lctx(proc_t p
, struct __mac_set_lctx_args
*uap
, int *ret __unused
)
1617 struct user_mac mac
;
1618 struct label
*intlabel
;
1623 if (IS_64BIT_PROCESS(p
)) {
1624 struct user64_mac mac64
;
1625 error
= copyin(uap
->mac_p
, &mac64
, sizeof(mac64
));
1626 mac
.m_buflen
= mac64
.m_buflen
;
1627 mac
.m_string
= mac64
.m_string
;
1629 struct user32_mac mac32
;
1630 error
= copyin(uap
->mac_p
, &mac32
, sizeof(mac32
));
1631 mac
.m_buflen
= mac32
.m_buflen
;
1632 mac
.m_string
= mac32
.m_string
;
1637 error
= mac_check_structmac_consistent(&mac
);
1641 MALLOC(buffer
, char *, mac
.m_buflen
, M_MACTEMP
, M_WAITOK
);
1642 error
= copyinstr(mac
.m_string
, buffer
, mac
.m_buflen
, &ulen
);
1644 FREE(buffer
, M_MACTEMP
);
1647 AUDIT_ARG(mac_string
, buffer
);
1649 intlabel
= mac_lctx_label_alloc();
1650 error
= mac_lctx_label_internalize(intlabel
, buffer
);
1651 FREE(buffer
, M_MACTEMP
);
1656 if (p
->p_lctx
== NULL
) {
1662 error
= mac_lctx_check_label_update(p
->p_lctx
, intlabel
);
1667 mac_lctx_label_update(p
->p_lctx
, intlabel
);
1670 mac_lctx_label_free(intlabel
);
1677 __mac_get_lcid(proc_t p __unused
, struct __mac_get_lcid_args
*uap __unused
, int *ret __unused
)
1684 __mac_get_lctx(proc_t p __unused
, struct __mac_get_lctx_args
*uap __unused
, int *ret __unused
)
1691 __mac_set_lctx(proc_t p __unused
, struct __mac_set_lctx_args
*uap __unused
, int *ret __unused
)
1699 __mac_get_fd(proc_t p
, struct __mac_get_fd_args
*uap
, int *ret __unused
)
1701 struct fileproc
*fp
;
1703 struct user_mac mac
;
1704 char *elements
, *buffer
;
1707 kauth_cred_t my_cred
;
1708 #if CONFIG_MACF_SOCKET
1710 #endif /* MAC_SOCKET */
1711 struct label
*intlabel
;
1713 AUDIT_ARG(fd
, uap
->fd
);
1715 if (IS_64BIT_PROCESS(p
)) {
1716 struct user64_mac mac64
;
1717 error
= copyin(uap
->mac_p
, &mac64
, sizeof(mac64
));
1718 mac
.m_buflen
= mac64
.m_buflen
;
1719 mac
.m_string
= mac64
.m_string
;
1721 struct user32_mac mac32
;
1722 error
= copyin(uap
->mac_p
, &mac32
, sizeof(mac32
));
1723 mac
.m_buflen
= mac32
.m_buflen
;
1724 mac
.m_string
= mac32
.m_string
;
1730 error
= mac_check_structmac_consistent(&mac
);
1734 MALLOC(elements
, char *, mac
.m_buflen
, M_MACTEMP
, M_WAITOK
);
1735 error
= copyinstr(mac
.m_string
, elements
, mac
.m_buflen
, &ulen
);
1737 FREE(elements
, M_MACTEMP
);
1740 AUDIT_ARG(mac_string
, elements
);
1742 MALLOC(buffer
, char *, mac
.m_buflen
, M_MACTEMP
, M_WAITOK
);
1743 error
= fp_lookup(p
, uap
->fd
, &fp
, 0);
1745 FREE(buffer
, M_MACTEMP
);
1746 FREE(elements
, M_MACTEMP
);
1750 my_cred
= kauth_cred_proc_ref(p
);
1751 error
= mac_file_check_get(my_cred
, fp
->f_fglob
, elements
, mac
.m_buflen
);
1752 kauth_cred_unref(&my_cred
);
1754 fp_drop(p
, uap
->fd
, fp
, 0);
1755 FREE(buffer
, M_MACTEMP
);
1756 FREE(elements
, M_MACTEMP
);
1760 switch (fp
->f_fglob
->fg_type
) {
1762 intlabel
= mac_vnode_label_alloc();
1763 if (intlabel
== NULL
) {
1767 vp
= (struct vnode
*)fp
->f_fglob
->fg_data
;
1768 error
= vnode_getwithref(vp
);
1770 mac_vnode_label_copy(vp
->v_label
, intlabel
);
1771 error
= mac_vnode_label_externalize(intlabel
,
1773 mac
.m_buflen
, M_WAITOK
);
1776 mac_vnode_label_free(intlabel
);
1779 #if CONFIG_MACF_SOCKET
1780 so
= (struct socket
*) fp
->f_fglob
->fg_data
;
1781 intlabel
= mac_socket_label_alloc(MAC_WAITOK
);
1783 mac_socket_label_copy(so
->so_label
, intlabel
);
1785 error
= mac_socket_label_externalize(intlabel
, elements
, buffer
, mac
.m_buflen
);
1786 mac_socket_label_free(intlabel
);
1793 case DTYPE_FSEVENTS
:
1795 error
= ENOSYS
; // only sockets/vnodes so far
1798 fp_drop(p
, uap
->fd
, fp
, 0);
1801 error
= copyout(buffer
, mac
.m_string
, strlen(buffer
)+1);
1803 FREE(buffer
, M_MACTEMP
);
1804 FREE(elements
, M_MACTEMP
);
1809 mac_get_filelink(proc_t p
, user_addr_t mac_p
, user_addr_t path_p
, int follow
)
1813 char *elements
, *buffer
;
1814 struct nameidata nd
;
1815 struct label
*intlabel
;
1816 struct user_mac mac
;
1820 if (IS_64BIT_PROCESS(p
)) {
1821 struct user64_mac mac64
;
1822 error
= copyin(mac_p
, &mac64
, sizeof(mac64
));
1823 mac
.m_buflen
= mac64
.m_buflen
;
1824 mac
.m_string
= mac64
.m_string
;
1826 struct user32_mac mac32
;
1827 error
= copyin(mac_p
, &mac32
, sizeof(mac32
));
1828 mac
.m_buflen
= mac32
.m_buflen
;
1829 mac
.m_string
= mac32
.m_string
;
1835 error
= mac_check_structmac_consistent(&mac
);
1839 MALLOC(elements
, char *, mac
.m_buflen
, M_MACTEMP
, M_WAITOK
);
1840 MALLOC(buffer
, char *, mac
.m_buflen
, M_MACTEMP
, M_WAITOK
| M_ZERO
);
1842 error
= copyinstr(mac
.m_string
, elements
, mac
.m_buflen
, &ulen
);
1844 FREE(buffer
, M_MACTEMP
);
1845 FREE(elements
, M_MACTEMP
);
1848 AUDIT_ARG(mac_string
, elements
);
1850 ctx
= vfs_context_current();
1852 NDINIT(&nd
, LOOKUP
, OP_LOOKUP
,
1853 LOCKLEAF
| (follow
? FOLLOW
: NOFOLLOW
) | AUDITVNPATH1
,
1854 UIO_USERSPACE
, path_p
, ctx
);
1857 FREE(buffer
, M_MACTEMP
);
1858 FREE(elements
, M_MACTEMP
);
1865 intlabel
= mac_vnode_label_alloc();
1866 mac_vnode_label_copy(vp
->v_label
, intlabel
);
1867 error
= mac_vnode_label_externalize(intlabel
, elements
, buffer
,
1868 mac
.m_buflen
, M_WAITOK
);
1869 mac_vnode_label_free(intlabel
);
1871 error
= copyout(buffer
, mac
.m_string
, strlen(buffer
) + 1);
1875 FREE(buffer
, M_MACTEMP
);
1876 FREE(elements
, M_MACTEMP
);
1882 __mac_get_file(proc_t p
, struct __mac_get_file_args
*uap
,
1886 return (mac_get_filelink(p
, uap
->mac_p
, uap
->path_p
, 1));
1890 __mac_get_link(proc_t p
, struct __mac_get_link_args
*uap
,
1894 return (mac_get_filelink(p
, uap
->mac_p
, uap
->path_p
, 0));
1898 __mac_set_fd(proc_t p
, struct __mac_set_fd_args
*uap
, int *ret __unused
)
1901 struct fileproc
*fp
;
1902 struct user_mac mac
;
1903 struct vfs_context
*ctx
= vfs_context_current();
1907 struct label
*intlabel
;
1908 #if CONFIG_MACF_SOCKET
1913 AUDIT_ARG(fd
, uap
->fd
);
1915 if (IS_64BIT_PROCESS(p
)) {
1916 struct user64_mac mac64
;
1917 error
= copyin(uap
->mac_p
, &mac64
, sizeof(mac64
));
1918 mac
.m_buflen
= mac64
.m_buflen
;
1919 mac
.m_string
= mac64
.m_string
;
1921 struct user32_mac mac32
;
1922 error
= copyin(uap
->mac_p
, &mac32
, sizeof(mac32
));
1923 mac
.m_buflen
= mac32
.m_buflen
;
1924 mac
.m_string
= mac32
.m_string
;
1929 error
= mac_check_structmac_consistent(&mac
);
1933 MALLOC(buffer
, char *, mac
.m_buflen
, M_MACTEMP
, M_WAITOK
);
1934 error
= copyinstr(mac
.m_string
, buffer
, mac
.m_buflen
, &ulen
);
1936 FREE(buffer
, M_MACTEMP
);
1939 AUDIT_ARG(mac_string
, buffer
);
1941 error
= fp_lookup(p
, uap
->fd
, &fp
, 0);
1943 FREE(buffer
, M_MACTEMP
);
1948 error
= mac_file_check_set(vfs_context_ucred(ctx
), fp
->f_fglob
, buffer
, mac
.m_buflen
);
1950 fp_drop(p
, uap
->fd
, fp
, 0);
1951 FREE(buffer
, M_MACTEMP
);
1955 switch (fp
->f_fglob
->fg_type
) {
1958 if (mac_label_vnodes
== 0) {
1963 intlabel
= mac_vnode_label_alloc();
1965 error
= mac_vnode_label_internalize(intlabel
, buffer
);
1967 mac_vnode_label_free(intlabel
);
1972 vp
= (struct vnode
*)fp
->f_fglob
->fg_data
;
1974 error
= vnode_getwithref(vp
);
1976 error
= vn_setlabel(vp
, intlabel
, ctx
);
1979 mac_vnode_label_free(intlabel
);
1983 #if CONFIG_MACF_SOCKET
1984 intlabel
= mac_socket_label_alloc(MAC_WAITOK
);
1985 error
= mac_socket_label_internalize(intlabel
, buffer
);
1987 so
= (struct socket
*) fp
->f_fglob
->fg_data
;
1989 error
= mac_socket_label_update(vfs_context_ucred(ctx
), so
, intlabel
);
1992 mac_socket_label_free(intlabel
);
1999 case DTYPE_FSEVENTS
:
2001 error
= ENOSYS
; // only sockets/vnodes so far
2005 fp_drop(p
, uap
->fd
, fp
, 0);
2006 FREE(buffer
, M_MACTEMP
);
2011 mac_set_filelink(proc_t p
, user_addr_t mac_p
, user_addr_t path_p
,
2014 register struct vnode
*vp
;
2015 struct vfs_context
*ctx
= vfs_context_current();
2016 struct label
*intlabel
;
2017 struct nameidata nd
;
2018 struct user_mac mac
;
2023 if (mac_label_vnodes
== 0)
2026 if (IS_64BIT_PROCESS(p
)) {
2027 struct user64_mac mac64
;
2028 error
= copyin(mac_p
, &mac64
, sizeof(mac64
));
2029 mac
.m_buflen
= mac64
.m_buflen
;
2030 mac
.m_string
= mac64
.m_string
;
2032 struct user32_mac mac32
;
2033 error
= copyin(mac_p
, &mac32
, sizeof(mac32
));
2034 mac
.m_buflen
= mac32
.m_buflen
;
2035 mac
.m_string
= mac32
.m_string
;
2040 error
= mac_check_structmac_consistent(&mac
);
2042 printf("mac_set_file: failed structure consistency check\n");
2046 MALLOC(buffer
, char *, mac
.m_buflen
, M_MACTEMP
, M_WAITOK
);
2047 error
= copyinstr(mac
.m_string
, buffer
, mac
.m_buflen
, &ulen
);
2049 FREE(buffer
, M_MACTEMP
);
2052 AUDIT_ARG(mac_string
, buffer
);
2054 intlabel
= mac_vnode_label_alloc();
2055 error
= mac_vnode_label_internalize(intlabel
, buffer
);
2056 FREE(buffer
, M_MACTEMP
);
2058 mac_vnode_label_free(intlabel
);
2062 NDINIT(&nd
, LOOKUP
, OP_LOOKUP
,
2063 LOCKLEAF
| (follow
? FOLLOW
: NOFOLLOW
) | AUDITVNPATH1
,
2064 UIO_USERSPACE
, path_p
, ctx
);
2067 mac_vnode_label_free(intlabel
);
2074 error
= vn_setlabel(vp
, intlabel
, ctx
);
2076 mac_vnode_label_free(intlabel
);
2082 __mac_set_file(proc_t p
, struct __mac_set_file_args
*uap
,
2086 return (mac_set_filelink(p
, uap
->mac_p
, uap
->path_p
, 1));
2090 __mac_set_link(proc_t p
, struct __mac_set_link_args
*uap
,
2094 return (mac_set_filelink(p
, uap
->mac_p
, uap
->path_p
, 0));
2098 * __mac_syscall: Perform a MAC policy system call
2100 * Parameters: p Process calling this routine
2101 * uap User argument descriptor (see below)
2104 * Indirect: uap->policy Name of target MAC policy
2105 * uap->call MAC policy-specific system call to perform
2106 * uap->arg MAC policy-specific system call arguments
2108 * Returns: 0 Success
2113 __mac_syscall(proc_t p
, struct __mac_syscall_args
*uap
, int *retv __unused
)
2115 struct mac_policy_conf
*mpc
;
2116 char target
[MAC_MAX_POLICY_NAME
];
2121 error
= copyinstr(uap
->policy
, target
, sizeof(target
), &ulen
);
2124 AUDIT_ARG(value32
, uap
->call
);
2125 AUDIT_ARG(mac_string
, target
);
2129 for (i
= 0; i
< mac_policy_list
.staticmax
; i
++) {
2130 mpc
= mac_policy_list
.entries
[i
].mpc
;
2134 if (strcmp(mpc
->mpc_name
, target
) == 0 &&
2135 mpc
->mpc_ops
->mpo_policy_syscall
!= NULL
) {
2136 error
= mpc
->mpc_ops
->mpo_policy_syscall(p
,
2137 uap
->call
, uap
->arg
);
2141 if (mac_policy_list_conditional_busy() != 0) {
2142 for (; i
<= mac_policy_list
.maxindex
; i
++) {
2143 mpc
= mac_policy_list
.entries
[i
].mpc
;
2147 if (strcmp(mpc
->mpc_name
, target
) == 0 &&
2148 mpc
->mpc_ops
->mpo_policy_syscall
!= NULL
) {
2149 error
= mpc
->mpc_ops
->mpo_policy_syscall(p
,
2150 uap
->call
, uap
->arg
);
2154 mac_policy_list_unbusy();
2162 mac_mount_label_get(struct mount
*mp
, user_addr_t mac_p
)
2164 char *elements
, *buffer
;
2165 struct label
*label
;
2166 struct user_mac mac
;
2170 if (IS_64BIT_PROCESS(current_proc())) {
2171 struct user64_mac mac64
;
2172 error
= copyin(mac_p
, &mac64
, sizeof(mac64
));
2173 mac
.m_buflen
= mac64
.m_buflen
;
2174 mac
.m_string
= mac64
.m_string
;
2176 struct user32_mac mac32
;
2177 error
= copyin(mac_p
, &mac32
, sizeof(mac32
));
2178 mac
.m_buflen
= mac32
.m_buflen
;
2179 mac
.m_string
= mac32
.m_string
;
2184 error
= mac_check_structmac_consistent(&mac
);
2188 MALLOC(elements
, char *, mac
.m_buflen
, M_MACTEMP
, M_WAITOK
);
2189 error
= copyinstr(mac
.m_string
, elements
, mac
.m_buflen
, &ulen
);
2191 FREE(elements
, M_MACTEMP
);
2194 AUDIT_ARG(mac_string
, elements
);
2196 label
= mp
->mnt_mntlabel
;
2197 MALLOC(buffer
, char *, mac
.m_buflen
, M_MACTEMP
, M_WAITOK
| M_ZERO
);
2198 error
= mac_mount_label_externalize(label
, elements
, buffer
,
2200 FREE(elements
, M_MACTEMP
);
2203 error
= copyout(buffer
, mac
.m_string
, strlen(buffer
) + 1);
2204 FREE(buffer
, M_MACTEMP
);
2210 * __mac_get_mount: Get mount point label information for a given pathname
2212 * Parameters: p (ignored)
2213 * uap User argument descriptor (see below)
2216 * Indirect: uap->path Pathname
2217 * uap->mac_p MAC info
2219 * Returns: 0 Success
2223 __mac_get_mount(proc_t p __unused
, struct __mac_get_mount_args
*uap
,
2226 struct nameidata nd
;
2227 struct vfs_context
*ctx
= vfs_context_current();
2231 NDINIT(&nd
, LOOKUP
, OP_LOOKUP
, FOLLOW
| AUDITVNPATH1
,
2232 UIO_USERSPACE
, uap
->path
, ctx
);
2237 mp
= nd
.ni_vp
->v_mount
;
2240 return mac_mount_label_get(mp
, uap
->mac_p
);
2244 * mac_schedule_userret()
2246 * Schedule a callback to the mpo_thread_userret hook. The mpo_thread_userret
2247 * hook is called just before the thread exit from the kernel in ast_taken().
2249 * Returns: 0 Success
2253 mac_schedule_userret(void)
2256 act_set_astmacf(current_thread());
2263 * Do a Mach exception. This should only be done in the mpo_thread_userret
2266 * params: code exception code
2267 * subcode exception subcode
2269 * MAC_DOEXCF_TRACED Only do exception if being
2273 * Returns: 0 Success
2277 mac_do_machexc(int64_t code
, int64_t subcode
, uint32_t flags
)
2279 mach_exception_data_type_t codes
[EXCEPTION_CODE_MAX
];
2280 proc_t p
= current_proc();
2282 /* Only allow execption codes in MACF's reserved range. */
2283 if ((code
< EXC_MACF_MIN
) || (code
> EXC_MACF_MAX
))
2286 if (flags
& MAC_DOEXCF_TRACED
&&
2287 !(p
->p_lflag
& P_LTRACED
&& (p
->p_lflag
& P_LPPWAIT
) == 0))
2291 /* Send the Mach exception */
2292 codes
[0] = (mach_exception_data_type_t
)code
;
2293 codes
[1] = (mach_exception_data_type_t
)subcode
;
2295 return (bsd_exception(EXC_SOFTWARE
, codes
, 2) != KERN_SUCCESS
);
2301 mac_policy_register(struct mac_policy_conf
*mpc __unused
,
2302 mac_policy_handle_t
*handlep __unused
, void *xd __unused
)
2309 mac_policy_unregister(mac_policy_handle_t handle __unused
)
2316 mac_audit_text(char *text __unused
, mac_policy_handle_t handle __unused
)
2323 mac_mount_label_get(struct mount
*mp __unused
, user_addr_t mac_p __unused
)
2329 mac_vnop_setxattr(struct vnode
*vp __unused
, const char *name __unused
, char *buf __unused
, size_t len __unused
)
2336 mac_vnop_getxattr(struct vnode
*vp __unused
, const char *name __unused
,
2337 char *buf __unused
, size_t len __unused
, size_t *attrlen __unused
)
2344 mac_vnop_removexattr(struct vnode
*vp __unused
, const char *name __unused
)
2351 __mac_get_pid(proc_t p __unused
, struct __mac_get_pid_args
*uap __unused
, int *ret __unused
)
2358 __mac_get_proc(proc_t p __unused
, struct __mac_get_proc_args
*uap __unused
, int *ret __unused
)
2365 __mac_set_proc(proc_t p __unused
, struct __mac_set_proc_args
*uap __unused
, int *ret __unused
)
2372 __mac_get_file(proc_t p __unused
, struct __mac_get_file_args
*uap __unused
, int *ret __unused
)
2379 __mac_get_link(proc_t p __unused
, struct __mac_get_link_args
*uap __unused
, int *ret __unused
)
2386 __mac_set_file(proc_t p __unused
, struct __mac_set_file_args
*uap __unused
, int *ret __unused
)
2393 __mac_set_link(proc_t p __unused
, struct __mac_set_link_args
*uap __unused
, int *ret __unused
)
2400 __mac_get_fd(proc_t p __unused
, struct __mac_get_fd_args
*uap __unused
, int *ret __unused
)
2407 __mac_set_fd(proc_t p __unused
, struct __mac_set_fd_args
*uap __unused
, int *ret __unused
)
2414 __mac_syscall(proc_t p __unused
, struct __mac_syscall_args
*uap __unused
, int *ret __unused
)
2421 __mac_get_lcid(proc_t p __unused
, struct __mac_get_lcid_args
*uap __unused
, int *ret __unused
)
2428 __mac_get_lctx(proc_t p __unused
, struct __mac_get_lctx_args
*uap __unused
, int *ret __unused
)
2435 __mac_set_lctx(proc_t p __unused
, struct __mac_set_lctx_args
*uap __unused
, int *ret __unused
)
2442 __mac_get_mount(proc_t p __unused
,
2443 struct __mac_get_mount_args
*uap __unused
, int *ret __unused
)
2450 mac_schedule_userret(void)
2457 mac_do_machexc(int64_t code __unused
, int64_t subcode __unused
, uint32_t flags __unused
)