static mach_port_t register_service(const char *service_name)
	{
	mach_port_t port = MACH_PORT_NULL;
	kern_return_t kr;

	if (KERN_SUCCESS == (kr = bootstrap_check_in(bootstrap_port, (char *)service_name, &port)))
		{
		if (KERN_SUCCESS != (kr = mach_port_insert_right(mach_task_self(), port, port, MACH_MSG_TYPE_MAKE_SEND)))
			helplog(ASL_LEVEL_ERR, "mach_port_insert_right: %s", mach_error_string(kr));
		else
			return port;
		}
	if (KERN_SUCCESS != (kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port)))
		{ helplog(ASL_LEVEL_ERR, "mach_port_allocate: %s", mach_error_string(kr)); goto error; }
	if (KERN_SUCCESS != (kr = mach_port_insert_right(mach_task_self(), port, port, MACH_MSG_TYPE_MAKE_SEND)))
		{ helplog(ASL_LEVEL_ERR, "mach_port_insert_right: %s", mach_error_string(kr)); goto error; }

	// XXX bootstrap_register does not modify its second argument, but the prototype does not include const.
	if (KERN_SUCCESS != (kr = bootstrap_register(bootstrap_port, (char *)service_name, port)))
		{ helplog(ASL_LEVEL_ERR, "bootstrap_register failed: %s", mach_error_string(kr)); goto error; }

	return port;
error:
	if (MACH_PORT_NULL != port) mach_port_deallocate(mach_task_self(), port);
	return MACH_PORT_NULL;
	}
Esempio n. 2
0
static void allocate_segv_handler()
{
#ifdef JULIA_ENABLE_THREADING
    arraylist_new(&suspended_threads, jl_n_threads);
#endif
    pthread_t thread;
    pthread_attr_t attr;
    kern_return_t ret;
    mach_port_t self = mach_task_self();
    ret = mach_port_allocate(self, MACH_PORT_RIGHT_RECEIVE, &segv_port);
    HANDLE_MACH_ERROR("mach_port_allocate",ret);
    ret = mach_port_insert_right(self, segv_port, segv_port, MACH_MSG_TYPE_MAKE_SEND);
    HANDLE_MACH_ERROR("mach_port_insert_right",ret);
    // Alright, create a thread to serve as the listener for exceptions
    if (pthread_attr_init(&attr) != 0) {
        jl_error("pthread_attr_init failed");
    }
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    if (pthread_create(&thread, &attr, mach_segv_listener, NULL) != 0) {
        jl_error("pthread_create failed");
    }
    pthread_attr_destroy(&attr);
    for (int16_t tid = 0;tid < jl_n_threads;tid++) {
        attach_exception_port(pthread_mach_thread_np(jl_all_task_states[tid].system_id));
    }
}
Esempio n. 3
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);
}
Esempio n. 4
0
EXPORT
int start(mach_port_t task, pid_t infoPid) {
    kern_return_t kret;
    pthread_t tid[2];
    interface* face = find_interface(task);

    kret = mach_port_allocate(current_task(), MACH_PORT_RIGHT_RECEIVE, &face->server_port);
    RETURN_ON_MACH_ERROR("[-start] mach_port_allocate failed", kret);

    kret = mach_port_insert_right(current_task(), face->server_port, face->server_port, MACH_MSG_TYPE_MAKE_SEND);
    RETURN_ON_MACH_ERROR("[-start] mach_port_insert_right failed", kret);

    kret = task_set_exception_ports(task, EXC_MASK_ALL, face->server_port, EXCEPTION_DEFAULT|MACH_EXCEPTION_CODES, THREAD_STATE_NONE);
    RETURN_ON_MACH_ERROR("[-start] task_set_exception_ports failed", kret);

    int err = pthread_create(&tid[0], NULL, (void *(*)(void*))kqueue_loop, (void *)(unsigned long long)infoPid);
    if (err != 0)
        DEBUG_PRINT("\n[-start] can't create thread :[%s]", strerror(err));
    else
        DEBUG_PRINT("\n[-start] Thread created successfully %d\n", 0);

    err = pthread_create(&tid[1], NULL, (void *(*)(void*))exception_server, (void *(*)(void*))(unsigned long long)face->server_port);
    if (err != 0)
        DEBUG_PRINT("\n[-start] can't create thread :[%s]", strerror(err));
    else
        DEBUG_PRINT("\n[-start] Thread created successfully %d\n", 0);

    return 1;
}
Esempio n. 5
0
static mach_port_t checkin_or_register(char *bname) {
    kern_return_t kr;
    mach_port_t mp;

    /* If we're started by launchd or the old mach_init */
    kr = bootstrap_check_in(bootstrap_port, bname, &mp);
    if (kr == KERN_SUCCESS)
        return mp;

    /* We probably were not started by launchd or the old mach_init */
    kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &mp);
    if (kr != KERN_SUCCESS) {
        fprintf(stderr, "mach_port_allocate(): %s\n", mach_error_string(kr));
        exit(EXIT_FAILURE);
    }

    kr = mach_port_insert_right(mach_task_self(), mp, mp, MACH_MSG_TYPE_MAKE_SEND);
    if (kr != KERN_SUCCESS) {
        fprintf(stderr, "mach_port_insert_right(): %s\n", mach_error_string(kr));
        exit(EXIT_FAILURE);
    }

    kr = bootstrap_register(bootstrap_port, bname, mp);
    if (kr != KERN_SUCCESS) {
        fprintf(stderr, "bootstrap_register(): %s\n", mach_error_string(kr));
        exit(EXIT_FAILURE);
    }

    return mp;
}
Esempio n. 6
0
File: mach.c Progetto: Acorld/libxpc
static int
mach_lookup(const char *name, xpc_port_t *local, xpc_port_t *remote)
{
	mach_port_t mp, rmp;
	kern_return_t kr;

	kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE,
	    &mp);
	if (kr != KERN_SUCCESS) {
		errno = EPERM;
		return (-1);
	}

	kr = mach_port_insert_right(mach_task_self(), mp, mp,
	    MACH_MSG_TYPE_MAKE_SEND);
	if (kr != KERN_SUCCESS) {
		errno = EPERM;
		return (-1);
	}

	kr = bootstrap_look_up(bootstrap_port, name, &rmp);
	if (kr != KERN_SUCCESS) {
		debugf("bootstrap_look_up failed kr=%d", kr);
		errno = EBUSY;
		return (-1);
	}

	*local = (xpc_port_t)mp;
	*remote = (xpc_port_t)rmp;
	return (0);
}
void RegisterExceptionHandler(void) {
  mach_port_t task = mach_task_self();
  mach_port_t handler_port;
  kern_return_t rc;
  pthread_t tid;
  int err;

  /* Use the same mask as Breakpad. */
  exception_mask_t exception_mask =
    EXC_MASK_BAD_ACCESS |
    EXC_MASK_BAD_INSTRUCTION |
    EXC_MASK_ARITHMETIC |
    EXC_MASK_BREAKPOINT;

  rc = mach_port_allocate(task, MACH_PORT_RIGHT_RECEIVE, &handler_port);
  CHECK(rc == KERN_SUCCESS);

  rc = mach_port_insert_right(task, handler_port, handler_port,
                              MACH_MSG_TYPE_MAKE_SEND);
  CHECK(rc == KERN_SUCCESS);

  err = pthread_create(&tid, NULL, ExceptionHandlerThread,
                       (void *) (uintptr_t) handler_port);
  CHECK(err == 0);
  err = pthread_detach(tid);
  CHECK(err == 0);

  rc = task_set_exception_ports(mach_task_self(), exception_mask,
                                handler_port, EXCEPTION_DEFAULT,
                                THREAD_STATE_NONE);
  CHECK(rc == KERN_SUCCESS);
}
static mach_port_t checkin(char *service_name)
	{
	kern_return_t kr = KERN_SUCCESS;
	mach_port_t port = MACH_PORT_NULL;
	launch_data_t msg = NULL, reply = NULL, datum = NULL;

	if (NULL == (msg = launch_data_new_string(LAUNCH_KEY_CHECKIN)))
		{ helplog(ASL_LEVEL_ERR, "Could not create checkin message for launchd."); goto fin; }
	if (NULL == (reply = launch_msg(msg)))
		{ helplog(ASL_LEVEL_ERR, "Could not message launchd."); goto fin; }
	if (LAUNCH_DATA_ERRNO == launch_data_get_type(reply))
		{
		if (launch_data_get_errno(reply) == EACCES) { launch_data_free(msg); launch_data_free(reply); return(MACH_PORT_NULL); }
		helplog(ASL_LEVEL_ERR, "Launchd checkin failed: %s.", strerror(launch_data_get_errno(reply))); goto fin;
		}
	if (NULL == (datum = launch_data_dict_lookup(reply, LAUNCH_JOBKEY_MACHSERVICES)) || LAUNCH_DATA_DICTIONARY != launch_data_get_type(datum))
		{ helplog(ASL_LEVEL_ERR, "Launchd reply does not contain %s dictionary.", LAUNCH_JOBKEY_MACHSERVICES); goto fin; }
	if (NULL == (datum = launch_data_dict_lookup(datum, service_name)) || LAUNCH_DATA_MACHPORT != launch_data_get_type(datum))
		{ helplog(ASL_LEVEL_ERR, "Launchd reply does not contain %s Mach port.", service_name); goto fin; }
	if (MACH_PORT_NULL == (port = launch_data_get_machport(datum)))
		{ helplog(ASL_LEVEL_ERR, "Launchd gave me a null Mach port."); goto fin; }
	if (KERN_SUCCESS != (kr = mach_port_insert_right(mach_task_self(), port, port, MACH_MSG_TYPE_MAKE_SEND)))
		{ helplog(ASL_LEVEL_ERR, "mach_port_insert_right: %s", mach_error_string(kr)); goto fin; }

fin:
	if (NULL != msg)   launch_data_free(msg);
	if (NULL != reply) launch_data_free(reply);
	if (MACH_PORT_NULL == port) exit(EXIT_FAILURE);
	return port;
	}
Esempio n. 9
0
int ethernet_open (char *dev_name, device_t master_device, 
		   struct port_bucket *etherport_bucket,
		   struct port_class *etherreadclass)
{
  error_t err;

  assert (ether_port == MACH_PORT_NULL);

  err = ports_create_port (etherreadclass, etherport_bucket,
			   sizeof (struct port_info), &readpt);
  if (err)
    error (2, err, "ports_create_port");
  readptname = ports_get_right (readpt);
  mach_port_insert_right (mach_task_self (), readptname, readptname,
			  MACH_MSG_TYPE_MAKE_SEND);

  mach_port_set_qlimit (mach_task_self (), readptname, MACH_PORT_QLIMIT_MAX);

  err = device_open (master_device, D_WRITE | D_READ, "eth", &ether_port);
  mach_port_deallocate (mach_task_self (), master_device);
  if (err)
    error (2, err, "device_open: %s", dev_name);

  err = device_set_filter (ether_port, ports_get_right (readpt),
			   MACH_MSG_TYPE_MAKE_SEND, 0,
			   (unsigned short *)ether_filter, ether_filter_len);
  if (err)
    error (2, err, "device_set_filter: %s", dev_name);

  set_promisc (dev_name, ether_port, 1);
  return 0;
}
bool
MemoryProtectionExceptionHandler::install()
{
    MOZ_ASSERT(!sExceptionHandlerInstalled);

    // If the exception handler is disabled, report success anyway.
    if (MemoryProtectionExceptionHandler::isDisabled())
        return true;

    kern_return_t ret;
    mach_port_t task = mach_task_self();

    // Allocate a new exception port with receive rights.
    sMachExceptionState.current = {};
    MachExceptionParameters& current = sMachExceptionState.current;
    ret = mach_port_allocate(task, MACH_PORT_RIGHT_RECEIVE, &current.port);
    if (ret != KERN_SUCCESS)
        return false;

    // Give the new port send rights as well.
    ret = mach_port_insert_right(task, current.port, current.port, MACH_MSG_TYPE_MAKE_SEND);
    if (ret != KERN_SUCCESS) {
        mach_port_deallocate(task, current.port);
        current = {};
        return false;
    }

    // Start the thread that will receive the messages from our exception port.
    if (!sMachExceptionState.handlerThread.init(MachExceptionHandler)) {
        mach_port_deallocate(task, current.port);
        current = {};
        return false;
    }

    // Set the other properties of our new exception handler.
    current.mask = EXC_MASK_BAD_ACCESS;
    current.behavior = exception_behavior_t(EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES);
    current.flavor = THREAD_STATE_NONE;

    // Tell the task to use our exception handler, and save the previous one.
    sMachExceptionState.previous = {};
    MachExceptionParameters& previous = sMachExceptionState.previous;
    mach_msg_type_number_t previousCount = 1;
    ret = task_swap_exception_ports(task, current.mask, current.port, current.behavior,
                                    current.flavor, &previous.mask, &previousCount,
                                    &previous.port, &previous.behavior, &previous.flavor);
    if (ret != KERN_SUCCESS) {
        TerminateMachExceptionHandlerThread();
        mach_port_deallocate(task, current.port);
        previous = {};
        current = {};
        return false;
    }

    // We should have info on the previous exception handler, even if it's null.
    MOZ_ASSERT(previousCount == 1);

    sExceptionHandlerInstalled = true;
    return sExceptionHandlerInstalled;
}
Esempio n. 11
0
int
ethernet_open (struct device *dev)
{
  error_t err;
  device_t master_device;
  struct ether_device *edev = (struct ether_device *) dev->priv;

  assert (edev->ether_port == MACH_PORT_NULL);

  err = ports_create_port (etherreadclass, etherport_bucket,
			   sizeof (struct port_info), &edev->readpt);
  assert_perror (err);
  edev->readptname = ports_get_right (edev->readpt);
  mach_port_insert_right (mach_task_self (), edev->readptname, edev->readptname,
			  MACH_MSG_TYPE_MAKE_SEND);

  mach_port_set_qlimit (mach_task_self (), edev->readptname, MACH_PORT_QLIMIT_MAX);

  master_device = file_name_lookup (dev->name, O_READ | O_WRITE, 0);
  if (master_device != MACH_PORT_NULL)
    {
      /* The device name here is the path of a device file.  */
      err = device_open (master_device, D_WRITE | D_READ, "eth", &edev->ether_port);
      mach_port_deallocate (mach_task_self (), master_device);
      if (err)
	error (2, err, "device_open on %s", dev->name);

      err = device_set_filter (edev->ether_port, ports_get_right (edev->readpt),
			       MACH_MSG_TYPE_MAKE_SEND, 0,
			       bpf_ether_filter, bpf_ether_filter_len);
      if (err)
	error (2, err, "device_set_filter on %s", dev->name);
    }
  else
    {
      /* No, perhaps a Mach device?  */
      int file_errno = errno;
      err = get_privileged_ports (0, &master_device);
      if (err)
	{
	  error (0, file_errno, "file_name_lookup %s", dev->name);
	  error (2, err, "and cannot get device master port");
	}
      err = device_open (master_device, D_WRITE | D_READ, dev->name, &edev->ether_port);
      mach_port_deallocate (mach_task_self (), master_device);
      if (err)
	{
	  error (0, file_errno, "file_name_lookup %s", dev->name);
	  error (2, err, "device_open(%s)", dev->name);
	}

      err = device_set_filter (edev->ether_port, ports_get_right (edev->readpt),
			       MACH_MSG_TYPE_MAKE_SEND, 0,
			       ether_filter, ether_filter_len);
      if (err)
	error (2, err, "device_set_filter on %s", dev->name);
    }

  return 0;
}
Esempio n. 12
0
void CEeExecutor::AddExceptionHandler()
{
    assert(g_eeExecutor == nullptr);
    g_eeExecutor = this;

#if defined(_WIN32)
    m_handler = AddVectoredExceptionHandler(TRUE, &CEeExecutor::HandleException);
    assert(m_handler != NULL);
#elif defined(__ANDROID__)
    struct sigaction sigAction;
    sigAction.sa_handler	= nullptr;
    sigAction.sa_sigaction	= &HandleException;
    sigAction.sa_flags		= SA_SIGINFO;
    sigemptyset(&sigAction.sa_mask);
    int result = sigaction(SIGSEGV, &sigAction, nullptr);
    assert(result >= 0);
#elif defined(__APPLE__)
    kern_return_t result = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &m_port);
    assert(result == KERN_SUCCESS);

    m_handlerThread = std::thread([this] () {
        HandlerThreadProc();
    });

    result = mach_port_insert_right(mach_task_self(), m_port, m_port, MACH_MSG_TYPE_MAKE_SEND);
    assert(result == KERN_SUCCESS);

    result = thread_set_exception_ports(mach_thread_self(), EXC_MASK_BAD_ACCESS, m_port, EXCEPTION_STATE | MACH_EXCEPTION_CODES, STATE_FLAVOR);
    assert(result == KERN_SUCCESS);

    result = mach_port_mod_refs(mach_task_self(), m_port, MACH_PORT_RIGHT_SEND, -1);
    assert(result == KERN_SUCCESS);
#endif
}
Esempio n. 13
0
void Connection::setShouldCloseConnectionOnMachExceptions()
{
    ASSERT(m_exceptionPort == MACH_PORT_NULL);

    if (mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &m_exceptionPort) != KERN_SUCCESS)
        ASSERT_NOT_REACHED();

    if (mach_port_insert_right(mach_task_self(), m_exceptionPort, m_exceptionPort, MACH_MSG_TYPE_MAKE_SEND) != KERN_SUCCESS)
        ASSERT_NOT_REACHED();
}
Esempio n. 14
0
int
main (int argc, char **argv)
{
  mach_port_t bootstrap;
  mach_port_t control;
  error_t err;

  /* Parse our options...  */
  argp_parse (&argp, argc, argv, 0, 0, 0);

  task_get_bootstrap_port (mach_task_self (), &bootstrap);
  if (bootstrap == MACH_PORT_NULL)
    error (1, 0, "Must be started as a translator");

  linktarget = argv[1];

  /* Reply to our parent */
  mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &control);
  mach_port_insert_right (mach_task_self (), control, control,
			  MACH_MSG_TYPE_MAKE_SEND);
  err =
    fsys_startup (bootstrap, 0, control, MACH_MSG_TYPE_COPY_SEND, &realnode);
  mach_port_deallocate (mach_task_self (), control);
  mach_port_deallocate (mach_task_self (), bootstrap);
  if (err)
    error (1, err, "Starting up translator");

  io_restrict_auth (realnode, &realnodenoauth, 0, 0, 0, 0);
  mach_port_deallocate (mach_task_self (), realnode);

  /* Mark us as important.  */
  mach_port_t proc = getproc ();
  if (proc == MACH_PORT_NULL)
    error (2, err, "cannot get a handle to our process");

  err = proc_mark_important (proc);
  /* This might fail due to permissions or because the old proc server
     is still running, ignore any such errors.  */
  if (err && err != EPERM && err != EMIG_BAD_ID)
    error (2, err, "Cannot mark us as important");

  mach_port_deallocate (mach_task_self (), proc);

  /* Launch */
  while (1)
    {
      /* The timeout here is 10 minutes */
      err = mach_msg_server_timeout (fsys_server, 0, control,
				     MACH_RCV_TIMEOUT, 1000 * 60 * 10);
      if (err == MACH_RCV_TIMED_OUT)
	exit (0);
    }
}
Esempio n. 15
0
void
darwin_arm_init_thread_exception_port()
{
	// Called by each new OS thread to bind its EXC_BAD_ACCESS exception
	// to mach_exception_handler_port_set.
	int ret;
	mach_port_t port = MACH_PORT_NULL;

	ret = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port);
	if (ret) {
		fprintf(stderr, "runtime/cgo: mach_port_allocate failed: %d\n", ret);
		abort();
	}
	ret = mach_port_insert_right(
		mach_task_self(),
		port,
		port,
		MACH_MSG_TYPE_MAKE_SEND);
	if (ret) {
		fprintf(stderr, "runtime/cgo: mach_port_insert_right failed: %d\n", ret);
		abort();
	}

	ret = thread_set_exception_ports(
		mach_thread_self(),
		EXC_MASK_BAD_ACCESS,
		port,
		EXCEPTION_DEFAULT,
		THREAD_STATE_NONE);
	if (ret) {
		fprintf(stderr, "runtime/cgo: thread_set_exception_ports failed: %d\n", ret);
		abort();
	}

	ret = pthread_mutex_lock(&mach_exception_handler_port_set_mu);
	if (ret) {
		fprintf(stderr, "runtime/cgo: pthread_mutex_lock failed: %d\n", ret);
		abort();
	}
	ret = mach_port_move_member(
		mach_task_self(),
		port,
		mach_exception_handler_port_set);
	if (ret) {
		fprintf(stderr, "runtime/cgo: mach_port_move_member failed: %d\n", ret);
		abort();
	}
	ret = pthread_mutex_unlock(&mach_exception_handler_port_set_mu);
	if (ret) {
		fprintf(stderr, "runtime/cgo: pthread_mutex_unlock failed: %d\n", ret);
		abort();
	}
}
Esempio n. 16
0
/*
 * kern_return_t
 * bootstrap_create_service(mach_port_t bootstrap_port,
 *		      name_t service_name,
 *		      mach_port_t *service_port)
 *
 * Creates a service named "service_name" and returns send rights to that
 * port in "service_port."  The port may later be checked in as if this
 * port were configured in the bootstrap configuration file.
 *
 * Errors:	Returns appropriate kernel errors on rpc failure.
 *		Returns BOOTSTRAP_NAME_IN_USE, if service already exists.
 */
kern_return_t
x_bootstrap_create_service(
	mach_port_t bootstrap_port,
	name_t	service_name,
	mach_port_t *service_port)
{
	server_t *serverp;
	service_t *servicep;
	bootstrap_info_t *bootstrap;
	kern_return_t result;

	bootstrap = lookup_bootstrap_by_port(bootstrap_port);
	if (!bootstrap || !active_bootstrap(bootstrap))
		return BOOTSTRAP_NOT_PRIVILEGED;

	debug("Service creation attempt for service %s bootstrap %x",
	      service_name, bootstrap_port);

	servicep = lookup_service_by_name(bootstrap, service_name);
	if (servicep) {
		debug("Service creation attempt for service %s failed, "
			"service already exists", service_name);
		return BOOTSTRAP_NAME_IN_USE;
	}

	serverp = lookup_server_by_port(bootstrap_port);

	result = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE,  service_port);
	if (result != KERN_SUCCESS)
		kern_fatal(result, "port_allocate");
	result = mach_port_insert_right(mach_task_self(), *service_port, *service_port, MACH_MSG_TYPE_MAKE_SEND);
	if (result != KERN_SUCCESS)
		kern_fatal(result, "failed to insert send right");

	if (serverp)
		serverp->activity++;

	servicep = new_service(bootstrap,
				service_name,
				*service_port,
				!ACTIVE,
				DECLARED,
				serverp);

	info("Created new service %x in bootstrap %x: %s", 
	    servicep->port, bootstrap->bootstrap_port, service_name);

	return BOOTSTRAP_SUCCESS;
}
Esempio n. 17
0
void mach_exn_init() {
    kern_return_t r;
    mach_port_t me;
    pthread_t thread;
    pthread_attr_t attr;
    exception_mask_t mask;
    
    me = mach_task_self();
    r = mach_port_allocate(me,MACH_PORT_RIGHT_RECEIVE,&exception_port);
    if(r != MACH_MSG_SUCCESS) DIE("mach_port_allocate");
    
    r = mach_port_insert_right(me,exception_port,exception_port,
    	MACH_MSG_TYPE_MAKE_SEND);
    if(r != MACH_MSG_SUCCESS) DIE("mach_port_insert_right");
    
    /* for others see mach/exception_types.h */
    mask = EXC_MASK_BAD_ACCESS;
    
    /* get the old exception ports */
    r = task_get_exception_ports(
        me,
        mask,
        old_exc_ports.masks,
        &old_exc_ports.count,
        old_exc_ports.ports,
        old_exc_ports.behaviors,
        old_exc_ports.flavors
    );
    if(r != MACH_MSG_SUCCESS) DIE("task_get_exception_ports");
    
    /* set the new exception ports */
    r = task_set_exception_ports(
        me,
        mask,
        exception_port,
        EXCEPTION_DEFAULT,
        MACHINE_THREAD_STATE
    );
    if(r != MACH_MSG_SUCCESS) DIE("task_set_exception_ports");
    
    if(pthread_attr_init(&attr) != 0) DIE("pthread_attr_init");
    if(pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED) != 0) 
        DIE("pthread_attr_setdetachedstate");
    
    if(pthread_create(&thread,&attr,exc_thread,NULL) != 0)
        DIE("pthread_create");
    pthread_attr_destroy(&attr);
}
Esempio n. 18
0
/* tell the kernel that we want EXC_BAD_ACCESS exceptions sent to the
   exception port (which is being listened to do by the mach
   exception handling thread). */
kern_return_t
mach_thread_init(mach_port_t thread_exception_port)
{
    kern_return_t ret;
    mach_port_t current_mach_thread;

    /* allocate a named port for the thread */
    FSHOW((stderr, "Allocating mach port %x\n", thread_exception_port));
    ret = mach_port_allocate_name(current_mach_task,
                                  MACH_PORT_RIGHT_RECEIVE,
                                  thread_exception_port);
    if (ret) {
        lose("mach_port_allocate_name failed with return_code %d\n", ret);
    }

    /* establish the right for the thread_exception_port to send messages */
    ret = mach_port_insert_right(current_mach_task,
                                 thread_exception_port,
                                 thread_exception_port,
                                 MACH_MSG_TYPE_MAKE_SEND);
    if (ret) {
        lose("mach_port_insert_right failed with return_code %d\n", ret);
    }

    current_mach_thread = mach_thread_self();
    ret = thread_set_exception_ports(current_mach_thread,
                                     EXC_MASK_BAD_ACCESS | EXC_MASK_BAD_INSTRUCTION,
                                     thread_exception_port,
                                     EXCEPTION_DEFAULT,
                                     THREAD_STATE_NONE);
    if (ret) {
        lose("thread_set_exception_ports failed with return_code %d\n", ret);
    }

    ret = mach_port_deallocate (current_mach_task, current_mach_thread);
    if (ret) {
        lose("mach_port_deallocate failed with return_code %d\n", ret);
    }

    ret = mach_port_move_member(current_mach_task,
                                thread_exception_port,
                                mach_exception_handler_port_set);
    if (ret) {
        lose("mach_port_move_member failed with return_code %d\n", ret);
    }

    return ret;
}
Esempio n. 19
0
int main() {
  kern_return_t kr = 0;
  mach_port_t exc_port;
  mach_port_t task = mach_task_self();
  pthread_t exception_thread;
  int err;
  
	mach_msg_type_number_t maskCount = 1;
	exception_mask_t mask;
	exception_handler_t handler;
	exception_behavior_t behavior;
	thread_state_flavor_t flavor;

	if ((kr = mach_port_allocate(task, MACH_PORT_RIGHT_RECEIVE, &exc_port)) != KERN_SUCCESS) {
		fprintf(stderr, "mach_port_allocate: %#x\n", 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: %#x\n", kr);
		exit(1);
	}

	if ((kr = task_get_exception_ports(task, EXC_MASK_ALL, &mask, &maskCount, &handler, &behavior, &flavor)) != KERN_SUCCESS) {
		fprintf(stderr,"task_get_exception_ports: %#x\n", kr);
		exit(1);
	}

	if ((err = pthread_create(&exception_thread, NULL, server_thread, &exc_port)) != 0) {
		fprintf(stderr, "pthread_create server_thread: %s\n", strerror(err));
		exit(1);
	}
  
	pthread_detach(exception_thread);

  if ((kr = task_set_exception_ports(task, EXC_MASK_ALL, exc_port, EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES, flavor)) != KERN_SUCCESS) {
    fprintf(stderr, "task_set_exception_ports: %#x\n", kr);
    exit(1);
  }
  puts("Starting exception stuff");
  int a = 1;
  int b = 0;
  float c = a / b;
  int cat = *(int *)(0x13371337);
  printf("Have c %f and cat %d\n", c, cat);
  puts("End.");

}
Esempio n. 20
0
File: pager.c Progetto: Larhard/hurd
/* Create a new pager in USER_PAGER with NPAGES pages, and return a
   mapping to the memory in *USER.  */
error_t
user_pager_create (struct user_pager *user_pager, unsigned int npages,
		   struct cons_display **user)
{
  error_t err;
  struct user_pager_info *upi;

  upi = calloc (1, sizeof (struct user_pager_info)
		+ sizeof (vm_address_t) * npages);
  if (!upi)
    return errno;

  upi->memobj_npages = npages;

  /* XXX Are the values 1 and MEMORY_OBJECT_COPY_DELAY correct? */
  user_pager->pager = pager_create (upi, pager_bucket,
				    1, MEMORY_OBJECT_COPY_DELAY, 0);
  if (!user_pager->pager)
    {
      free (upi);
      return errno;
    }
  user_pager->memobj = pager_get_port (user_pager->pager);
  ports_port_deref (user_pager->pager);

  mach_port_insert_right (mach_task_self (), user_pager->memobj,
			  user_pager->memobj, MACH_MSG_TYPE_MAKE_SEND);

  *user = 0;
  err = vm_map (mach_task_self (),
		(vm_address_t *) user,
		(vm_size_t) npages * vm_page_size,
		(vm_address_t) 0,
		1 /* ! (flags & MAP_FIXED) */,
		user_pager->memobj, 0 /* (vm_offset_t) offset */,
		0 /* ! (flags & MAP_SHARED) */,
                VM_PROT_READ | VM_PROT_WRITE,
                VM_PROT_READ | VM_PROT_WRITE,
                VM_INHERIT_NONE);
  if (err)
    {
      /* UPI will be cleaned up by libpager.  */
      mach_port_deallocate (mach_task_self (), user_pager->memobj);
      return err;
    }

  return 0;
}
Esempio n. 21
0
dns_service_discovery_ref DNSServiceDomainEnumerationCreate (int registrationDomains, DNSServiceDomainEnumerationReply 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;

    if (!serverPort) {
        return NULL;
    }

    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.enumCallback = callBack;

    result = DNSServiceDomainEnumerationCreate_rpc(serverPort, clientPort, registrationDomains);

    if (result != KERN_SUCCESS) {
        printf("There was an error creating an enumerator, %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;
}
Esempio n. 22
0
void EstablishDylanExceptionHandlers(void)
{
  if (exception_port == MACH_PORT_NULL) {
    // Need a port we can receive exceptions on
    kern_return_t rc
      = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE,
                           &exception_port);
    if (rc != KERN_SUCCESS) {
      mach_error("mach_port_allocate send", rc);
      abort();
    }

    // Need to be able to send on it too
    rc = mach_port_insert_right(mach_task_self(), exception_port, exception_port,
                                MACH_MSG_TYPE_MAKE_SEND);
    if (rc != KERN_SUCCESS) {
      mach_error("mach_port_insert_right", rc);
      abort();
    }

    // Spawn a thread to serve exception requests
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    pthread_t thread;
    int prc = pthread_create(&thread, &attr, catcher, NULL);
    pthread_attr_destroy(&attr);
    if (prc != 0) {
      fprintf(stderr, "%s: pthread_create returned %d\n",
              __func__, prc);
      abort();
    }
  }

  // Set this thread's exception port
  kern_return_t rc
    = thread_set_exception_ports(mach_thread_self(),
                                 EXC_MASK_ARITHMETIC|EXC_MASK_BREAKPOINT,
                                 exception_port,
                                 EXCEPTION_STATE_IDENTITY|MACH_EXCEPTION_CODES,
                                 THREAD_STATE_FLAVOR);
  if (rc != KERN_SUCCESS) {
    mach_error("thread_set_exception_ports", rc);
    abort();
  }

  primitive_reset_float_environment();
}
Esempio n. 23
0
void InstallExceptionHandler()
{
	mach_port_t port;
	CheckKR("mach_port_allocate", mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port));
	std::thread exc_thread(ExceptionThread, port);
	exc_thread.detach();
	// Obtain a send right for thread_set_exception_ports to copy...
	CheckKR("mach_port_insert_right", mach_port_insert_right(mach_task_self(), port, port, MACH_MSG_TYPE_MAKE_SEND));
	// Mach tries the following exception ports in order: thread, task, host.
	// Debuggers set the task port, so we grab the thread port.
	CheckKR("thread_set_exception_ports", thread_set_exception_ports(mach_thread_self(), EXC_MASK_BAD_ACCESS, port, EXCEPTION_STATE | MACH_EXCEPTION_CODES, x86_THREAD_STATE64));
	// ...and get rid of our copy so that MACH_NOTIFY_NO_SENDERS works.
	CheckKR("mach_port_mod_refs", mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_SEND, -1));
	mach_port_t previous;
	CheckKR("mach_port_request_notification", mach_port_request_notification(mach_task_self(), port, MACH_NOTIFY_NO_SENDERS, 0, port, MACH_MSG_TYPE_MAKE_SEND_ONCE, &previous));
}
Esempio n. 24
0
void registerDarwinExceptionHandler(void) {
    // Create the Mach exception port
    mach_port_t self = mach_task_self();
    assert(mach_port_allocate(self, MACH_PORT_RIGHT_RECEIVE, &mach_ex_port) == KERN_SUCCESS);
    assert(mach_port_insert_right(self, mach_ex_port, mach_ex_port, MACH_MSG_TYPE_MAKE_SEND) == KERN_SUCCESS);
    
    // Create the thread which receives the exceptions
    pthread_t thread;
    pthread_attr_t attr;
    assert(!pthread_attr_init(&attr));
    assert(!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED));
    assert(!pthread_create(&thread, &attr, exceptionHandlerEntryPoint, NULL));
    pthread_attr_destroy(&attr);
    
    assert(task_set_exception_ports(self, EXC_MASK_BAD_ACCESS, mach_ex_port, EXCEPTION_DEFAULT, MACHINE_THREAD_STATE) == KERN_SUCCESS);
}
Esempio n. 25
0
/* Return the active translator control port for NODE.  If there is no
   translator, active or passive, MACH_PORT_NULL is returned in CONTROL_PORT.
   If there is a translator, it is started if necessary, and returned in
   CONTROL_PORT.  *DIR_PORT should be a port right to use as the new
   translators parent directory.  If it is MACH_PORT_NULL, a port is created
   from DIR and PARENT_PORT and stored in *DIR_PORT; otherwise DIR and
   PARENT_PORT are not used.  Neither NODE or DIR should be locked when
   calling this function.  */
error_t
treefs_node_get_active_trans (struct treefs_node *node,
			      struct treefs_node *dir,
			      mach_port_t parent_port,
			      mach_port_t *control_port,
			      mach_port_t *dir_port)
{
  /* Fill in dir_port */
  void make_dir_port ()
    {
      pthread_mutex_lock (&dir->lock);
      *dir_port = treefs_node_make_right (dir, 0, parent_port, 0);
      mach_port_insert_right (mach_task_self (),
			      *dir_port, *dir_port, MACH_MSG_TYPE_MAKE_SEND);
      pthread_mutex_unlock (&dir->lock);
    }
Esempio n. 26
0
bool exception_handler_install_platform() {
  if (s_installed) {
    return true;
  }

  // allocate port to listen for exceptions
  if (mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE,
                         &s_listen_port) != KERN_SUCCESS) {
    return false;
  }

  // http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/mach_port_insert_right.html
  if (mach_port_insert_right(mach_task_self(), s_listen_port, s_listen_port,
                             MACH_MSG_TYPE_MAKE_SEND) != KERN_SUCCESS) {
    return false;
  }

  // filter out any exception other than EXC_BAD_ACCESS
  // http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/task_set_exception_ports.html
  if (task_set_exception_ports(mach_task_self(), exception_mask, s_listen_port,
                               EXCEPTION_DEFAULT,
                               MACHINE_THREAD_STATE) != KERN_SUCCESS) {
    return false;
  }

  // launch thread to listen for exceptions
  pthread_attr_t attr;
  pthread_t thread;

  if (pthread_attr_init(&attr) != 0) {
    return false;
  }

  if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0) {
    return false;
  }

  if (pthread_create(&thread, &attr, &mach_exception_thread, NULL) != 0) {
    return -1;
  }

  pthread_attr_destroy(&attr);

  s_installed = true;

  return true;
}
Esempio n. 27
0
/* Initialize the Mach exception handler thread.
   Return 0 if OK, -1 on error.  */
static int
mach_initialize ()
{
  mach_port_t self;
  exception_mask_t mask;
  pthread_attr_t attr;
  pthread_t thread;

  self = mach_task_self ();

  /* Allocate a port on which the thread shall listen for exceptions.  */
  if (mach_port_allocate (self, MACH_PORT_RIGHT_RECEIVE, &our_exception_port)
      != KERN_SUCCESS)
    return -1;

  /* See http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/mach_port_insert_right.html.  */
  if (mach_port_insert_right (self, our_exception_port, our_exception_port,
                              MACH_MSG_TYPE_MAKE_SEND)
      != KERN_SUCCESS)
    return -1;

  /* The exceptions we want to catch.  Only EXC_BAD_ACCESS is interesting
     for us (see above in function catch_exception_raise).  */
  mask = EXC_MASK_BAD_ACCESS;

  /* Create the thread listening on the exception port.  */
  if (pthread_attr_init (&attr) != 0)
    return -1;
  if (pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED) != 0)
    return -1;
  if (pthread_create (&thread, &attr, mach_exception_thread, NULL) != 0)
    return -1;
  pthread_attr_destroy (&attr);

  /* Replace the exception port info for these exceptions with our own.
     Note that we replace the exception port for the entire task, not only
     for a particular thread.  This has the effect that when our exception
     port gets the message, the thread specific exception port has already
     been asked, and we don't need to bother about it.
     See http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/task_set_exception_ports.html.  */
  if (task_set_exception_ports (self, mask, our_exception_port,
                                EXCEPTION_DEFAULT, MACHINE_THREAD_STATE)
      != KERN_SUCCESS)
    return -1;

  return 0;
}
Esempio n. 28
0
static bool xnu_create_exception_thread(RDebug *dbg) {
	kern_return_t kr;
	int ret;
	mach_port_t exception_port = MACH_PORT_NULL;
        // Got the mach port for the current process
	mach_port_t task_self = mach_task_self ();
	task_t task = pid_to_task (dbg->pid);
	if (task == -1) {
		eprintf ("error to get task for the debugging process"
			" xnu_start_exception_thread\n");
		return false;
	}
	if (!MACH_PORT_VALID (task_self)) {
		eprintf ("error to get the task for the current process"
			" xnu_start_exception_thread\n");
		return false;
	}
        // Allocate an exception port that we will use to track our child process
        kr = mach_port_allocate (task_self, MACH_PORT_RIGHT_RECEIVE,
				&exception_port);
	RETURN_ON_MACH_ERROR ("error to allocate mach_port exception\n", R_FALSE);
        // Add the ability to send messages on the new exception port
        kr  = mach_port_insert_right (task_self, exception_port,
				exception_port, MACH_MSG_TYPE_MAKE_SEND);
	RETURN_ON_MACH_ERROR ("error to allocate insert right\n", R_FALSE);
        // Save the original state of the exception ports for our child process
        ret = xnu_save_exception_ports (dbg);
	if (ret == R_FALSE) {
		eprintf ("error to save exception port info\n");
		return false;
	}
        // Set the ability to get all exceptions on this port
	kr = task_set_exception_ports (task, EXC_MASK_ALL, exception_port,
				EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES,
				THREAD_STATE_NONE);
	RETURN_ON_MACH_ERROR ("error to set port to receive exceptions\n", R_FALSE);
        // Create the exception thread
	//TODO where to save the exception thread
	//TODO see options pthread_create
        ret = pthread_create (&dbg->ex->thread, NULL, xnu_exception_thread, dbg);
	if (ret) {
		perror ("pthread_create");
		return false;
	}
	return true;
}
Esempio n. 29
0
bool TargetException::setExceptionCallback(ExceptionCallback callback)
{
	m_callback = std::move(callback);
    auto kr = mach_port_allocate(mach_task_self(),MACH_PORT_RIGHT_RECEIVE,&m_exceptionPort);
    if (kr != KERN_SUCCESS)
    {
        log(QString("mach_port_allocate failde: %1").arg(mach_error_string(kr)), LogType::Error);
        return false;
    }

    kr = mach_port_insert_right(mach_task_self(), m_exceptionPort, m_exceptionPort, MACH_MSG_TYPE_MAKE_SEND);
    if (kr != KERN_SUCCESS)
    {
        log(QString("mach_port_insert_right failde: %1").arg(mach_error_string(kr)), LogType::Error);
        return false;
    }

    kr = task_get_exception_ports(
            g_task,
            EXC_MASK_ALL,
            m_oldExcPorts.masks,
            &m_oldExcPorts.count,
            m_oldExcPorts.ports,
            m_oldExcPorts.behaviors,
            m_oldExcPorts.flavors
    );
    if (kr != KERN_SUCCESS)
    {
        log(QString("task_get_exception_ports failde: %1").arg(mach_error_string(kr)), LogType::Error);
        return false;
    }

    kr = task_set_exception_ports(
            g_task, EXC_MASK_ALL, m_exceptionPort,
            EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES,
            THREAD_STATE_NONE
    );

    if (kr != KERN_SUCCESS)
    {
        log(QString("task_set_exception_ports failde: %1").arg(mach_error_string(kr)), LogType::Error);
        return false;
    }

    return true;
}
Esempio n. 30
0
bool xnu_create_exception_thread(RDebug *dbg) {
#if __POWERPC__
	return false;
#else
	kern_return_t kr;
	mach_port_t exception_port = MACH_PORT_NULL;
	mach_port_t req_port;
        // Got the mach port for the current process
	mach_port_t task_self = mach_task_self ();
	task_t task = pid_to_task (dbg->pid);
	if (!task) {
		eprintf ("error to get task for the debuggee process"
			" xnu_start_exception_thread\n");
		return false;
	}
	if (!MACH_PORT_VALID (task_self)) {
		eprintf ("error to get the task for the current process"
			" xnu_start_exception_thread\n");
		return false;
	}
        // Allocate an exception port that we will use to track our child process
        kr = mach_port_allocate (task_self, MACH_PORT_RIGHT_RECEIVE,
				&exception_port);
	RETURN_ON_MACH_ERROR ("error to allocate mach_port exception\n", false);
        // Add the ability to send messages on the new exception port
	kr = mach_port_insert_right (task_self, exception_port, exception_port,
				     MACH_MSG_TYPE_MAKE_SEND);
	RETURN_ON_MACH_ERROR ("error to allocate insert right\n", false);
	// Atomically swap out (and save) the child process's exception ports
	// for the one we just created. We'll want to receive all exceptions.
	ex.count = (sizeof (ex.ports) / sizeof (*ex.ports));
	kr = task_swap_exception_ports (task, EXC_MASK_ALL, exception_port,
		EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES, THREAD_STATE_NONE,
		ex.masks, &ex.count, ex.ports, ex.behaviors, ex.flavors);
	RETURN_ON_MACH_ERROR ("failed to swap exception ports\n", false);
	//get notification when process die
	kr = mach_port_request_notification (task_self, task, MACH_NOTIFY_DEAD_NAME,
		 0, exception_port, MACH_MSG_TYPE_MAKE_SEND_ONCE, &req_port);
	if (kr != KERN_SUCCESS) {
		eprintf ("Termination notification request failed\n");
	}
	ex.exception_port = exception_port;
	return true;
#endif
}