void default_pager_thread( void *arg) { default_pager_thread_t *dpt; mach_port_t pset; kern_return_t kr; static char here[] = "default_pager_thread"; mach_msg_options_t server_options; dpt = (default_pager_thread_t *)arg; cthread_set_data(cthread_self(), (char *) dpt); /* * Threads handling external objects cannot have * privileges. Otherwise a burst of data-requests for an * external object could empty the free-page queue, * because the fault code only reserves real pages for * requests sent to internal objects. */ if (dpt->dpt_internal) { default_pager_thread_privileges(); pset = default_pager_internal_set; } else { pset = default_pager_external_set; } dpt->dpt_initialized_p = TRUE; /* Ready for requests. */ server_options = MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_SEQNO); for (;;) { kr = mach_msg_server(default_pager_demux_object, default_pager_msg_size, pset, server_options); Panic("mach_msg_server failed"); } }
/* 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; }
/* 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; }
int main(int ac, char *av[]) { char *p = NULL; kern_return_t kr = KERN_FAILURE; long n; int ch; mach_msg_header_t hdr; while ((ch = getopt(ac, av, "dt:")) != -1) switch (ch) { case 'd': opt_debug = 1; break; case 't': n = strtol(optarg, &p, 0); if ('\0' == optarg[0] || '\0' != *p || n > LONG_MAX || n < 0) { fprintf(stderr, "Invalid idle timeout: %s\n", optarg); exit(EXIT_FAILURE); } maxidle = n; break; case '?': default: fprintf(stderr, "Usage: mDNSResponderHelper [-d] [-t maxidle]\n"); exit(EXIT_FAILURE); } ac -= optind; av += optind; (void)ac; // Unused (void)av; // Unused initialize_logging(); helplog(ASL_LEVEL_INFO, "Starting"); initialize_id(); #ifndef NO_SECURITYFRAMEWORK // We should normally be running as a system daemon. However, that might not be the case in some scenarios (e.g. debugging). // Explicitly ensure that our Keychain operations utilize the system domain. if (opt_debug) SecKeychainSetPreferenceDomain(kSecPreferencesDomainSystem); #endif gPort = register_service(kmDNSHelperServiceName); if (!gPort) exit(EXIT_FAILURE); if (maxidle) actualidle = maxidle; signal(SIGTERM, handle_sigterm); if (initialize_timer()) exit(EXIT_FAILURE); for (n=0; n<100000; n++) if (!gRunLoop) usleep(100); if (!gRunLoop) { helplog(ASL_LEVEL_ERR, "gRunLoop not set after waiting"); exit(EXIT_FAILURE); } for(;;) { hdr.msgh_bits = 0; hdr.msgh_local_port = gPort; hdr.msgh_remote_port = MACH_PORT_NULL; hdr.msgh_size = sizeof(hdr); hdr.msgh_id = 0; kr = mach_msg(&hdr, MACH_RCV_LARGE | MACH_RCV_MSG, 0, hdr.msgh_size, gPort, 0, 0); if (MACH_RCV_TOO_LARGE != kr) helplog(ASL_LEVEL_ERR, "main MACH_RCV_MSG error: %d %X %s", kr, kr, mach_error_string(kr)); kr = mach_msg_server_once(helper_server, MAX_MSG_SIZE, gPort, MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT) | MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0)); if (KERN_SUCCESS != kr) { helplog(ASL_LEVEL_ERR, "mach_msg_server: %d %X %s", kr, kr, mach_error_string(kr)); exit(EXIT_FAILURE); } } exit(EXIT_SUCCESS); }
/* * Initialize and Run the default pager */ void default_pager(void) { int i, id; static char here[] = "default_pager"; mach_msg_options_t server_options; default_pager_thread_t dpt; default_pager_thread_t **dpt_array; default_pager_thread_privileges(); /* * Wire down code, data, stack */ wire_all_memory(); /* * Give me space for the thread array and zero it. */ i = default_pager_internal_count + default_pager_external_count + 1; dpt_array = (default_pager_thread_t **) kalloc(i * sizeof(default_pager_thread_t *)); memset(dpt_array, 0, i * sizeof(default_pager_thread_t *)); /* Setup my thread structure. */ id = 0; dpt.dpt_thread = cthread_self(); dpt.dpt_buffer = 0; dpt.dpt_internal = FALSE; dpt.dpt_id = id++; dpt.dpt_initialized_p = TRUE; cthread_set_data(cthread_self(), (char *) &dpt); dpt_array[0] = &dpt; /* * Now we create the threads that will actually * manage objects. */ for (i = 0; i < default_pager_internal_count; i++) { dpt_array[id] = start_default_pager_thread(id, TRUE); id++; } for (i = 0; i < default_pager_external_count; i++) { dpt_array[id] = start_default_pager_thread(id, FALSE); id++; } /* Is everybody ready? */ for (i = 0; i < id; i++) while (!dpt_array[i]) cthread_yield(); /* Tell the bootstrap process to go ahead. */ bootstrap_completed(bootstrap_port, mach_task_self()); /* Start servicing requests. */ server_options = MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_SEQNO); for (;;) { mach_msg_server(default_pager_demux_default, default_pager_msg_size, default_pager_default_set, server_options); Panic("default server"); } }