* i386/i386/copy_user.h: add copyin/copyout helpers for ports and vm addresses. * include/mach/mach_types.h: replace mach_port_t with mach_port_name_t * kern/ipc_host.c: Likewise * kern/ipc_tt.c: Likewise * kern/ipc_tt.h: Likewise * kern/syscall_sw.c Likewise * kern/syscall_subr.c Likewise * kern/syscall_subr.h: Likewise * kern/ipc_mig.h: replace mach_port_t with mach_port_name_t and vm_* types with rpc_vm_* counterpart. * kern/ipc_mig.c: update syscall prototypes and adapt to kernel types - for vm types use copyin_address() and copyout_address() helpers - for mach_port_name_t use copyin_port() and copyout_port() helpers
Signed-off-by: Luca Dariz <l...@orpolo.org> --- i386/i386/copy_user.h | 64 ++++++++++++++++++++++++++++++++ include/mach/mach_traps.h | 18 ++------- kern/ipc_host.c | 2 +- kern/ipc_mig.c | 78 ++++++++++++++++++++------------------- kern/ipc_mig.h | 58 ++++++++++++++--------------- kern/ipc_tt.c | 6 +-- kern/ipc_tt.h | 2 +- kern/syscall_subr.c | 2 +- kern/syscall_subr.h | 2 +- kern/syscall_sw.c | 2 +- 10 files changed, 145 insertions(+), 89 deletions(-) diff --git a/i386/i386/copy_user.h b/i386/i386/copy_user.h index ab932401..20487529 100644 --- a/i386/i386/copy_user.h +++ b/i386/i386/copy_user.h @@ -2,11 +2,75 @@ #ifndef COPY_USER_H #define COPY_USER_H +#include <stdint.h> + #include <sys/types.h> #include <machine/locore.h> #include <mach/message.h> +/* + * The copyin_32to64() and copyout_64to32() routines are meant for data types + * that have different size in kernel and user space. They should be independent + * of endianness and hopefully can be reused in the future on other archs. + * These types are e.g.: + * - port names vs port pointers, on a 64-bit kernel + * - memory addresses, on a 64-bit kernel and 32-bit user + */ + +static inline int copyin_32to64(uint32_t *uaddr, uint64_t *kaddr) +{ + uint32_t rkaddr; + int ret; + ret = copyin(uaddr, &rkaddr, sizeof(uint32_t)); + if (ret) + return ret; + *kaddr = rkaddr; + return 0; +} + +static inline int copyout_64to32(uint64_t *kaddr, uint32_t *uaddr) +{ + uint32_t rkaddr=*kaddr; + return copyout(&rkaddr, uaddr, sizeof(uint32_t)); +} + +static inline int copyin_address(rpc_vm_offset_t *uaddr, vm_offset_t *kaddr) +{ +#ifdef __x86_64 + return copyin_32to64(uaddr, kaddr); +#else + return copyin(uaddr, kaddr, sizeof(*uaddr)); +#endif +} + +static inline int copyout_address(vm_offset_t *kaddr, rpc_vm_offset_t *uaddr) +{ +#ifdef __x86_64 + return copyout_64to32(kaddr, uaddr); +#else + return copyout(kaddr, uaddr, sizeof(*kaddr)); +#endif +} + +static inline int copyin_port(mach_port_name_t *uaddr, mach_port_t *kaddr) +{ +#ifdef __x86_64 + return copyin_32to64(uaddr, kaddr); +#else + return copyin(uaddr, kaddr, sizeof(*uaddr)); +#endif +} + +static inline int copyout_port(mach_port_t *kaddr, mach_port_name_t *uaddr) +{ +#ifdef __x86_64 + return copyout_64to32(kaddr, uaddr); +#else + return copyout(kaddr, uaddr, sizeof(*kaddr)); +#endif +} + // XXX we could add another field to kmsg to store the user-side size, but then we // should check if we can obtain it for rpc and notifications originating from // the kernel diff --git a/include/mach/mach_traps.h b/include/mach/mach_traps.h index 0433707a..2a87f62a 100644 --- a/include/mach/mach_traps.h +++ b/include/mach/mach_traps.h @@ -35,19 +35,9 @@ #include <mach/port.h> -mach_port_t mach_reply_port - (void); - -mach_port_t mach_thread_self - (void); - -#ifdef __386BSD__ -#undef mach_task_self -#endif -mach_port_t mach_task_self - (void); - -mach_port_t mach_host_self - (void); +mach_port_name_t mach_reply_port (void); +mach_port_name_t mach_thread_self (void); +mach_port_name_t mach_task_self (void); +mach_port_name_t mach_host_self (void); #endif /* _MACH_MACH_TRAPS_H_ */ diff --git a/kern/ipc_host.c b/kern/ipc_host.c index a02eb6f6..6163beff 100644 --- a/kern/ipc_host.c +++ b/kern/ipc_host.c @@ -94,7 +94,7 @@ void ipc_host_init(void) * or other errors. */ -mach_port_t +mach_port_name_t mach_host_self(void) { ipc_port_t sright; diff --git a/kern/ipc_mig.c b/kern/ipc_mig.c index 22dac420..f77c189b 100644 --- a/kern/ipc_mig.c +++ b/kern/ipc_mig.c @@ -29,6 +29,7 @@ #include <mach/message.h> #include <mach/thread_status.h> #include <machine/locore.h> +#include <machine/copy_user.h> #include <kern/ast.h> #include <kern/debug.h> #include <kern/ipc_tt.h> @@ -619,13 +620,13 @@ kern_return_t thread_set_state_KERNEL( kern_return_t syscall_vm_map( - mach_port_t target_map, - vm_offset_t *address, - vm_size_t size, - vm_offset_t mask, + mach_port_name_t target_map, + rpc_vm_offset_t *address, + rpc_vm_size_t size, + rpc_vm_offset_t mask, boolean_t anywhere, - mach_port_t memory_object, - vm_offset_t offset, + mach_port_name_t memory_object, + rpc_vm_offset_t offset, boolean_t copy, vm_prot_t cur_protection, vm_prot_t max_protection, @@ -651,12 +652,12 @@ syscall_vm_map( } else port = (ipc_port_t) memory_object; - copyin(address, &addr, sizeof(vm_offset_t)); + copyin_address(address, &addr); result = vm_map(map, &addr, size, mask, anywhere, port, offset, copy, cur_protection, max_protection, inheritance); if (result == KERN_SUCCESS) - copyout(&addr, address, sizeof(vm_offset_t)); + copyout_address(&addr, address); if (IP_VALID(port)) ipc_port_release_send(port); vm_map_deallocate(map); @@ -665,9 +666,9 @@ syscall_vm_map( } kern_return_t syscall_vm_allocate( - mach_port_t target_map, - vm_offset_t *address, - vm_size_t size, + mach_port_name_t target_map, + rpc_vm_offset_t *address, + rpc_vm_size_t size, boolean_t anywhere) { vm_map_t map; @@ -678,19 +679,19 @@ kern_return_t syscall_vm_allocate( if (map == VM_MAP_NULL) return MACH_SEND_INTERRUPTED; - copyin(address, &addr, sizeof(vm_offset_t)); + copyin_address(address, &addr); result = vm_allocate(map, &addr, size, anywhere); if (result == KERN_SUCCESS) - copyout(&addr, address, sizeof(vm_offset_t)); + copyout_address(&addr, address); vm_map_deallocate(map); return result; } kern_return_t syscall_vm_deallocate( - mach_port_t target_map, - vm_offset_t start, - vm_size_t size) + mach_port_name_t target_map, + rpc_vm_offset_t start, + rpc_vm_size_t size) { vm_map_t map; kern_return_t result; @@ -706,9 +707,9 @@ kern_return_t syscall_vm_deallocate( } kern_return_t syscall_task_create( - mach_port_t parent_task, - boolean_t inherit_memory, - mach_port_t *child_task) /* OUT */ + mach_port_name_t parent_task, + boolean_t inherit_memory, + mach_port_name_t *child_task) /* OUT */ { task_t t, c; ipc_port_t port; @@ -726,15 +727,14 @@ kern_return_t syscall_task_create( (void) ipc_kmsg_copyout_object(current_space(), (ipc_object_t) port, MACH_MSG_TYPE_PORT_SEND, &name); - copyout(&name, child_task, - sizeof(mach_port_t)); + copyout_port(&name, child_task); } task_deallocate(t); return result; } -kern_return_t syscall_task_terminate(mach_port_t task) +kern_return_t syscall_task_terminate(mach_port_name_t task) { task_t t; kern_return_t result; @@ -749,7 +749,7 @@ kern_return_t syscall_task_terminate(mach_port_t task) return result; } -kern_return_t syscall_task_suspend(mach_port_t task) +kern_return_t syscall_task_suspend(mach_port_name_t task) { task_t t; kern_return_t result; @@ -765,9 +765,9 @@ kern_return_t syscall_task_suspend(mach_port_t task) } kern_return_t syscall_task_set_special_port( - mach_port_t task, - int which_port, - mach_port_t port_name) + mach_port_name_t task, + int which_port, + mach_port_name_t port_name) { task_t t; ipc_port_t port; @@ -798,9 +798,9 @@ kern_return_t syscall_task_set_special_port( kern_return_t syscall_mach_port_allocate( - mach_port_t task, + mach_port_name_t task, mach_port_right_t right, - mach_port_t *namep) + mach_port_name_t *namep) { ipc_space_t space; mach_port_t name; @@ -812,7 +812,9 @@ syscall_mach_port_allocate( kr = mach_port_allocate(space, right, &name); if (kr == KERN_SUCCESS) - copyout(&name, namep, sizeof(mach_port_t)); + { + copyout_port(&name, namep); + } is_release(space); return kr; @@ -820,9 +822,9 @@ syscall_mach_port_allocate( kern_return_t syscall_mach_port_allocate_name( - mach_port_t task, - mach_port_right_t right, - mach_port_t name) + mach_port_name_t task, + mach_port_right_t right, + mach_port_name_t name) { ipc_space_t space; kern_return_t kr; @@ -839,8 +841,8 @@ syscall_mach_port_allocate_name( kern_return_t syscall_mach_port_deallocate( - mach_port_t task, - mach_port_t name) + mach_port_name_t task, + mach_port_name_t name) { ipc_space_t space; kern_return_t kr; @@ -857,10 +859,10 @@ syscall_mach_port_deallocate( kern_return_t syscall_mach_port_insert_right( - mach_port_t task, - mach_port_t name, - mach_port_t right, - mach_msg_type_name_t rightType) + mach_port_name_t task, + mach_port_name_t name, + mach_port_name_t right, + mach_msg_type_name_t rightType) { ipc_space_t space; ipc_object_t object; diff --git a/kern/ipc_mig.h b/kern/ipc_mig.h index 6f063eca..a343c595 100644 --- a/kern/ipc_mig.h +++ b/kern/ipc_mig.h @@ -64,62 +64,62 @@ extern mach_msg_return_t mach_msg_rpc_from_kernel( mach_msg_size_t reply_size); extern kern_return_t syscall_vm_map( - mach_port_t target_map, - vm_offset_t *address, - vm_size_t size, - vm_offset_t mask, + mach_port_name_t target_map, + rpc_vm_offset_t *address, + rpc_vm_size_t size, + rpc_vm_offset_t mask, boolean_t anywhere, - mach_port_t memory_object, - vm_offset_t offset, + mach_port_name_t memory_object, + rpc_vm_offset_t offset, boolean_t copy, vm_prot_t cur_protection, vm_prot_t max_protection, vm_inherit_t inheritance); extern kern_return_t syscall_vm_allocate( - mach_port_t target_map, - vm_offset_t *address, - vm_size_t size, + mach_port_name_t target_map, + rpc_vm_offset_t *address, + rpc_vm_size_t size, boolean_t anywhere); extern kern_return_t syscall_vm_deallocate( - mach_port_t target_map, - vm_offset_t start, - vm_size_t size); + mach_port_name_t target_map, + rpc_vm_offset_t start, + rpc_vm_size_t size); extern kern_return_t syscall_task_create( - mach_port_t parent_task, - boolean_t inherit_memory, - mach_port_t *child_task); + mach_port_name_t parent_task, + boolean_t inherit_memory, + mach_port_name_t *child_task); -extern kern_return_t syscall_task_terminate(mach_port_t task); +extern kern_return_t syscall_task_terminate(mach_port_name_t task); -extern kern_return_t syscall_task_suspend(mach_port_t task); +extern kern_return_t syscall_task_suspend(mach_port_name_t task); extern kern_return_t syscall_task_set_special_port( - mach_port_t task, + mach_port_name_t task, int which_port, - mach_port_t port_name); + mach_port_name_t port_name); extern kern_return_t syscall_mach_port_allocate( - mach_port_t task, - mach_port_right_t right, - mach_port_t *namep); + mach_port_name_t task, + mach_port_right_t right, + mach_port_name_t *namep); extern kern_return_t syscall_mach_port_deallocate( - mach_port_t task, - mach_port_t name); + mach_port_name_t task, + mach_port_name_t name); extern kern_return_t syscall_mach_port_insert_right( - mach_port_t task, - mach_port_t name, - mach_port_t right, + mach_port_name_t task, + mach_port_name_t name, + mach_port_name_t right, mach_msg_type_name_t rightType); extern kern_return_t syscall_mach_port_allocate_name( - mach_port_t task, + mach_port_name_t task, mach_port_right_t right, - mach_port_t name); + mach_port_name_t name); extern kern_return_t syscall_thread_depress_abort(mach_port_t thread); diff --git a/kern/ipc_tt.c b/kern/ipc_tt.c index 04a5a92f..1f8c5136 100644 --- a/kern/ipc_tt.c +++ b/kern/ipc_tt.c @@ -511,7 +511,7 @@ retrieve_thread_exception(thread) * or other errors. */ -mach_port_t +mach_port_name_t mach_task_self(void) { task_t task = current_task(); @@ -532,7 +532,7 @@ mach_task_self(void) * or other errors. */ -mach_port_t +mach_port_name_t mach_thread_self(void) { thread_t thread = current_thread(); @@ -554,7 +554,7 @@ mach_thread_self(void) * or other errors. */ -mach_port_t +mach_port_name_t mach_reply_port(void) { ipc_port_t port; diff --git a/kern/ipc_tt.h b/kern/ipc_tt.h index 78cb43ad..5c667387 100644 --- a/kern/ipc_tt.h +++ b/kern/ipc_tt.h @@ -86,7 +86,7 @@ convert_port_to_space(struct ipc_port *); extern void space_deallocate(ipc_space_t); -mach_port_t +mach_port_name_t mach_reply_port (void); #endif /* _KERN_IPC_TT_H_ */ diff --git a/kern/syscall_subr.c b/kern/syscall_subr.c index 6d23462c..d1ea0af1 100644 --- a/kern/syscall_subr.c +++ b/kern/syscall_subr.c @@ -152,7 +152,7 @@ void thread_switch_continue(void) * even if that violates priority order. */ kern_return_t thread_switch( - mach_port_t thread_name, + mach_port_name_t thread_name, int option, mach_msg_timeout_t option_time) { diff --git a/kern/syscall_subr.h b/kern/syscall_subr.h index b6b61ab2..c9a2777f 100644 --- a/kern/syscall_subr.h +++ b/kern/syscall_subr.h @@ -33,7 +33,7 @@ extern int swtch(void); extern int swtch_pri(int); -extern int thread_switch(mach_port_t, int, mach_msg_timeout_t); +extern int thread_switch(mach_port_name_t, int, mach_msg_timeout_t); extern void thread_depress_timeout(thread_t); extern kern_return_t thread_depress_abort(thread_t); extern void mach_print(const char *); diff --git a/kern/syscall_sw.c b/kern/syscall_sw.c index a383e467..7f958a7e 100644 --- a/kern/syscall_sw.c +++ b/kern/syscall_sw.c @@ -60,7 +60,7 @@ boolean_t kern_invalid_debug = FALSE; -mach_port_t null_port(void) +mach_port_name_t null_port(void) { if (kern_invalid_debug) SoftDebugger("null_port mach trap"); return(MACH_PORT_NULL); -- 2.30.2