xref: /xnu-8020.101.4/security/mac_mach.c (revision e7776783b89a353188416a9a346c6cdb4928faad)
1*e7776783SApple OSS Distributions /*
2*e7776783SApple OSS Distributions  * Copyright (c) 2015 Apple Inc. All rights reserved.
3*e7776783SApple OSS Distributions  *
4*e7776783SApple OSS Distributions  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5*e7776783SApple OSS Distributions  *
6*e7776783SApple OSS Distributions  * This file contains Original Code and/or Modifications of Original Code
7*e7776783SApple OSS Distributions  * as defined in and that are subject to the Apple Public Source License
8*e7776783SApple OSS Distributions  * Version 2.0 (the 'License'). You may not use this file except in
9*e7776783SApple OSS Distributions  * compliance with the License. The rights granted to you under the License
10*e7776783SApple OSS Distributions  * may not be used to create, or enable the creation or redistribution of,
11*e7776783SApple OSS Distributions  * unlawful or unlicensed copies of an Apple operating system, or to
12*e7776783SApple OSS Distributions  * circumvent, violate, or enable the circumvention or violation of, any
13*e7776783SApple OSS Distributions  * terms of an Apple operating system software license agreement.
14*e7776783SApple OSS Distributions  *
15*e7776783SApple OSS Distributions  * Please obtain a copy of the License at
16*e7776783SApple OSS Distributions  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17*e7776783SApple OSS Distributions  *
18*e7776783SApple OSS Distributions  * The Original Code and all software distributed under the License are
19*e7776783SApple OSS Distributions  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20*e7776783SApple OSS Distributions  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21*e7776783SApple OSS Distributions  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22*e7776783SApple OSS Distributions  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23*e7776783SApple OSS Distributions  * Please see the License for the specific language governing rights and
24*e7776783SApple OSS Distributions  * limitations under the License.
25*e7776783SApple OSS Distributions  *
26*e7776783SApple OSS Distributions  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27*e7776783SApple OSS Distributions  */
28*e7776783SApple OSS Distributions 
29*e7776783SApple OSS Distributions #include <mach/exception_types.h>
30*e7776783SApple OSS Distributions #include <mach/mach_types.h>
31*e7776783SApple OSS Distributions #include <osfmk/kern/exception.h>
32*e7776783SApple OSS Distributions #include <osfmk/kern/task.h>
33*e7776783SApple OSS Distributions #include <sys/codesign.h>
34*e7776783SApple OSS Distributions #include <sys/param.h>
35*e7776783SApple OSS Distributions #include <sys/user.h>
36*e7776783SApple OSS Distributions #include <sys/proc.h>
37*e7776783SApple OSS Distributions #include <sys/proc_internal.h>
38*e7776783SApple OSS Distributions #include <sys/kauth.h>
39*e7776783SApple OSS Distributions 
40*e7776783SApple OSS Distributions #include <kern/task.h>
41*e7776783SApple OSS Distributions #include <kern/telemetry.h>
42*e7776783SApple OSS Distributions 
43*e7776783SApple OSS Distributions #include <security/mac_framework.h>
44*e7776783SApple OSS Distributions #include <security/mac_internal.h>
45*e7776783SApple OSS Distributions #include <security/mac_mach_internal.h>
46*e7776783SApple OSS Distributions 
47*e7776783SApple OSS Distributions #if CONFIG_CSR
48*e7776783SApple OSS Distributions #include <sys/csr.h>
49*e7776783SApple OSS Distributions // Panic on internal builds, just log otherwise.
50*e7776783SApple OSS Distributions #define MAC_MACH_UNEXPECTED(fmt...) \
51*e7776783SApple OSS Distributions 	if (csr_check(CSR_ALLOW_APPLE_INTERNAL) == 0) { panic(fmt); } else { printf(fmt); }
52*e7776783SApple OSS Distributions #else
53*e7776783SApple OSS Distributions #define MAC_MACH_UNEXPECTED(fmt...) printf(fmt)
54*e7776783SApple OSS Distributions #endif
55*e7776783SApple OSS Distributions 
56*e7776783SApple OSS Distributions static struct proc *
mac_task_get_proc(struct task * task)57*e7776783SApple OSS Distributions mac_task_get_proc(struct task *task)
58*e7776783SApple OSS Distributions {
59*e7776783SApple OSS Distributions 	if (task == current_task()) {
60*e7776783SApple OSS Distributions 		return proc_self();
61*e7776783SApple OSS Distributions 	}
62*e7776783SApple OSS Distributions 
63*e7776783SApple OSS Distributions 	/*
64*e7776783SApple OSS Distributions 	 * Tasks don't really hold a reference on a proc unless the
65*e7776783SApple OSS Distributions 	 * calling thread belongs to the task in question.
66*e7776783SApple OSS Distributions 	 */
67*e7776783SApple OSS Distributions 	int pid = task_pid(task);
68*e7776783SApple OSS Distributions 	struct proc *p = proc_find(pid);
69*e7776783SApple OSS Distributions 
70*e7776783SApple OSS Distributions 	if (p != NULL) {
71*e7776783SApple OSS Distributions 		if (proc_task(p) == task) {
72*e7776783SApple OSS Distributions 			return p;
73*e7776783SApple OSS Distributions 		}
74*e7776783SApple OSS Distributions 		proc_rele(p);
75*e7776783SApple OSS Distributions 	}
76*e7776783SApple OSS Distributions 	return NULL;
77*e7776783SApple OSS Distributions }
78*e7776783SApple OSS Distributions 
79*e7776783SApple OSS Distributions int
mac_task_check_expose_task(struct task * task,mach_task_flavor_t flavor)80*e7776783SApple OSS Distributions mac_task_check_expose_task(struct task *task, mach_task_flavor_t flavor)
81*e7776783SApple OSS Distributions {
82*e7776783SApple OSS Distributions 	int error;
83*e7776783SApple OSS Distributions 
84*e7776783SApple OSS Distributions 	assert(flavor <= TASK_FLAVOR_NAME);
85*e7776783SApple OSS Distributions 
86*e7776783SApple OSS Distributions 	struct proc *p = mac_task_get_proc(task);
87*e7776783SApple OSS Distributions 	if (p == NULL) {
88*e7776783SApple OSS Distributions 		return ESRCH;
89*e7776783SApple OSS Distributions 	}
90*e7776783SApple OSS Distributions 	struct proc_ident pident = proc_ident(p);
91*e7776783SApple OSS Distributions 
92*e7776783SApple OSS Distributions 	struct ucred *cred = kauth_cred_get();
93*e7776783SApple OSS Distributions 	proc_rele(p);
94*e7776783SApple OSS Distributions 
95*e7776783SApple OSS Distributions 	/* Also call the old hook for compatability, deprecating in rdar://66356944. */
96*e7776783SApple OSS Distributions 	if (flavor == TASK_FLAVOR_CONTROL) {
97*e7776783SApple OSS Distributions 		MAC_CHECK(proc_check_expose_task, cred, &pident);
98*e7776783SApple OSS Distributions 		if (error) {
99*e7776783SApple OSS Distributions 			return error;
100*e7776783SApple OSS Distributions 		}
101*e7776783SApple OSS Distributions 	}
102*e7776783SApple OSS Distributions 
103*e7776783SApple OSS Distributions 	MAC_CHECK(proc_check_expose_task_with_flavor, cred, &pident, flavor);
104*e7776783SApple OSS Distributions 
105*e7776783SApple OSS Distributions 	return error;
106*e7776783SApple OSS Distributions }
107*e7776783SApple OSS Distributions 
108*e7776783SApple OSS Distributions int
mac_task_check_task_id_token_get_task(struct task * task,mach_task_flavor_t flavor)109*e7776783SApple OSS Distributions mac_task_check_task_id_token_get_task(struct task *task, mach_task_flavor_t flavor)
110*e7776783SApple OSS Distributions {
111*e7776783SApple OSS Distributions 	int error;
112*e7776783SApple OSS Distributions 	struct proc *target_proc = NULL;
113*e7776783SApple OSS Distributions 	struct proc_ident *pidentp = NULL;
114*e7776783SApple OSS Distributions 	struct proc_ident pident;
115*e7776783SApple OSS Distributions 
116*e7776783SApple OSS Distributions 	assert(flavor <= TASK_FLAVOR_NAME);
117*e7776783SApple OSS Distributions 
118*e7776783SApple OSS Distributions 	if (!is_corpsetask(task)) {
119*e7776783SApple OSS Distributions 		/* only live task has proc */
120*e7776783SApple OSS Distributions 		target_proc = mac_task_get_proc(task);
121*e7776783SApple OSS Distributions 		if (target_proc == NULL) {
122*e7776783SApple OSS Distributions 			return ESRCH;
123*e7776783SApple OSS Distributions 		}
124*e7776783SApple OSS Distributions 		pident = proc_ident(target_proc);
125*e7776783SApple OSS Distributions 		pidentp = &pident;
126*e7776783SApple OSS Distributions 		proc_rele(target_proc);
127*e7776783SApple OSS Distributions 	}
128*e7776783SApple OSS Distributions 
129*e7776783SApple OSS Distributions 	kauth_cred_t cred = kauth_cred_proc_ref(current_proc());
130*e7776783SApple OSS Distributions 
131*e7776783SApple OSS Distributions 	/* pidentp is NULL for corpse task */
132*e7776783SApple OSS Distributions 	MAC_CHECK(proc_check_task_id_token_get_task, cred, pidentp, flavor);
133*e7776783SApple OSS Distributions 	kauth_cred_unref(&cred);
134*e7776783SApple OSS Distributions 	return error;
135*e7776783SApple OSS Distributions }
136*e7776783SApple OSS Distributions 
137*e7776783SApple OSS Distributions int
mac_task_check_get_movable_control_port(void)138*e7776783SApple OSS Distributions mac_task_check_get_movable_control_port(void)
139*e7776783SApple OSS Distributions {
140*e7776783SApple OSS Distributions 	int error;
141*e7776783SApple OSS Distributions 	struct proc *p = current_proc();
142*e7776783SApple OSS Distributions 
143*e7776783SApple OSS Distributions 	kauth_cred_t cred = kauth_cred_proc_ref(p);
144*e7776783SApple OSS Distributions 	MAC_CHECK(proc_check_get_movable_control_port, cred);
145*e7776783SApple OSS Distributions 	kauth_cred_unref(&cred);
146*e7776783SApple OSS Distributions 	return error;
147*e7776783SApple OSS Distributions }
148*e7776783SApple OSS Distributions 
149*e7776783SApple OSS Distributions int
mac_task_check_set_host_special_port(struct task * task,int id,struct ipc_port * port)150*e7776783SApple OSS Distributions mac_task_check_set_host_special_port(struct task *task, int id, struct ipc_port *port)
151*e7776783SApple OSS Distributions {
152*e7776783SApple OSS Distributions 	int error;
153*e7776783SApple OSS Distributions 
154*e7776783SApple OSS Distributions 	struct proc *p = mac_task_get_proc(task);
155*e7776783SApple OSS Distributions 	if (p == NULL) {
156*e7776783SApple OSS Distributions 		return ESRCH;
157*e7776783SApple OSS Distributions 	}
158*e7776783SApple OSS Distributions 
159*e7776783SApple OSS Distributions 	kauth_cred_t cred = kauth_cred_proc_ref(p);
160*e7776783SApple OSS Distributions 	MAC_CHECK(proc_check_set_host_special_port, cred, id, port);
161*e7776783SApple OSS Distributions 	kauth_cred_unref(&cred);
162*e7776783SApple OSS Distributions 	proc_rele(p);
163*e7776783SApple OSS Distributions 	return error;
164*e7776783SApple OSS Distributions }
165*e7776783SApple OSS Distributions 
166*e7776783SApple OSS Distributions int
mac_task_check_set_host_exception_port(struct task * task,unsigned int exception)167*e7776783SApple OSS Distributions mac_task_check_set_host_exception_port(struct task *task, unsigned int exception)
168*e7776783SApple OSS Distributions {
169*e7776783SApple OSS Distributions 	int error;
170*e7776783SApple OSS Distributions 
171*e7776783SApple OSS Distributions 	struct proc *p = mac_task_get_proc(task);
172*e7776783SApple OSS Distributions 	if (p == NULL) {
173*e7776783SApple OSS Distributions 		return ESRCH;
174*e7776783SApple OSS Distributions 	}
175*e7776783SApple OSS Distributions 
176*e7776783SApple OSS Distributions 	kauth_cred_t cred = kauth_cred_proc_ref(p);
177*e7776783SApple OSS Distributions 	MAC_CHECK(proc_check_set_host_exception_port, cred, exception);
178*e7776783SApple OSS Distributions 	kauth_cred_unref(&cred);
179*e7776783SApple OSS Distributions 	proc_rele(p);
180*e7776783SApple OSS Distributions 	return error;
181*e7776783SApple OSS Distributions }
182*e7776783SApple OSS Distributions 
183*e7776783SApple OSS Distributions int
mac_task_check_get_task_special_port(struct task * task,struct task * target,int which)184*e7776783SApple OSS Distributions mac_task_check_get_task_special_port(struct task *task, struct task *target, int which)
185*e7776783SApple OSS Distributions {
186*e7776783SApple OSS Distributions 	int error;
187*e7776783SApple OSS Distributions 	struct proc *target_proc = NULL;
188*e7776783SApple OSS Distributions 	struct proc_ident *pidentp = NULL;
189*e7776783SApple OSS Distributions 	struct proc_ident pident;
190*e7776783SApple OSS Distributions 
191*e7776783SApple OSS Distributions 	struct proc *p = mac_task_get_proc(task);
192*e7776783SApple OSS Distributions 	if (p == NULL) {
193*e7776783SApple OSS Distributions 		return ESRCH;
194*e7776783SApple OSS Distributions 	}
195*e7776783SApple OSS Distributions 
196*e7776783SApple OSS Distributions 	if (!is_corpsetask(target)) {
197*e7776783SApple OSS Distributions 		/* only live task has proc */
198*e7776783SApple OSS Distributions 		target_proc = mac_task_get_proc(target);
199*e7776783SApple OSS Distributions 		if (target_proc == NULL) {
200*e7776783SApple OSS Distributions 			proc_rele(p);
201*e7776783SApple OSS Distributions 			return ESRCH;
202*e7776783SApple OSS Distributions 		}
203*e7776783SApple OSS Distributions 		pident = proc_ident(target_proc);
204*e7776783SApple OSS Distributions 		pidentp = &pident;
205*e7776783SApple OSS Distributions 		proc_rele(target_proc);
206*e7776783SApple OSS Distributions 	}
207*e7776783SApple OSS Distributions 
208*e7776783SApple OSS Distributions 	kauth_cred_t cred = kauth_cred_proc_ref(p);
209*e7776783SApple OSS Distributions 	proc_rele(p);
210*e7776783SApple OSS Distributions 
211*e7776783SApple OSS Distributions 	/* pidentp is NULL for corpse task */
212*e7776783SApple OSS Distributions 	MAC_CHECK(proc_check_get_task_special_port, cred, pidentp, which);
213*e7776783SApple OSS Distributions 	kauth_cred_unref(&cred);
214*e7776783SApple OSS Distributions 	return error;
215*e7776783SApple OSS Distributions }
216*e7776783SApple OSS Distributions 
217*e7776783SApple OSS Distributions int
mac_task_check_set_task_special_port(struct task * task,struct task * target,int which,struct ipc_port * port)218*e7776783SApple OSS Distributions mac_task_check_set_task_special_port(struct task *task, struct task *target, int which, struct ipc_port *port)
219*e7776783SApple OSS Distributions {
220*e7776783SApple OSS Distributions 	int error;
221*e7776783SApple OSS Distributions 
222*e7776783SApple OSS Distributions 	struct proc *p = mac_task_get_proc(task);
223*e7776783SApple OSS Distributions 	if (p == NULL) {
224*e7776783SApple OSS Distributions 		return ESRCH;
225*e7776783SApple OSS Distributions 	}
226*e7776783SApple OSS Distributions 
227*e7776783SApple OSS Distributions 	/*
228*e7776783SApple OSS Distributions 	 * task_set_special_port() is a CONTROL level interface, so we are guaranteed
229*e7776783SApple OSS Distributions 	 * by MIG intrans that target is not a corpse.
230*e7776783SApple OSS Distributions 	 */
231*e7776783SApple OSS Distributions 	assert(!is_corpsetask(target));
232*e7776783SApple OSS Distributions 
233*e7776783SApple OSS Distributions 	struct proc *targetp = mac_task_get_proc(target);
234*e7776783SApple OSS Distributions 	if (targetp == NULL) {
235*e7776783SApple OSS Distributions 		proc_rele(p);
236*e7776783SApple OSS Distributions 		return ESRCH;
237*e7776783SApple OSS Distributions 	}
238*e7776783SApple OSS Distributions 
239*e7776783SApple OSS Distributions 	struct proc_ident pident = proc_ident(targetp);
240*e7776783SApple OSS Distributions 	kauth_cred_t cred = kauth_cred_proc_ref(p);
241*e7776783SApple OSS Distributions 	proc_rele(targetp);
242*e7776783SApple OSS Distributions 	proc_rele(p);
243*e7776783SApple OSS Distributions 
244*e7776783SApple OSS Distributions 	MAC_CHECK(proc_check_set_task_special_port, cred, &pident, which, port);
245*e7776783SApple OSS Distributions 	kauth_cred_unref(&cred);
246*e7776783SApple OSS Distributions 	return error;
247*e7776783SApple OSS Distributions }
248*e7776783SApple OSS Distributions 
249*e7776783SApple OSS Distributions int
mac_task_check_dyld_process_info_notify_register(void)250*e7776783SApple OSS Distributions mac_task_check_dyld_process_info_notify_register(void)
251*e7776783SApple OSS Distributions {
252*e7776783SApple OSS Distributions 	int error;
253*e7776783SApple OSS Distributions 	struct proc *p = current_proc();
254*e7776783SApple OSS Distributions 
255*e7776783SApple OSS Distributions 	kauth_cred_t cred = kauth_cred_proc_ref(p);
256*e7776783SApple OSS Distributions 	MAC_CHECK(proc_check_dyld_process_info_notify_register, cred);
257*e7776783SApple OSS Distributions 	kauth_cred_unref(&cred);
258*e7776783SApple OSS Distributions 	return error;
259*e7776783SApple OSS Distributions }
260*e7776783SApple OSS Distributions 
261*e7776783SApple OSS Distributions int
mac_task_check_set_host_exception_ports(struct task * task,unsigned int exception_mask)262*e7776783SApple OSS Distributions mac_task_check_set_host_exception_ports(struct task *task, unsigned int exception_mask)
263*e7776783SApple OSS Distributions {
264*e7776783SApple OSS Distributions 	int error = 0;
265*e7776783SApple OSS Distributions 	int exception;
266*e7776783SApple OSS Distributions 
267*e7776783SApple OSS Distributions 	struct proc *p = mac_task_get_proc(task);
268*e7776783SApple OSS Distributions 	if (p == NULL) {
269*e7776783SApple OSS Distributions 		return ESRCH;
270*e7776783SApple OSS Distributions 	}
271*e7776783SApple OSS Distributions 
272*e7776783SApple OSS Distributions 	kauth_cred_t cred = kauth_cred_proc_ref(p);
273*e7776783SApple OSS Distributions 	for (exception = FIRST_EXCEPTION; exception < EXC_TYPES_COUNT; exception++) {
274*e7776783SApple OSS Distributions 		if (exception_mask & (1 << exception)) {
275*e7776783SApple OSS Distributions 			MAC_CHECK(proc_check_set_host_exception_port, cred, exception);
276*e7776783SApple OSS Distributions 			if (error) {
277*e7776783SApple OSS Distributions 				break;
278*e7776783SApple OSS Distributions 			}
279*e7776783SApple OSS Distributions 		}
280*e7776783SApple OSS Distributions 	}
281*e7776783SApple OSS Distributions 	kauth_cred_unref(&cred);
282*e7776783SApple OSS Distributions 	proc_rele(p);
283*e7776783SApple OSS Distributions 	return error;
284*e7776783SApple OSS Distributions }
285*e7776783SApple OSS Distributions 
286*e7776783SApple OSS Distributions void
mac_thread_userret(struct thread * td)287*e7776783SApple OSS Distributions mac_thread_userret(struct thread *td)
288*e7776783SApple OSS Distributions {
289*e7776783SApple OSS Distributions 	MAC_PERFORM(thread_userret, td);
290*e7776783SApple OSS Distributions }
291*e7776783SApple OSS Distributions 
292*e7776783SApple OSS Distributions void
mac_thread_telemetry(struct thread * t,int err,void * data,size_t length)293*e7776783SApple OSS Distributions mac_thread_telemetry(struct thread *t, int err, void *data, size_t length)
294*e7776783SApple OSS Distributions {
295*e7776783SApple OSS Distributions 	MAC_PERFORM(thread_telemetry, t, err, data, length);
296*e7776783SApple OSS Distributions }
297*e7776783SApple OSS Distributions 
298*e7776783SApple OSS Distributions void
mac_proc_notify_exec_complete(struct proc * proc)299*e7776783SApple OSS Distributions mac_proc_notify_exec_complete(struct proc *proc)
300*e7776783SApple OSS Distributions {
301*e7776783SApple OSS Distributions 	thread_t thread = current_thread();
302*e7776783SApple OSS Distributions 
303*e7776783SApple OSS Distributions 	/*
304*e7776783SApple OSS Distributions 	 * Since this MAC hook was designed to support upcalls, make sure the hook
305*e7776783SApple OSS Distributions 	 * is called with kernel importance propagation enabled so any daemons
306*e7776783SApple OSS Distributions 	 * can get any appropriate importance donations.
307*e7776783SApple OSS Distributions 	 */
308*e7776783SApple OSS Distributions 	thread_enable_send_importance(thread, TRUE);
309*e7776783SApple OSS Distributions 	MAC_PERFORM(proc_notify_exec_complete, proc);
310*e7776783SApple OSS Distributions 	thread_enable_send_importance(thread, FALSE);
311*e7776783SApple OSS Distributions }
312*e7776783SApple OSS Distributions 
313*e7776783SApple OSS Distributions /**** Exception Policy
314*e7776783SApple OSS Distributions  *
315*e7776783SApple OSS Distributions  * Note that the functions below do not fully follow the usual convention for mac policy functions
316*e7776783SApple OSS Distributions  * in the kernel. Besides avoiding confusion in how the mac function names are mixed with the actual
317*e7776783SApple OSS Distributions  * policy function names, we diverge because the exception policy is somewhat special:
318*e7776783SApple OSS Distributions  * It is used in places where allocation and association must be separate, and its labels do not
319*e7776783SApple OSS Distributions  * only belong to one type of object as usual, but to two (on exception actions and on tasks as
320*e7776783SApple OSS Distributions  * crash labels).
321*e7776783SApple OSS Distributions  */
322*e7776783SApple OSS Distributions 
323*e7776783SApple OSS Distributions struct label *
mac_exc_label(struct exception_action * action)324*e7776783SApple OSS Distributions mac_exc_label(struct exception_action *action)
325*e7776783SApple OSS Distributions {
326*e7776783SApple OSS Distributions 	return mac_label_verify(&action->label);
327*e7776783SApple OSS Distributions }
328*e7776783SApple OSS Distributions 
329*e7776783SApple OSS Distributions void
mac_exc_set_label(struct exception_action * action,struct label * label)330*e7776783SApple OSS Distributions mac_exc_set_label(struct exception_action *action, struct label *label)
331*e7776783SApple OSS Distributions {
332*e7776783SApple OSS Distributions 	action->label = label;
333*e7776783SApple OSS Distributions }
334*e7776783SApple OSS Distributions 
335*e7776783SApple OSS Distributions // Label allocation and deallocation, may sleep.
336*e7776783SApple OSS Distributions 
337*e7776783SApple OSS Distributions struct label *
mac_exc_create_label(struct exception_action * action)338*e7776783SApple OSS Distributions mac_exc_create_label(struct exception_action *action)
339*e7776783SApple OSS Distributions {
340*e7776783SApple OSS Distributions 	return mac_labelzone_alloc_for_owner(action ? &action->label : NULL, MAC_WAITOK, ^(struct label *label) {
341*e7776783SApple OSS Distributions 		// Policy initialization of the label, typically performs allocations as well.
342*e7776783SApple OSS Distributions 		// (Unless the policy's full data really fits into a pointer size.)
343*e7776783SApple OSS Distributions 		MAC_PERFORM(exc_action_label_init, label);
344*e7776783SApple OSS Distributions 	});
345*e7776783SApple OSS Distributions }
346*e7776783SApple OSS Distributions 
347*e7776783SApple OSS Distributions void
mac_exc_free_label(struct label * label)348*e7776783SApple OSS Distributions mac_exc_free_label(struct label *label)
349*e7776783SApple OSS Distributions {
350*e7776783SApple OSS Distributions 	MAC_PERFORM(exc_action_label_destroy, label);
351*e7776783SApple OSS Distributions 	mac_labelzone_free(label);
352*e7776783SApple OSS Distributions }
353*e7776783SApple OSS Distributions 
354*e7776783SApple OSS Distributions // Action label initialization and teardown, may sleep.
355*e7776783SApple OSS Distributions 
356*e7776783SApple OSS Distributions void
mac_exc_associate_action_label(struct exception_action * action,struct label * label)357*e7776783SApple OSS Distributions mac_exc_associate_action_label(struct exception_action *action, struct label *label)
358*e7776783SApple OSS Distributions {
359*e7776783SApple OSS Distributions 	mac_exc_set_label(action, label);
360*e7776783SApple OSS Distributions 	MAC_PERFORM(exc_action_label_associate, action, mac_exc_label(action));
361*e7776783SApple OSS Distributions }
362*e7776783SApple OSS Distributions 
363*e7776783SApple OSS Distributions void
mac_exc_free_action_label(struct exception_action * action)364*e7776783SApple OSS Distributions mac_exc_free_action_label(struct exception_action *action)
365*e7776783SApple OSS Distributions {
366*e7776783SApple OSS Distributions 	mac_exc_free_label(mac_exc_label(action));
367*e7776783SApple OSS Distributions 	mac_exc_set_label(action, NULL);
368*e7776783SApple OSS Distributions }
369*e7776783SApple OSS Distributions 
370*e7776783SApple OSS Distributions // Action label update and inheritance, may NOT sleep and must be quick.
371*e7776783SApple OSS Distributions 
372*e7776783SApple OSS Distributions int
mac_exc_update_action_label(struct exception_action * action,struct label * newlabel)373*e7776783SApple OSS Distributions mac_exc_update_action_label(struct exception_action *action,
374*e7776783SApple OSS Distributions     struct label *newlabel)
375*e7776783SApple OSS Distributions {
376*e7776783SApple OSS Distributions 	int error;
377*e7776783SApple OSS Distributions 
378*e7776783SApple OSS Distributions 	MAC_CHECK(exc_action_label_update, action, mac_exc_label(action), newlabel);
379*e7776783SApple OSS Distributions 
380*e7776783SApple OSS Distributions 	return error;
381*e7776783SApple OSS Distributions }
382*e7776783SApple OSS Distributions 
383*e7776783SApple OSS Distributions int
mac_exc_inherit_action_label(struct exception_action * parent,struct exception_action * child)384*e7776783SApple OSS Distributions mac_exc_inherit_action_label(struct exception_action *parent,
385*e7776783SApple OSS Distributions     struct exception_action *child)
386*e7776783SApple OSS Distributions {
387*e7776783SApple OSS Distributions 	return mac_exc_update_action_label(child, mac_exc_label(parent));
388*e7776783SApple OSS Distributions }
389*e7776783SApple OSS Distributions 
390*e7776783SApple OSS Distributions int
mac_exc_update_task_crash_label(struct task * task,struct label * label)391*e7776783SApple OSS Distributions mac_exc_update_task_crash_label(struct task *task, struct label *label)
392*e7776783SApple OSS Distributions {
393*e7776783SApple OSS Distributions 	int error;
394*e7776783SApple OSS Distributions 
395*e7776783SApple OSS Distributions 	assert(task != kernel_task);
396*e7776783SApple OSS Distributions 
397*e7776783SApple OSS Distributions 	struct label *crash_label = get_task_crash_label(task);
398*e7776783SApple OSS Distributions 
399*e7776783SApple OSS Distributions 	MAC_CHECK(exc_action_label_update, NULL, crash_label, label);
400*e7776783SApple OSS Distributions 
401*e7776783SApple OSS Distributions 	return error;
402*e7776783SApple OSS Distributions }
403*e7776783SApple OSS Distributions 
404*e7776783SApple OSS Distributions // Process label creation, may sleep.
405*e7776783SApple OSS Distributions 
406*e7776783SApple OSS Distributions struct label *
mac_exc_create_label_for_proc(struct proc * proc)407*e7776783SApple OSS Distributions mac_exc_create_label_for_proc(struct proc *proc)
408*e7776783SApple OSS Distributions {
409*e7776783SApple OSS Distributions 	struct label *label = mac_exc_create_label(NULL);
410*e7776783SApple OSS Distributions 	MAC_PERFORM(exc_action_label_populate, label, proc);
411*e7776783SApple OSS Distributions 	return label;
412*e7776783SApple OSS Distributions }
413*e7776783SApple OSS Distributions 
414*e7776783SApple OSS Distributions struct label *
mac_exc_create_label_for_current_proc(void)415*e7776783SApple OSS Distributions mac_exc_create_label_for_current_proc(void)
416*e7776783SApple OSS Distributions {
417*e7776783SApple OSS Distributions 	return mac_exc_create_label_for_proc(current_proc());
418*e7776783SApple OSS Distributions }
419*e7776783SApple OSS Distributions 
420*e7776783SApple OSS Distributions // Exception handler policy checking, may sleep.
421*e7776783SApple OSS Distributions 
422*e7776783SApple OSS Distributions int
mac_exc_action_check_exception_send(struct task * victim_task,struct exception_action * action)423*e7776783SApple OSS Distributions mac_exc_action_check_exception_send(struct task *victim_task, struct exception_action *action)
424*e7776783SApple OSS Distributions {
425*e7776783SApple OSS Distributions 	int error = 0;
426*e7776783SApple OSS Distributions 
427*e7776783SApple OSS Distributions 	struct proc *p = get_bsdtask_info(victim_task);
428*e7776783SApple OSS Distributions 	struct label *bsd_label = NULL;
429*e7776783SApple OSS Distributions 	struct label *label = NULL;
430*e7776783SApple OSS Distributions 
431*e7776783SApple OSS Distributions 	if (p != NULL) {
432*e7776783SApple OSS Distributions 		// Create a label from the still existing bsd process...
433*e7776783SApple OSS Distributions 		label = bsd_label = mac_exc_create_label_for_proc(p);
434*e7776783SApple OSS Distributions 	} else {
435*e7776783SApple OSS Distributions 		// ... otherwise use the crash label on the task.
436*e7776783SApple OSS Distributions 		label = get_task_crash_label(victim_task);
437*e7776783SApple OSS Distributions 	}
438*e7776783SApple OSS Distributions 
439*e7776783SApple OSS Distributions 	if (label == NULL) {
440*e7776783SApple OSS Distributions 		MAC_MACH_UNEXPECTED("mac_exc_action_check_exception_send: no exc_action label for process");
441*e7776783SApple OSS Distributions 		return EPERM;
442*e7776783SApple OSS Distributions 	}
443*e7776783SApple OSS Distributions 
444*e7776783SApple OSS Distributions 	MAC_CHECK(exc_action_check_exception_send, label, action, mac_exc_label(action));
445*e7776783SApple OSS Distributions 
446*e7776783SApple OSS Distributions 	if (bsd_label != NULL) {
447*e7776783SApple OSS Distributions 		mac_exc_free_label(bsd_label);
448*e7776783SApple OSS Distributions 	}
449*e7776783SApple OSS Distributions 
450*e7776783SApple OSS Distributions 	return error;
451*e7776783SApple OSS Distributions }
452*e7776783SApple OSS Distributions 
453*e7776783SApple OSS Distributions int
mac_schedule_telemetry(void)454*e7776783SApple OSS Distributions mac_schedule_telemetry(void)
455*e7776783SApple OSS Distributions {
456*e7776783SApple OSS Distributions 	return telemetry_macf_mark_curthread();
457*e7776783SApple OSS Distributions }
458