From 05b0fe74bb6eb10a49333d42f9f1677235863f85 Mon Sep 17 00:00:00 2001 From: Alexandra Ellwood Date: Tue, 12 Jun 2007 21:07:16 +0000 Subject: Add advisory locking to CCAPI Added code to trash client crashes. Reorganized server launch to make it easier to implement platform specific code. ticket: new status: open git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@19573 dc483132-0cff-0310-8789-dd5450dbe970 --- src/ccapi/server/mac/ccs_os_pipe.c | 44 +------ src/ccapi/server/mac/ccs_os_server.c | 236 +++++++++++++++++++++++++++++++++++ src/ccapi/server/mac/main.c | 233 ---------------------------------- 3 files changed, 238 insertions(+), 275 deletions(-) create mode 100644 src/ccapi/server/mac/ccs_os_server.c delete mode 100644 src/ccapi/server/mac/main.c (limited to 'src/ccapi/server/mac') diff --git a/src/ccapi/server/mac/ccs_os_pipe.c b/src/ccapi/server/mac/ccs_os_pipe.c index d22ffe353..0b5fa8952 100644 --- a/src/ccapi/server/mac/ccs_os_pipe.c +++ b/src/ccapi/server/mac/ccs_os_pipe.c @@ -28,51 +28,11 @@ #include "ccs_os_pipe.h" #include -/* On Mac OS X ccs_os_pipe_t is a mach_port_t */ +/* On Mac OS X ccs_pipe_t is a mach_port_t */ /* ------------------------------------------------------------------------ */ -cc_int32 ccs_os_pipe_copy (ccs_os_pipe_t *out_pipe, - ccs_os_pipe_t in_pipe) -{ - cc_int32 err = ccNoError; - - if (!out_pipe) { err = cci_check_error (ccErrBadParam); } - - if (!err) { - *out_pipe = in_pipe; - } - - return cci_check_error (err); -} - -/* ------------------------------------------------------------------------ */ - -cc_int32 ccs_os_pipe_release (ccs_os_pipe_t io_pipe) -{ - return ccNoError; -} - -/* ------------------------------------------------------------------------ */ - -cc_int32 ccs_os_pipe_compare (ccs_os_pipe_t in_pipe, - ccs_os_pipe_t in_compare_to_pipe, - cc_uint32 *out_equal) -{ - cc_int32 err = ccNoError; - - if (!out_equal) { err = cci_check_error (ccErrBadParam); } - - if (!err) { - *out_equal = (in_pipe == in_compare_to_pipe); - } - - return cci_check_error (err); -} - -/* ------------------------------------------------------------------------ */ - -cc_int32 ccs_os_pipe_valid (ccs_os_pipe_t in_pipe) +cc_int32 ccs_os_pipe_valid (ccs_pipe_t in_pipe) { return MACH_PORT_VALID (in_pipe); } diff --git a/src/ccapi/server/mac/ccs_os_server.c b/src/ccapi/server/mac/ccs_os_server.c new file mode 100644 index 000000000..eefac4c8a --- /dev/null +++ b/src/ccapi/server/mac/ccs_os_server.c @@ -0,0 +1,236 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccs_common.h" + +#include +#include +#include "cci_mig_requestServer.h" +#include "cci_mig_reply.h" +#include "ccs_os_server.h" + + +/* ------------------------------------------------------------------------ */ + +static boolean_t ccs_server_demux (mach_msg_header_t *request, + mach_msg_header_t *reply) +{ + boolean_t handled = false; + + if (!handled) { + handled = ccs_server (request, reply); + } + + if (!handled && request->msgh_id == MACH_NOTIFY_NO_SENDERS) { + kern_return_t err = KERN_SUCCESS; + + err = ccs_server_remove_client (request->msgh_local_port); + + if (!err) { + /* Check here for a client in our table and free rights associated with it */ + err = mach_port_mod_refs (mach_task_self (), request->msgh_local_port, + MACH_PORT_RIGHT_RECEIVE, -1); + } + + if (!err) { + handled = 1; /* was a port we are tracking */ + } + + cci_check_error (err); + } + + return handled; +} + +/* ------------------------------------------------------------------------ */ + +kern_return_t ccs_mipc_create_client_connection (mach_port_t in_server_port, + mach_port_t *out_connection_port) +{ + kern_return_t err = KERN_SUCCESS; + mach_port_t connection_port = MACH_PORT_NULL; + mach_port_t old_notification_target = MACH_PORT_NULL; + + if (!err) { + err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &connection_port); + } + + if (!err) { + err = mach_port_move_member (mach_task_self (), connection_port, kipc_server_get_listen_portset ()); + } + + if (!err) { + /* request no-senders notification so we can tell when client quits/crashes */ + err = mach_port_request_notification (mach_task_self (), connection_port, + MACH_NOTIFY_NO_SENDERS, 1, connection_port, + MACH_MSG_TYPE_MAKE_SEND_ONCE, &old_notification_target ); + } + + if (!err) { + err = ccs_server_add_client (connection_port); + } + + if (!err) { + *out_connection_port = connection_port; + connection_port = MACH_PORT_NULL; + } + + if (MACH_PORT_VALID (connection_port)) { mach_port_deallocate (mach_task_self (), connection_port); } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +kern_return_t ccs_mipc_request (mach_port_t in_connection_port, + mach_port_t in_reply_port, + cci_mipc_inl_request_t in_inl_request, + mach_msg_type_number_t in_inl_requestCnt, + cci_mipc_ool_request_t in_ool_request, + mach_msg_type_number_t in_ool_requestCnt) +{ + kern_return_t err = KERN_SUCCESS; + cci_stream_t request_stream = NULL; + + if (!err) { + err = cci_stream_new (&request_stream); + } + + if (!err) { + if (in_inl_requestCnt) { + err = cci_stream_write (request_stream, in_inl_request, in_inl_requestCnt); + + } else if (in_ool_requestCnt) { + err = cci_stream_write (request_stream, in_ool_request, in_ool_requestCnt); + + } else { + err = cci_check_error (ccErrBadInternalMessage); + } + } + + if (!err) { + err = ccs_server_handle_request (in_connection_port, in_reply_port, request_stream); + } + + cci_stream_release (request_stream); + if (in_ool_requestCnt) { vm_deallocate (mach_task_self (), (vm_address_t) in_ool_request, in_ool_requestCnt); } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_os_server_initialize (int argc, const char *argv[]) +{ + cc_int32 err = 0; + + openlog (argv[0], LOG_CONS | LOG_PID, LOG_AUTH); + syslog (LOG_INFO, "Starting up."); + + syslog (LOG_NOTICE, "Exiting: %s (%d)", kipc_error_string (err), err); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_os_server_cleanup (int argc, const char *argv[]) +{ + cc_int32 err = 0; + + openlog (argv[0], LOG_CONS | LOG_PID, LOG_AUTH); + syslog (LOG_INFO, "Starting up."); + + syslog (LOG_NOTICE, "Exiting: %s (%d)", kipc_error_string (err), err); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_os_server_listen_loop (int argc, const char *argv[]) +{ + /* Run the Mach IPC listen loop. + * This will call ccs_mipc_create_client_connection for new clients + * and ccs_mipc_request for existing clients */ + + return cci_check_error (kipc_server_run_server (ccs_server_demux)); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_os_server_send_reply (ccs_pipe_t in_reply_pipe, + cci_stream_t in_reply_stream) +{ + kern_return_t err = KERN_SUCCESS; + cci_mipc_inl_reply_t inl_reply; + mach_msg_type_number_t inl_reply_length = 0; + cci_mipc_ool_reply_t ool_reply = NULL; + mach_msg_type_number_t ool_reply_length = 0; + + if (!ccs_pipe_valid (in_reply_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!in_reply_stream ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + /* depending on how big the message is, use the fast inline buffer or + * the slow dynamically allocated buffer */ + mach_msg_type_number_t reply_length = cci_stream_size (in_reply_stream); + + if (reply_length > kCCAPIMaxILMsgSize) { + cci_debug_printf ("%s choosing out of line buffer (size is %d)", + __FUNCTION__, reply_length); + + err = vm_read (mach_task_self (), + (vm_address_t) cci_stream_data (in_reply_stream), reply_length, + (vm_address_t *) &ool_reply, &ool_reply_length); + + } else { + //cci_debug_printf ("%s choosing in line buffer (size is %d)", + // __FUNCTION__, reply_length); + + inl_reply_length = reply_length; + memcpy (inl_reply, cci_stream_data (in_reply_stream), reply_length); + } + } + + if (!err) { + err = ccs_mipc_reply (in_reply_pipe, + inl_reply, inl_reply_length, + ool_reply, ool_reply_length); + } + + if (!err) { + /* Because we use ",dealloc" ool_reply will be freed by mach. Don't double free it. */ + ool_reply = NULL; + ool_reply_length = 0; + } + + if (ool_reply_length) { vm_deallocate (mach_task_self (), (vm_address_t) ool_reply, ool_reply_length); } + + return cci_check_error (err); +} diff --git a/src/ccapi/server/mac/main.c b/src/ccapi/server/mac/main.c deleted file mode 100644 index 0753a240b..000000000 --- a/src/ccapi/server/mac/main.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * $Header$ - * - * Copyright 2006 Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. Furthermore if you modify this software you must label - * your software as modified software and not distribute it in such a - * fashion that it might be confused with the original M.I.T. software. - * M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - */ - -#include "ccs_common.h" - -#include -#include -#include "cci_mig_requestServer.h" -#include "cci_mig_reply.h" -#include "ccs_os_server.h" - -/* ------------------------------------------------------------------------ */ - -static boolean_t ccs_server_demux (mach_msg_header_t *request, - mach_msg_header_t *reply) -{ - boolean_t handled = false; - - if (!handled) { - handled = ccs_server (request, reply); - } - - if (!handled && request->msgh_id == MACH_NOTIFY_NO_SENDERS) { - kern_return_t err = KERN_SUCCESS; - - err = ccs_server_remove_client (request->msgh_local_port); - - if (!err) { - /* Check here for a client in our table and free rights associated with it */ - err = mach_port_mod_refs (mach_task_self (), request->msgh_local_port, - MACH_PORT_RIGHT_RECEIVE, -1); - } - - if (!err) { - handled = 1; /* was a port we are tracking */ - } - - cci_check_error (err); - } - - return handled; -} - -/* ------------------------------------------------------------------------ */ - -int main (int argc, const char *argv[]) -{ - cc_int32 err = 0; - - openlog (argv[0], LOG_CONS | LOG_PID, LOG_AUTH); - syslog (LOG_INFO, "Starting up."); - - if (!err) { - err = ccs_server_initialize (); - } - - if (!err) { - err = kipc_server_run_server (ccs_server_demux); - } - - /* cleanup ccs resources */ - ccs_server_cleanup (); - - syslog (LOG_NOTICE, "Exiting: %s (%d)", kipc_error_string (err), err); - - /* exit */ - return err ? 1 : 0; -} - -/* ------------------------------------------------------------------------ */ - -kern_return_t ccs_mipc_create_client_connection (mach_port_t in_server_port, - mach_port_t *out_connection_port) -{ - kern_return_t err = KERN_SUCCESS; - mach_port_t connection_port = MACH_PORT_NULL; - mach_port_t old_notification_target = MACH_PORT_NULL; - - if (!err) { - err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &connection_port); - } - - if (!err) { - err = mach_port_move_member (mach_task_self (), connection_port, kipc_server_get_listen_portset ()); - } - - if (!err) { - /* request no-senders notification so we can tell when client quits/crashes */ - err = mach_port_request_notification (mach_task_self (), connection_port, - MACH_NOTIFY_NO_SENDERS, 1, connection_port, - MACH_MSG_TYPE_MAKE_SEND_ONCE, &old_notification_target ); - } - - if (!err) { - err = ccs_server_add_client (connection_port); - } - - if (!err) { - *out_connection_port = connection_port; - connection_port = MACH_PORT_NULL; - } - - if (MACH_PORT_VALID (connection_port)) { mach_port_deallocate (mach_task_self (), connection_port); } - - return cci_check_error (err); -} - -/* ------------------------------------------------------------------------ */ - -cc_int32 ccs_os_server_send_reply (ccs_pipe_t in_reply_pipe, - cci_stream_t in_reply_stream) -{ - kern_return_t err = KERN_SUCCESS; - cci_mipc_inl_reply_t inl_reply; - mach_msg_type_number_t inl_reply_length = 0; - cci_mipc_ool_reply_t ool_reply = NULL; - mach_msg_type_number_t ool_reply_length = 0; - - if (!ccs_pipe_valid (in_reply_pipe)) { err = cci_check_error (ccErrBadParam); } - if (!in_reply_stream ) { err = cci_check_error (ccErrBadParam); } - - if (!err) { - /* depending on how big the message is, use the fast inline buffer or - * the slow dynamically allocated buffer */ - mach_msg_type_number_t reply_length = cci_stream_size (in_reply_stream); - - if (reply_length > kCCAPIMaxILMsgSize) { - cci_debug_printf ("%s choosing out of line buffer (size is %d)", - __FUNCTION__, reply_length); - - err = vm_read (mach_task_self (), - (vm_address_t) cci_stream_data (in_reply_stream), reply_length, - (vm_address_t *) &ool_reply, &ool_reply_length); - - } else { - //cci_debug_printf ("%s choosing in line buffer (size is %d)", - // __FUNCTION__, reply_length); - - inl_reply_length = reply_length; - memcpy (inl_reply, cci_stream_data (in_reply_stream), reply_length); - } - } - - if (!err) { - err = ccs_mipc_reply (ccs_pipe_os (in_reply_pipe), - inl_reply, inl_reply_length, - ool_reply, ool_reply_length); - } - - if (!err) { - /* Because we use ",dealloc" ool_reply will be freed by mach. Don't double free it. */ - ool_reply = NULL; - ool_reply_length = 0; - } - - if (ool_reply_length) { vm_deallocate (mach_task_self (), (vm_address_t) ool_reply, ool_reply_length); } - - return cci_check_error (err); -} - - -/* ------------------------------------------------------------------------ */ - -kern_return_t ccs_mipc_request (mach_port_t in_connection_port, - mach_port_t in_reply_port, - cci_mipc_inl_request_t in_inl_request, - mach_msg_type_number_t in_inl_requestCnt, - cci_mipc_ool_request_t in_ool_request, - mach_msg_type_number_t in_ool_requestCnt) -{ - kern_return_t err = KERN_SUCCESS; - cci_stream_t request_stream = NULL; - ccs_pipe_t connection_pipe = NULL; - ccs_pipe_t reply_pipe = NULL; - - if (!err) { - err = cci_stream_new (&request_stream); - } - - if (!err) { - if (in_inl_requestCnt) { - err = cci_stream_write (request_stream, in_inl_request, in_inl_requestCnt); - - } else if (in_ool_requestCnt) { - err = cci_stream_write (request_stream, in_ool_request, in_ool_requestCnt); - - } else { - err = cci_check_error (ccErrBadInternalMessage); - } - } - - if (!err) { - err = ccs_pipe_new (&connection_pipe, in_connection_port); - } - - if (!err) { - err = ccs_pipe_new (&reply_pipe, in_reply_port); - } - - if (!err) { - err = ccs_server_handle_request (connection_pipe, reply_pipe, request_stream); - } - - ccs_pipe_release (connection_pipe); - ccs_pipe_release (reply_pipe); - cci_stream_release (request_stream); - if (in_ool_requestCnt) { vm_deallocate (mach_task_self (), (vm_address_t) in_ool_request, in_ool_requestCnt); } - - return cci_check_error (err); -} -- cgit