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-2006 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 <ipc/ipc_space.h>
55 #include <ipc/ipc_port.h>
56 #include <ipc/ipc_labelh.h>
57 #include <kern/ipc_kobject.h>
58 #include <mach/security.h>
59 #include <security/mac_mach_internal.h>
62 zone_t ipc_labelh_zone
;
65 * Create a new label handle in the task described by the specified space.
66 * The specified label is used in the label handle. The associated port
67 * name is copied out to namep and the task is granted send and receive rights.
70 labelh_new_user(ipc_space_t space
, struct label
*inl
, mach_port_name_t
*namep
)
77 if (space
== IS_NULL
|| space
->is_task
== NULL
)
78 return (KERN_INVALID_TASK
);
80 /* XXX - perform entrypoint check here? */
83 * Note: the calling task will have a receive right for the port.
84 * This is different from label handles that reference tasks
85 * where the kernel holds the receive right and the caller only
88 kr
= ipc_port_alloc(space
, namep
, &port
);
89 if (kr
!= KERN_SUCCESS
)
91 ip_reference(port
); /* ipc_port_alloc() does not add a reference */
93 /* Convert right to MACH_PORT_TYPE_SEND_RECEIVE */
97 entry
= ipc_entry_lookup(space
, *namep
);
99 entry
->ie_bits
|= MACH_PORT_TYPE_SEND
;
100 is_write_unlock(space
);
102 /* Allocate new label handle, insert port and label. */
103 lh
= (ipc_labelh_t
)zalloc(ipc_labelh_zone
);
107 lh
->lh_type
= LABELH_TYPE_USER
;
108 lh
->lh_references
= 1; /* unused for LABELH_TYPE_USER */
110 /* Must call ipc_kobject_set() with port unlocked. */
111 ip_unlock(lh
->lh_port
);
112 ipc_kobject_set(lh
->lh_port
, (ipc_kobject_t
)lh
, IKOT_LABELH
);
114 return (KERN_SUCCESS
);
118 mac_label_new(ipc_space_t space
, mach_port_name_t
*namep
, labelstr_t labelstr
)
123 mac_task_label_init(&inl
);
124 if (mac_task_label_internalize(&inl
, labelstr
))
125 return (KERN_INVALID_ARGUMENT
);
127 kr
= labelh_new_user(space
, &inl
, namep
);
128 if (kr
!= KERN_SUCCESS
) {
129 mac_task_label_destroy(&inl
);
133 return (KERN_SUCCESS
);
137 * This function should be used to allocate label handles
138 * that are stored in other kernel objects, such as tasks.
139 * They must be released along with that object.
140 * The caller gets one reference, which can be applied to either the
141 * port or the ipc_label_t structure itself.
144 labelh_new(int canblock
)
148 lh
= (ipc_labelh_t
)zalloc_canblock(ipc_labelh_zone
, canblock
);
150 lh
->lh_port
= ipc_port_alloc_kernel();
151 lh
->lh_type
= LABELH_TYPE_KERN
;
152 lh
->lh_references
= 1;
153 ipc_kobject_set(lh
->lh_port
, (ipc_kobject_t
)lh
, IKOT_LABELH
);
159 * Call with old label handle locked.
160 * Returned label handle is unlocked.
163 labelh_duplicate(ipc_labelh_t old
)
168 ip_lock(lh
->lh_port
);
169 mac_task_label_init(&lh
->lh_label
);
170 mac_task_label_copy(&old
->lh_label
, &lh
->lh_label
);
171 ip_unlock(lh
->lh_port
);
176 * Call with old label handle locked.
177 * Returned label handle is locked.
180 labelh_modify(ipc_labelh_t old
)
185 * A label handle may only have a single reference.
186 * If there are no other references this is a no-op.
187 * Otherwise, make a copy we can write to and return it.
189 if (old
->lh_references
== 1)
191 lh
= labelh_duplicate(old
);
193 lh_check_unlock(old
);
199 * Add or drop a reference on an (unlocked) label handle.
202 labelh_reference(ipc_labelh_t lh
)
211 * Release a reference on an (unlocked) label handle.
214 labelh_release(ipc_labelh_t lh
)
222 * Deallocate space associated with the label handle backed by the
223 * specified port. For kernel-allocated label handles the
224 * label handle reference count should be 0. For user-allocated
225 * handles the ref count is not used (it was initialized to 1).
228 labelh_destroy(ipc_port_t port
)
230 ipc_labelh_t lh
= (ipc_labelh_t
) port
->ip_kobject
;
232 mac_task_label_destroy(&lh
->lh_label
);
233 zfree(ipc_labelh_zone
, (vm_offset_t
)lh
);
237 mac_label_new(__unused ipc_space_t space
,
238 __unused mach_port_name_t
*namep
,
239 __unused labelstr_t labelstr
)
243 #endif /* MAC_MACH */