@@ -212,78 +212,67 @@ static void send_reply(mach_msg_header_t *request,
212212 }
213213 else
214214 {
215- kr = mach_port_mod_refs (task, req->thread , MACH_PORT_RIGHT_SEND, 1 );
216-
217- if (kr != KERN_SUCCESS)
218- {
219- goto skip_thread_port_extraction;
220- }
221-
222- kr = mach_port_extract_right (task, req->thread , MACH_MSG_TYPE_COPY_SEND, &thread, NULL );
223-
215+ kr = task_thread_for_unique_id (task, req->thread , &thread);
224216 if (kr != KERN_SUCCESS)
225217 {
226- mach_port_mod_refs (task, req-> thread , MACH_PORT_RIGHT_SEND, - 1 ) ;
227- req-> thread = MACH_PORT_NULL ;
228- goto skip_thread_port_extraction ;
218+ err = EAGAIN ;
219+ result = - 1 ;
220+ goto cleanup ;
229221 }
230222 }
231223
232- skip_thread_port_extraction:
224+ /* getting the syscall handler the kernel virtualisation layer previously has set */
225+ syscall_handler_t handler = NULL ;
226+
227+ /* checking syscall bounds */
228+ if (req->syscall_num < MAX_SYSCALLS)
233229 {
234- /* getting the syscall handler the kernel virtualisation layer previously has set */
235- syscall_handler_t handler = NULL ;
236-
237- /* checking syscall bounds */
238- if (req->syscall_num < MAX_SYSCALLS)
239- {
240- /* getting handler if bounds are valid */
241- handler = server->handlers [req->syscall_num];
242- }
243-
244- /* checking if the handler was set by the kernel virtualisation layer */
245- if (!handler)
246- {
247- klog_log (@" syscall" , @" syscall from pid %d failed (EXCEPTION: %d is not a valid syscall)" , proc_getpid (proc_copy), req->syscall_num );
248- err = ENOSYS;
249- result = -1 ;
250- goto cleanup;
251- }
252-
253- /* calling syscall handler */
254- result = handler (task, thread, proc_copy, req->args , (req->oolp .disposition == MACH_MSG_TYPE_MOVE_RECEIVE) ? NULL : (mach_port_t *)(req->oolp .address ), (req->oolp .disposition == MACH_MSG_TYPE_MOVE_RECEIVE) ? 0 : req->oolp .count , &out_ports, &out_ports_cnt, &err, &name, (req->oolp .disposition == MACH_MSG_TYPE_MOVE_RECEIVE) ? *((mach_port_t *)req->oolp .address ) : MACH_PORT_NULL);
255-
256- cleanup:
257-
258- /* deallocate what the guest requested via input ports (avoiding port leaks is a extremely good idea ^^) */
259- vm_deallocate (mach_task_self (), (mach_vm_address_t )req->oolp .address , req->oolp .count * sizeof (mach_port_t ));
260-
261- /* destroying copy of process */
262- if (proc_copy != NULL )
263- {
264- /* check for errno and log if errno is indeed set */
265- if (err != 0 && err != ENOSYS)
266- {
267- klog_log (@" syscall" , @" syscall(%s ) from pid %d failed (ERRNO=%s )" , name, proc_getpid (proc_copy), strerror (err));
268- }
269-
270- proc_copy_destroy (proc_copy);
271- }
272-
273- /* checking task and thread */
274- if (task != MACH_PORT_NULL)
275- {
276- mach_port_deallocate (mach_task_self (), task);
277- }
278-
279- if (thread != MACH_PORT_NULL)
230+ /* getting handler if bounds are valid */
231+ handler = server->handlers [req->syscall_num];
232+ }
233+
234+ /* checking if the handler was set by the kernel virtualisation layer */
235+ if (!handler)
236+ {
237+ klog_log (@" syscall" , @" syscall from pid %d failed (EXCEPTION: %d is not a valid syscall)" , proc_getpid (proc_copy), req->syscall_num );
238+ err = ENOSYS;
239+ result = -1 ;
240+ goto cleanup;
241+ }
242+
243+ /* calling syscall handler */
244+ result = handler (task, thread, proc_copy, req->args , (req->oolp .disposition == MACH_MSG_TYPE_MOVE_RECEIVE) ? NULL : (mach_port_t *)(req->oolp .address ), (req->oolp .disposition == MACH_MSG_TYPE_MOVE_RECEIVE) ? 0 : req->oolp .count , &out_ports, &out_ports_cnt, &err, &name, (req->oolp .disposition == MACH_MSG_TYPE_MOVE_RECEIVE) ? *((mach_port_t *)req->oolp .address ) : MACH_PORT_NULL);
245+
246+ cleanup:
247+
248+ /* deallocate what the guest requested via input ports (avoiding port leaks is a extremely good idea ^^) */
249+ vm_deallocate (mach_task_self (), (mach_vm_address_t )req->oolp .address , req->oolp .count * sizeof (mach_port_t ));
250+
251+ /* destroying copy of process */
252+ if (proc_copy != NULL )
253+ {
254+ /* check for errno and log if errno is indeed set */
255+ if (err != 0 && err != ENOSYS)
280256 {
281- mach_port_deallocate ( mach_task_self (), thread );
257+ klog_log ( @" syscall " , @" syscall( %s ) from pid %d failed (ERRNO= %s ) " , name, proc_getpid (proc_copy), strerror (err) );
282258 }
283259
284- /* reply !!!AFTER!!! deallocation */
285- send_reply (&buffer.header , result, out_ports, out_ports_cnt, err);
260+ proc_copy_destroy (proc_copy);
286261 }
262+
263+ /* checking task and thread */
264+ if (task != MACH_PORT_NULL)
265+ {
266+ mach_port_deallocate (mach_task_self (), task);
267+ }
268+
269+ if (thread != MACH_PORT_NULL)
270+ {
271+ mach_port_deallocate (mach_task_self (), thread);
272+ }
273+
274+ /* reply !!!AFTER!!! deallocation */
275+ send_reply (&buffer.header , result, out_ports, out_ports_cnt, err);
287276 }
288277
289278 return NULL ;
0 commit comments