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