From: Apple Date: Wed, 9 Dec 2015 05:18:59 +0000 (+0000) Subject: configd-802.20.7.tar.gz X-Git-Tag: os-x-10112^0 X-Git-Url: https://git.saurik.com/apple/configd.git/commitdiff_plain/77a550b625b42f93d03018146bc3f0751ff2eed8 configd-802.20.7.tar.gz --- diff --git a/Plugins/IPMonitor/ip_plugin.c b/Plugins/IPMonitor/ip_plugin.c index f488f6c..4f9a65f 100644 --- a/Plugins/IPMonitor/ip_plugin.c +++ b/Plugins/IPMonitor/ip_plugin.c @@ -2748,6 +2748,7 @@ IPv4RouteListCreateWithDictionary(IPv4RouteListRef routes, CFDictionaryRef dict, CFNumberRef rank_assertion) { + boolean_t add_broadcast = FALSE; boolean_t add_default = FALSE; boolean_t add_router_subnet = FALSE; boolean_t add_subnet = FALSE; @@ -2877,8 +2878,13 @@ IPv4RouteListCreateWithDictionary(IPv4RouteListRef routes, n++; } - if (ifindex != lo0_ifindex() && router.s_addr != 0) { - add_default = TRUE; + if (ifindex != lo0_ifindex()) { + if (router.s_addr != 0) { + add_default = TRUE; + n++; + } + /* allow traffic to 255.255.255.255 (rdar://problem/22794309) */ + add_broadcast = TRUE; n++; } if (allow_additional_routes) { @@ -2928,6 +2934,19 @@ IPv4RouteListCreateWithDictionary(IPv4RouteListRef routes, r->rank = primary_rank; r++; } + if (add_broadcast) { + /* add the broadcast route */ + if ((flags & kRouteFlagsIsNULL) != 0) { + r->flags |= kRouteFlagsIsNULL; + } + r->dest.s_addr = INADDR_BROADCAST; + r->mask.s_addr = INADDR_BROADCAST; + r->prefix_length = IPV4_ROUTE_ALL_BITS_SET; + r->ifindex = ifindex; + r->ifa = addr; + r->rank = primary_rank; + r++; + } /* add the subnet route */ if (add_subnet) { diff --git a/Plugins/KernelEventMonitor/ev_dlil.c b/Plugins/KernelEventMonitor/ev_dlil.c index 0e296ef..aff1b0d 100644 --- a/Plugins/KernelEventMonitor/ev_dlil.c +++ b/Plugins/KernelEventMonitor/ev_dlil.c @@ -53,6 +53,23 @@ create_interface_key(const char * if_name) } +static CFMutableDictionaryRef +copy_mutable_dictionary(CFDictionaryRef dict) +{ + CFMutableDictionaryRef newDict; + + if (isA_CFDictionary(dict) != NULL) { + newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict); + } + else { + newDict = CFDictionaryCreateMutable(NULL, + 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + } + return (newDict); +} + static CFMutableDictionaryRef copy_entity(CFStringRef key) { @@ -60,18 +77,10 @@ copy_entity(CFStringRef key) CFMutableDictionaryRef newDict = NULL; dict = cache_SCDynamicStoreCopyValue(store, key); + newDict = copy_mutable_dictionary(dict); if (dict != NULL) { - if (isA_CFDictionary(dict) != NULL) { - newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict); - } CFRelease(dict); } - if (newDict == NULL) { - newDict = CFDictionaryCreateMutable(NULL, - 0, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - } return (newDict); } @@ -79,13 +88,20 @@ copy_entity(CFStringRef key) static void interface_update_status(const char *if_name, CFBooleanRef active, boolean_t attach, - CFBooleanRef expensive) + CFBooleanRef expensive, boolean_t only_if_different) { CFStringRef key = NULL; - CFMutableDictionaryRef newDict = NULL; + CFMutableDictionaryRef newDict; + CFDictionaryRef oldDict; key = create_interface_key(if_name); - newDict = copy_entity(key); + oldDict = cache_SCDynamicStoreCopyValue(store, key); + if (oldDict != NULL && isA_CFDictionary(oldDict) == NULL) { + CFRelease(oldDict); + oldDict = NULL; + } + newDict = copy_mutable_dictionary(oldDict); + /* if new status available, update cache */ if (active != NULL) { CFDictionarySetValue(newDict, kSCPropNetLinkActive, active); @@ -104,17 +120,26 @@ interface_update_status(const char *if_name, CFDictionaryRemoveValue(newDict, kSCPropNetLinkExpensive); } - /* update status */ + /* update the SCDynamicStore */ if (CFDictionaryGetCount(newDict) > 0) { - SC_log(LOG_DEBUG, "Update interface link status: %s: %@", if_name, newDict); - cache_SCDynamicStoreSetValue(store, key, newDict); + /* set the value */ + if (!only_if_different + || oldDict == NULL + || !CFEqual(oldDict, newDict)) { + SC_log(LOG_DEBUG, "Update interface link status: %s: %@", if_name, newDict); + cache_SCDynamicStoreSetValue(store, key, newDict); + } } else { + /* remove the value */ SC_log(LOG_DEBUG, "Update interface link status: %s: ", if_name); cache_SCDynamicStoreRemoveValue(store, key); } CFRelease(key); CFRelease(newDict); + if (oldDict != NULL) { + CFRelease(oldDict); + } return; } @@ -311,7 +336,7 @@ interface_remove(const char *if_name) __private_extern__ void -link_update_status(const char *if_name, boolean_t attach) +link_update_status(const char *if_name, boolean_t attach, boolean_t only_if_different) { CFBooleanRef active = NULL; CFBooleanRef expensive; @@ -354,12 +379,38 @@ link_update_status(const char *if_name, boolean_t attach) expensive = interface_update_expensive(if_name); /* update status */ - interface_update_status(if_name, active, attach, expensive); + interface_update_status(if_name, active, attach, expensive, only_if_different); close(sock); return; } +__private_extern__ +void +link_update_status_if_missing(const char * if_name) +{ + CFStringRef key; + CFDictionaryRef dict; + + key = create_interface_key(if_name); + dict = cache_SCDynamicStoreCopyValue(store, key); + if (dict != NULL) { + /* it's already present, don't update */ + CFRelease(dict); + goto done; + } + link_update_status(if_name, FALSE, FALSE); + dict = cache_SCDynamicStoreCopyValue(store, key); + if (dict != NULL) { + /* our action made it appear */ + messages_add_msg_with_arg("added missing link status", if_name); + CFRelease(dict); + } + done: + CFRelease(key); + return; +} + __private_extern__ CFMutableArrayRef interfaceListCopy(void) @@ -443,11 +494,15 @@ interfaceListAddInterface(CFMutableArrayRef ifList, const char * if_name) /* interface was added, prime the link-specific values */ added = TRUE; CFArrayAppendValue(ifList, interface); - link_update_status(if_name, TRUE); + link_update_status(if_name, TRUE, FALSE); #ifdef KEV_DL_LINK_QUALITY_METRIC_CHANGED link_update_quality_metric(if_name); #endif /* KEV_DL_LINK_QUALITY_METRIC_CHANGED */ } + else { + /* only update the link status if it is different */ + link_update_status(if_name, FALSE, TRUE); + } CFRelease(interface); return (added); } diff --git a/Plugins/KernelEventMonitor/ev_dlil.h b/Plugins/KernelEventMonitor/ev_dlil.h index e5318c8..deda140 100644 --- a/Plugins/KernelEventMonitor/ev_dlil.h +++ b/Plugins/KernelEventMonitor/ev_dlil.h @@ -51,7 +51,9 @@ void link_add (const char *if_name); void link_remove (const char *if_name); -void link_update_status (const char *if_name, boolean_t attach); +void link_update_status (const char *if_name, boolean_t attach, boolean_t only_if_different); + +void link_update_status_if_missing (const char * if_name); CFMutableArrayRef interfaceListCopy(void); diff --git a/Plugins/KernelEventMonitor/eventmon.c b/Plugins/KernelEventMonitor/eventmon.c index f5ab8f0..b120be2 100644 --- a/Plugins/KernelEventMonitor/eventmon.c +++ b/Plugins/KernelEventMonitor/eventmon.c @@ -59,6 +59,8 @@ #include "ev_ipv4.h" #include "ev_ipv6.h" #include +#include +#include // from ip_fw2.c #define KEV_LOG_SUBCLASS 10 @@ -141,6 +143,16 @@ messages_post(void) return; } +static void +check_interface_link_status(const char * if_name) +{ + if (S_messages == NULL) { + return; /* we're not in early boot of system */ + } + link_update_status_if_missing(if_name); + return; +} + __private_extern__ int dgram_socket(int domain) @@ -283,6 +295,10 @@ processEvent_Apple_Network(struct kern_event_msg *ev_msg) copy_if_name(&ev->link_data, ifr_name, sizeof(ifr_name)); SC_log(LOG_INFO, "Process IPv4 address change: %s: %d", (char *)ifr_name, ev_msg->event_code); ipv4_interface_update(NULL, ifr_name); + if (ev_msg->event_code + != KEV_INET_ADDR_DELETED) { + check_interface_link_status(ifr_name); + } break; } case KEV_INET_ARPCOLLISION : { @@ -372,6 +388,10 @@ processEvent_Apple_Network(struct kern_event_msg *ev_msg) ETHER_ADDR_LEN, &ev->ia_mac); } + if (ev_msg->event_code + != KEV_INET6_ADDR_DELETED) { + check_interface_link_status(ifr_name); + } break; default : @@ -476,7 +496,7 @@ processEvent_Apple_Network(struct kern_event_msg *ev_msg) SC_log(LOG_INFO, "Process interface link %s: %s", (ev_msg->event_code == KEV_DL_LINK_ON) ? "up" : "down", (char *)ifr_name); - link_update_status(ifr_name, FALSE); + link_update_status(ifr_name, FALSE, FALSE); break; #ifdef KEV_DL_LINK_QUALITY_METRIC_CHANGED @@ -693,19 +713,43 @@ schedule_timer(void) return; } +static boolean_t +kernel_events_lost(void) +{ + boolean_t events_lost = FALSE; + struct kevtstat kevtstat; + size_t len = sizeof(kevtstat); + const char * mibvar = "net.systm.kevt.stats"; + static u_int64_t old_kes_nomem; + + if (sysctlbyname(mibvar, &kevtstat, &len, 0, 0) < 0) { + SC_log(LOG_NOTICE, "sysctl(%s) failed, %s", + mibvar, strerror(errno)); + } + else if (old_kes_nomem != kevtstat.kes_nomem) { + SC_log(LOG_NOTICE, "KernelEventMonitor: lost kernel event"); + old_kes_nomem = kevtstat.kes_nomem; + events_lost = TRUE; + } + return (events_lost); +} + static void check_for_new_interfaces(void * context) { static int count; - char msg[32]; count++; - snprintf(msg, sizeof(msg), "timeout %d (of %d)", count, MAX_TIMER_COUNT); - cache_open(); - update_interfaces(msg, FALSE); - cache_write(store); - cache_close(); - messages_post(); + if (kernel_events_lost()) { + char msg[32]; + + snprintf(msg, sizeof(msg), "timeout %d (of %d)", count, MAX_TIMER_COUNT); + cache_open(); + update_interfaces(msg, FALSE); + cache_write(store); + cache_close(); + messages_post(); + } /* schedule the next timer, if needed */ if (count < MAX_TIMER_COUNT) { diff --git a/SystemConfiguration.fproj/SCDNotifierInformViaFD.c b/SystemConfiguration.fproj/SCDNotifierInformViaFD.c index aecd743..77a7611 100644 --- a/SystemConfiguration.fproj/SCDNotifierInformViaFD.c +++ b/SystemConfiguration.fproj/SCDNotifierInformViaFD.c @@ -47,16 +47,15 @@ Boolean SCDynamicStoreNotifyFileDescriptor(SCDynamicStoreRef store, - int32_t identifier, - int *fd) + int32_t identifier, + int *fd) { - size_t n; + int fildes[2] = { -1, -1 }; + fileport_t fileport = MACH_PORT_NULL; + int ret; int sc_status; - int sock; SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store; kern_return_t status; - char tmpdir[PATH_MAX]; - struct sockaddr_un un; if (store == NULL) { /* sorry, you must provide a session */ @@ -76,53 +75,30 @@ SCDynamicStoreNotifyFileDescriptor(SCDynamicStoreRef store, return FALSE; } - if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { + ret = pipe(fildes); + if (ret == -1) { _SCErrorSet(errno); - SC_log(LOG_ERR, "socket() failed: %s", strerror(errno)); - return FALSE; + SC_log(LOG_ERR, "pipe() failed: %s", strerror(errno)); + goto fail; } - /* establish a UNIX domain socket for server->client notification */ - - n = confstr(_CS_DARWIN_USER_TEMP_DIR, tmpdir, sizeof(tmpdir)); - if ((n <= 0) || (n >= sizeof(tmpdir))) { - (void) strlcpy(tmpdir, _PATH_TMP, sizeof(tmpdir)); - } - - bzero(&un, sizeof(un)); - un.sun_family = AF_UNIX; - snprintf(un.sun_path, - sizeof(un.sun_path)-1, - "%s%s-%d-%d", - tmpdir, - "SCDynamicStoreNotifyFileDescriptor", - getpid(), - storePrivate->server); - - /* ensure that the path does not already exist */ - (void) unlink(un.sun_path); + /* + * send fildes[1], the sender's fd, to configd using a fileport and + * return fildes[0] to the caller. + */ - if (bind(sock, (struct sockaddr *)&un, sizeof(un)) == -1) { + fileport = MACH_PORT_NULL; + ret = fileport_makeport(fildes[1], &fileport); + if (ret < 0) { _SCErrorSet(errno); - SC_log(LOG_ERR, "bind() failed: %s", strerror(errno)); - (void) unlink(un.sun_path); - (void) close(sock); - return FALSE; - } - - if (listen(sock, 0) == -1) { - _SCErrorSet(errno); - SC_log(LOG_ERR, "listen() failed: %s", strerror(errno)); - (void) unlink(un.sun_path); - (void) close(sock); - return FALSE; + SC_log(LOG_ERR, "fileport_makeport() failed: %s", strerror(errno)); + goto fail; } retry : status = notifyviafd(storePrivate->server, - un.sun_path, - (mach_msg_type_number_t)strlen(un.sun_path), + fileport, identifier, (int *)&sc_status); @@ -135,29 +111,28 @@ SCDynamicStoreNotifyFileDescriptor(SCDynamicStoreRef store, if (status != KERN_SUCCESS) { _SCErrorSet(status); - return FALSE; + goto fail; } - (void) unlink(un.sun_path); - if (sc_status != kSCStatusOK) { _SCErrorSet(sc_status); - SC_log(LOG_NOTICE, "SCDynamicStoreNotifyFileDescriptor server error: %s", SCErrorString(sc_status)); - (void) close(sock); - return FALSE; + goto fail; } - *fd = accept(sock, 0, 0); - if (*fd == -1) { - _SCErrorSet(errno); - SC_log(LOG_ERR, "accept() failed: %s", strerror(errno)); - (void) close(sock); - return FALSE; - } - (void) close(sock); + /* the SCDynamicStore server now has a copy of the write side, close our reference */ + (void) close(fildes[1]); + + /* and keep the read side */ + *fd = fildes[0]; /* set notifier active */ storePrivate->notifyStatus = Using_NotifierInformViaFD; return TRUE; + + fail : + + if (fildes[0] != -1) close(fildes[0]); + if (fildes[1] != -1) close(fildes[1]); + return FALSE; } diff --git a/SystemConfiguration.fproj/SCProxies.c b/SystemConfiguration.fproj/SCProxies.c index a7e288e..6870719 100644 --- a/SystemConfiguration.fproj/SCProxies.c +++ b/SystemConfiguration.fproj/SCProxies.c @@ -2,14 +2,14 @@ * Copyright (c) 2000-2004, 2006-2013 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -17,7 +17,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_LICENSE_HEADER_END@ */ @@ -35,6 +35,9 @@ #include #include +#if !TARGET_OS_SIMULATOR +#include +#endif // !TARGET_OS_SIMULATOR @@ -403,12 +406,12 @@ SCDynamicStoreCopyProxiesWithOptions(SCDynamicStoreRef store, CFDictionaryRef op { Boolean bypass = FALSE; CFStringRef key; - CFDictionaryRef proxies; + CFDictionaryRef proxies = NULL; if (options != NULL) { CFBooleanRef bypassGlobalOption; - if (isA_CFDictionary(options) == NULL) { + if (!isA_CFDictionary(options)) { _SCErrorSet(kSCStatusInvalidArgument); return NULL; } @@ -426,6 +429,21 @@ SCDynamicStoreCopyProxiesWithOptions(SCDynamicStoreRef store, CFDictionaryRef op proxies = SCDynamicStoreCopyValue(store, key); CFRelease(key); + if (isA_CFDictionary(proxies) && + CFDictionaryContainsKey(proxies, kSCPropNetProxiesBypassAllowed)) { + CFMutableDictionaryRef newProxies; + + newProxies = CFDictionaryCreateMutableCopy(NULL, 0, proxies); + CFRelease(proxies); + + /* + * Remove kSCPropNetProxiesBypassAllowed property from network + * service based configurations. + */ + CFDictionaryRemoveValue(newProxies, kSCPropNetProxiesBypassAllowed); + proxies = newProxies; + } + if (proxies != NULL) { CFDictionaryRef base = proxies; @@ -497,6 +515,21 @@ _SCNetworkProxiesCopyMatchingInternal(CFDictionaryRef globalConfiguration, scoped = CFDictionaryGetValue(globalConfiguration, kSCPropNetProxiesScoped); if (scoped == NULL) { +#if !TARGET_OS_SIMULATOR + if (CFDictionaryContainsKey(globalConfiguration, kSCPropNetProxiesBypassAllowed) && + ne_session_always_on_vpn_configs_present()) { + /* + * The kSCPropNetProxiesBypassAllowed key will be present + * for managed proxy configurations where bypassing is *not* + * allowed. + * + * Also (for now), forcing the use of the managed proxy + * configurations will only be done with AOVPN present. + */ + goto useDefault; + } +#endif // !TARGET_OS_SIMULATOR + // if no scoped proxy configurations _SCErrorSet(kSCStatusOK); return NULL; @@ -620,6 +653,10 @@ _SCNetworkProxiesCopyMatchingInternal(CFDictionaryRef globalConfiguration, // no matches, return "global" proxy configuration +#if !TARGET_OS_SIMULATOR + useDefault : +#endif // !TARGET_OS_SIMULATOR + newProxy = CFDictionaryCreateMutableCopy(NULL, 0, globalConfiguration); CFDictionaryRemoveValue(newProxy, kSCPropNetProxiesScoped); CFDictionaryRemoveValue(newProxy, kSCPropNetProxiesServices); diff --git a/SystemConfiguration.fproj/config.defs b/SystemConfiguration.fproj/config.defs index a6665c3..7c7a335 100644 --- a/SystemConfiguration.fproj/config.defs +++ b/SystemConfiguration.fproj/config.defs @@ -1,15 +1,15 @@ /* - * Copyright (c) 2000, 2001, 2003-2005, 2011, 2012 Apple Inc. All rights reserved. + * Copyright (c) 2000, 2001, 2003-2005, 2011, 2012, 2015 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -17,7 +17,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_LICENSE_HEADER_END@ */ @@ -60,6 +60,21 @@ type task_move_send_t = MACH_MSG_TYPE_MOVE_SEND */ +/* + * CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION + * + * Be very careful when adding, removing, or changing any + * of the MiG routes below. Everything tends to work fine + * when the SCDynamicStore client code (in the framework) + * and SCDynamicStore server code (in configd) are in sync. + * But, when the two are NOT in sync as is often the + * case when running the iOS Simulator, the conflict can + * be problematic. + * + * CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION + */ + + /* * Connection management API's */ @@ -165,13 +180,10 @@ routine notifychanges ( server : mach_port_t; routine notifyviaport ( server : mach_port_t; port : mach_port_move_send_t; - msgid : mach_msg_id_t; + msgid : mach_msg_id_t; /* must be zero */ out status : int); -routine notifyviafd ( server : mach_port_t; - path : xmlData; - identifier : int; - out status : int); + skip; /* was notifyviafd (passing UNIX domain socket filename) */ routine notifyviasignal ( server : mach_port_t; task : task_t /*task_move_send_t*/; @@ -186,7 +198,11 @@ routine notifyset ( server : mach_port_t; patterns : xmlData; out status : int); - skip; /* reserved for future use */ +routine notifyviafd ( server : mach_port_t; + fileport : mach_port_move_send_t; + identifier : int; + out status : int); + skip; /* reserved for future use */ skip; /* reserved for future use */ diff --git a/configd.tproj/_SCD.c b/configd.tproj/_SCD.c index 8d30d47..1bcc18b 100644 --- a/configd.tproj/_SCD.c +++ b/configd.tproj/_SCD.c @@ -268,11 +268,15 @@ pushNotifications(FILE *_configd_trace) /* * Post notification as mach message */ - SC_trace(_configd_trace, "%s : %5d : port = %d, msgid = %d\n", + SC_trace(_configd_trace, "%s : %5d : port = %d\n", "-->port", storePrivate->server, - storePrivate->notifyPort, - storePrivate->notifyPortIdentifier); + storePrivate->notifyPort); + + /* use a random (and non-zero) identifier */ + while (storePrivate->notifyPortIdentifier == 0) { + storePrivate->notifyPortIdentifier = (mach_msg_id_t)random(); + } _SC_sendMachMessage(storePrivate->notifyPort, storePrivate->notifyPortIdentifier); } diff --git a/configd.tproj/_SCD.h b/configd.tproj/_SCD.h index bcc94e4..535ed9e 100644 --- a/configd.tproj/_SCD.h +++ b/configd.tproj/_SCD.h @@ -1,15 +1,15 @@ /* - * Copyright (c) 2000, 2001, 2003, 2004, 2006, 2009, 2011 Apple Inc. All rights reserved. + * Copyright (c) 2000, 2001, 2003, 2004, 2006, 2009, 2011, 2015 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -17,7 +17,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_LICENSE_HEADER_END@ */ @@ -172,9 +172,7 @@ __SCDynamicStoreNotifyMachPort (SCDynamicStoreRef store, mach_port_t port); int -__SCDynamicStoreNotifyFileDescriptor (SCDynamicStoreRef store, - int32_t identifier, - int *fd); +__SCDynamicStoreNotifyFileDescriptor (SCDynamicStoreRef store); int __SCDynamicStoreNotifySignal (SCDynamicStoreRef store, diff --git a/configd.tproj/_notifyviafd.c b/configd.tproj/_notifyviafd.c index e96132d..fbc7b00 100644 --- a/configd.tproj/_notifyviafd.c +++ b/configd.tproj/_notifyviafd.c @@ -32,6 +32,7 @@ */ #include +#include #include #include #include @@ -44,12 +45,9 @@ __private_extern__ int -__SCDynamicStoreNotifyFileDescriptor(SCDynamicStoreRef store, - int32_t identifier, - int *fd) +__SCDynamicStoreNotifyFileDescriptor(SCDynamicStoreRef store) { SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store; - int sock; CFStringRef sessionKey; CFDictionaryRef info; @@ -58,13 +56,6 @@ __SCDynamicStoreNotifyFileDescriptor(SCDynamicStoreRef store, return kSCStatusNotifierActive; } - if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { - SC_log(LOG_ERR, "socket() failed: %s", strerror(errno)); - return kSCStatusFailed; - } - - *fd = sock; - /* push out a notification if any changes are pending */ sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), storePrivate->server); info = CFDictionaryGetValue(sessionData, sessionKey); @@ -88,102 +79,60 @@ __SCDynamicStoreNotifyFileDescriptor(SCDynamicStoreRef store, __private_extern__ kern_return_t -_notifyviafd(mach_port_t server, - xmlData_t pathRef, - mach_msg_type_number_t pathLen, - int identifier, - int *sc_status +_notifyviafd(mach_port_t server, + fileport_t fileport, + int identifier, + int *sc_status ) { - int bufSiz; + int fd = -1; + int flags; serverSessionRef mySession = getSession(server); - int nbioYes; - int sock; SCDynamicStorePrivateRef storePrivate; - struct sockaddr_un un; - - /* - * if socket currently open, close it! - */ - /* validate the UNIX domain socket path */ - if (pathLen > (sizeof(un.sun_path) - 1)) { - SC_log(LOG_INFO, "domain socket path length too long!"); - (void) vm_deallocate(mach_task_self(), (vm_address_t)pathRef, pathLen); - *sc_status = kSCStatusFailed; + + /* get notification file descriptor */ + fd = fileport_makefd(fileport); + mach_port_deallocate(mach_task_self(), fileport); + if (fd < 0) { + *sc_status = errno; return KERN_SUCCESS; } - /* un-serialize the UNIX domain socket path */ - un.sun_family = AF_UNIX; - bcopy(pathRef, un.sun_path, pathLen); - un.sun_path[pathLen] = '\0'; - (void) vm_deallocate(mach_task_self(), (vm_address_t)pathRef, pathLen); - - if (mySession == NULL) { - *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */ - return KERN_SUCCESS; + flags = fcntl(fd, F_GETFL, 0); + if (flags == -1) { + *sc_status = errno; + goto fail; } - storePrivate = (SCDynamicStorePrivateRef)mySession->store; - /* check permissions */ - if (!hasRootAccess(mySession)) { - struct stat statbuf; - - bzero(&statbuf, sizeof(statbuf)); - if (stat(un.sun_path, &statbuf) == -1) { - *sc_status = errno; - SC_log(LOG_INFO, "stat() failed: %s", strerror(errno)); - return KERN_SUCCESS; - } - if (mySession->callerEUID != statbuf.st_uid) { - *sc_status = kSCStatusAccessError; - SC_log(LOG_INFO, "permissions error [eUID]"); - return KERN_SUCCESS; - } + flags |= O_NONBLOCK; + if (fcntl(fd, F_SETFL, flags) == -1) { + *sc_status = errno; + goto fail; } - if (!hasPathAccess(mySession, un.sun_path)) { - *sc_status = kSCStatusAccessError; - SC_log(LOG_INFO, "permissions error [path]"); - return KERN_SUCCESS; + if (mySession == NULL) { + *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */ + goto fail; } + storePrivate = (SCDynamicStorePrivateRef)mySession->store; - /* do common sanity checks, get socket */ - *sc_status = __SCDynamicStoreNotifyFileDescriptor(mySession->store, identifier, &sock); + /* do common sanity checks */ + *sc_status = __SCDynamicStoreNotifyFileDescriptor(mySession->store); /* check status of __SCDynamicStoreNotifyFileDescriptor() */ if (*sc_status != kSCStatusOK) { - return KERN_SUCCESS; - } - - /* establish the connection, get ready for a read() */ - if (connect(sock, (struct sockaddr *)&un, sizeof(un)) == -1) { - *sc_status = errno; - SC_log(LOG_INFO, "connect() failed: %s", strerror(errno)); - (void) close(sock); - return KERN_SUCCESS; - } - - bufSiz = sizeof(storePrivate->notifyFileIdentifier); - if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &bufSiz, sizeof(bufSiz)) == -1) { - *sc_status = errno; - SC_log(LOG_INFO, "setsockopt() failed: %s", strerror(errno)); - (void) close(sock); - return KERN_SUCCESS; - } - - nbioYes = 1; - if (ioctl(sock, FIONBIO, &nbioYes) == -1) { - *sc_status = errno; - SC_log(LOG_INFO, "ioctl(,FIONBIO,) failed: %s", strerror(errno)); - (void) close(sock); - return KERN_SUCCESS; + goto fail; } /* set notifier active */ storePrivate->notifyStatus = Using_NotifierInformViaFD; - storePrivate->notifyFile = sock; + storePrivate->notifyFile = fd; storePrivate->notifyFileIdentifier = identifier; return KERN_SUCCESS; + + fail : + + if (fd >= 0) close(fd); + return KERN_SUCCESS; } diff --git a/configd.tproj/_notifyviaport.c b/configd.tproj/_notifyviaport.c index 8f52a78..8c7e219 100644 --- a/configd.tproj/_notifyviaport.c +++ b/configd.tproj/_notifyviaport.c @@ -1,15 +1,15 @@ /* - * Copyright (c) 2000, 2001, 2003, 2004, 2006, 2009, 2011 Apple Inc. All rights reserved. + * Copyright (c) 2000, 2001, 2003, 2004, 2006, 2009, 2011, 2015 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -17,7 +17,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_LICENSE_HEADER_END@ */ @@ -49,6 +49,11 @@ __SCDynamicStoreNotifyMachPort(SCDynamicStoreRef store, return kSCStatusNotifierActive; } + if (identifier != 0) { + /* sorry, the message ID (never used, no longer supported) must be zero */ + return kSCStatusInvalidArgument; + } + if (port == MACH_PORT_NULL) { /* sorry, you must specify a valid mach port */ return kSCStatusInvalidArgument; @@ -110,7 +115,6 @@ _notifyviaport(mach_port_t server, __MACH_PORT_DEBUG(TRUE, "*** _notifyviaport", port); storePrivate->notifyStatus = Using_NotifierInformViaMachPort; storePrivate->notifyPort = port; - storePrivate->notifyPortIdentifier = identifier; return KERN_SUCCESS; } diff --git a/configd.tproj/configd_server.h b/configd.tproj/configd_server.h index 7363bd6..1b9fbd4 100644 --- a/configd.tproj/configd_server.h +++ b/configd.tproj/configd_server.h @@ -1,15 +1,15 @@ /* - * Copyright (c) 2000-2006, 2008, 2011 Apple Inc. All rights reserved. + * Copyright (c) 2000-2006, 2008, 2011. 2015 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -17,7 +17,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_LICENSE_HEADER_END@ */ @@ -35,6 +35,7 @@ #define _S_CONFIGD_SERVER_H #include +#include #include #include @@ -163,8 +164,7 @@ kern_return_t _notifyviaport (mach_port_t server, int *status); kern_return_t _notifyviafd (mach_port_t server, - xmlData_t pathRef, - mach_msg_type_number_t pathLen, + fileport_t fileport, int identifier, int *status); diff --git a/configd.xcodeproj/project.pbxproj b/configd.xcodeproj/project.pbxproj index 9d2744d..853f071 100644 --- a/configd.xcodeproj/project.pbxproj +++ b/configd.xcodeproj/project.pbxproj @@ -6091,6 +6091,7 @@ buildSettings = { FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)"; GCC_DYNAMIC_NO_PIC = NO; + HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders"; INSTALL_PATH = /usr/libexec; LIBRARY_SEARCH_PATHS = ( "$(SYMROOT)", @@ -6105,6 +6106,7 @@ buildSettings = { FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)"; GCC_DYNAMIC_NO_PIC = NO; + HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders"; INSTALL_PATH = /usr/libexec; LIBRARY_SEARCH_PATHS = ( "$(SYMROOT)", @@ -6312,6 +6314,7 @@ buildSettings = { APPLY_RULES_IN_COPY_FILES = YES; FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)"; + HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders"; INSTALL_PATH = /usr/libexec; LIBRARY_SEARCH_PATHS = ( "$(SYMROOT)", @@ -6328,6 +6331,7 @@ buildSettings = { APPLY_RULES_IN_COPY_FILES = YES; FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)"; + HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders"; INSTALL_PATH = /usr/libexec; LIBRARY_SEARCH_PATHS = ( "$(SYMROOT)", @@ -6813,6 +6817,7 @@ "$(SYMROOT)", "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", ); + HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders"; INSTALL_PATH = /usr/libexec; LIBRARY_SEARCH_PATHS = ( "$(SYMROOT)", @@ -6834,6 +6839,7 @@ "$(SYMROOT)", "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", ); + HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders"; INSTALL_PATH = /usr/libexec; LIBRARY_SEARCH_PATHS = ( "$(SYMROOT)",