From c4baf67b71e20d1fdd2cc6bda1a2ea15e9853cdd Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Thu, 21 Nov 2013 17:23:31 +0100 Subject: ipc: implement mach_port_{set,clear}_protected_payload * include/mach/mach_port.defs: Add mach_port_{set,clear}_protected_payload. * ipc/mach_port.c: Implement mach_port_{set,clear}_protected_payload. * doc/mach.texi (Receive Rights): Document mach_port_{set,clear}_protected_payload. --- doc/mach.texi | 35 ++++++++++++++++++++++ include/mach/mach_port.defs | 18 +++++++++++ ipc/mach_port.c | 73 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 126 insertions(+) diff --git a/doc/mach.texi b/doc/mach.texi index 2da670f..3175df1 100644 --- a/doc/mach.texi +++ b/doc/mach.texi @@ -2715,6 +2715,41 @@ In addition to the normal diagnostic return codes from the call's server (normally the kernel), the call may return @code{mach_msg} return codes. @end deftypefun +@deftypefun kern_return_t mach_port_set_protected_payload (@w{ipc_space_t @var{task}}, @w{mach_port_t @var{name}}, @w{unsigned long @var{payload}}) +The function @code{mach_port_set_protected_payload} sets the protected +payload associated with the right @var{name} to @var{payload}. +Section @ref{Message Receive} describes how setting a protected +payload affects the messages delivered to @var{name}. + +The function returns @code{KERN_SUCCESS} if the call succeeded, +@code{KERN_INVALID_TASK} if @var{task} was invalid, +@code{KERN_INVALID_NAME} if @var{name} did not denote a right and +@code{KERN_INVALID_RIGHT} if @var{name} denoted a right, but not a +receive right. + +The @code{mach_port_set_protected_payload} call is actually an RPC to +@var{task}, normally a send right for a task port, but potentially any +send right. In addition to the normal diagnostic return codes from +the call's server (normally the kernel), the call may return +@code{mach_msg} return codes. +@end deftypefun + +@deftypefun kern_return_t mach_port_clear_protected_payload (@w{ipc_space_t @var{task}}, @w{mach_port_t @var{name}}, @w{unsigned long @var{payload}}) +The function @code{mach_port_clear_protected_payload} clears the +protected payload associated with the right @var{name}. + +The function returns @code{KERN_SUCCESS} if the call succeeded, +@code{KERN_INVALID_TASK} if @var{task} was invalid, +@code{KERN_INVALID_NAME} if @var{name} did not denote a right and +@code{KERN_INVALID_RIGHT} if @var{name} denoted a right, but not a +receive right. + +The @code{mach_port_clear_protected_payload} call is actually an RPC +to @var{task}, normally a send right for a task port, but potentially +any send right. In addition to the normal diagnostic return codes +from the call's server (normally the kernel), the call may return +@code{mach_msg} return codes. +@end deftypefun @node Port Sets @subsection Port Sets diff --git a/include/mach/mach_port.defs b/include/mach/mach_port.defs index 769d892..c7e8526 100644 --- a/include/mach/mach_port.defs +++ b/include/mach/mach_port.defs @@ -349,3 +349,21 @@ skip; /* mach_port_create_act */ #endif /* MIGRATING_THREADS */ +/* + * Only valid for receive rights. + * Set the protected payload for this right to the given value. + */ + +routine mach_port_set_protected_payload( + task : ipc_space_t; + name : mach_port_name_t; + payload : natural_t); + +/* + * Only valid for receive rights. + * Clear the protected payload for this right. + */ + +routine mach_port_clear_protected_payload( + task : ipc_space_t; + name : mach_port_name_t); diff --git a/ipc/mach_port.c b/ipc/mach_port.c index 4a4efcc..4ff39f2 100644 --- a/ipc/mach_port.c +++ b/ipc/mach_port.c @@ -1564,3 +1564,76 @@ mach_port_set_syscall_right( } #endif #endif /* MIGRATING_THREADS */ + +/* + * Routine: mach_port_set_protected_payload [kernel call] + * Purpose: + * Changes a receive right's protected payload. + * Conditions: + * Nothing locked. + * Returns: + * KERN_SUCCESS Set protected payload. + * KERN_INVALID_TASK The space is null. + * KERN_INVALID_TASK The space is dead. + * KERN_INVALID_NAME The name doesn't denote a right. + * KERN_INVALID_RIGHT Name doesn't denote receive rights. + */ + +kern_return_t +mach_port_set_protected_payload( + ipc_space_t space, + mach_port_t name, + unsigned long payload) +{ + ipc_port_t port; + kern_return_t kr; + + if (space == IS_NULL) + return KERN_INVALID_TASK; + + kr = ipc_port_translate_receive(space, name, &port); + if (kr != KERN_SUCCESS) + return kr; + /* port is locked and active */ + + ipc_port_set_protected_payload(port, payload); + + ip_unlock(port); + return KERN_SUCCESS; +} + +/* + * Routine: mach_port_clear_protected_payload [kernel call] + * Purpose: + * Clears a receive right's protected payload. + * Conditions: + * Nothing locked. + * Returns: + * KERN_SUCCESS Clear protected payload. + * KERN_INVALID_TASK The space is null. + * KERN_INVALID_TASK The space is dead. + * KERN_INVALID_NAME The name doesn't denote a right. + * KERN_INVALID_RIGHT Name doesn't denote receive rights. + */ + +kern_return_t +mach_port_clear_protected_payload( + ipc_space_t space, + mach_port_t name) +{ + ipc_port_t port; + kern_return_t kr; + + if (space == IS_NULL) + return KERN_INVALID_TASK; + + kr = ipc_port_translate_receive(space, name, &port); + if (kr != KERN_SUCCESS) + return kr; + /* port is locked and active */ + + ipc_port_clear_protected_payload(port); + + ip_unlock(port); + return KERN_SUCCESS; +} -- cgit v1.2.3