Esempio n. 1
0
/*
 *	Routine:	ipc_mqueue_peek
 *	Purpose:
 *		Peek at a (non-set) message queue to see if it has a message
 *		matching the sequence number provided (if zero, then the
 *		first message in the queue) and return vital info about the
 *		message.
 *
 *	Conditions:
 *		Locks may be held by callers, so this routine cannot block.
 *		Caller holds reference on the message queue.
 */
unsigned
ipc_mqueue_peek(ipc_mqueue_t 		mq,
		mach_port_seqno_t	*seqnop,
		mach_msg_size_t		*msg_sizep,
		mach_msg_id_t		*msg_idp,
		mach_msg_max_trailer_t 	*msg_trailerp)
{
	ipc_kmsg_queue_t kmsgq;
	ipc_kmsg_t kmsg; 
	mach_port_seqno_t seqno, msgoff;
	int res = 0;
	spl_t s;

	assert(!imq_is_set(mq));

	s = splsched();
	imq_lock(mq);

	seqno = (seqnop != NULL) ? seqno = *seqnop : 0;

	if (seqno == 0) {
		seqno = mq->imq_seqno;
		msgoff = 0;
	} else if (seqno >= mq->imq_seqno && 
		   seqno < mq->imq_seqno + mq->imq_msgcount) {
		msgoff = seqno - mq->imq_seqno;
	} else
		goto out;

	/* look for the message that would match that seqno */
	kmsgq = &mq->imq_messages;
	kmsg = ipc_kmsg_queue_first(kmsgq);
	while (msgoff-- && kmsg != IKM_NULL) {
		kmsg = ipc_kmsg_queue_next(kmsgq, kmsg);
	}
	if (kmsg == IKM_NULL)
		goto out;

	/* found one - return the requested info */
	if (seqnop != NULL)
		*seqnop = seqno;
	if (msg_sizep != NULL)
		*msg_sizep = kmsg->ikm_header->msgh_size;
	if (msg_idp != NULL)
		*msg_idp = kmsg->ikm_header->msgh_id;
	if (msg_trailerp != NULL)
		memcpy(msg_trailerp, 
		       (mach_msg_max_trailer_t *)((vm_offset_t)kmsg->ikm_header +
						  round_msg(kmsg->ikm_header->msgh_size)),
		       sizeof(mach_msg_max_trailer_t));
	res = 1;

 out:
	imq_unlock(mq);
	splx(s);
	return res;
}
Esempio n. 2
0
static inline size_t machMessageSize(size_t bodySize, size_t numberOfPortDescriptors = 0, size_t numberOfOOLMemoryDescriptors = 0)
{
    size_t size = sizeof(mach_msg_header_t) + bodySize;
    if (numberOfPortDescriptors || numberOfOOLMemoryDescriptors) {
        size += sizeof(mach_msg_body_t);
        if (numberOfPortDescriptors)
            size += (numberOfPortDescriptors * sizeof(mach_msg_port_descriptor_t));
        if (numberOfOOLMemoryDescriptors)
            size += (numberOfOOLMemoryDescriptors * sizeof(mach_msg_ool_ports_descriptor_t));
    }
    return round_msg(size);
}
Esempio n. 3
0
size_t MachMessage::messageSize(size_t bodySize, size_t portDescriptorCount, size_t memoryDescriptorCount)
{
    size_t messageSize = sizeof(mach_msg_header_t) + bodySize;

    if (portDescriptorCount || memoryDescriptorCount) {
        messageSize += sizeof(mach_msg_body_t);

        if (portDescriptorCount)
            messageSize += (portDescriptorCount * sizeof(mach_msg_port_descriptor_t));
        if (memoryDescriptorCount)
            messageSize += (memoryDescriptorCount * sizeof(mach_msg_ool_descriptor_t));
    }

    return round_msg(messageSize);
}
Esempio n. 4
0
mach_msg_return_t
msg_receive_error(
	ipc_kmsg_t		kmsg,
	mach_vm_address_t	msg_addr,
	mach_msg_option_t	option,
	mach_port_seqno_t	seqno,
	ipc_space_t		space)
{
	mach_vm_address_t	context;
	mach_msg_trailer_size_t trailer_size;
	mach_msg_max_trailer_t	*trailer;

	context = kmsg->ikm_header->msgh_remote_port->ip_context;

	/*
	 * Copy out the destination port in the message.
 	 * Destroy all other rights and memory in the message.
	 */
	ipc_kmsg_copyout_dest(kmsg, space);

	/*
	 * Build a minimal message with the requested trailer.
	 */
	trailer = (mach_msg_max_trailer_t *) 
			((vm_offset_t)kmsg->ikm_header +
			round_msg(sizeof(mach_msg_header_t)));
	kmsg->ikm_header->msgh_size = sizeof(mach_msg_header_t);
	bcopy(  (char *)&trailer_template, 
		(char *)trailer, 
		sizeof(trailer_template));

	trailer_size = ipc_kmsg_add_trailer(kmsg, space, 
			option, current_thread(), seqno,
			TRUE, context);

	/*
	 * Copy the message to user space
	 */
	if (ipc_kmsg_put(msg_addr, kmsg, kmsg->ikm_header->msgh_size +
			trailer_size) == MACH_RCV_INVALID_DATA)
		return(MACH_RCV_INVALID_DATA);
	else 
		return(MACH_MSG_SUCCESS);
}
Esempio n. 5
0
/* Routine Query */
mig_external kern_return_t libinfoDSmig_Query
(
	mach_port_t server,
	int32_t proc,
	inline_data_t request,
	mach_msg_type_number_t requestCnt,
	inline_data_t reply,
	mach_msg_type_number_t *replyCnt,
	vm_offset_t *ooreply,
	mach_msg_type_number_t *ooreplyCnt,
	security_token_t *usertoken
)
{

#ifdef  __MigPackStructs
#pragma pack(4)
#endif
	typedef struct {
		mach_msg_header_t Head;
		NDR_record_t NDR;
		int32_t proc;
		mach_msg_type_number_t requestCnt;
		char request[16384];
	} Request;
#ifdef  __MigPackStructs
#pragma pack()
#endif

#ifdef  __MigPackStructs
#pragma pack(4)
#endif
	typedef struct {
		mach_msg_header_t Head;
		/* start of the kernel processed data */
		mach_msg_body_t msgh_body;
		mach_msg_ool_descriptor_t ooreply;
		/* end of the kernel processed data */
		NDR_record_t NDR;
		mach_msg_type_number_t replyCnt;
		char reply[16384];
		mach_msg_type_number_t ooreplyCnt;
		mach_msg_max_trailer_t trailer;
	} Reply;
#ifdef  __MigPackStructs
#pragma pack()
#endif

#ifdef  __MigPackStructs
#pragma pack(4)
#endif
	typedef struct {
		mach_msg_header_t Head;
		/* start of the kernel processed data */
		mach_msg_body_t msgh_body;
		mach_msg_ool_descriptor_t ooreply;
		/* end of the kernel processed data */
		NDR_record_t NDR;
		mach_msg_type_number_t replyCnt;
		char reply[16384];
		mach_msg_type_number_t ooreplyCnt;
	} __Reply;
#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;
		Reply Out;
	} Mess;

	Request *InP = &Mess.In;
	Reply *Out0P = &Mess.Out;
	Reply *Out1P = NULL;

	mach_msg_return_t msg_result;
	unsigned int msgh_size;
	mach_msg_max_trailer_t *TrailerP;
#if	__MigTypeCheck
	unsigned int trailer_size;
#endif	/* __MigTypeCheck */

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

	__DeclareSendRpc(50001, "Query")

	InP->NDR = NDR_record;

	InP->proc = proc;

	if (requestCnt > 16384) {
		{ return MIG_ARRAY_TOO_LARGE; }
	}
	(void)memcpy((char *) InP->request, (const char *) request, requestCnt);

	InP->requestCnt = requestCnt;

	msgh_size = (mach_msg_size_t)(sizeof(Request) - 16384) + (_WALIGN_(requestCnt));
	InP->Head.msgh_bits =
		MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE);
	/* msgh_size passed as argument */
	InP->Head.msgh_request_port = server;
	InP->Head.msgh_reply_port = mig_get_reply_port();
	InP->Head.msgh_id = 50001;

	__BeforeSendRpc(50001, "Query")
	msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0)|MACH_MSG_OPTION_NONE|MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_SENDER), msgh_size, (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
	__AfterSendRpc(50001, "Query")
	if (msg_result != MACH_MSG_SUCCESS) {
		__MachMsgErrorWithoutTimeout(msg_result);
		{ return msg_result; }
	}


#if	defined(__MIG_check__Reply__Query_t__defined)
	check_result = __MIG_check__Reply__Query_t((__Reply__Query_t *)Out0P, (__Reply__Query_t **)&Out1P);
	if (check_result != MACH_MSG_SUCCESS)
		{ return check_result; }
#endif	/* defined(__MIG_check__Reply__Query_t__defined) */

	TrailerP = (mach_msg_max_trailer_t *)((vm_offset_t)Out0P +
		round_msg(Out0P->Head.msgh_size));
	if (TrailerP->msgh_trailer_type != MACH_MSG_TRAILER_FORMAT_0)
		{ return MIG_TRAILER_ERROR ; }
#if	__MigTypeCheck
	trailer_size = TrailerP->msgh_trailer_size -
		(mach_msg_size_t)(sizeof(mach_msg_trailer_type_t) - sizeof(mach_msg_trailer_size_t));
#endif	/* __MigTypeCheck */
#if	__MigTypeCheck
	if (trailer_size < (mach_msg_size_t)sizeof(security_token_t))
		{ return MIG_TRAILER_ERROR ; }
	trailer_size -= (mach_msg_size_t)sizeof(security_token_t);
#endif	/* __MigTypeCheck */

	if (Out0P->replyCnt > 16384) {
		(void)memcpy((char *) reply, (const char *) Out0P->reply,  16384);
		*replyCnt = Out0P->replyCnt;
		{ return MIG_ARRAY_TOO_LARGE; }
	}
	(void)memcpy((char *) reply, (const char *) Out0P->reply, Out0P->replyCnt);

	*replyCnt = Out0P->replyCnt;

	*ooreply = (vm_offset_t)(Out0P->ooreply.address);
	*ooreplyCnt = Out1P->ooreplyCnt;

	*usertoken = TrailerP->msgh_sender;

	return KERN_SUCCESS;
}
Esempio n. 6
0
/* Routine GetProcedureNumber */
mig_external kern_return_t libinfoDSmig_GetProcedureNumber
(
	mach_port_t server,
	proc_name_t name,
	int32_t *procno,
	security_token_t *usertoken
)
{

#ifdef  __MigPackStructs
#pragma pack(4)
#endif
	typedef struct {
		mach_msg_header_t Head;
		NDR_record_t NDR;
		mach_msg_type_number_t nameOffset; /* MiG doesn't use it */
		mach_msg_type_number_t nameCnt;
		char name[256];
	} Request;
#ifdef  __MigPackStructs
#pragma pack()
#endif

#ifdef  __MigPackStructs
#pragma pack(4)
#endif
	typedef struct {
		mach_msg_header_t Head;
		NDR_record_t NDR;
		kern_return_t RetCode;
		int32_t procno;
		mach_msg_max_trailer_t trailer;
	} Reply;
#ifdef  __MigPackStructs
#pragma pack()
#endif

#ifdef  __MigPackStructs
#pragma pack(4)
#endif
	typedef struct {
		mach_msg_header_t Head;
		NDR_record_t NDR;
		kern_return_t RetCode;
		int32_t procno;
	} __Reply;
#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;
		Reply Out;
	} Mess;

	Request *InP = &Mess.In;
	Reply *Out0P = &Mess.Out;

	mach_msg_return_t msg_result;
	unsigned int msgh_size;
	mach_msg_max_trailer_t *TrailerP;
#if	__MigTypeCheck
	unsigned int trailer_size;
#endif	/* __MigTypeCheck */

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

	__DeclareSendRpc(50000, "GetProcedureNumber")

	InP->NDR = NDR_record;

	InP->nameCnt = mig_strncpy(InP->name, name, 256);

	msgh_size = (mach_msg_size_t)(sizeof(Request) - 256) + (_WALIGN_(InP->nameCnt));
	InP->Head.msgh_bits =
		MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE);
	/* msgh_size passed as argument */
	InP->Head.msgh_request_port = server;
	InP->Head.msgh_reply_port = mig_get_reply_port();
	InP->Head.msgh_id = 50000;

	__BeforeSendRpc(50000, "GetProcedureNumber")
	msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0)|MACH_MSG_OPTION_NONE|MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_SENDER), msgh_size, (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
	__AfterSendRpc(50000, "GetProcedureNumber")
	if (msg_result != MACH_MSG_SUCCESS) {
		__MachMsgErrorWithoutTimeout(msg_result);
		{ return msg_result; }
	}


#if	defined(__MIG_check__Reply__GetProcedureNumber_t__defined)
	check_result = __MIG_check__Reply__GetProcedureNumber_t((__Reply__GetProcedureNumber_t *)Out0P);
	if (check_result != MACH_MSG_SUCCESS)
		{ return check_result; }
#endif	/* defined(__MIG_check__Reply__GetProcedureNumber_t__defined) */

	TrailerP = (mach_msg_max_trailer_t *)((vm_offset_t)Out0P +
		round_msg(Out0P->Head.msgh_size));
	if (TrailerP->msgh_trailer_type != MACH_MSG_TRAILER_FORMAT_0)
		{ return MIG_TRAILER_ERROR ; }
#if	__MigTypeCheck
	trailer_size = TrailerP->msgh_trailer_size -
		(mach_msg_size_t)(sizeof(mach_msg_trailer_type_t) - sizeof(mach_msg_trailer_size_t));
#endif	/* __MigTypeCheck */
#if	__MigTypeCheck
	if (trailer_size < (mach_msg_size_t)sizeof(security_token_t))
		{ return MIG_TRAILER_ERROR ; }
	trailer_size -= (mach_msg_size_t)sizeof(security_token_t);
#endif	/* __MigTypeCheck */

	*procno = Out0P->procno;

	*usertoken = TrailerP->msgh_sender;

	return KERN_SUCCESS;
}
Esempio n. 7
0
File: IPC.c Progetto: aosm/Startup
static void* handleIPCMessage (void* aMsgParam, CFIndex aMessageSize, CFAllocatorRef anAllocator, void* aMachPort)
{
    SystemStarterIPCMessage*     aMessage = (SystemStarterIPCMessage*) aMsgParam;
    SystemStarterIPCMessage*     aReplyMessage = NULL;
    
    CFDataRef aResult = NULL;
    CFDataRef aData = NULL;

    if (aMessage->aHeader.msgh_bits & MACH_MSGH_BITS_COMPLEX)
      {
        warning(CFSTR("Ignoring out-of-line IPC message.\n"));
        return NULL;
      }
    else
      {
        mach_msg_security_trailer_t* aSecurityTrailer = (mach_msg_security_trailer_t*)
        ((uint8_t*)aMessage + round_msg(sizeof(SystemStarterIPCMessage) + aMessage->aByteLength));

        /* CFRunLoop includes the format 0 message trailer with the passed message. */
        if (aSecurityTrailer->msgh_trailer_type == MACH_MSG_TRAILER_FORMAT_0 &&
            aSecurityTrailer->msgh_sender.val[0] != 0)
          {
            warning(CFSTR("Ignoring IPC message sent from uid %d\n."), aSecurityTrailer->msgh_sender.val[0]);
            return NULL;
          }
      }

    if (aMessage->aProtocol != kIPCProtocolVersion)
      {
        warning(CFSTR("Unsupported IPC protocol version number: %d.  Message ignored.\n"), aMessage->aProtocol);
        return NULL;
      }

    aData = CFDataCreateWithBytesNoCopy(NULL,
                                        (uint8_t*)aMessage + sizeof(SystemStarterIPCMessage),
                                        aMessage->aByteLength,
                                        kCFAllocatorNull);
    /*
     * Dispatch the IPC message.
     */
    if (aData)
      {
        StartupContext	aStartupContext = NULL;
        CFStringRef	anErrorString   = NULL;
        CFDictionaryRef	anIPCMessage    = (CFDictionaryRef) CFPropertyListCreateFromXMLData(NULL, aData, kCFPropertyListImmutable, &anErrorString);
        
        if (gDebugFlag == 2) debug(CFSTR("\nIPC message = %@\n"), anIPCMessage);

        if (aMachPort)
          {
            CFMachPortContext aMachPortContext;
            CFMachPortGetContext((CFMachPortRef)aMachPort, &aMachPortContext);
            aStartupContext = (StartupContext)aMachPortContext.info;
          }
        
        if (anIPCMessage && CFGetTypeID(anIPCMessage) == CFDictionaryGetTypeID())
          {
            /* switch on the type of the IPC message */
            CFStringRef anIPCMessageType = CFDictionaryGetValue(anIPCMessage, kIPCMessageKey);
            if (anIPCMessageType && CFGetTypeID(anIPCMessageType) == CFStringGetTypeID())
              {
                if (CFEqual(anIPCMessageType, kIPCConsoleMessage))
                  {
                    consoleMessage(aStartupContext, anIPCMessage);
                  }
                else if (CFEqual(anIPCMessageType, kIPCStatusMessage))
                  {
                    statusMessage(aStartupContext, anIPCMessage);
                  }
                else if (CFEqual(anIPCMessageType, kIPCQueryMessage))
                  {
                    aResult = queryConfigSetting(aStartupContext, anIPCMessage);
                  }
                else if (CFEqual(anIPCMessageType, kIPCLoadDisplayBundleMessage))
                  {
                    loadDisplayBundle(aStartupContext, anIPCMessage);
                  }
                else if (CFEqual(anIPCMessageType, kIPCUnloadDisplayBundleMessage))
                  {
                    unloadDisplayBundle(aStartupContext, anIPCMessage);
                  }
              }
          }
        else
          {
            error(CFSTR("Unable to parse IPC message: %@\n"), anErrorString);
          }
        CFRelease(aData);
      }
    else
      {
        error(CFSTR("Out of memory.  Could not allocate space for IPC message.\n"));
      }

    /*
     * Generate a Mach message for the result data.
     */
    if (!aResult) aResult = CFDataCreateWithBytesNoCopy(NULL, "", 1, kCFAllocatorNull);
    if (aResult)
    {
        CFIndex aDataSize = CFDataGetLength(aResult);
        CFIndex aReplyMessageSize = round_msg(sizeof(SystemStarterIPCMessage) + aDataSize + 3);
        aReplyMessage = CFAllocatorAllocate(kCFAllocatorSystemDefault, aReplyMessageSize, 0);
        if (aReplyMessage)
          {
            aReplyMessage->aHeader.msgh_id = -1 * (SInt32)aMessage->aHeader.msgh_id;
            aReplyMessage->aHeader.msgh_size = aReplyMessageSize;
            aReplyMessage->aHeader.msgh_remote_port = aMessage->aHeader.msgh_remote_port;
            aReplyMessage->aHeader.msgh_local_port = MACH_PORT_NULL;
            aReplyMessage->aHeader.msgh_reserved = 0;
            aReplyMessage->aHeader.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE, 0);
            aReplyMessage->aBody.msgh_descriptor_count = 0;
            aReplyMessage->aProtocol = kIPCProtocolVersion;
            aReplyMessage->aByteLength = CFDataGetLength(aResult);
            memmove((uint8_t*)aReplyMessage + sizeof(SystemStarterIPCMessage),
                    CFDataGetBytePtr(aResult),
                    CFDataGetLength(aResult));
          }
        CFRelease(aResult);
    }
    if (!aReplyMessage)
      {
        error(CFSTR("Out of memory.  Could not allocate IPC result.\n"));
      }
    return aReplyMessage;
}