Example #1
0
void setup_shared_port() {
  kern_return_t err;
  // get a send right to the port we're going to overwrite so that we can both
  // restore it for ourselves and send it to our child
  err = task_get_special_port(mach_task_self(), STOLEN_SPECIAL_PORT, &saved_special_port);
  MACH_ERR("saving original special port value", err);

  // allocate the shared port we want our child to have a send right to
  err = mach_port_allocate(mach_task_self(),
                           MACH_PORT_RIGHT_RECEIVE,
                           &shared_port_parent);

  MACH_ERR("allocating shared port", err);

  // insert the send right
  err = mach_port_insert_right(mach_task_self(),
                               shared_port_parent,
                               shared_port_parent,
                               MACH_MSG_TYPE_MAKE_SEND);
  MACH_ERR("inserting MAKE_SEND into shared port", err);

  // stash the port in the STOLEN_SPECIAL_PORT slot such that the send right survives the fork
  err = task_set_special_port(mach_task_self(), STOLEN_SPECIAL_PORT, shared_port_parent);
  MACH_ERR("setting special port", err);
}
Example #2
0
void
mach_init_ports(void)
{
	mach_port_array_t	ports;
	mach_msg_type_number_t	ports_count;
	kern_return_t		kr;

	/*
	 *	Find those ports important to every task.
	 */
	kr = task_get_special_port(mach_task_self(),
				   TASK_BOOTSTRAP_PORT,
				   &bootstrap_port);
	if (kr != KERN_SUCCESS)
	    return;

	kr = mach_ports_lookup(mach_task_self(), &ports,
			       &ports_count);
	if ((kr != KERN_SUCCESS) ||
	    (ports_count < MACH_PORTS_SLOTS_USED))
	    return;

	name_server_port = ports[NAME_SERVER_SLOT];
	environment_port = ports[ENVIRONMENT_SLOT];
	service_port     = ports[SERVICE_SLOT];

	/* get rid of out-of-line data so brk has a chance of working */

	(void) vm_deallocate(mach_task_self(),
			     (vm_offset_t) ports,
			     (vm_size_t) (ports_count * sizeof *ports));
}
Example #3
0
mach_port_t sharkctl_create_port(void) {
    mach_port_t bootstrap_port, shark_port = 0;
    task_get_special_port(mach_task_self(), TASK_BOOTSTRAP_PORT,
                          &bootstrap_port);
    bootstrap_look_up(bootstrap_port, "CHUD_IPC", &shark_port);
    return shark_port;
}
Example #4
0
mach_port_t recover_shared_port_child() {
  kern_return_t err;

  // grab the shared port which our parent stashed somewhere in the special ports
  mach_port_t shared_port_child = MACH_PORT_NULL;
  err = task_get_special_port(mach_task_self(), STOLEN_SPECIAL_PORT, &shared_port_child);
  MACH_ERR("child getting stashed port", err);

  LOG("child got stashed port");

  // say hello to our parent and send a reply port so it can send us back the special port to restore

  // allocate a reply port
  mach_port_t reply_port;
  err = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &reply_port);
  MACH_ERR("child allocating reply port", err);

  // send the reply port in a hello message
  simple_msg_send_t msg = {0};

  msg.header.msgh_size = sizeof(msg);
  msg.header.msgh_local_port = reply_port;
  msg.header.msgh_remote_port = shared_port_child;

  msg.header.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE);

  err = mach_msg_send(&msg.header);
  MACH_ERR("child sending task port message", err);

  LOG("child sent hello message to parent over shared port");

  // wait for a message on the reply port containing the stolen port to restore
  port_msg_rcv_t stolen_port_msg = {0};
  err = mach_msg(&stolen_port_msg.header, MACH_RCV_MSG, 0, sizeof(stolen_port_msg), reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
  MACH_ERR("child receiving stolen port\n", err);

  // extract the port right from the message
  mach_port_t stolen_port_to_restore = stolen_port_msg.port.name;
  if (stolen_port_to_restore == MACH_PORT_NULL) {
    FAIL("child received invalid stolen port to restore");
  }

  // restore the special port for the child
  err = task_set_special_port(mach_task_self(), STOLEN_SPECIAL_PORT, stolen_port_to_restore);
  MACH_ERR("child restoring special port", err);

  LOG("child restored stolen port");
  return shared_port_child;
}
// use the other task port to try to get a send right to the host-priv port
mach_port_t get_host_priv(mach_port_t other_task) {
  mach_port_t our_host = mach_host_self();
  mach_port_t other_host = MACH_PORT_NULL;
  
  kern_return_t err = task_get_special_port(other_task, TASK_HOST_PORT, &other_host);
  if (err != KERN_SUCCESS) {
    printf("failed to get other task's host port\n");
    return MACH_PORT_NULL;
  }
  
  if (other_host != MACH_PORT_NULL && other_host != our_host) {
    printf("got the host priv port, dankeschoen!\n");
    return other_host;
  }
  
  printf("other task has the same host port as us\n");
  
  return MACH_PORT_NULL;
}
int main()
{
	kern_return_t kr;
	mach_port_t bport, port, pset;
	struct msg_recv message;
	struct msg_send reply;
	struct kevent64_s kev;
	int kq, r;

	task_get_special_port(mach_task_self(), TASK_BOOTSTRAP_PORT, &bport);
	syslog(LOG_ERR, "bootstrap port: %d", bport);

	kr = bootstrap_check_in(bootstrap_port, "mach.service-test", &port);
	if (kr != KERN_SUCCESS) {
		syslog(LOG_ERR, "bootstrap_check_in: kr=%d", kr);
		exit(1);
	}

	syslog(LOG_ERR, "service port: %d", port);

	kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_PORT_SET, &pset);
	if (kr != KERN_SUCCESS) {
		syslog(LOG_ERR, "mach_port_allocate: kr=%d", kr);
		exit(1);
	}

	kr = mach_port_move_member(mach_task_self(), port, pset);
	if (kr != KERN_SUCCESS) {
		syslog(LOG_ERR, "mach_port_move_member: kr=%d", kr);
		exit(1);
	}

	kq = kqueue();
	syslog(LOG_ERR, "kqueue fd: %d", kq);

	memset(&kev, 0, sizeof(struct kevent64_s));
	EV_SET64(&kev, pset, EVFILT_MACHPORT, EV_ADD | EV_ENABLE, 0, 0, 0, 0, 0);
	if (kevent64(kq, &kev, 1, NULL, 0, 0, NULL) < 0) {
		syslog(LOG_ERR, "kevent64: %s (%d)", strerror(errno), errno);
		return 0;
	}

	for (;;) {
		message.hdr.msgh_local_port = port;
		message.hdr.msgh_size = sizeof(struct msg_recv);

		r = kevent64(kq, NULL, 0, &kev, 1, 0, NULL);
		if (r < 0) {
			syslog(LOG_ERR, "kevent64 failed: %s (%d)", strerror(errno), errno);
			continue;
		}

		syslog(LOG_ERR, "kevent64: events=%d", r);

		kr = mach_msg_receive((mach_msg_header_t *)&message);
		if (kr != KERN_SUCCESS)
			syslog(LOG_ERR, "mach_msg_receive failure: kr=%d", kr);
		else
			syslog(LOG_ERR, "received message on port %d: body=%s", message.hdr.msgh_remote_port, message.body);

		memset(&reply, 0, sizeof(struct msg_send));
		sprintf(&reply.body[0], "hello buddy");
		reply.hdr.msgh_local_port = MACH_PORT_NULL;
		reply.hdr.msgh_remote_port = message.hdr.msgh_remote_port;
		reply.hdr.msgh_size = sizeof(struct msg_send);
		reply.hdr.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0);
		kr = mach_msg_send((mach_msg_header_t *)&reply);
		if (kr != KERN_SUCCESS)
			syslog(LOG_ERR, "mach_msg_send failure: kr=%d", kr);
	}
}