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