From 5c88273d3223836be3abe06ae09902f8a9536051 Mon Sep 17 00:00:00 2001 From: Apple Date: Wed, 12 Oct 2011 14:39:22 +0000 Subject: [PATCH 1/1] launchd-392.35.tar.gz --- launchd.xcodeproj/project.pbxproj | 10 +- launchd/src/IPC.h | 2 +- launchd/src/StartupItems.h | 2 +- launchd/src/SystemStarter.h | 2 +- launchd/src/SystemStarterIPC.h | 2 +- launchd/src/config.h | 2 +- launchd/src/launchctl.c | 16 ++- launchd/src/launchd.c | 4 +- launchd/src/launchd_core_logic.c | 169 +++++++++++++++++++++++++----- launchd/src/launchd_ktrace.h | 2 +- launchd/src/launchd_runtime.c | 22 ++-- launchd/src/launchproxy.c | 4 +- launchd/src/libvproc.c | 2 - 13 files changed, 181 insertions(+), 58 deletions(-) diff --git a/launchd.xcodeproj/project.pbxproj b/launchd.xcodeproj/project.pbxproj index 0218d29..d8c88e1 100644 --- a/launchd.xcodeproj/project.pbxproj +++ b/launchd.xcodeproj/project.pbxproj @@ -78,6 +78,7 @@ 4B1D92010F8BDE7D00125940 /* launchd.ops in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4B1D91ED0F8BDE1A00125940 /* launchd.ops */; }; 4B287733111A509400C07B35 /* launchd_helper.defs in Sources */ = {isa = PBXBuildFile; fileRef = 4B287732111A509400C07B35 /* launchd_helper.defs */; settings = {ATTRIBUTES = (Client, Server, ); }; }; 4B28781B111A61A400C07B35 /* launchd_helper.defs in Sources */ = {isa = PBXBuildFile; fileRef = 4B287732111A509400C07B35 /* launchd_helper.defs */; }; + 4B43EAF414101C5800E9E776 /* ServiceManagement.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B43EAF314101C5800E9E776 /* ServiceManagement.framework */; }; 4B9A1C1F132759F700019C67 /* events.defs in Sources */ = {isa = PBXBuildFile; fileRef = 4B0A30FF131F24AC002DE2E5 /* events.defs */; settings = {ATTRIBUTES = (Server, ); }; }; 4B9EDCA20EAFC77E00A78496 /* DiskArbitration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B9EDCA10EAFC77E00A78496 /* DiskArbitration.framework */; }; 4BA2F5FD1243063D00C2AADD /* init.defs in Sources */ = {isa = PBXBuildFile; fileRef = 4BA2F5FC1243063D00C2AADD /* init.defs */; }; @@ -378,6 +379,7 @@ 4B10F1F30F43BF5C00875782 /* launchctl */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = launchctl; sourceTree = BUILT_PRODUCTS_DIR; }; 4B1D91ED0F8BDE1A00125940 /* launchd.ops */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = launchd.ops; path = launchd/src/launchd.ops; sourceTree = ""; }; 4B287732111A509400C07B35 /* launchd_helper.defs */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.mig; name = launchd_helper.defs; path = launchd/src/launchd_helper.defs; sourceTree = ""; }; + 4B43EAF314101C5800E9E776 /* ServiceManagement.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ServiceManagement.framework; path = /System/Library/Frameworks/ServiceManagement.framework; sourceTree = ""; }; 4B9EDCA10EAFC77E00A78496 /* DiskArbitration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DiskArbitration.framework; path = /System/Library/Frameworks/DiskArbitration.framework; sourceTree = ""; }; 4BA2F5FC1243063D00C2AADD /* init.defs */ = {isa = PBXFileReference; explicitFileType = sourcecode.mig; fileEncoding = 4; name = init.defs; path = /usr/local/include/xpc/init.defs; sourceTree = SDKROOT; }; 7215DE4B0EFAF2EC00ABD81E /* libauditd.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libauditd.dylib; path = /usr/lib/libauditd.dylib; sourceTree = ""; }; @@ -488,6 +490,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 4B43EAF414101C5800E9E776 /* ServiceManagement.framework in Frameworks */, FCC841CC0EA7138700C01666 /* IOKit.framework in Frameworks */, FC3628080E9345E10054F1A3 /* CoreFoundation.framework in Frameworks */, FCD713740E95DE49001B0111 /* libedit.dylib in Frameworks */, @@ -598,6 +601,7 @@ FC36280C0E9345F60054F1A3 /* Frameworks */ = { isa = PBXGroup; children = ( + 4B43EAF314101C5800E9E776 /* ServiceManagement.framework */, 4B9EDCA10EAFC77E00A78496 /* DiskArbitration.framework */, FC36292C0E934AA40054F1A3 /* libbsm.dylib */, 7215DE4B0EFAF2EC00ABD81E /* libauditd.dylib */, @@ -954,7 +958,7 @@ ); runOnlyForDeploymentPostprocessing = 1; shellPath = /bin/sh; - shellScript = "install -o \"$INSTALL_OWNER\" -g \"$INSTALL_GROUP\" -m 0755 -d \"$DSTROOT\"/System/Library/LaunchAgents\ninstall -o \"$INSTALL_OWNER\" -g \"$INSTALL_GROUP\" -m 0755 -d \"$DSTROOT\"/System/Library/LaunchDaemons\ninstall -o \"$INSTALL_OWNER\" -g \"$INSTALL_GROUP\" -m 0755 -d \"$DSTROOT\"/Library/LaunchAgents\ninstall -o \"$INSTALL_OWNER\" -g \"$INSTALL_GROUP\" -m 0755 -d \"$DSTROOT\"/Library/LaunchDaemons\ninstall -o \"$INSTALL_OWNER\" -g \"$INSTALL_GROUP\" -m 0755 -d \"$DSTROOT\"/private/etc/mach_init.d\ninstall -o \"$INSTALL_OWNER\" -g \"$INSTALL_GROUP\" -m 0755 -d \"$DSTROOT\"/private/etc/mach_init_per_login_session.d\ninstall -o \"$INSTALL_OWNER\" -g \"$INSTALL_GROUP\" -m 0755 -d \"$DSTROOT\"/private/etc/mach_init_per_user.d\n/Developer/Makefiles/bin/compress-man-pages.pl -d \"$DSTROOT\" /usr/share/man"; + shellScript = "install -o \"$INSTALL_OWNER\" -g \"$INSTALL_GROUP\" -m 0755 -d \"$DSTROOT\"/System/Library/LaunchAgents\ninstall -o \"$INSTALL_OWNER\" -g \"$INSTALL_GROUP\" -m 0755 -d \"$DSTROOT\"/System/Library/LaunchDaemons\ninstall -o \"$INSTALL_OWNER\" -g \"$INSTALL_GROUP\" -m 0755 -d \"$DSTROOT\"/Library/LaunchAgents\ninstall -o \"$INSTALL_OWNER\" -g \"$INSTALL_GROUP\" -m 0755 -d \"$DSTROOT\"/Library/LaunchDaemons\n/Developer/Makefiles/bin/compress-man-pages.pl -d \"$DSTROOT\" /usr/share/man"; showEnvVarsInLog = 0; }; FC7B87B20EA7195F00542082 /* ShellScript */ = { @@ -968,7 +972,7 @@ ); runOnlyForDeploymentPostprocessing = 1; shellPath = /bin/sh; - shellScript = "/Developer/Makefiles/bin/compress-man-pages.pl -d \"$DSTROOT\" /usr/share/man\n/bin/mkdir -p \"$DSTROOT/private/var/db/launchd.db/com.apple.launchd\"\n/usr/sbin/chown root:wheel \"$DSTROOT/private/var/db/launchd.db\"\n/usr/sbin/chown root:wheel \"$DSTROOT/private/var/db/launchd.db/com.apple.launchd\"\n"; + shellScript = "/Developer/Makefiles/bin/compress-man-pages.pl -d \"$DSTROOT\" /usr/share/man\n/bin/mkdir -p \"$DSTROOT/private/var/db/launchd.db/com.apple.launchd\"\n/usr/sbin/chown root:wheel \"$DSTROOT/private/var/db/launchd.db\"\n/usr/sbin/chown root:wheel \"$DSTROOT/private/var/db/launchd.db/com.apple.launchd\"\n/bin/mkdir -p \"$DSTROOT/private/etc/mach_init.d\"\n/bin/mkdir -p \"$DSTROOT/private/etc/mach_init_per_user.d\"\n/bin/mkdir -p \"$DSTROOT/private/etc/mach_init_per_login_session.d\"\n/usr/sbin/chown root:wheel \"$DSTROOT/private/etc/mach_init.d\"\n/usr/sbin/chown root:wheel \"$DSTROOT/private/etc/mach_init_per_user.d\"\n/usr/sbin/chown root:wheel \"$DSTROOT/private/etc/mach_init_per_login_session.d\""; showEnvVarsInLog = 0; }; FC7B87EE0EA71A4900542082 /* ShellScript */ = { @@ -1038,7 +1042,7 @@ ); runOnlyForDeploymentPostprocessing = 1; shellPath = /bin/sh; - shellScript = "install -o \"$INSTALL_OWNER\" -g \"$INSTALL_GROUP\" -m 0755 -d \"$DSTROOT\"/System/Library/LaunchAgents\ninstall -o \"$INSTALL_OWNER\" -g \"$INSTALL_GROUP\" -m 0755 -d \"$DSTROOT\"/System/Library/LaunchDaemons\ninstall -o \"$INSTALL_OWNER\" -g \"$INSTALL_GROUP\" -m 0755 -d \"$DSTROOT\"/Library/LaunchAgents\ninstall -o \"$INSTALL_OWNER\" -g \"$INSTALL_GROUP\" -m 0755 -d \"$DSTROOT\"/Library/LaunchDaemons\ninstall -o \"$INSTALL_OWNER\" -g \"$INSTALL_GROUP\" -m 0755 -d \"$DSTROOT\"/private/etc/mach_init.d\ninstall -o \"$INSTALL_OWNER\" -g \"$INSTALL_GROUP\" -m 0755 -d \"$DSTROOT\"/private/etc/mach_init_per_login_session.d\ninstall -o \"$INSTALL_OWNER\" -g \"$INSTALL_GROUP\" -m 0755 -d \"$DSTROOT\"/private/etc/mach_init_per_user.d\n/Developer/Makefiles/bin/compress-man-pages.pl -d \"$DSTROOT\" /usr/share/man"; + shellScript = "install -o \"$INSTALL_OWNER\" -g \"$INSTALL_GROUP\" -m 0755 -d \"$DSTROOT\"/System/Library/LaunchAgents\ninstall -o \"$INSTALL_OWNER\" -g \"$INSTALL_GROUP\" -m 0755 -d \"$DSTROOT\"/System/Library/LaunchDaemons\ninstall -o \"$INSTALL_OWNER\" -g \"$INSTALL_GROUP\" -m 0755 -d \"$DSTROOT\"/Library/LaunchAgents\ninstall -o \"$INSTALL_OWNER\" -g \"$INSTALL_GROUP\" -m 0755 -d \"$DSTROOT\"/Library/LaunchDaemons\n/Developer/Makefiles/bin/compress-man-pages.pl -d \"$DSTROOT\" /usr/share/man"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ diff --git a/launchd/src/IPC.h b/launchd/src/IPC.h index b28226c..d85a482 100644 --- a/launchd/src/IPC.h +++ b/launchd/src/IPC.h @@ -35,4 +35,4 @@ **/ void MonitorStartupItem (StartupContext aStartupContext, CFMutableDictionaryRef anItem); -#endif +#endif /* _IPC_H_ */ diff --git a/launchd/src/StartupItems.h b/launchd/src/StartupItems.h index 5cf6c08..f50b47c 100644 --- a/launchd/src/StartupItems.h +++ b/launchd/src/StartupItems.h @@ -112,4 +112,4 @@ void StartupItemSetStatus(CFMutableDictionaryRef aStatusDict, CFMutableDictionar */ bool StartupItemSecurityCheck(const char *aPath); -#endif +#endif /* _StartupItems_H_ */ diff --git a/launchd/src/SystemStarter.h b/launchd/src/SystemStarter.h index 417d307..6a6c0ab 100644 --- a/launchd/src/SystemStarter.h +++ b/launchd/src/SystemStarter.h @@ -48,4 +48,4 @@ typedef enum { void CF_syslog(int level, CFStringRef message, ...); extern bool gVerboseFlag; -#endif +#endif /* _SYSTEM_STARTER_H_ */ diff --git a/launchd/src/SystemStarterIPC.h b/launchd/src/SystemStarterIPC.h index 9dc0023..3a94095 100644 --- a/launchd/src/SystemStarterIPC.h +++ b/launchd/src/SystemStarterIPC.h @@ -85,4 +85,4 @@ typedef struct SystemStarterIPCMessage { #define kIPCConfigSettingVerboseFlag CFSTR("VerboseFlag") #define kIPCConfigSettingNetworkUp CFSTR("NetworkUp") -#endif +#endif /* _SYSTEM_STARTER_IPC_H */ diff --git a/launchd/src/config.h b/launchd/src/config.h index 9f46ab6..4c12664 100644 --- a/launchd/src/config.h +++ b/launchd/src/config.h @@ -4,4 +4,4 @@ #define HAVE_QUARANTINE TARGET_HAVE_QUARANTINE #define HAVE_SANDBOX TARGET_HAVE_SANDBOX #define HAVE_LIBAUDITD !TARGET_OS_EMBEDDED -#endif +#endif /* __CONFIG_H__ */ diff --git a/launchd/src/launchctl.c b/launchd/src/launchctl.c index 3b86dcc..25b3b3f 100644 --- a/launchd/src/launchctl.c +++ b/launchd/src/launchctl.c @@ -18,7 +18,7 @@ * @APPLE_APACHE_LICENSE_HEADER_END@ */ -static const char *const __rcs_file_version__ = "$Revision: 24957 $"; +static const char *const __rcs_file_version__ = "$Revision: 25182 $"; #include "config.h" #include "launch.h" @@ -33,6 +33,7 @@ static const char *const __rcs_file_version__ = "$Revision: 24957 $"; #include #include #include +#include #include #include #include @@ -2275,13 +2276,7 @@ bootstrap_cmd(int argc, char *const argv[]) load_launchd_items[6] = "local"; the_argc += 2; } - if (strcasecmp(session_type, VPROCMGR_SESSION_LOGINWINDOW) == 0) { - load_launchd_items[the_argc] = "/etc/mach_init_per_login_session.d"; - the_argc += 1; - } } else if (strcasecmp(session_type, VPROCMGR_SESSION_AQUA) == 0) { - load_launchd_items[5] = "/etc/mach_init_per_user.d"; - the_argc += 1; /* For now, we'll just load user Background agents when * bootstrapping the Aqua session. This way, we can * safely assume that the home directory is present. If @@ -2290,7 +2285,7 @@ bootstrap_cmd(int argc, char *const argv[]) * risk of deadlocking against mount_url. But this fix should * satisfy . */ - the_argc_user = 5; + the_argc_user = 4; /* We want to read environment.plist, which is in the user's home directory. * Since the dance to mount a network home directory is fairly complex, all we @@ -2320,6 +2315,9 @@ bootstrap_cmd(int argc, char *const argv[]) vproc_err_t err = vproc_swap_integer(NULL, VPROC_GSK_WEIRD_BOOTSTRAP, &junk, NULL); if (!err) { retval = load_and_unload_cmd(the_argc_user, load_launchd_items_user); +#if TARGET_OS_MAC + _SMLoginItemBootstrapItems(); +#endif } } @@ -3685,7 +3683,7 @@ do_potential_fsck(void) const char *remount_tool[] = { "mount", "-uw", "/", NULL }; #if TARGET_OS_EMBEDDED const char *nvram_tool[] = { "/usr/sbin/nvram", "auto-boot=false", NULL }; -#endif +#endif /* TARGET_OS_EMBEDDED */ struct statfs sfs; if (!assumes(statfs("/", &sfs) != -1)) { diff --git a/launchd/src/launchd.c b/launchd/src/launchd.c index 78e1738..56e5807 100644 --- a/launchd/src/launchd.c +++ b/launchd/src/launchd.c @@ -447,7 +447,7 @@ pid1_magic_init(void) runtime_syslog(LOG_DEBUG, "Audit Session ID: %i", g_audit_session); g_audit_session_port = _audit_session_self(); -#endif +#endif // !TARGET_OS_EMBEDDED strcpy(g_launchd_database_dir, LAUNCHD_DB_PREFIX "/com.apple.launchd"); } @@ -555,7 +555,7 @@ launchd_SessionCreate(void) } else { runtime_syslog(LOG_WARNING, "Could not set audit session: %s.", strerror(errno)); } -#endif +#endif // !TARGET_OS_EMBEDDED } void diff --git a/launchd/src/launchd_core_logic.c b/launchd/src/launchd_core_logic.c index c04a496..9e50f96 100644 --- a/launchd/src/launchd_core_logic.c +++ b/launchd/src/launchd_core_logic.c @@ -16,7 +16,7 @@ * @APPLE_APACHE_LICENSE_HEADER_END@ */ -static const char *const __rcs_file_version__ = "$Revision: 24984 $"; +static const char *const __rcs_file_version__ = "$Revision: 25247 $"; #include "config.h" #include "launchd_core_logic.h" @@ -80,6 +80,7 @@ static const char *const __rcs_file_version__ = "$Revision: 24984 $"; #include #include #include +#include #include #include @@ -95,6 +96,7 @@ static const char *const __rcs_file_version__ = "$Revision: 24984 $"; #if TARGET_OS_EMBEDDED #include #else +extern int gL1CacheEnabled; /* To make my life easier. */ typedef struct jetsam_priority_entry { pid_t pid; @@ -133,7 +135,7 @@ enum { #if !TARGET_OS_EMBEDDED #include "domainServer.h" #include "init.h" -#endif +#endif /* !TARGET_OS_EMBEDDED */ #include "eventsServer.h" #ifndef POSIX_SPAWN_OSX_TALAPP_START @@ -219,7 +221,7 @@ static void machservice_resetport(job_t j, struct machservice *ms); static struct machservice *machservice_new(job_t j, const char *name, mach_port_t *serviceport, bool pid_local); #ifndef __LAUNCH_DISABLE_XPC_SUPPORT__ static struct machservice *machservice_new_alias(job_t aj, struct machservice *orig); -#endif +#endif /* __LAUNCH_DISABLE_XPC_SUPPORT__ */ static void machservice_ignore(job_t j, struct machservice *ms); static void machservice_watch(job_t j, struct machservice *ms); static void machservice_delete(job_t j, struct machservice *, bool port_died); @@ -447,7 +449,7 @@ struct jobmgr_s { static jobmgr_t _s_xpc_system_domain; static LIST_HEAD(, jobmgr_s) _s_xpc_user_domains; static LIST_HEAD(, jobmgr_s) _s_xpc_session_domains; -#endif +#endif /* __LAUNCH_DISABLE_XPC_SUPPORT__ */ #define jobmgr_assumes(jm, e) \ (unlikely(!(e)) ? jobmgr_log_bug(jm, __LINE__), false : true) @@ -458,7 +460,7 @@ static jobmgr_t jobmgr_new_xpc_singleton_domain(jobmgr_t jm, name_t name); static jobmgr_t jobmgr_find_xpc_per_user_domain(jobmgr_t jm, uid_t uid); static jobmgr_t jobmgr_find_xpc_per_session_domain(jobmgr_t jm, au_asid_t asid); static job_t xpc_domain_import_service(jobmgr_t jm, launch_data_t pload); -#endif +#endif /* __LAUNCH_DISABLE_XPC_SUPPORT__ */ static job_t jobmgr_import2(jobmgr_t jm, launch_data_t pload); static jobmgr_t jobmgr_parent(jobmgr_t jm); static jobmgr_t jobmgr_do_garbage_collection(jobmgr_t jm); @@ -695,7 +697,7 @@ static job_t job_new_anonymous(jobmgr_t jm, pid_t anonpid) __attribute__((malloc static job_t job_new(jobmgr_t jm, const char *label, const char *prog, const char *const *argv) __attribute__((malloc, nonnull(1,2), warn_unused_result)); #ifndef __LAUNCH_DISABLE_XPC_SUPPORT__ static job_t job_new_alias(jobmgr_t jm, job_t src); -#endif +#endif /* __LAUNCH_DISABLE_XPC_SUPPORT__ */ static job_t job_new_via_mach_init(job_t j, const char *cmd, uid_t uid, bool ond) __attribute__((malloc, nonnull, warn_unused_result)); static job_t job_new_subjob(job_t j, uuid_t identifier); static void job_kill(job_t j); @@ -1154,7 +1156,7 @@ jobmgr_remove(jobmgr_t jm) (void)jobmgr_assumes(jm, kr == KERN_SUCCESS); } } -#endif +#endif /* !TARGET_OS_EMBEDDED */ if (jm->req_ctx) { (void)jobmgr_assumes(jm, vm_deallocate(mach_task_self(), jm->req_ctx, jm->req_ctx_sz) == KERN_SUCCESS); } @@ -1425,16 +1427,9 @@ job_remove(job_t j) if (j->shutdown_monitor) { _s_shutdown_monitor = NULL; } - if (j->workaround9359725) { - /* We may have forcibly removed this job by simulating an exit. If this - * is the case, we don't want to hear about these events anymore, lest - * we get a stale context pointer and crash trying to dereference it. - */ - kevent_mod((uintptr_t)j->p, EVFILT_PROC, EV_DELETE, 0, 0, NULL); - } - + kevent_mod((uintptr_t)j, EVFILT_TIMER, EV_DELETE, 0, 0, NULL); - + LIST_REMOVE(j, sle); LIST_REMOVE(j, label_hash_sle); @@ -1446,6 +1441,7 @@ job_remove(job_t j) job_log(j, LOG_DEBUG, "Removed"); + j->kqjob_callback = (kq_callback)0x8badf00d; free(j); } @@ -2046,7 +2042,7 @@ job_new_alias(jobmgr_t jm, job_t src) return j; } -#endif +#endif /* __LAUNCH_DISABLE_XPC_SUPPORT__ */ job_t job_import(launch_data_t pload) @@ -2284,7 +2280,7 @@ job_import_string(job_t j, const char *key, const char *value) else if (strcasecmp(value, LAUNCH_KEY_POSIXSPAWNTYPE_IOSAPP) == 0) { j->pstype = POSIX_SPAWN_IOS_APP_START; } -#endif +#endif /* TARGET_OS_EMBEDDED */ else { job_log(j, LOG_ERR, "Unknown value for key %s: %s", key, value); } @@ -3898,6 +3894,28 @@ job_callback_timer(job_t j, void *ident) (void)job_assumes(j, host_reboot(mach_host_self(), HOST_REBOOT_DEBUGGER) == KERN_SUCCESS); } + /* We've simulated the exit, so we have to cancel the kevent for + * this job, otherwise we may get a kevent later down the road that + * has a stale context pointer (if we've removed the job). Or worse, + * it'll corrupt our data structures if the job still exists or the + * allocation was recycled. + * + * If the failing process had a tracer attached to it, we need to + * remove out NOTE_EXIT for that tracer too, otherwise the same + * thing might happen. + * + * Note that, if we're not shutting down, this will result in a + * zombie process just hanging around forever. But if the process + * didn't exit after receiving SIGKILL, odds are it would've just + * stuck around forever anyway. + * + * See . + */ + kevent_mod((uintptr_t)j->p, EVFILT_PROC, EV_DELETE, 0, 0, NULL); + if (j->tracing_pid) { + kevent_mod((uintptr_t)j->tracing_pid, EVFILT_PROC, EV_DELETE, 0, 0, NULL); + } + struct kevent bogus_exit; EV_SET(&bogus_exit, j->p, EVFILT_PROC, 0, NOTE_EXIT, 0, 0); jobmgr_callback(j->mgr, &bogus_exit); @@ -4448,6 +4466,67 @@ out: free(pids); } +static struct passwd * +job_getpwnam(job_t j, const char *name) +{ + /* + * methodology for system daemons + * + * first lookup user record without any opendirectoryd interaction, + * we don't know what interprocess dependencies might be in flight. + * if that fails, we re-enable opendirectoryd interaction and + * re-issue the lookup. We have to disable the libinfo L1 cache + * otherwise libinfo will return the negative cache entry on the retry + */ + +#if !TARGET_OS_EMBEDDED + struct passwd *pw = NULL; + + if (pid1_magic && j->mgr == root_jobmgr) { + si_search_module_set_flags("ds", 1 /* SEARCH_MODULE_FLAG_DISABLED */); + gL1CacheEnabled = false; + + pw = getpwnam(name); + + si_search_module_set_flags("ds", 0); + } + + if (pw == NULL) { + pw = getpwnam(name); + } + + return pw; +#else + return getpwnam(name); +#endif +} + +static struct group * +job_getgrnam(job_t j, const char *name) +{ +#if !TARGET_OS_EMBEDDED + struct group *gr = NULL; + + if (pid1_magic && j->mgr == root_jobmgr) { + si_search_module_set_flags("ds", 1 /* SEARCH_MODULE_FLAG_DISABLED */); + gL1CacheEnabled = false; + + gr = getgrnam(name); + + si_search_module_set_flags("ds", 0); + } + + if (gr == NULL) { + gr = getgrnam(name); + } + + return gr; +#else +#pragma unused (j) + return getgrnam(name); +#endif +} + void job_postfork_test_user(job_t j) { @@ -4469,7 +4548,7 @@ job_postfork_test_user(job_t j) goto out_bad; } - if ((pwe = getpwnam(user_env_var)) == NULL) { + if ((pwe = job_getpwnam(j, user_env_var)) == NULL) { job_log(j, LOG_ERR, "The account \"%s\" has been deleted out from under us!", user_env_var); goto out_bad; } @@ -4543,7 +4622,7 @@ job_postfork_become_user(job_t j) } if (j->username) { - if ((pwe = getpwnam(j->username)) == NULL) { + if ((pwe = job_getpwnam(j, j->username)) == NULL) { job_log(j, LOG_ERR, "getpwnam(\"%s\") failed", j->username); _exit(EXIT_FAILURE); } @@ -4587,7 +4666,7 @@ job_postfork_become_user(job_t j) if (j->groupname) { struct group *gre; - if (unlikely((gre = getgrnam(j->groupname)) == NULL)) { + if (unlikely((gre = job_getgrnam(j, j->groupname)) == NULL)) { job_log(j, LOG_ERR, "getgrnam(\"%s\") failed", j->groupname); _exit(EXIT_FAILURE); } @@ -5958,7 +6037,7 @@ machservice_new_alias(job_t j, struct machservice *orig) return ms; } -#endif +#endif /* __LAUNCH_DISABLE_XPC_SUPPORT__ */ bootstrap_status_t machservice_status(struct machservice *ms) @@ -6138,6 +6217,9 @@ jobmgr_do_garbage_collection(jobmgr_t jm) jobmgr_log(jm, LOG_DEBUG, "No submanagers left."); } else { jobmgr_log(jm, LOG_DEBUG, "Still have submanagers."); + SLIST_FOREACH(jmi, &jm->submgrs, sle) { + jobmgr_log(jm, LOG_DEBUG, "Submanager: %s", jmi->name); + } } size_t actives = 0; @@ -6578,7 +6660,7 @@ jobmgr_find_xpc_per_session_domain(jobmgr_t jm, au_asid_t asid) return jmi; } -#endif +#endif /* __LAUNCH_DISABLE_XPC_SUPPORT__ */ job_t jobmgr_init_session(jobmgr_t jm, const char *session_type, bool sflag) @@ -8693,6 +8775,10 @@ job_mig_parent(job_t j, mach_port_t srp, mach_port_t *parentport) kern_return_t job_mig_get_root_bootstrap(job_t j, mach_port_t *rootbsp) { + if (!j) { + return BOOTSTRAP_NO_MEMORY; + } + if (inherited_bootstrap_port == MACH_PORT_NULL) { *rootbsp = root_jobmgr->jm_port; (void)job_assumes(j, launchd_mport_make_send(root_jobmgr->jm_port) == KERN_SUCCESS); @@ -8922,6 +9008,10 @@ out_bad: kern_return_t job_mig_transaction_count_for_pid(job_t j, pid_t p, int32_t *cnt, boolean_t *condemned) { + if (!j) { + return BOOTSTRAP_NO_MEMORY; + } + kern_return_t kr = KERN_FAILURE; struct ldcred *ldc = runtime_get_caller_creds(); if ((ldc->euid != geteuid()) && (ldc->euid != 0)) { @@ -8973,6 +9063,10 @@ job_mig_pid_is_managed(job_t j __attribute__((unused)), pid_t p, boolean_t *mana kern_return_t job_mig_port_for_label(job_t j __attribute__((unused)), name_t label, mach_port_t *mp) { + if (!j) { + return BOOTSTRAP_NO_MEMORY; + } + struct ldcred *ldc = runtime_get_caller_creds(); kern_return_t kr = BOOTSTRAP_NOT_PRIVILEGED; @@ -9005,6 +9099,10 @@ job_mig_port_for_label(job_t j __attribute__((unused)), name_t label, mach_port_ kern_return_t job_mig_set_security_session(job_t j, uuid_t uuid, mach_port_t asport) { + if (!j) { + return BOOTSTRAP_NO_MEMORY; + } + uuid_string_t uuid_str; uuid_unparse(uuid, uuid_str); job_log(j, LOG_DEBUG, "Setting session %u for UUID %s...", asport, uuid_str); @@ -9210,6 +9308,10 @@ out: kern_return_t job_mig_init_session(job_t j, name_t session_type, mach_port_t asport) { + if (!j) { + return BOOTSTRAP_NO_MEMORY; + } + job_t j2; kern_return_t kr = BOOTSTRAP_NO_MEMORY; @@ -9264,6 +9366,10 @@ job_mig_switch_to_session(job_t j, mach_port_t requestor_port, name_t session_na return BOOTSTRAP_NO_MEMORY; } + if (j->mgr->shutting_down) { + return BOOTSTRAP_UNKNOWN_SERVICE; + } + job_log(j, LOG_DEBUG, "Job wants to move to %s session.", session_name); if (!job_assumes(j, pid1_magic == false)) { @@ -9492,6 +9598,9 @@ job_mig_subset(job_t j, mach_port_t requestorport, mach_port_t *subsetportp) if (!launchd_assumes(j != NULL)) { return BOOTSTRAP_NO_MEMORY; } + if (j->mgr->shutting_down) { + return BOOTSTRAP_UNKNOWN_SERVICE; + } jmr = j->mgr; @@ -9612,9 +9721,13 @@ xpc_domain_import2(job_t j, mach_port_t reqport, mach_port_t dport) job_log(j, LOG_ERR, "XPC domains may only reside in PID 1."); return BOOTSTRAP_NOT_PRIVILEGED; } - if (!MACH_PORT_VALID(reqport)) { + if (!j || !MACH_PORT_VALID(reqport)) { return BOOTSTRAP_UNKNOWN_SERVICE; } + if (root_jobmgr->shutting_down) { + jobmgr_log(root_jobmgr, LOG_ERR, "Attempt to create new domain while shutting down."); + return BOOTSTRAP_NOT_PRIVILEGED; + } kern_return_t kr = BOOTSTRAP_NO_MEMORY; /* All XPC domains are children of the root job manager. What we're creating @@ -9816,7 +9929,7 @@ xpc_domain_get_service_name(job_t j, event_name_t name) (void)strlcpy(name, ms->name, sizeof(event_name_t)); return BOOTSTRAP_SUCCESS; } -#endif +#endif /* __LAUNCH_DISABLE_XPC_SUPPORT__ */ kern_return_t xpc_events_get_channel_name(job_t j __attribute__((unused)), event_name_t stream __attribute__((unused)), uint64_t token __attribute__((unused)), event_name_t name __attribute__((unused))) @@ -9919,7 +10032,7 @@ xpc_events_find_channel(job_t j, event_name_t stream, mach_port_t *p) msi->event_channel = true; *p = sp; - machservice_watch(j, msi); + (void)job_dispatch(j, false); } else { errno = BOOTSTRAP_NO_MEMORY; } @@ -10239,7 +10352,7 @@ job_mig_event_source_check_in(job_t j, name_t name, mach_port_t ping_port, vm_of kern_return_t job_mig_event_set_state(job_t j, name_t name, uint64_t token, boolean_t state) { - if (!j->event_monitor) { + if (!j || !j->event_monitor) { return BOOTSTRAP_NOT_PRIVILEGED; } @@ -10272,7 +10385,7 @@ jobmgr_init(bool sflag) _s_xpc_system_domain->req_asid = g_audit_session; _s_xpc_system_domain->req_asport = g_audit_session_port; _s_xpc_system_domain->shortdesc = "system"; -#endif +#endif /* __LAUNCH_DISABLE_XPC_SUPPORT__ */ if (pid1_magic) { root_jobmgr->monitor_shutdown = true; } diff --git a/launchd/src/launchd_ktrace.h b/launchd/src/launchd_ktrace.h index a8eab4f..5e21c5a 100644 --- a/launchd/src/launchd_ktrace.h +++ b/launchd/src/launchd_ktrace.h @@ -34,4 +34,4 @@ void runtime_ktrace1(runtime_ktrace_code_t code); void runtime_ktrace0(runtime_ktrace_code_t code); void runtime_ktrace(runtime_ktrace_code_t code, long a, long b, long c); -#endif +#endif /* __LAUNCHD_KTRACE_H__ */ diff --git a/launchd/src/launchd_runtime.c b/launchd/src/launchd_runtime.c index ac0e712..9514078 100644 --- a/launchd/src/launchd_runtime.c +++ b/launchd/src/launchd_runtime.c @@ -18,7 +18,7 @@ * @APPLE_APACHE_LICENSE_HEADER_END@ */ -static const char *const __rcs_file_version__ = "$Revision: 24912 $"; +static const char *const __rcs_file_version__ = "$Revision: 25122 $"; #include "config.h" #include "launchd_runtime.h" @@ -78,7 +78,7 @@ static const char *const __rcs_file_version__ = "$Revision: 24912 $"; #if !TARGET_OS_EMBEDDED #include "domainServer.h" -#endif +#endif /* !TARGET_OS_EMBEDDED */ #include "eventsServer.h" static mach_port_t ipc_port_set; @@ -557,9 +557,19 @@ x_handle_kqueue(mach_port_t junk __attribute__((unused)), integer_t fd) log_kevent_struct(LOG_EMERG, &kev[0], i); } #else - runtime_ktrace(RTKT_LAUNCHD_BSD_KEVENT|DBG_FUNC_START, kevi->ident, kevi->filter, kevi->fflags); - (*((kq_callback *)kevi->udata))(kevi->udata, kevi); - runtime_ktrace0(RTKT_LAUNCHD_BSD_KEVENT|DBG_FUNC_END); + struct job_check_s { + kq_callback kqc; + }; + + struct job_check_s *check = kevi->udata; + if (check && check->kqc) { + runtime_ktrace(RTKT_LAUNCHD_BSD_KEVENT|DBG_FUNC_START, kevi->ident, kevi->filter, kevi->fflags); + (*((kq_callback *)kevi->udata))(kevi->udata, kevi); + runtime_ktrace0(RTKT_LAUNCHD_BSD_KEVENT|DBG_FUNC_END); + } else { + runtime_syslog(LOG_ERR, "The following kevent had invalid context data. Please file a bug with the following information:"); + log_kevent_struct(LOG_EMERG, &kev[0], i); + } #endif } } @@ -1119,7 +1129,7 @@ launchd_runtime2(mach_msg_size_t msg_size, mig_reply_error_t *bufRequest, mig_re } #else (void)xpc_events_server(&bufRequest->Head, &bufReply->Head); -#endif +#endif /* !TARGET_OS_EMBEDDED */ } } diff --git a/launchd/src/launchproxy.c b/launchd/src/launchproxy.c index 693bc1b..d3290aa 100644 --- a/launchd/src/launchproxy.c +++ b/launchd/src/launchproxy.c @@ -39,7 +39,7 @@ #if !TARGET_OS_EMBEDDED #include #include -#endif +#endif // !TARGET_OS_EMBEDDED #include "launch.h" @@ -206,7 +206,7 @@ int main(int argc __attribute__((unused)), char *argv[]) syslog(LOG_NOTICE, "%s: Setting Audit Session ID failed: %d", prog, errno); } } -#endif +#endif // !TARGET_OS_EMBEDDED fcntl(r, F_SETFL, 0); fcntl(r, F_SETFD, 1); dup2(r, STDIN_FILENO); diff --git a/launchd/src/libvproc.c b/launchd/src/libvproc.c index e6dcc34..536d05f 100644 --- a/launchd/src/libvproc.c +++ b/launchd/src/libvproc.c @@ -59,8 +59,6 @@ static mach_port_t get_root_bootstrap_port(void); - #define _vproc_set_crash_log_message(x) - static int64_t cached_pid = -1; static struct vproc_shmem_s *vproc_shmem; static pthread_once_t shmem_inited = PTHREAD_ONCE_INIT; -- 2.45.2