From: Apple Date: Tue, 12 Aug 2014 18:11:02 +0000 (+0000) Subject: configd-596.15.tar.gz X-Git-Tag: os-x-1093^0 X-Git-Url: https://git.saurik.com/apple/configd.git/commitdiff_plain/6f870c060efc60e067aebc5814c89f110eec9777 configd-596.15.tar.gz --- diff --git a/Plugins/IPMonitor/Info.plist b/Plugins/IPMonitor/Info.plist index 91375db..4da4b0c 100644 --- a/Plugins/IPMonitor/Info.plist +++ b/Plugins/IPMonitor/Info.plist @@ -15,11 +15,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.13 + 1.13.1 CFBundleSignature ???? CFBundleVersion - 1.13 + 1.13.1 Requires com.apple.SystemConfiguration.IPConfiguration diff --git a/Plugins/InterfaceNamer/Info.plist b/Plugins/InterfaceNamer/Info.plist index 7e483e3..243a5ab 100644 --- a/Plugins/InterfaceNamer/Info.plist +++ b/Plugins/InterfaceNamer/Info.plist @@ -17,10 +17,10 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.13 + 1.13.1 CFBundleSignature ???? CFBundleVersion - 1.13 + 1.13.1 diff --git a/Plugins/KernelEventMonitor/Info.plist b/Plugins/KernelEventMonitor/Info.plist index a138cb7..1e48680 100644 --- a/Plugins/KernelEventMonitor/Info.plist +++ b/Plugins/KernelEventMonitor/Info.plist @@ -15,11 +15,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.13 + 1.13.1 CFBundleSignature ???? CFBundleVersion - 1.13 + 1.13.1 Requires com.apple.SystemConfiguration.InterfaceNamer diff --git a/Plugins/LinkConfiguration/Info.plist b/Plugins/LinkConfiguration/Info.plist index ebb5b27..92fd2d8 100644 --- a/Plugins/LinkConfiguration/Info.plist +++ b/Plugins/LinkConfiguration/Info.plist @@ -15,11 +15,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.13 + 1.13.1 CFBundleSignature ???? CFBundleVersion - 1.13 + 1.13.1 Requires com.apple.SystemConfiguration.InterfaceNamer diff --git a/Plugins/Logger/Info-Embedded.plist b/Plugins/Logger/Info-Embedded.plist index 7963f2d..6655898 100644 --- a/Plugins/Logger/Info-Embedded.plist +++ b/Plugins/Logger/Info-Embedded.plist @@ -15,11 +15,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.13 + 1.13.1 CFBundleSignature ???? CFBundleVersion - 1.13 + 1.13.1 Enabled Verbose diff --git a/Plugins/Logger/Info.plist b/Plugins/Logger/Info.plist index 3a86ea7..adde38f 100644 --- a/Plugins/Logger/Info.plist +++ b/Plugins/Logger/Info.plist @@ -15,11 +15,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.13 + 1.13.1 CFBundleSignature ???? CFBundleVersion - 1.13 + 1.13.1 Enabled Verbose diff --git a/Plugins/PreferencesMonitor/Info.plist b/Plugins/PreferencesMonitor/Info.plist index f7ba563..3670a68 100644 --- a/Plugins/PreferencesMonitor/Info.plist +++ b/Plugins/PreferencesMonitor/Info.plist @@ -15,11 +15,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.13 + 1.13.1 CFBundleSignature ???? CFBundleVersion - 1.13 + 1.13.1 Builtin Requires diff --git a/Plugins/SCNetworkReachability/Info.plist b/Plugins/SCNetworkReachability/Info.plist index e2077df..26d3a95 100644 --- a/Plugins/SCNetworkReachability/Info.plist +++ b/Plugins/SCNetworkReachability/Info.plist @@ -17,10 +17,10 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.13 + 1.13.1 CFBundleSignature ???? CFBundleVersion - 1.13 + 1.13.1 diff --git a/Plugins/SimulatorSupport/Info.plist b/Plugins/SimulatorSupport/Info.plist index 72ccafd..9d70b6b 100644 --- a/Plugins/SimulatorSupport/Info.plist +++ b/Plugins/SimulatorSupport/Info.plist @@ -17,10 +17,10 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.13 + 1.13.1 CFBundleSignature ???? CFBundleVersion - 1.13 + 1.13.1 diff --git a/SCMonitor/Info.plist b/SCMonitor/Info.plist index e930da3..4761e78 100644 --- a/SCMonitor/Info.plist +++ b/SCMonitor/Info.plist @@ -15,11 +15,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.13 + 1.13.1 CFBundleSignature ???? CFBundleVersion - 1.13 + 1.13.1 CFPlugInDynamicRegistration NO CFPlugInFactories diff --git a/SystemConfiguration.fproj/Info-Embedded.plist b/SystemConfiguration.fproj/Info-Embedded.plist index 9f9b512..1fb3706 100644 --- a/SystemConfiguration.fproj/Info-Embedded.plist +++ b/SystemConfiguration.fproj/Info-Embedded.plist @@ -7,7 +7,7 @@ CFBundleExecutable SystemConfiguration CFBundleGetInfoString - 1.13 + 1.13.1 CFBundleIdentifier com.apple.SystemConfiguration CFBundleInfoDictionaryVersion @@ -17,10 +17,10 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.13 + 1.13.1 CFBundleSignature ???? CFBundleVersion - 1.13 + 1.13.1 diff --git a/SystemConfiguration.fproj/Info.plist b/SystemConfiguration.fproj/Info.plist index 9f9b512..1fb3706 100644 --- a/SystemConfiguration.fproj/Info.plist +++ b/SystemConfiguration.fproj/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable SystemConfiguration CFBundleGetInfoString - 1.13 + 1.13.1 CFBundleIdentifier com.apple.SystemConfiguration CFBundleInfoDictionaryVersion @@ -17,10 +17,10 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.13 + 1.13.1 CFBundleSignature ???? CFBundleVersion - 1.13 + 1.13.1 diff --git a/SystemConfiguration.fproj/SCDNotifierInformViaCallback.c b/SystemConfiguration.fproj/SCDNotifierInformViaCallback.c index 02e7d48..e5fc043 100644 --- a/SystemConfiguration.fproj/SCDNotifierInformViaCallback.c +++ b/SystemConfiguration.fproj/SCDNotifierInformViaCallback.c @@ -43,6 +43,10 @@ #include "SCDynamicStoreInternal.h" #include "config.h" /* MiG generated file */ +#if !TARGET_IPHONE_SIMULATOR || (defined(IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED) && (IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED >= 1090)) +#define HAVE_MACHPORT_GUARDS +#endif + static CFStringRef notifyMPCopyDescription(const void *info) @@ -107,51 +111,72 @@ rlsSchedule(void *info, CFRunLoopRef rl, CFStringRef mode) , CFRelease , notifyMPCopyDescription }; + kern_return_t kr; mach_port_t oldNotify; +#ifdef HAVE_MACHPORT_GUARDS + mach_port_options_t opts; +#endif // HAVE_MACHPORT_GUARDS mach_port_t port; int sc_status; - kern_return_t status; #ifdef DEBUG SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" activate callback runloop source")); #endif /* DEBUG */ - /* Allocating port (for server response) */ - status = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port); - if (status != KERN_SUCCESS) { - SCLog(TRUE, LOG_ERR, CFSTR("rlsSchedule mach_port_allocate(): %s"), mach_error_string(status)); - return; + /* allocate a mach port for the SCDynamicStore notifications */ + + retry_allocate : + +#ifdef HAVE_MACHPORT_GUARDS + bzero(&opts, sizeof(opts)); + opts.flags = MPO_CONTEXT_AS_GUARD|MPO_INSERT_SEND_RIGHT; + + kr = mach_port_construct(mach_task_self(), &opts, store, &port); +#else // HAVE_MACHPORT_GUARDS + kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port); +#endif // HAVE_MACHPORT_GUARDS + + if (kr != KERN_SUCCESS) { + SCLog(TRUE, LOG_ERR, CFSTR("rlsSchedule could not allocate mach port: %s"), mach_error_string(kr)); + if ((kr == KERN_NO_SPACE) || (kr == KERN_RESOURCE_SHORTAGE)) { + sleep(1); + goto retry_allocate; + } else { + return; + } } - status = mach_port_insert_right(mach_task_self(), - port, - port, - MACH_MSG_TYPE_MAKE_SEND); - if (status != KERN_SUCCESS) { +#ifndef HAVE_MACHPORT_GUARDS + kr = mach_port_insert_right(mach_task_self(), + port, + port, + MACH_MSG_TYPE_MAKE_SEND); + if (kr != KERN_SUCCESS) { /* * We can't insert a send right into our own port! This should * only happen if someone stomped on OUR port (so let's leave * the port alone). */ - SCLog(TRUE, LOG_ERR, CFSTR("rlsSchedule mach_port_insert_right(): %s"), mach_error_string(status)); + SCLog(TRUE, LOG_ERR, CFSTR("rlsSchedule mach_port_insert_right(): %s"), mach_error_string(kr)); return; } +#endif // HAVE_MACHPORT_GUARDS /* Request a notification when/if the server dies */ - status = mach_port_request_notification(mach_task_self(), - port, - MACH_NOTIFY_NO_SENDERS, - 1, - port, - MACH_MSG_TYPE_MAKE_SEND_ONCE, - &oldNotify); - if (status != KERN_SUCCESS) { + kr = mach_port_request_notification(mach_task_self(), + port, + MACH_NOTIFY_NO_SENDERS, + 1, + port, + MACH_MSG_TYPE_MAKE_SEND_ONCE, + &oldNotify); + if (kr != KERN_SUCCESS) { /* * We can't request a notification for our own port! This should * only happen if someone stomped on OUR port (so let's leave * the port alone). */ - SCLog(TRUE, LOG_ERR, CFSTR("rlsSchedule mach_port_request_notification(): %s"), mach_error_string(status)); + SCLog(TRUE, LOG_ERR, CFSTR("rlsSchedule mach_port_request_notification(): %s"), mach_error_string(kr)); return; } @@ -162,29 +187,37 @@ rlsSchedule(void *info, CFRunLoopRef rl, CFStringRef mode) retry : __MACH_PORT_DEBUG(TRUE, "*** rlsSchedule", port); - status = notifyviaport(storePrivate->server, port, 0, (int *)&sc_status); + kr = notifyviaport(storePrivate->server, port, 0, (int *)&sc_status); if (__SCDynamicStoreCheckRetryAndHandleError(store, - status, + kr, &sc_status, "rlsSchedule notifyviaport()")) { goto retry; } - if (status != KERN_SUCCESS) { - if ((status == MACH_SEND_INVALID_DEST) || (status == MIG_SERVER_DIED)) { + if (kr != KERN_SUCCESS) { + if ((kr == MACH_SEND_INVALID_DEST) || (kr == MIG_SERVER_DIED)) { /* remove the send right that we tried (but failed) to pass to the server */ (void) mach_port_deallocate(mach_task_self(), port); } /* remove our receive right */ +#ifdef HAVE_MACHPORT_GUARDS + (void) mach_port_destruct(mach_task_self(), port, 0, store); +#else // HAVE_MACHPORT_GUARDS (void) mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_RECEIVE, -1); +#endif // HAVE_MACHPORT_GUARDS return; } if (sc_status != kSCStatusOK) { /* something [else] didn't work, remove our receive right */ +#ifdef HAVE_MACHPORT_GUARDS + (void) mach_port_destruct(mach_task_self(), port, 0, store); +#else // HAVE_MACHPORT_GUARDS (void) mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_RECEIVE, -1); +#endif // HAVE_MACHPORT_GUARDS return; } @@ -245,7 +278,7 @@ rlsCancel(void *info, CFRunLoopRef rl, CFStringRef mode) if (n == 0) { int sc_status; - kern_return_t status; + kern_return_t kr; #ifdef DEBUG SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" cancel callback runloop source")); @@ -280,18 +313,22 @@ rlsCancel(void *info, CFRunLoopRef rl, CFStringRef mode) storePrivate->rlsNotifyPort = NULL; /* and, finally, remove our receive right */ - (void)mach_port_mod_refs(mach_task_self(), mp, MACH_PORT_RIGHT_RECEIVE, -1); +#ifdef HAVE_MACHPORT_GUARDS + (void) mach_port_destruct(mach_task_self(), mp, 0, store); +#else // HAVE_MACHPORT_GUARDS + (void) mach_port_mod_refs(mach_task_self(), mp, MACH_PORT_RIGHT_RECEIVE, -1); +#endif // HAVE_MACHPORT_GUARDS } if (storePrivate->server != MACH_PORT_NULL) { - status = notifycancel(storePrivate->server, (int *)&sc_status); + kr = notifycancel(storePrivate->server, (int *)&sc_status); (void) __SCDynamicStoreCheckRetryAndHandleError(store, - status, + kr, &sc_status, "rlsCancel notifycancel()"); - if (status != KERN_SUCCESS) { + if (kr != KERN_SUCCESS) { return; } } diff --git a/SystemConfiguration.fproj/SCDOpen.c b/SystemConfiguration.fproj/SCDOpen.c index abe9727..e03cfff 100644 --- a/SystemConfiguration.fproj/SCDOpen.c +++ b/SystemConfiguration.fproj/SCDOpen.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2006, 2008-2013 Apple Inc. All rights reserved. + * Copyright (c) 2000-2006, 2008-2014 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -136,15 +136,17 @@ __SCDynamicStoreDeallocate(CFTypeRef cf) (void) SCDynamicStoreNotifyCancel(store); if (storePrivate->server != MACH_PORT_NULL) { - if (!storePrivate->serverNullSession) { - /* - * Remove our send right to the SCDynamicStore server (and that will - * result in our session being closed). - */ - __MACH_PORT_DEBUG(TRUE, "*** __SCDynamicStoreDeallocate", storePrivate->server); - (void) mach_port_deallocate(mach_task_self(), storePrivate->server); - } - + /* + * Remove our send right to the SCDynamicStore server. + * + * In the case of a "real" session this will result in our + * session being closed. + * + * In the case of a "NULL" session, we just remove the + * the send right reference we are holding. + */ + __MACH_PORT_DEBUG(TRUE, "*** __SCDynamicStoreDeallocate", storePrivate->server); + (void) mach_port_deallocate(mach_task_self(), storePrivate->server); storePrivate->server = MACH_PORT_NULL; } @@ -371,14 +373,17 @@ updateServerPort(SCDynamicStorePrivateRef storePrivate, mach_port_t *server, int pthread_mutex_lock(&_sc_lock); if (_sc_server != MACH_PORT_NULL) { if (*server == _sc_server) { - // if the server we tried returned the error, deallocate - // our send [or dead name] right - (void)mach_port_deallocate(mach_task_self(), _sc_server); + mach_port_t old_port; - // and [re-]lookup the name to the server + // if the server we tried returned the error, save the old port, + // [re-]lookup the name to the server, and deallocate the original + // send [or dead name] right + + old_port = _sc_server; _sc_server = __SCDynamicStoreServerPort(storePrivate, sc_status_p); + (void)mach_port_deallocate(mach_task_self(), old_port); } else { - // another thread has refreshed the SCDynamicStore server port + // another thread has refreshed the [main] SCDynamicStore server port } } else { _sc_server = __SCDynamicStoreServerPort(storePrivate, sc_status_p); @@ -393,6 +398,7 @@ updateServerPort(SCDynamicStorePrivateRef storePrivate, mach_port_t *server, int static Boolean __SCDynamicStoreAddSession(SCDynamicStorePrivateRef storePrivate) { + kern_return_t kr = KERN_SUCCESS; CFDataRef myName; /* serialized name */ xmlData_t myNameRef; CFIndex myNameLen; @@ -401,7 +407,6 @@ __SCDynamicStoreAddSession(SCDynamicStorePrivateRef storePrivate) CFIndex myOptionsLen = 0; int sc_status = kSCStatusFailed; mach_port_t server; - kern_return_t status = KERN_SUCCESS; if (!_SCSerializeString(storePrivate->name, &myName, (void **)&myNameRef, &myNameLen)) { goto done; @@ -416,56 +421,55 @@ __SCDynamicStoreAddSession(SCDynamicStorePrivateRef storePrivate) } /* open a new session with the server */ - server = _sc_server; + server = MACH_PORT_NULL; updateServerPort(storePrivate, &server, &sc_status); - while (TRUE) { - if (server != MACH_PORT_NULL) { - if (!storePrivate->serverNullSession) { - // if SCDynamicStore session - status = configopen(server, - myNameRef, - myNameLen, - myOptionsRef, - myOptionsLen, - &storePrivate->server, - (int *)&sc_status); - } else { - // if NULL session - if (storePrivate->server == MACH_PORT_NULL) { - // use the [main] SCDynamicStore server port + while (server != MACH_PORT_NULL) { + // if SCDynamicStore server available + + if (!storePrivate->serverNullSession) { + // if SCDynamicStore session + kr = configopen(server, + myNameRef, + (mach_msg_type_number_t)myNameLen, + myOptionsRef, + (mach_msg_type_number_t)myOptionsLen, + &storePrivate->server, + (int *)&sc_status); + } else { + // if NULL session + if (storePrivate->server == MACH_PORT_NULL) { + // use the [main] SCDynamicStore server port + kr = mach_port_mod_refs(mach_task_self(), server, MACH_PORT_RIGHT_SEND, +1); + if (kr == KERN_SUCCESS) { storePrivate->server = server; sc_status = kSCStatusOK; - status = KERN_SUCCESS; } else { - // if the server port we used returned an error storePrivate->server = MACH_PORT_NULL; - status = MACH_SEND_INVALID_DEST; } + } else { + // if the server port we used returned an error + storePrivate->server = MACH_PORT_NULL; + kr = MACH_SEND_INVALID_DEST; } + } - if (status == KERN_SUCCESS) { - break; - } + if (kr == KERN_SUCCESS) { + break; + } - // our [cached] server port is not valid - if ((status != MACH_SEND_INVALID_DEST) && (status != MIG_SERVER_DIED)) { - // if we got an unexpected error, don't retry - sc_status = status; - break; - } + // our [cached] server port is not valid + if ((kr != MACH_SEND_INVALID_DEST) && (kr != MIG_SERVER_DIED)) { + // if we got an unexpected error, don't retry + sc_status = kr; + break; } updateServerPort(storePrivate, &server, &sc_status); - - if (server == MACH_PORT_NULL) { - // if SCDynamicStore server not available - break; - } } __MACH_PORT_DEBUG(TRUE, "*** SCDynamicStoreAddSession", storePrivate->server); @@ -480,13 +484,13 @@ __SCDynamicStoreAddSession(SCDynamicStorePrivateRef storePrivate) return TRUE; case BOOTSTRAP_UNKNOWN_SERVICE : SCLog(TRUE, - (status == KERN_SUCCESS) ? LOG_DEBUG : LOG_ERR, + (kr == KERN_SUCCESS) ? LOG_DEBUG : LOG_ERR, CFSTR("SCDynamicStore server not available")); sc_status = kSCStatusNoStoreServer; break; default : SCLog(TRUE, - (status == KERN_SUCCESS) ? LOG_DEBUG : LOG_ERR, + (kr == KERN_SUCCESS) ? LOG_DEBUG : LOG_ERR, CFSTR("SCDynamicStoreAddSession configopen(): %s"), SCErrorString(sc_status)); break; @@ -507,32 +511,12 @@ __SCDynamicStoreNullSession(void) tsd = __SCGetThreadSpecificData(); if (tsd->_sc_store == NULL) { -#if !TARGET_IPHONE_SIMULATOR storePrivate = __SCDynamicStoreCreatePrivate(NULL, CFSTR("NULL session"), NULL, NULL); assert(storePrivate != NULL); - storePrivate->server = _sc_server; storePrivate->serverNullSession = TRUE; -#else - /* - * In the simulator, this code may be talking to an older version of - * configd that still requires a valid session. Instead of using a - * "NULL" session that uses the server mach port, set up a "normal" - * session in thread-local storage. - */ - storePrivate = __SCDynamicStoreCreatePrivate(NULL, - CFSTR("Thread local session"), - NULL, - NULL); - assert(storePrivate != NULL); - /* - * Use MACH_PORT_NULL here to trigger the call to - * __SCDynamicStoreAddSession below. - */ - storePrivate->server = MACH_PORT_NULL; -#endif /* TARGET_IPHONE_SIMULATOR */ tsd->_sc_store = (SCDynamicStoreRef)storePrivate; } @@ -571,14 +555,8 @@ __SCDynamicStoreCheckRetryAndHandleError(SCDynamicStoreRef store, } if ((status == MACH_SEND_INVALID_DEST) || (status == MIG_SERVER_DIED)) { - /* the server's gone */ - if (!storePrivate->serverNullSession) { - /* - * remove the session's dead name right (and not the - * not the "server" port) - */ - (void) mach_port_deallocate(mach_task_self(), storePrivate->server); - } + /* the server's gone, remove the session's dead name right */ + (void) mach_port_deallocate(mach_task_self(), storePrivate->server); storePrivate->server = MACH_PORT_NULL; /* reconnect */ diff --git a/SystemConfiguration.fproj/helper/SCHelper_server.c b/SystemConfiguration.fproj/helper/SCHelper_server.c index 01fd485..160dd69 100644 --- a/SystemConfiguration.fproj/helper/SCHelper_server.c +++ b/SystemConfiguration.fproj/helper/SCHelper_server.c @@ -2047,9 +2047,15 @@ _helperinit(mach_port_t server, sessionPrivate = (SCHelperSessionPrivateRef)session; // create per-session port - (void) mach_port_allocate(mach_task_self(), - MACH_PORT_RIGHT_RECEIVE, - &sessionPrivate->port); + kr = mach_port_allocate(mach_task_self(), + MACH_PORT_RIGHT_RECEIVE, + &sessionPrivate->port); + if (kr != KERN_SUCCESS) { + SCLog(TRUE, LOG_ERR, CFSTR("_helperinit(): mach_port_allocate() failed: %s"), mach_error_string(kr)); + *status = kr; + goto done; + } + *newSession = sessionPrivate->port; (void) mach_port_set_attributes(mach_task_self(), diff --git a/configd.tproj/session.c b/configd.tproj/session.c index f6c8821..2a4d55e 100644 --- a/configd.tproj/session.c +++ b/configd.tproj/session.c @@ -41,6 +41,10 @@ #include #include +#if !TARGET_IPHONE_SIMULATOR || (defined(IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED) && (IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED >= 1090)) +#define HAVE_MACHPORT_GUARDS +#endif + /* information maintained for each active session */ static serverSessionRef *sessions = NULL; @@ -133,9 +137,11 @@ __private_extern__ serverSessionRef addSession(mach_port_t server, CFStringRef (*copyDescription)(const void *info)) { - CFMachPortContext context = { 0, NULL, NULL, NULL, NULL }; - mach_port_t mp = server; - int n = -1; + CFMachPortContext context = { 0, NULL, NULL, NULL, NULL }; + kern_return_t kr; + mach_port_t mp = server; + int n = -1; + serverSessionRef newSession = NULL; /* save current (SCDynamicStore) runloop */ if (sessionRunLoop == NULL) { @@ -149,12 +155,18 @@ addSession(mach_port_t server, CFStringRef (*copyDescription)(const void *info)) nSessions = 64; sessions = malloc(nSessions * sizeof(serverSessionRef)); + + // allocate a new session for "the" server + newSession = calloc(1, sizeof(serverSession)); } else { - int i; + int i; +#ifdef HAVE_MACHPORT_GUARDS + mach_port_options_t opts; +#endif // HAVE_MACHPORT_GUARDS /* check to see if we already have an open session (note: slot 0 is the "server" port) */ for (i = 1; i <= lastSession; i++) { - serverSessionRef thisSession = sessions[i]; + serverSessionRef thisSession = sessions[i]; if (thisSession == NULL) { /* found an empty slot */ @@ -190,19 +202,45 @@ addSession(mach_port_t server, CFStringRef (*copyDescription)(const void *info)) } } + // allocate a session for this client + newSession = calloc(1, sizeof(serverSession)); + // create mach port for SCDynamicStore client mp = MACH_PORT_NULL; - (void) mach_port_allocate(mach_task_self(), - MACH_PORT_RIGHT_RECEIVE, - &mp); - } - // allocate a new session for this server - sessions[n] = malloc(sizeof(serverSession)); - bzero(sessions[n], sizeof(serverSession)); + retry_allocate : + +#ifdef HAVE_MACHPORT_GUARDS + bzero(&opts, sizeof(opts)); + opts.flags = MPO_CONTEXT_AS_GUARD; + + kr = mach_port_construct(mach_task_self(), &opts, newSession, &mp); +#else // HAVE_MACHPORT_GUARDS + kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &mp); +#endif // HAVE_MACHPORT_GUARDS + + if (kr != KERN_SUCCESS) { + char *err = NULL; + + SCLog(TRUE, LOG_ERR, CFSTR("addSession: could not allocate mach port: %s"), mach_error_string(kr)); + if ((kr == KERN_NO_SPACE) || (kr == KERN_RESOURCE_SHORTAGE)) { + sleep(1); + goto retry_allocate; + } + + (void) asprintf(&err, "addSession: could not allocate mach port: %s", mach_error_string(kr)); + _SC_crash(err != NULL ? err : "addSession: could not allocate mach port", + NULL, + NULL); + if (err != NULL) free(err); + + free(newSession); + return NULL; + } + } // create server port - context.info = sessions[n]; + context.info = newSession; context.copyDescription = copyDescription; // @@ -210,19 +248,31 @@ addSession(mach_port_t server, CFStringRef (*copyDescription)(const void *info)) // right present to ensure that CF does not establish // its dead name notification. // - sessions[n]->serverPort = _SC_CFMachPortCreateWithPort("SCDynamicStore/session", - mp, - configdCallback, - &context); + newSession->serverPort = _SC_CFMachPortCreateWithPort("SCDynamicStore/session", + mp, + configdCallback, + &context); if (n > 0) { // insert send right that will be moved to the client - (void) mach_port_insert_right(mach_task_self(), - mp, - mp, - MACH_MSG_TYPE_MAKE_SEND); + kr = mach_port_insert_right(mach_task_self(), + mp, + mp, + MACH_MSG_TYPE_MAKE_SEND); + if (kr != KERN_SUCCESS) { + /* + * We can't insert a send right into our own port! This should + * only happen if someone stomped on OUR port (so let's leave + * the port alone). + */ + SCLog(TRUE, LOG_ERR, CFSTR("addSession mach_port_insert_right(): %s"), mach_error_string(kr)); + + free(newSession); + return NULL; + } } + sessions[n] = newSession; sessions[n]->key = mp; // sessions[n]->serverRunLoopSource = NULL; // sessions[n]->store = NULL; @@ -232,7 +282,7 @@ addSession(mach_port_t server, CFStringRef (*copyDescription)(const void *info)) sessions[n]->callerWriteEntitlement = kCFNull; /* UNKNOWN */ #endif // TARGET_OS_IPHONE || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080/*FIXME*/) - return sessions[n]; + return newSession; } @@ -271,7 +321,11 @@ cleanupSession(mach_port_t server) /* * Our send right has already been removed. Remove our receive right. */ +#ifdef HAVE_MACHPORT_GUARDS + (void) mach_port_destruct(mach_task_self(), server, 0, thisSession); +#else // HAVE_MACHPORT_GUARDS (void) mach_port_mod_refs(mach_task_self(), server, MACH_PORT_RIGHT_RECEIVE, -1); +#endif // HAVE_MACHPORT_GUARDS #if TARGET_OS_IPHONE || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080/*FIXME*/) /*