1/*
2 * Copyright (c) 2011 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
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.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
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.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29#include <mach/mach_types.h>
30#include <mach/mach_traps.h>
31#include <mach/mach_vm_server.h>
32#include <mach/mach_port_server.h>
33#include <mach/vm_map.h>
34#include <kern/task.h>
35#include <kern/ipc_tt.h>
36#include <vm/vm_protos.h>
37
38int
39_kernelrpc_mach_vm_allocate_trap(struct _kernelrpc_mach_vm_allocate_trap_args *args)
40{
41	mach_vm_offset_t addr;
42	task_t task = port_name_to_task(args->target);
43	int rv = MACH_SEND_INVALID_DEST;
44
45	if (task != current_task())
46		goto done;
47
48	if (copyin(args->addr, (char *)&addr, sizeof (addr)))
49		goto done;
50
51	rv = mach_vm_allocate(task->map, &addr, args->size, args->flags);
52	if (rv == KERN_SUCCESS)
53		rv = copyout(&addr, args->addr, sizeof (addr));
54
55done:
56	if (task)
57		task_deallocate(task);
58	return (rv);
59}
60
61int
62_kernelrpc_mach_vm_deallocate_trap(struct _kernelrpc_mach_vm_deallocate_args *args)
63{
64	task_t task = port_name_to_task(args->target);
65	int rv = MACH_SEND_INVALID_DEST;
66
67	if (task != current_task())
68		goto done;
69
70	rv = mach_vm_deallocate(task->map, args->address, args->size);
71
72done:
73	if (task)
74		task_deallocate(task);
75	return (rv);
76}
77
78int
79_kernelrpc_mach_vm_protect_trap(struct _kernelrpc_mach_vm_protect_args *args)
80{
81	task_t task = port_name_to_task(args->target);
82	int rv = MACH_SEND_INVALID_DEST;
83
84	if (task != current_task())
85		goto done;
86
87	rv = mach_vm_protect(task->map, args->address, args->size,
88	    args->set_maximum, args->new_protection);
89
90done:
91	if (task)
92		task_deallocate(task);
93	return (rv);
94}
95
96int
97_kernelrpc_mach_vm_map_trap(struct _kernelrpc_mach_vm_map_trap_args *args)
98{
99	mach_vm_offset_t addr;
100	task_t task = port_name_to_task(args->target);
101	int rv = MACH_SEND_INVALID_DEST;
102
103	if (task != current_task())
104		goto done;
105
106	if (copyin(args->addr, (char *)&addr, sizeof (addr)))
107		goto done;
108
109	rv = mach_vm_map(task->map, &addr, args->size, args->mask, args->flags,
110			IPC_PORT_NULL, 0, FALSE, args->cur_protection, VM_PROT_ALL,
111			VM_INHERIT_DEFAULT);
112	if (rv == KERN_SUCCESS)
113		rv = copyout(&addr, args->addr, sizeof (addr));
114
115done:
116	if (task)
117		task_deallocate(task);
118	return (rv);
119}
120
121int
122_kernelrpc_mach_port_allocate_trap(struct _kernelrpc_mach_port_allocate_args *args)
123{
124	task_t task = port_name_to_task(args->target);
125	mach_port_name_t name;
126	int rv = MACH_SEND_INVALID_DEST;
127
128	if (task != current_task())
129		goto done;
130
131	rv = mach_port_allocate(task->itk_space, args->right, &name);
132	if (rv == KERN_SUCCESS)
133		rv = copyout(&name, args->name, sizeof (name));
134
135
136done:
137	if (task)
138		task_deallocate(task);
139	return (rv);
140}
141
142int
143_kernelrpc_mach_port_destroy_trap(struct _kernelrpc_mach_port_destroy_args *args)
144{
145	task_t task = port_name_to_task(args->target);
146	int rv = MACH_SEND_INVALID_DEST;
147
148	if (task != current_task())
149		goto done;
150
151	rv = mach_port_destroy(task->itk_space, args->name);
152
153done:
154	if (task)
155		task_deallocate(task);
156	return (rv);
157}
158
159int
160_kernelrpc_mach_port_deallocate_trap(struct _kernelrpc_mach_port_deallocate_args *args)
161{
162	task_t task = port_name_to_task(args->target);
163	int rv = MACH_SEND_INVALID_DEST;
164
165	if (task != current_task())
166		goto done;
167
168	rv = mach_port_deallocate(task->itk_space, args->name);
169
170done:
171	if (task)
172		task_deallocate(task);
173	return (rv);
174}
175
176int
177_kernelrpc_mach_port_mod_refs_trap(struct _kernelrpc_mach_port_mod_refs_args *args)
178{
179	task_t task = port_name_to_task(args->target);
180	int rv = MACH_SEND_INVALID_DEST;
181
182	if (task != current_task())
183		goto done;
184
185	rv = mach_port_mod_refs(task->itk_space, args->name, args->right, args->delta);
186
187done:
188	if (task)
189		task_deallocate(task);
190	return (rv);
191}
192
193
194int
195_kernelrpc_mach_port_move_member_trap(struct _kernelrpc_mach_port_move_member_args *args)
196{
197	task_t task = port_name_to_task(args->target);
198	int rv = MACH_SEND_INVALID_DEST;
199
200	if (task != current_task())
201		goto done;
202
203	rv = mach_port_move_member(task->itk_space, args->member, args->after);
204
205done:
206	if (task)
207		task_deallocate(task);
208	return (rv);
209}
210
211int
212_kernelrpc_mach_port_insert_right_trap(struct _kernelrpc_mach_port_insert_right_args *args)
213{
214	task_t task = port_name_to_task(args->target);
215	ipc_port_t port;
216	mach_msg_type_name_t disp;
217	int rv = MACH_SEND_INVALID_DEST;
218
219	if (task != current_task())
220		goto done;
221
222	rv = ipc_object_copyin(task->itk_space, args->poly, args->polyPoly,
223	    (ipc_object_t *)&port);
224	if (rv != KERN_SUCCESS)
225		goto done;
226	disp = ipc_object_copyin_type(args->polyPoly);
227
228	rv = mach_port_insert_right(task->itk_space, args->name, port, disp);
229
230done:
231	if (task)
232		task_deallocate(task);
233	return (rv);
234}
235
236int
237_kernelrpc_mach_port_insert_member_trap(struct _kernelrpc_mach_port_insert_member_args *args)
238{
239	task_t task = port_name_to_task(args->target);
240	int rv = MACH_SEND_INVALID_DEST;
241
242	if (task != current_task())
243		goto done;
244
245	rv = mach_port_insert_member(task->itk_space, args->name, args->pset);
246
247done:
248	if (task)
249		task_deallocate(task);
250	return (rv);
251}
252
253
254int
255_kernelrpc_mach_port_extract_member_trap(struct _kernelrpc_mach_port_extract_member_args *args)
256{
257	task_t task = port_name_to_task(args->target);
258	int rv = MACH_SEND_INVALID_DEST;
259
260	if (task != current_task())
261		goto done;
262
263	rv = mach_port_extract_member(task->itk_space, args->name, args->pset);
264
265done:
266	if (task)
267		task_deallocate(task);
268	return (rv);
269}
270
271int
272_kernelrpc_mach_port_construct_trap(struct _kernelrpc_mach_port_construct_args *args)
273{
274	task_t task = port_name_to_task(args->target);
275	mach_port_name_t name;
276	int rv = MACH_SEND_INVALID_DEST;
277	mach_port_options_t options;
278
279	if (copyin(args->options, (char *)&options, sizeof (options))) {
280		rv = MACH_SEND_INVALID_DATA;
281		goto done;
282	}
283
284	if (task != current_task())
285		goto done;
286
287	rv = mach_port_construct(task->itk_space, &options, args->context, &name);
288	if (rv == KERN_SUCCESS)
289		rv = copyout(&name, args->name, sizeof (name));
290
291done:
292	if (task)
293		task_deallocate(task);
294	return (rv);
295}
296
297int
298_kernelrpc_mach_port_destruct_trap(struct _kernelrpc_mach_port_destruct_args *args)
299{
300	task_t task = port_name_to_task(args->target);
301	int rv = MACH_SEND_INVALID_DEST;
302
303	if (task != current_task())
304		goto done;
305
306	rv = mach_port_destruct(task->itk_space, args->name, args->srdelta, args->guard);
307
308done:
309	if (task)
310		task_deallocate(task);
311	return (rv);
312}
313
314int
315_kernelrpc_mach_port_guard_trap(struct _kernelrpc_mach_port_guard_args *args)
316{
317	task_t task = port_name_to_task(args->target);
318	int rv = MACH_SEND_INVALID_DEST;
319
320	if (task != current_task())
321		goto done;
322
323	rv = mach_port_guard(task->itk_space, args->name, args->guard, args->strict);
324
325done:
326	if (task)
327		task_deallocate(task);
328	return (rv);
329}
330
331int
332_kernelrpc_mach_port_unguard_trap(struct _kernelrpc_mach_port_unguard_args *args)
333{
334	task_t task = port_name_to_task(args->target);
335	int rv = MACH_SEND_INVALID_DEST;
336
337	if (task != current_task())
338		goto done;
339
340	rv = mach_port_unguard(task->itk_space, args->name, args->guard);
341
342done:
343	if (task)
344		task_deallocate(task);
345	return (rv);
346}
347
348