X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/d1ecb069dfe24481e4a83f44cb5217a2b06746d7..3e170ce000f1506b7b5d2c5c7faec85ceabb573d:/osfmk/kern/ipc_kobject.c diff --git a/osfmk/kern/ipc_kobject.c b/osfmk/kern/ipc_kobject.c index a0cc915a8..1789ae5f6 100644 --- a/osfmk/kern/ipc_kobject.c +++ b/osfmk/kern/ipc_kobject.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2008 Apple Inc. All rights reserved. + * Copyright (c) 2000-2010 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -72,10 +72,7 @@ #include #include -#include -#include #include -#include #include #include @@ -93,16 +90,16 @@ #include #include #include -#include #include #include #include #include #include -#include #include #include #include +#include +#include #if VM32_SUPPORT #include #endif @@ -133,13 +130,17 @@ #include #include #include -#include +#include +#include #include #include #include +extern char *proc_name_address(void *p); +extern int proc_pid(void *p); + /* * Routine: ipc_kobject_notify * Purpose: @@ -159,20 +160,16 @@ typedef struct { #endif } mig_hash_t; -#define MAX_MIG_ENTRIES 1024 +#define MAX_MIG_ENTRIES 1031 #define MIG_HASH(x) (x) #ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) #endif /* max */ -mig_hash_t mig_buckets[MAX_MIG_ENTRIES]; -int mig_table_max_displ; -mach_msg_size_t mig_reply_size; - -#if CONFIG_MACF -#include -#endif +static mig_hash_t mig_buckets[MAX_MIG_ENTRIES]; +static int mig_table_max_displ; +static mach_msg_size_t mig_reply_size = sizeof(mig_reply_error_t); @@ -187,9 +184,7 @@ const struct mig_subsystem *mig_e[] = { (const struct mig_subsystem *)&processor_subsystem, (const struct mig_subsystem *)&processor_set_subsystem, (const struct mig_subsystem *)&is_iokit_subsystem, - (const struct mig_subsystem *)&memory_object_name_subsystem, (const struct mig_subsystem *)&lock_set_subsystem, - (const struct mig_subsystem *)&ledger_subsystem, (const struct mig_subsystem *)&task_subsystem, (const struct mig_subsystem *)&thread_act_subsystem, #if VM32_SUPPORT @@ -197,6 +192,8 @@ const struct mig_subsystem *mig_e[] = { #endif (const struct mig_subsystem *)&UNDReply_subsystem, (const struct mig_subsystem *)&default_pager_object_subsystem, + (const struct mig_subsystem *)&mach_voucher_subsystem, + (const struct mig_subsystem *)&mach_voucher_attr_control_subsystem, #if XK_PROXY (const struct mig_subsystem *)&do_uproxy_xk_uproxy_subsystem, @@ -207,10 +204,6 @@ const struct mig_subsystem *mig_e[] = { #if MCMSG && iPSC860 (const struct mig_subsystem *)&mcmsg_info_subsystem, #endif /* MCMSG && iPSC860 */ - -#if CONFIG_MACF - (const struct mig_subsystem *)&security_subsystem, -#endif }; void @@ -224,7 +217,6 @@ mig_init(void) range = mig_e[i]->end - mig_e[i]->start; if (!mig_e[i]->start || range < 0) panic("the msgh_ids in mig_e[] aren't valid!"); - mig_reply_size = max(mig_reply_size, mig_e[i]->maxsize); for (j = 0; j < range; j++) { if (mig_e[i]->routine[j].stub_routine) { @@ -317,13 +309,21 @@ ipc_kobject_server( #define InP ((mach_msg_header_t *) request->ikm_header) #define OutP ((mig_reply_error_t *) reply->ikm_header) + /* + * MIG should really assure no data leakage - + * but until it does, pessimistically zero the + * whole reply buffer. + */ + bzero((void *)OutP, reply_size); + OutP->NDR = NDR_record; OutP->Head.msgh_size = sizeof(mig_reply_error_t); OutP->Head.msgh_bits = - MACH_MSGH_BITS(MACH_MSGH_BITS_LOCAL(InP->msgh_bits), 0); + MACH_MSGH_BITS_SET(MACH_MSGH_BITS_LOCAL(InP->msgh_bits), 0, 0, 0); OutP->Head.msgh_remote_port = InP->msgh_local_port; - OutP->Head.msgh_local_port = MACH_PORT_NULL; + OutP->Head.msgh_local_port = MACH_PORT_NULL; + OutP->Head.msgh_voucher_port = MACH_PORT_NULL; OutP->Head.msgh_id = InP->msgh_id + 100; #undef InP @@ -382,6 +382,17 @@ ipc_kobject_server( } *destp = IP_NULL; + /* + * Destroy voucher. The kernel MIG servers never take ownership + * of vouchers sent in messages. Swallow any such rights here. + */ + if (IP_VALID(request->ikm_voucher)) { + assert(MACH_MSG_TYPE_PORT_SEND == + MACH_MSGH_BITS_VOUCHER(request->ikm_header->msgh_bits)); + ipc_port_release_send(request->ikm_voucher); + request->ikm_voucher = IP_NULL; + } + if (!(reply->ikm_header->msgh_bits & MACH_MSGH_BITS_COMPLEX) && ((mig_reply_error_t *) reply->ikm_header)->RetCode != KERN_SUCCESS) kr = ((mig_reply_error_t *) reply->ikm_header)->RetCode; @@ -457,11 +468,6 @@ ipc_kobject_set( { ip_lock(port); ipc_kobject_set_atomically(port, kobject, type); - -#if CONFIG_MACF_MACH - mac_port_label_update_kobject (&port->ip_label, type); -#endif - ip_unlock(port); } @@ -511,12 +517,6 @@ ipc_kobject_destroy( host_notify_port_destroy(port); break; -#if CONFIG_MACF_MACH - case IKOT_LABELH: - labelh_destroy(port); - break; -#endif - default: break; } @@ -533,40 +533,49 @@ ipc_kobject_notify( ((mig_reply_error_t *) reply_header)->RetCode = MIG_NO_REPLY; switch (request_header->msgh_id) { case MACH_NOTIFY_NO_SENDERS: - if(ip_kotype(port) == IKOT_NAMED_ENTRY) { - ip_lock(port); - - /* - * Bring the sequence number and mscount in - * line with ipc_port_destroy assertion. - */ - port->ip_mscount = 0; - port->ip_messages.imq_seqno = 0; - ipc_port_destroy(port); /* releases lock */ - return TRUE; - } - if (ip_kotype(port) == IKOT_UPL) { - upl_no_senders( - request_header->msgh_remote_port, - (mach_port_mscount_t) - ((mach_no_senders_notification_t *) - request_header)->not_count); - reply_header->msgh_remote_port = MACH_PORT_NULL; - return TRUE; - } + switch (ip_kotype(port)) { + case IKOT_VOUCHER: + ipc_voucher_notify(request_header); + return TRUE; + + case IKOT_VOUCHER_ATTR_CONTROL: + ipc_voucher_attr_control_notify(request_header); + return TRUE; + + case IKOT_SEMAPHORE: + semaphore_notify(request_header); + return TRUE; + + case IKOT_NAMED_ENTRY: + ip_lock(port); + + /* + * Bring the sequence number and mscount in + * line with ipc_port_destroy assertion. + */ + port->ip_mscount = 0; + port->ip_messages.imq_seqno = 0; + ipc_port_destroy(port); /* releases lock */ + return TRUE; + + case IKOT_UPL: + upl_no_senders( + request_header->msgh_remote_port, + (mach_port_mscount_t) + ((mach_no_senders_notification_t *) + request_header)->not_count); + reply_header->msgh_remote_port = MACH_PORT_NULL; + return TRUE; + #if CONFIG_AUDIT - if (ip_kotype(port) == IKOT_AU_SESSIONPORT) { - audit_session_nosenders(request_header); - return TRUE; - } + case IKOT_AU_SESSIONPORT: + audit_session_nosenders(request_header); + return TRUE; #endif -#if CONFIG_EMBEDDED - if (ip_kotype(port) == IKOT_FILEPORT) { - fileport_notify(request_header); - return TRUE; - } -#endif - + case IKOT_FILEPORT: + fileport_notify(request_header); + return TRUE; + } break; case MACH_NOTIFY_PORT_DELETED: @@ -588,72 +597,12 @@ ipc_kobject_notify( return iokit_notify(request_header); } #endif + case IKOT_TASK_RESUME: + { + return task_suspension_notify(request_header); + } + default: return FALSE; } } - - - -#include -#if MACH_COUNTERS && MACH_KDB - -#include -#include - -#define printf kdbprintf - -extern void kobjserver_stats(void); -extern void bucket_stats_print(mig_hash_t *bucket); - -extern void kobjserver_stats_clear(void); - - -void -kobjserver_stats_clear(void) -{ - int i; - for (i = 0; i < MAX_MIG_ENTRIES; i++) { - mig_buckets[i].callcount = 0; - } -} - -void -kobjserver_stats(void) -{ - register unsigned int i, n = sizeof(mig_e)/sizeof(struct mig_subsystem); - register unsigned int howmany; - register mach_msg_id_t j, pos, nentry, range; - - db_printf("Kobject server call counts:\n"); - for (i = 0; i < n; i++) { - db_printf(" "); - db_printsym((vm_offset_t)mig_e[i], DB_STGY_ANY); - db_printf(":\n"); - range = mig_e[i]->end - mig_e[i]->start; - if (!mig_e[i]->start || range < 0) continue; - - for (j = 0; j < range; j++) { - nentry = j + mig_e[i]->start; - for (pos = MIG_HASH(nentry) % MAX_MIG_ENTRIES, howmany = 1; - mig_buckets[pos].num; - pos++, pos = pos % MAX_MIG_ENTRIES, howmany++) { - if (mig_buckets[pos].num == nentry) - bucket_stats_print(&mig_buckets[pos]); - } - } - } -} - -void -bucket_stats_print(mig_hash_t *bucket) -{ - if (bucket->callcount) { - db_printf(" "); - db_printsym((vm_offset_t)bucket->routine, DB_STGY_ANY); - db_printf(" (%d):\t%d\n", bucket->num, bucket->callcount); - } -} - - -#endif /* MACH_COUNTERS && MACH_KDB */