Example #1
0
static void protMustSend(mach_msg_header_t *head)
{
  kern_return_t kr;
  kr = mach_msg(head,
                MACH_SEND_MSG,
                head->msgh_size,
                /* recv_size */ 0,
                MACH_PORT_NULL,
                MACH_MSG_TIMEOUT_NONE,
                MACH_PORT_NULL);
  AVER(kr == KERN_SUCCESS);
  if (kr != KERN_SUCCESS)
    mach_error("ERROR: MPS mach_msg send", kr); /* .trans.must */
}
Example #2
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;
}
Example #3
0
/* -----------------------------------------------------------------------------
----------------------------------------------------------------------------- */
void
server_handle_request(CFMachPortRef port, void *msg, CFIndex size, void *info)
{
    mach_msg_return_t 	r;
    mach_msg_header_t *	request = (mach_msg_header_t *)msg;
    mach_msg_header_t *	reply;
    char		reply_s[128] __attribute__ ((aligned (4)));		// Wcast-align fix - force alignment

    if (process_notification(request) == FALSE) {
		if (_pppcontroller_subsystem.maxsize > sizeof(reply_s)) {
			syslog(LOG_ERR, "PPPController: %d > %ld",
				_pppcontroller_subsystem.maxsize, sizeof(reply_s));
			reply = (mach_msg_header_t *)
			malloc(_pppcontroller_subsystem.maxsize);
		}
		else {
			reply = ALIGNED_CAST(mach_msg_header_t *)reply_s;
		}
		if (pppcontroller_server(request, reply) == FALSE) {
			syslog(LOG_INFO, "unknown message ID (%d) received",
			   request->msgh_id);
			mach_msg_destroy(request);
		}
		else {
			int		options;

			options = MACH_SEND_MSG;
			if (MACH_MSGH_BITS_REMOTE(reply->msgh_bits) == MACH_MSG_TYPE_MOVE_SEND) {
				options |= MACH_SEND_TIMEOUT;
			}
			r = mach_msg(reply,
				 options,
				 reply->msgh_size,
				 0,
				 MACH_PORT_NULL,
				 MACH_MSG_TIMEOUT_NONE,
				 MACH_PORT_NULL);
			if (r != MACH_MSG_SUCCESS) {
				syslog(LOG_INFO, "PPPController: mach_msg(send): %s", 
					mach_error_string(r));
				mach_msg_destroy(reply);
			}
		}
		if (reply != ALIGNED_CAST(mach_msg_header_t *)reply_s) {
			free(reply);
		}
    }
    return;
}
Example #4
0
/* SimpleRoutine consume_send_once_right */
mig_external kern_return_t _dispatch_send_consume_send_once_right
(
    mach_port_t _port
)
{

#ifdef  __MigPackStructs
#pragma pack(4)
#endif
    typedef struct {
        mach_msg_header_t Head;
    } Request;
#ifdef  __MigPackStructs
#pragma pack()
#endif
    /*
     * typedef struct {
     * 	mach_msg_header_t Head;
     * 	NDR_record_t NDR;
     * 	kern_return_t RetCode;
     * } mig_reply_error_t;
     */

    union {
        Request In;
    } Mess;

    Request *InP = &Mess.In;

    mach_msg_return_t msg_result;

#ifdef	__MIG_check__Reply__consume_send_once_right_t__defined
    kern_return_t check_result;
#endif	/* __MIG_check__Reply__consume_send_once_right_t__defined */

    __DeclareSendSimple(79, "consume_send_once_right")

    InP->Head.msgh_bits =
        MACH_MSGH_BITS(18, 0);
    /* msgh_size passed as argument */
    InP->Head.msgh_request_port = _port;
    InP->Head.msgh_reply_port = MACH_PORT_NULL;
    InP->Head.msgh_id = 79;

    __BeforeSendSimple(79, "consume_send_once_right")
    msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request), 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
    __AfterSendSimple(79, "consume_send_once_right")
    return msg_result;
}
Example #5
0
void SignalHandler(int signum)
{
	SignalMessage	msg;
	
	msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND,0);
	msg.header.msgh_size = sizeof(msg) - sizeof(mach_msg_trailer_t);
	msg.header.msgh_remote_port = gSignalPort;
	msg.header.msgh_local_port = MACH_PORT_NULL;
	msg.header.msgh_id = kSignalMessage;
	msg.body.msgh_descriptor_count = 0;
	msg.signum = signum;
	
	mach_msg(&msg.header,(MACH_SEND_MSG | MACH_SEND_TIMEOUT),
			 msg.header.msgh_size,0,MACH_PORT_NULL,0,MACH_PORT_NULL);
}
Example #6
0
/*
 * Exception thread handler.
 */
static
void *
mach_exception_thread (void *arg)
{
	for (;;) {
		mach_exception_msg_t request;
		mach_exception_msg_t reply;
		mach_msg_return_t result;

		/* receive from "mach_exception_port" */
		result = mach_msg (&request.msg.header,
				   MACH_RCV_MSG | MACH_RCV_LARGE,
				   0,
				   sizeof (request),
				   mach_exception_port,
				   MACH_MSG_TIMEOUT_NONE,
				   MACH_PORT_NULL);

		g_assert (result == MACH_MSG_SUCCESS);

		/* dispatch to catch_exception_raise () */
		exc_server (&request.msg.header, &reply.msg.header);

		/* send back to sender */
		result = mach_msg (&reply.msg.header,
				   MACH_SEND_MSG,
				   reply.msg.header.msgh_size,
				   0,
				   MACH_PORT_NULL,
				   MACH_MSG_TIMEOUT_NONE,
				   MACH_PORT_NULL);

		g_assert (result == MACH_MSG_SUCCESS);
	}
	return NULL;
}
Example #7
0
/* this is the thread which forwards of exceptions read from the exception
   server off to our exception catchers and then back out to the other
   thread */
void exception_thread(void *shared_thread_state)
{
  mach_msg_header_t *message;
  mach_msg_header_t *reply;
  kern_return_t retval;

#ifdef USE_THREAD_LOCAL
  pthread_setspecific(scheme_thread_local_key, shared_thread_state);
#endif

  /* allocate the space for the message and reply */
  message = (mach_msg_header_t*)malloc(sizeof(mach_exc_msg_t));
  reply = (mach_msg_header_t*)malloc(sizeof(mach_reply_msg_t));
  /* do this loop forever */
  while(1) {
    /* block until we get an exception message */
    retval = mach_msg(message, MACH_RCV_MSG, 0, sizeof(mach_exc_msg_t), 
		      exc_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
    if(retval != KERN_SUCCESS) {
      GCPRINT(GCOUTF, "Message receive failed: %s\n", mach_error_string(retval));
      abort();
    }
    /* forward off the handling of this message */
    if(!exc_server(message, reply)) {
      GCPRINT(GCOUTF, "INTERNAL ERROR: exc_server() didn't like something\n");
      abort();
    }
    /* send the message back out to the thread */
    retval = mach_msg(reply, MACH_SEND_MSG, sizeof(mach_reply_msg_t), 0, 
		      MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
    if(retval != KERN_SUCCESS) {
      GCPRINT(GCOUTF, "Message send failed: %s\n", mach_error_string(retval));
      abort();
    }
  }
}
Example #8
0
/* this is the thread which forwards of exceptions read from the exception
   server off to our exception catchers and then back out to the other
   thread */
void exception_thread(void)
{
  mach_msg_header_t *message;
  mach_msg_header_t *reply;
  kern_return_t retval;
  
  /* allocate the space for the message and reply */
  message = (mach_msg_header_t*)malloc(sizeof(mach_exc_msg_t));
  reply = (mach_msg_header_t*)malloc(sizeof(mach_reply_msg_t));
  /* do this loop forever */
  while(1) {
    /* block until we get an exception message */
    retval = mach_msg(message, MACH_RCV_MSG, 0, sizeof(mach_exc_msg_t), 
		      exc_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
    /* forward off the handling of this message */
    if(!exc_server(message, reply)) {
      GCPRINT(GCOUTF, "INTERNAL ERROR: exc_server() didn't like something\n");
      abort();
    }
    /* send the message back out to the thread */
    retval = mach_msg(reply, MACH_SEND_MSG, sizeof(mach_reply_msg_t), 0, 
		      MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
  }
}
Example #9
0
static void *mach_exception_thread(void *data) {
  while (true) {
    struct {
      mach_msg_header_t head;
      mach_msg_body_t msgh_body;
      char data[1024];
    } msg;
    struct {
      mach_msg_header_t head;
      char data[1024];
    } reply;

    // wait for a message on the exception port
    mach_msg_return_t ret =
        mach_msg(&msg.head, MACH_RCV_MSG | MACH_RCV_LARGE, 0, sizeof(msg),
                 s_listen_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
    if (ret != MACH_MSG_SUCCESS) {
      LOG_INFO("mach_msg receive failed with %d %s", ret,
               mach_error_string(ret));
      break;
    }

    // call exc_server, which will call back into catch_exception_raise
    exc_server(&msg.head, &reply.head);

    // send the reply
    ret = mach_msg(&reply.head, MACH_SEND_MSG, reply.head.msgh_size, 0,
                   MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
    if (ret != MACH_MSG_SUCCESS) {
      LOG_INFO("mach_msg send failed with %d %s", ret, mach_error_string(ret));
      break;
    }
  }

  return NULL;
}
Example #10
0
void PAL_DispatchException(PCONTEXT pContext, PEXCEPTION_RECORD pExRecord)
{

    MSG_SET_THREAD MsgSet;
    kern_return_t MachRet;
    EXCEPTION_POINTERS pointers;

    pointers.ExceptionRecord = pExRecord;
    pointers.ContextRecord = pContext;

    // Raise the exception
    SEHRaiseException(&pointers, 0);

    // We need to send a message to the worker thread so that it can set our thread context

    // Setup the heaer
    MsgSet.m_MsgHdr.msgh_size = sizeof(MsgSet);
    MsgSet.m_MsgHdr.msgh_bits = MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_MAKE_SEND|MACH_MSG_TYPE_MOVE_RECEIVE); // Simple Message
    MsgSet.m_MsgHdr.msgh_remote_port = s_ExceptionPort; // Send, dest port
    MsgSet.m_MsgHdr.msgh_local_port = MACH_PORT_NULL;   // We're not expecting a msg back
    MsgSet.m_MsgHdr.msgh_id = SET_THREAD_MESSAGE_ID; // Message ID
    MsgSet.m_MsgHdr.msgh_reserved = 0; // Not used

    // Setup the thread and thread context
    MsgSet.m_ThreadPort = mach_thread_self();
    MsgSet.m_ThreadContext = *pContext;

    // Send the  message to the exception port
    MachRet = mach_msg(&MsgSet.m_MsgHdr,
                       MACH_SEND_MSG,
                       MsgSet.m_MsgHdr.msgh_size,
                       0,
                       MACH_PORT_NULL,
                       MACH_MSG_TIMEOUT_NONE,
                       MACH_PORT_NULL);

    if (MachRet != KERN_SUCCESS)
    {
        UTIL_SetLastErrorFromMach(MachRet);
        ExitProcess(GetLastError());
    }

    // Make sure we don't do anything
    while(1)
    {
        sched_yield();
    }
}
Example #11
0
void Connection::receiveSourceEventHandler()
{
    char buffer[inlineMessageMaxSize];
    
    mach_msg_header_t* header = reinterpret_cast<mach_msg_header_t*>(&buffer);
    
    kern_return_t kr = mach_msg(header, MACH_RCV_MSG | MACH_RCV_LARGE | MACH_RCV_TIMEOUT, 0, sizeof(buffer), m_receivePort, 0, MACH_PORT_NULL);
    if (kr == MACH_RCV_TIMED_OUT)
        return;

    if (kr != MACH_MSG_SUCCESS) {

        ASSERT_NOT_REACHED();
        // FIXME: Handle MACH_RCV_MSG_TOO_LARGE.
        return;
    }
    
    MessageID messageID = MessageID::fromInt(header->msgh_id);
    std::auto_ptr<ArgumentDecoder> arguments = createArgumentDecoder(header);
    ASSERT(arguments.get());

    if (messageID == MessageID(CoreIPCMessage::InitializeConnection)) {
        ASSERT(m_isServer);
        ASSERT(!m_isConnected);
        ASSERT(!m_sendPort);

        MachPort port;
        if (!arguments->decode(port)) {
            // FIXME: Disconnect.
            return;
        }

        m_sendPort = port.port();
        
        // Set the dead name source if needed.
        if (m_sendPort)
            initializeDeadNameSource();
        
        m_isConnected = true;

        // Send any pending outgoing messages.
        sendOutgoingMessages();
        
        return;
    }
    
    processIncomingMessage(messageID, arguments);
}    
Example #12
0
IOReturn IODataQueueWaitForAvailableData(IODataQueueMemory *dataQueue, mach_port_t notifyPort)
{
    IOReturn kr;
    struct {
            mach_msg_header_t msgHdr;
//            OSNotificationHeader notifyHeader;
            mach_msg_trailer_t trailer;
    } msg;
    
    if (dataQueue && (notifyPort != MACH_PORT_NULL)) {
        kr = mach_msg(&msg.msgHdr, MACH_RCV_MSG, 0, sizeof(msg), notifyPort, 0, MACH_PORT_NULL);
    } else {
        kr = kIOReturnBadArgument;
    }

    return kr;
}
static void
TerminateMachExceptionHandlerThread()
{
    // Send a simple quit message to the exception handler thread.
    mach_msg_header_t msg;
    msg.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0);
    msg.msgh_size = static_cast<mach_msg_size_t>(sizeof(msg));
    msg.msgh_remote_port = sMachExceptionState.current.port;
    msg.msgh_local_port = MACH_PORT_NULL;
    msg.msgh_reserved = 0;
    msg.msgh_id = sIDQuit;
    kern_return_t ret = mach_msg(&msg, MACH_SEND_MSG, sizeof(msg), 0, MACH_PORT_NULL,
                                 MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);

    if (ret == MACH_MSG_SUCCESS)
        sMachExceptionState.handlerThread.join();
    else
        MOZ_CRASH("MachExceptionHandler: Handler thread failed to terminate!");
}
Example #14
0
static int
recv_port (mach_port_t recv_port, mach_port_t *port)
{
    kern_return_t       err;
    struct {
        mach_msg_header_t          header;
        mach_msg_body_t            body;
        mach_msg_port_descriptor_t task_port;
        mach_msg_trailer_t         trailer;
    } msg;

    err = mach_msg (&msg.header, MACH_RCV_MSG,
                    0, sizeof msg, recv_port,
                    MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
    CHECK_MACH_ERROR (err, "mach_msg failed:");

    *port = msg.task_port.name;
    return 0;
}
Example #15
0
error_t
send (mach_msg_id_t msgid)
{
  error_t err;
  Message.Request = RequestTemplate;
  Message.Request.Head.msgh_id = msgid;
  err = mach_msg (&Message.Request.Head,
		  MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE,
		  sizeof Message.Request,
		  sizeof Message.Reply,
		  Message.Request.Head.msgh_local_port,
		  MACH_MSG_TIMEOUT_NONE,
		  MACH_PORT_NULL);
  if (err)
    return err;

  /* XXX typecheck */
  return Message.Reply.RetCode;
}
Example #16
0
STATIC void
server_handle_request(CFMachPortRef port, void * msg, CFIndex size, void * info)
{
    mach_msg_return_t 	r;
    mach_msg_header_t *	request = (mach_msg_header_t *)msg;
    mach_msg_header_t *	reply;
    char		reply_s[eapolcfg_auth_subsystem.maxsize];

    if (process_notification(request) == FALSE) {
	reply = (mach_msg_header_t *)reply_s;
	if (eapolcfg_auth_server(request, reply) == FALSE) {
	    syslog(LOG_NOTICE,
		   "eapolcfg_auth: unknown message ID (%d)",
		   request->msgh_id);
	    mach_msg_destroy(request);
	}
	else {
	    int		options;

	    S_handled_request = TRUE;

	    options = MACH_SEND_MSG;
	    if (MACH_MSGH_BITS_REMOTE(reply->msgh_bits)
                != MACH_MSG_TYPE_MOVE_SEND_ONCE) {
		options |= MACH_SEND_TIMEOUT;
	    }
	    r = mach_msg(reply,
			 options,
			 reply->msgh_size,
			 0,
			 MACH_PORT_NULL,
			 MACH_MSG_TIMEOUT_NONE,
			 MACH_PORT_NULL);
	    if (r != MACH_MSG_SUCCESS) {
		syslog(LOG_NOTICE, "eapolcfg_auth: mach_msg(send): %s", 
		       mach_error_string(r));
		mach_msg_destroy(reply);
	    }
	}
    }
    return;
}
Example #17
0
mach_port_t do_parent(mach_port_t shared_port) {
    kern_return_t err;

    // wait for our child to send us its task port
    port_msg_rcv_t msg = {0};
    err = mach_msg(&msg.header,
                   MACH_RCV_MSG,
                   0,
                   sizeof(msg),
                   shared_port,
                   MACH_MSG_TIMEOUT_NONE,
                   MACH_PORT_NULL);
    MACH_ERR("parent receiving child task port message", err);

    mach_port_t child_task_port = msg.port.name;
    if (child_task_port == MACH_PORT_NULL) {
        FAIL("invalid child task port");
    }

    return child_task_port;
}
Example #18
0
/* -----------------------------------------------------------------------------
----------------------------------------------------------------------------- */
void mach_client_notify (mach_port_t port, CFStringRef serviceID, u_long event, u_long error)
{
	mach_msg_empty_send_t	msg;
	kern_return_t			status;

	/* Post notification as mach message */
	msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0);
	msg.header.msgh_size = sizeof(msg);
	msg.header.msgh_remote_port = port;
	msg.header.msgh_local_port = MACH_PORT_NULL;
	msg.header.msgh_id = 0;
	status = mach_msg(&msg.header,		/* msg */
			  MACH_SEND_MSG|MACH_SEND_TIMEOUT,	/* options */
			  msg.header.msgh_size,		/* send_size */
			  0,						/* rcv_size */
			  MACH_PORT_NULL,			/* rcv_name */
			  0,						/* timeout */
			  MACH_PORT_NULL);			/* notify */

	if (status == MACH_SEND_TIMEOUT)
		mach_msg_destroy(&msg.header);
}
Example #19
0
File: send.c Project: ctos/bpi
void receive_integer( mach_port_t source, int *ip )
{
    kern_return_t err;

    struct integer_message message;


    err = mach_msg( &(message.head), MACH_RCV_MSG, 0,message.head.msgh_size, source,MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL );

    if( err == MACH_MSG_SUCCESS )
    {
        printf( "success: the message was received\n" );
    }
    else
    {
        perror( "error: Some unexpected error ocurred\n" );
    }

    *ip = message.inline_integer;

    return;
}
void bad_xpc(mach_port_t p) {
  kern_return_t err;
  struct xpc_bad_ool msg = {0};

  msg.hdr.msgh_bits = MACH_MSGH_BITS_SET(MACH_MSG_TYPE_COPY_SEND, 0, 0, MACH_MSGH_BITS_COMPLEX);
  msg.hdr.msgh_size = sizeof(msg);
  msg.hdr.msgh_remote_port = p;
  msg.hdr.msgh_id   = 0x10000000;
  
  msg.body.msgh_descriptor_count = 0;

  msg.ool0.address = 0x414141414141;
  msg.ool0.size = 0x4000;
  msg.ool0.type = MACH_MSG_OOL_DESCRIPTOR;
  
  msg.port1.name = 0x41414141;  // port name to mach_port_deallocate in target
  msg.port1.disposition = 0x11;
  msg.port1.type = MACH_MSG_PORT_DESCRIPTOR;
  
  msg.ool2.address = 0x414141414141;
  msg.ool2.size = 0x4000;
  msg.ool2.type = MACH_MSG_OOL_DESCRIPTOR;
  

  err = mach_msg(&msg.hdr,
                 MACH_SEND_MSG|MACH_MSG_OPTION_NONE,
                 msg.hdr.msgh_size,
                 0,
                 MACH_PORT_NULL,
                 MACH_MSG_TIMEOUT_NONE,
                 MACH_PORT_NULL);
  if (err != KERN_SUCCESS) {
    printf("xpc message send failed: %s\n", mach_error_string(err));
    exit(EXIT_FAILURE);
  } else {
    printf("sent xpc message\n");
  }

}
void do_free(mach_port_t host_service, mach_port_t target_port) {
  kern_return_t err;
  
  int port_count = 0x10000;
  mach_port_t* ports = malloc(port_count * sizeof(mach_port_t));
  for (int i = 0; i < port_count; i++) {
    ports[i] = target_port;
  }
  
  // build the message to free the target port name
  struct launchd_ool_msg* free_msg = malloc(sizeof(struct launchd_ool_msg));
  memset(free_msg, 0, sizeof(struct launchd_ool_msg));
  
  free_msg->hdr.msgh_bits = MACH_MSGH_BITS_COMPLEX | MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0);
  free_msg->hdr.msgh_size = sizeof(struct launchd_ool_msg);
  free_msg->hdr.msgh_remote_port = host_service;
  free_msg->hdr.msgh_local_port = MACH_PORT_NULL;
  free_msg->hdr.msgh_id = msgh_id_to_get_destroyed;
  
  free_msg->body.msgh_descriptor_count = 1;
  
  free_msg->ool_ports.address = ports;
  free_msg->ool_ports.count = port_count;
  free_msg->ool_ports.deallocate = 0;
  free_msg->ool_ports.disposition = MACH_MSG_TYPE_COPY_SEND;
  free_msg->ool_ports.type = MACH_MSG_OOL_PORTS_DESCRIPTOR;
  free_msg->ool_ports.copy = MACH_MSG_PHYSICAL_COPY;
  
  // send the free message
  err = mach_msg(&free_msg->hdr,
                 MACH_SEND_MSG|MACH_MSG_OPTION_NONE,
                 (mach_msg_size_t)sizeof(struct launchd_ool_msg),
                 0,
                 MACH_PORT_NULL,
                 MACH_MSG_TIMEOUT_NONE,
                 MACH_PORT_NULL);
  printf("free message: %s\n", mach_error_string(err));
}
Example #22
0
mach_port_t recover_shared_port_parent() {
  kern_return_t err;

  // restore the special port for ourselves
  err = task_set_special_port(mach_task_self(), STOLEN_SPECIAL_PORT, saved_special_port);
  MACH_ERR("parent restoring special port", err);

  // wait for a message from the child on the shared port
  simple_msg_rcv_t msg = {0};
  err = mach_msg(&msg.header,
                 MACH_RCV_MSG,
                 0,
                 sizeof(msg),
                 shared_port_parent,
                 MACH_MSG_TIMEOUT_NONE,
                 MACH_PORT_NULL);
  MACH_ERR("parent receiving child hello message", err);

  LOG("parent received hello message from child");

  // send the special port to our child over the hello message's reply port
  port_msg_send_t special_port_msg = {0};

  special_port_msg.header.msgh_size        = sizeof(special_port_msg);
  special_port_msg.header.msgh_local_port  = MACH_PORT_NULL;
  special_port_msg.header.msgh_remote_port = msg.header.msgh_remote_port;
  special_port_msg.header.msgh_bits        = MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(msg.header.msgh_bits), 0) | MACH_MSGH_BITS_COMPLEX;
  special_port_msg.body.msgh_descriptor_count = 1;

  special_port_msg.port.name        = saved_special_port;
  special_port_msg.port.disposition = MACH_MSG_TYPE_COPY_SEND;
  special_port_msg.port.type        = MACH_MSG_PORT_DESCRIPTOR;

  err = mach_msg_send(&special_port_msg.header);
  MACH_ERR("parent sending special port back to child", err);

  return shared_port_parent;
}
void spoof(mach_port_t port, uint32_t name) {
  kern_return_t err;
  struct notification_msg not = {0};
  
  not.not_header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0);
  not.not_header.msgh_size = sizeof(struct notification_msg);
  not.not_header.msgh_remote_port = port;
  not.not_header.msgh_local_port = MACH_PORT_NULL;
  not.not_header.msgh_id = 0110; // MACH_NOTIFY_DEAD_NAME
  
  not.NDR = NDR_record;
  
  not.not_port = name;
  
  // send the fake notification message
  err = mach_msg(&not.not_header,
                 MACH_SEND_MSG|MACH_MSG_OPTION_NONE,
                 (mach_msg_size_t)sizeof(struct notification_msg),
                 0,
                 MACH_PORT_NULL,
                 MACH_MSG_TIMEOUT_NONE,
                 MACH_PORT_NULL);
}
Example #24
0
static void __DACommandSignal( int sig )
{
    /*
     * Process a SIGCHLD signal.  mach_msg() is safe from a signal handler.
     */

    mach_msg_header_t message;
    kern_return_t     status;

    message.msgh_bits        = MACH_MSGH_BITS( MACH_MSG_TYPE_COPY_SEND, 0 );
    message.msgh_id          = 0;
    message.msgh_local_port  = MACH_PORT_NULL;
    message.msgh_remote_port = CFMachPortGetPort( __gDACommandRunLoopSourcePort );
    message.msgh_reserved    = 0;
    message.msgh_size        = sizeof( message );

    status = mach_msg( &message, MACH_SEND_MSG | MACH_SEND_TIMEOUT, message.msgh_size, 0, MACH_PORT_NULL, 0, MACH_PORT_NULL );

    if ( status == MACH_SEND_TIMED_OUT )
    {
        mach_msg_destroy( &message );
    }
}
Example #25
0
kern_return_t	CACFMachPort::ReceiveMessage(UInt32 inMaxMessageSize, mach_msg_header_t* outMessage, mach_msg_timeout_t inTimeOut)
{
	//	snag the port
	mach_port_t thePort = CFMachPortGetPort(mMachPort);

	//	fill out the message header
	outMessage->msgh_bits = 0;
	outMessage->msgh_size = 0;
	outMessage->msgh_remote_port = MACH_PORT_NULL;
	outMessage->msgh_local_port = thePort;
	outMessage->msgh_reserved = 0;
	outMessage->msgh_id = 0;

	//	figure the options
	mach_msg_options_t theOptions = MACH_RCV_MSG;
	if(inTimeOut > 0)
	{
		theOptions |= MACH_RCV_TIMEOUT;
	}
	
	//	receive the messsage
	return mach_msg(outMessage, theOptions, 0, inMaxMessageSize, thePort, inTimeOut, MACH_PORT_NULL);
}
kern_return_t
oxpc_object_send_as_mach_message(
  oxpc_object_t obj,
  mach_port_t destination_port,
  mach_port_t reply_port)
{
  size_t msg_size = 0;
  mach_msg_header_t* msg = oxpc_object_serialize_to_mach_message(obj, destination_port, reply_port, &msg_size);

  if (!msg) {
    ERROR("unable to serialize oxpc object to mach message");
  }

  kern_return_t err;
  err = mach_msg(msg,
                 MACH_SEND_MSG|MACH_MSG_OPTION_NONE,
                 (mach_msg_size_t)msg_size,
                 0,
                 MACH_PORT_NULL,
                 MACH_MSG_TIMEOUT_NONE,
                 MACH_PORT_NULL);

  return err;
}
void *ExceptionHandlerThread(void *thread_arg) {
  mach_port_t handler_port = (mach_port_t) (uintptr_t) thread_arg;

  while (1) {
    struct {
      mach_msg_header_t header;
      uint8_t data[256];
    } receive;
    mach_msg_header_t reply;
    kern_return_t rc;

    receive.header.msgh_local_port = handler_port;
    receive.header.msgh_size = sizeof(receive);
    rc = mach_msg(&receive.header,
                  MACH_RCV_MSG | MACH_RCV_LARGE, 0,
                  receive.header.msgh_size, handler_port,
                  MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
    CHECK(rc == KERN_SUCCESS);
    CHECK(exc_server(&receive.header, &reply));
    exit(1);
  }

  return NULL;
}
Example #28
0
void CEeExecutor::HandlerThreadProc()
{
#pragma pack(push, 4)
	struct INPUT_MESSAGE
	{
		mach_msg_header_t head;
		NDR_record_t ndr;
		exception_type_t exception;
		mach_msg_type_number_t codeCount;
		intptr_t code[2];
		int flavor;
		mach_msg_type_number_t stateCount;
		natural_t state[STATE_FLAVOR_COUNT];
		mach_msg_trailer_t trailer;
	};
	struct OUTPUT_MESSAGE
	{
		mach_msg_header_t head;
		NDR_record_t ndr;
		kern_return_t result;
		int flavor;
		mach_msg_type_number_t stateCount;
		natural_t state[STATE_FLAVOR_COUNT];
	};
#pragma pack(pop)

	while(1)
	{
		kern_return_t result = KERN_SUCCESS;
		
		INPUT_MESSAGE inMsg;
		result = mach_msg(&inMsg.head, MACH_RCV_MSG | MACH_RCV_LARGE, 0, sizeof(inMsg), m_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
		assert(result == KERN_SUCCESS);
		
		assert(inMsg.head.msgh_id == 2406);	//MACH_EXCEPTION_RAISE_RPC
		
		bool success = HandleAccessFault(inMsg.code[1]);
		
		OUTPUT_MESSAGE outMsg;
		outMsg.head.msgh_bits			= MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(inMsg.head.msgh_bits), 0);
		outMsg.head.msgh_remote_port	= inMsg.head.msgh_remote_port;
		outMsg.head.msgh_local_port		= MACH_PORT_NULL;
		outMsg.head.msgh_id				= inMsg.head.msgh_id + 100;
		outMsg.head.msgh_size			= sizeof(outMsg);
		outMsg.ndr						= inMsg.ndr;

		if(success)
		{
			outMsg.result		= KERN_SUCCESS;
			outMsg.flavor		= STATE_FLAVOR;
			outMsg.stateCount	= STATE_FLAVOR_COUNT;
			memcpy(outMsg.state, inMsg.state, STATE_FLAVOR_COUNT * sizeof(natural_t));
		}
		else
		{
			outMsg.result		= KERN_FAILURE;
			outMsg.flavor		= 0;
			outMsg.stateCount	= 0;
		}
		
		result = mach_msg(&outMsg.head, MACH_SEND_MSG | MACH_RCV_LARGE, sizeof(outMsg), 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
		assert(result == KERN_SUCCESS);
	}
}
Example #29
0
void *mach_profile_listener(void *arg)
{
    (void)arg;
    int max_size = 512;
    mach_profiler_thread = mach_thread_self();
    mig_reply_error_t *bufRequest = (mig_reply_error_t *) malloc(max_size);
    while (1) {
        kern_return_t ret = mach_msg(&bufRequest->Head, MACH_RCV_MSG,
                                     0, max_size, profile_port,
                                     MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
        HANDLE_MACH_ERROR("mach_msg",ret);
        if (bt_size_cur < bt_size_max) {
            kern_return_t ret;
            // Suspend the thread so we may safely sample it
            ret = thread_suspend(main_thread);
            HANDLE_MACH_ERROR("thread_suspend",ret);

            // Do the actual sampling
            unsigned int count = MACHINE_THREAD_STATE_COUNT;
            x86_thread_state64_t state;

            // Get the state of the suspended thread
            ret = thread_get_state(main_thread,x86_THREAD_STATE64,(thread_state_t)&state,&count);
            HANDLE_MACH_ERROR("thread_get_state",ret);

            // Initialize the unwind context with the suspend thread's state
            unw_context_t uc; 
            memset(&uc,0,sizeof(unw_context_t));
            memcpy(&uc,&state,sizeof(x86_thread_state64_t));

            /*
             *  Unfortunately compact unwind info is incorrectly generated for quite a number of
             *  libraries by quite a large number of compilers. We can fall back to DWARF unwind info
             *  in some cases, but in quite a number of cases (especially libraries not compiled in debug
             *  mode, only the compact unwind info may be available). Even more unfortunately, there is no
             *  way to detect such bogus compact unwind info (other than noticing the resulting segfault).
             *  What we do here is ugly, but necessary until the compact unwind info situation improves.
             *  We try to use the compact unwind info and if that results in a segfault, we retry with DWARF info.
             *  Note that in a small number of cases this may result in bogus stack traces, but at least the topmost
             *  entry will always be correct, and the number of cases in which this is an issue is rather small.
             *  Other than that, this implementation is not incorrect as the other thread is paused while we are profiling
             *  and during stack unwinding we only ever read memory, but never write it.
             */

            forceDwarf = 0;
            unw_getcontext(&profiler_uc);

            if (forceDwarf == 0) {
                // Save the backtrace
                bt_size_cur += rec_backtrace_ctx((ptrint_t*)bt_data_prof+bt_size_cur, bt_size_max-bt_size_cur-1, &uc);
            }
            else if (forceDwarf == 1) {
                bt_size_cur += rec_backtrace_ctx_dwarf((ptrint_t*)bt_data_prof+bt_size_cur, bt_size_max-bt_size_cur-1, &uc);
            }
            else if (forceDwarf == -1) {
                JL_PRINTF(JL_STDERR, "Warning: Profiler attempt to access an invalid memory location\n");
            }

            forceDwarf = -2;

            // Mark the end of this block with 0
            bt_data_prof[bt_size_cur] = 0;
            bt_size_cur++;

            // We're done! Resume the thread. 
            ret = thread_resume(main_thread);
            HANDLE_MACH_ERROR("thread_resume",ret)

            if (running) {
                // Reset the alarm
                ret = clock_alarm(clk, TIME_RELATIVE, timerprof, profile_port);
                HANDLE_MACH_ERROR("clock_alarm",ret)
            }
        }
    }
Example #30
0
/*
 * This message server catches user task exceptions. Most user exceptions
 * will be received on the thread exception port. This server servers
 * only exceptions from unknown threads or from external debuggers.
 * It runs in a dedicated thread.
 */
void *
task_exception_catcher(
	void	*arg)
{
	struct server_thread_priv_data	priv_data;
	kern_return_t			kr;
#define MSG_BUFFER_SIZE	8192
	union request_msg {
		mach_msg_header_t	hdr;
		mig_reply_error_t	death_pill;
		char			space[MSG_BUFFER_SIZE];
	} *msg_buffer_1, *msg_buffer_2;
	mach_msg_header_t		*request;
	mig_reply_error_t		*reply;
	mach_msg_header_t		*tmp;

	cthread_set_name(cthread_self(), "task exc catcher");
	server_thread_set_priv_data(cthread_self(), &priv_data);

	uniproc_enter();

	kr = vm_allocate(mach_task_self(),
			 (vm_address_t *) &msg_buffer_1,
			 2 * sizeof *msg_buffer_1,
			 TRUE);
	if (kr != KERN_SUCCESS) {
		MACH3_DEBUG(0, kr, ("task_exception_catcher: vm_allocate"));
		panic("task_exception_catcher");
	}

	msg_buffer_2 = msg_buffer_1 + 1;
	request = &msg_buffer_1->hdr;
	reply = &msg_buffer_2->death_pill;

	do {
		uniproc_exit();
		kr = mach_msg(request, MACH_RCV_MSG,
			      0, sizeof *msg_buffer_1,
			      user_trap_port,
			      MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
		if (kr != MACH_MSG_SUCCESS) {
			MACH3_DEBUG(1, kr,
				    ("task_exception_catcher: mach_msg"));
			panic("task_exception_catcher: receive");
		}
		uniproc_enter();

		if (exc_server(request, &reply->Head)) {}
		else {
			printk("trap_exception_catcher: invalid message"
			       "(id = %d = 0x%x)\n",
			       request->msgh_id, request->msgh_id);
		}

		if (reply->Head.msgh_remote_port == MACH_PORT_NULL) {
			/* no reply port, just get another request */
			continue;
		}
		if (!(reply->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) &&
		    reply->RetCode == MIG_NO_REPLY) {
			/* deallocate reply port right */
			(void) mach_port_deallocate(mach_task_self(),
						    reply->Head.msgh_remote_port);
			continue;
		}

		/* Send reply to request and receive another */
		uniproc_exit();
		kr = mach_msg(&reply->Head,
			      MACH_SEND_MSG,
			      reply->Head.msgh_size,
			      0,
			      MACH_PORT_NULL,
			      MACH_MSG_TIMEOUT_NONE,
			      MACH_PORT_NULL);
		uniproc_enter();

		if (kr != MACH_MSG_SUCCESS) {
			if (kr == MACH_SEND_INVALID_DEST) {
				/* deallocate reply port right */
				/* XXX should destroy reply msg */
				(void) mach_port_deallocate(mach_task_self(),
							    reply->Head.msgh_remote_port);
			} else {
				MACH3_DEBUG(0, kr, ("mach_msg"));
				panic("task_exception_catcher: send");
			}
		}

		tmp = request;
		request = (mach_msg_header_t *) reply;
		reply = (mig_reply_error_t *) tmp;

	} while (1);
       
	cthread_detach(cthread_self());
	cthread_exit((void *) 0);
	/*NOTREACHED*/
	return (void *) 0;
}