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) 2005-2007 SPARTA, Inc.
30 * All rights reserved.
32 * Redistribution and use in source and binary forms, with or without
33 * modification, are permitted provided that the following conditions
35 * 1. Redistributions of source code must retain the above copyright
36 * notice, this list of conditions and the following disclaimer.
37 * 2. Redistributions in binary form must reproduce the above copyright
38 * notice, this list of conditions and the following disclaimer in the
39 * documentation and/or other materials provided with the distribution.
41 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54 #include <mach/message.h>
55 #include <kern/kern_types.h>
56 #include <kern/ipc_kobject.h>
57 #include <ipc/ipc_object.h>
58 #include <ipc/ipc_right.h>
59 #include <ipc/ipc_labelh.h>
60 #include <kern/task.h>
61 #include <security/mac_mach_internal.h>
62 #include <mach/security.h>
68 mach_port_name_t
*outlabel
)
73 if (space
== IS_NULL
|| space
->is_task
== NULL
)
74 return KERN_INVALID_TASK
;
76 lh
= space
->is_task
->label
;
78 lh
->lh_port
->ip_mscount
++;
79 lh
->lh_port
->ip_srights
++;
80 ip_reference(lh
->lh_port
);
81 ip_unlock(lh
->lh_port
);
82 kr
= ipc_object_copyout(space
, (ipc_object_t
) lh
->lh_port
,
83 MACH_MSG_TYPE_PORT_SEND
, 0, outlabel
);
84 if (kr
!= KERN_SUCCESS
) {
85 ip_release(lh
->lh_port
);
86 *outlabel
= MACH_PORT_NULL
;
89 return (KERN_SUCCESS
);
94 ipc_space_t space __unused
,
95 mach_port_name_t
*outlabel __unused
)
103 mach_get_task_label_text(
109 if (space
== IS_NULL
|| space
->is_task
== NULL
)
110 return KERN_INVALID_TASK
;
112 tasklabel_lock(space
->is_task
);
113 mac_task_label_externalize(&space
->is_task
->maclabel
, policies
, outl
,
115 tasklabel_unlock(space
->is_task
);
121 mach_get_task_label_text(
122 ipc_space_t space __unused
,
123 labelstr_t policies __unused
,
124 labelstr_t outl __unused
)
132 mac_task_check_service(
137 tasklabel_lock2(self
, obj
);
139 int rc
= mac_port_check_service(
140 &self
->maclabel
, &obj
->maclabel
,
143 tasklabel_unlock2(self
, obj
);
149 mac_task_check_service(
150 task_t self __unused
,
152 const char * perm __unused
)
161 __unused ipc_space_t space
,
167 struct label subjl
, objl
;
169 mac_task_label_init(&subjl
);
170 int rc
= mac_port_label_internalize(&subjl
, subj
);
172 mac_task_label_destroy(&subjl
);
173 return KERN_INVALID_ARGUMENT
;
175 mac_task_label_init(&objl
);
176 rc
= mac_port_label_internalize(&objl
, obj
);
178 mac_task_label_destroy(&subjl
);
179 mac_task_label_destroy(&objl
);
180 return KERN_INVALID_ARGUMENT
;
183 rc
= mac_port_check_service(&subjl
, &objl
, serv
, perm
);
184 mac_task_label_destroy(&subjl
);
185 mac_task_label_destroy(&objl
);
187 return rc
? KERN_NO_ACCESS
: KERN_SUCCESS
;
192 __unused ipc_space_t space
,
193 __unused labelstr_t subj
,
194 __unused labelstr_t obj
,
195 __unused labelstr_t serv
,
196 __unused labelstr_t perm
)
204 mac_port_check_service_obj(
207 mach_port_name_t obj
,
218 if (space
== IS_NULL
|| space
->is_task
== NULL
)
219 return KERN_INVALID_TASK
;
221 if (!MACH_PORT_VALID(obj
))
222 return KERN_INVALID_NAME
;
224 mac_task_label_init(&subjl
);
225 int rc
= mac_port_label_internalize(&subjl
, subj
);
227 mac_task_label_destroy(&subjl
);
228 return KERN_INVALID_ARGUMENT
;
231 kr
= ipc_right_lookup_write(space
, obj
, &entry
);
232 if (kr
!= KERN_SUCCESS
) {
233 mac_task_label_destroy(&subjl
);
237 objp
= entry
->ie_object
;
238 port
= (ipc_port_t
)objp
;
239 dead
= ipc_right_check(space
, port
, obj
, entry
);
241 is_write_unlock(space
);
243 mac_task_label_destroy(&subjl
);
244 return KERN_INVALID_RIGHT
;
248 is_write_unlock (space
);
250 objl
= io_getlabel(objp
);
253 return KERN_INVALID_ARGUMENT
;
256 rc
= mac_port_check_service(&subjl
, objl
, serv
, perm
);
257 io_unlocklabel(objp
);
260 mac_task_label_destroy(&subjl
);
261 return rc
? KERN_NO_ACCESS
: KERN_SUCCESS
;
265 mac_port_check_service_obj(
266 __unused ipc_space_t space
,
267 __unused labelstr_t subj
,
268 __unused mach_port_name_t obj
,
269 __unused labelstr_t serv
,
270 __unused labelstr_t perm
)
278 mac_port_check_access(
280 mach_port_name_t sub
,
281 mach_port_name_t obj
,
285 ipc_entry_t subi
, obji
;
286 ipc_object_t subp
, objp
;
288 struct label
*objl
, *subl
;
291 if (space
== IS_NULL
|| space
->is_task
== NULL
)
292 return KERN_INVALID_TASK
;
294 if (!MACH_PORT_VALID(obj
) || !MACH_PORT_VALID(sub
))
295 return KERN_INVALID_NAME
;
297 kr
= ipc_right_lookup_two_write(space
, obj
, &obji
, sub
, &subi
);
298 if (kr
!= KERN_SUCCESS
)
301 objp
= obji
->ie_object
;
302 subp
= subi
->ie_object
;
304 ipc_port_multiple_lock(); /* serialize (not necessary for LH, but simpler) */
307 is_write_unlock (space
);
309 objl
= io_getlabel(objp
);
312 subl
= io_getlabel(subp
);
316 rc
= mac_port_check_service(subl
, objl
, serv
, perm
);
317 io_unlocklabel(subp
);
319 io_unlocklabel(objp
);
321 ipc_port_multiple_unlock();
323 return rc
? KERN_NO_ACCESS
: KERN_SUCCESS
;
326 io_unlocklabel(subp
);
328 io_unlocklabel(objp
);
330 ipc_port_multiple_unlock();
331 return KERN_INVALID_ARGUMENT
;
335 mac_port_check_access(
336 __unused ipc_space_t space
,
337 __unused mach_port_name_t sub
,
338 __unused mach_port_name_t obj
,
339 __unused labelstr_t serv
,
340 __unused labelstr_t perm
)
350 mach_port_name_t sub
,
351 mach_port_name_t obj
,
353 mach_port_name_t
*outlabel
)
355 ipc_entry_t subi
, obji
;
356 ipc_object_t subp
, objp
;
358 struct label
*objl
, *subl
, outl
;
361 if (space
== IS_NULL
|| space
->is_task
== NULL
)
362 return KERN_INVALID_TASK
;
364 if (!MACH_PORT_VALID(obj
) || !MACH_PORT_VALID(sub
))
365 return KERN_INVALID_NAME
;
367 kr
= ipc_right_lookup_two_write(space
, obj
, &obji
, sub
, &subi
);
368 if (kr
!= KERN_SUCCESS
)
371 objp
= obji
->ie_object
;
372 subp
= subi
->ie_object
;
374 ipc_port_multiple_lock(); /* serialize (not necessary for LH, but simpler) */
377 is_write_unlock (space
);
379 objl
= io_getlabel(objp
);
382 subl
= io_getlabel(subp
);
386 mac_port_label_init(&outl
);
387 rc
= mac_port_label_compute(subl
, objl
, serv
, &outl
);
388 io_unlocklabel(subp
);
390 io_unlocklabel(objp
);
392 ipc_port_multiple_unlock();
395 kr
= labelh_new_user(space
, &outl
, outlabel
);
399 if (kr
!= KERN_SUCCESS
)
400 mac_port_label_destroy(&outl
);
405 io_unlocklabel(subp
);
407 io_unlocklabel(objp
);
409 ipc_port_multiple_unlock();
410 return KERN_INVALID_ARGUMENT
;
412 #else /* !MAC_MACH */
416 __unused ipc_space_t space
,
417 __unused mach_port_name_t sub
,
418 __unused mach_port_name_t obj
,
419 __unused labelstr_t serv
,
420 __unused mach_port_name_t
*outlabel
)
425 #endif /* MAC_MACH */