Revision: 23717 http://trac.macosforge.org/projects/launchd/changeset/23717 Author: dsorresso@apple.com Date: 2008-09-30 15:33:12 -0700 (Tue, 30 Sep 2008) Log Message: ----------- Initial set of changes for flattening of the per-user Mach namespace. Some highlights: Per-user launchd's now consult the root job manager's MachServices hash for all lookups. The root user now gets a per-user launchd, no longer uses a sub-manager of the system launchd. There is now a bstree launchctl subcommand that displays the entire Mach bootstrap tree. Added bootstrap_lookup_per_user_context() to libbootstrap (private). Changed to job_mig_lookup_per_user_context() to forward requests from root-owned processes onto the system launchd if they come through to a per-user launchd first. This will let root processes under a per-user bootstrap look up another per-user bootstrap (i.e. login(1)). This SPI is intended to replace vproc_move_subset_to_user() in the launchd PAM module. Changed job_mig_lookup_per_user_context() to return the current per-user context if the request's UID matches that of the per-user launchd it went to. Added bootstrap_lookup_children() to libbootstrap (private). Added bootstrap_root() to libbootstrap (private). Untested. Modified Paths: -------------- branches/PR-6046664/launchd/src/launchctl.c branches/PR-6046664/launchd/src/launchd.c branches/PR-6046664/launchd/src/launchd_core_logic.c branches/PR-6046664/launchd/src/launchd_runtime.c branches/PR-6046664/launchd/src/launchd_runtime.h branches/PR-6046664/launchd/src/launchproxy.c branches/PR-6046664/launchd/src/libbootstrap.c branches/PR-6046664/launchd/src/libbootstrap_private.h branches/PR-6046664/launchd/src/libbootstrap_public.h branches/PR-6046664/launchd/src/libvproc.c branches/PR-6046664/launchd/src/protocol_job.defs branches/PR-6046664/launchd/src/protocol_job_forward.defs branches/PR-6046664/launchd/src/protocol_job_reply.defs Modified: branches/PR-6046664/launchd/src/launchctl.c =================================================================== --- branches/PR-6046664/launchd/src/launchctl.c 2008-09-30 22:09:48 UTC (rev 23716) +++ branches/PR-6046664/launchd/src/launchctl.c 2008-09-30 22:33:12 UTC (rev 23717) @@ -22,6 +22,7 @@ #include "liblaunch_public.h" #include "liblaunch_private.h" +#include "libbootstrap_private.h" #include "libbootstrap_public.h" #include "libvproc_public.h" #include "libvproc_private.h" @@ -42,7 +43,12 @@ #include <sys/time.h> #include <sys/sysctl.h> #include <sys/stat.h> + +#ifndef SO_EXECPATH + #define SO_EXECPATH 0x1085 +#endif #include <sys/socket.h> + #include <sys/un.h> #include <sys/fcntl.h> #include <sys/event.h> @@ -180,7 +186,11 @@ static int getrusage_cmd(int argc, char *const argv[]); static int bsexec_cmd(int argc, char *const argv[]); static int bslist_cmd(int argc, char *const argv[]); +static int bstree_cmd(int argc, char * const argv[]); +static int _bslist_cmd(mach_port_t bsport, unsigned int depth); +static int _bstree_cmd(mach_port_t bsport, unsigned int depth); + static int exit_cmd(int argc, char *const argv[]) __attribute__((noreturn)); static int help_cmd(int argc, char *const argv[]); @@ -212,9 +222,10 @@ { "umask", umask_cmd, "Change launchd's umask" }, { "bsexec", bsexec_cmd, "Execute a process within a different Mach bootstrap subset" }, { "bslist", bslist_cmd, "List Mach bootstrap services and optional servers" }, + { "bstree", bstree_cmd, "Show the entire Mach bootstrap tree." }, { "exit", exit_cmd, "Exit the interactive invocation of launchctl" }, { "quit", exit_cmd, "Quit the interactive invocation of launchctl" }, - { "help", help_cmd, "This help output" }, + { "help", help_cmd, "This help output" } }; static bool istty; @@ -1646,7 +1657,7 @@ if (strcasecmp(session_type, VPROCMGR_SESSION_BACKGROUND) == 0) { read_launchd_conf(); -#if HAVE_SECURITY +#if 0 assumes(SessionCreate(sessionKeepCurrentBootstrap, 0) == 0); #endif } @@ -2546,6 +2557,8 @@ return 1; } } while (getrootbs && last_bport != bport); + } else if( strcmp(s, "0") == 0 ) { + bport = MACH_PORT_NULL; } else { int pid = atoi(s); @@ -2599,18 +2612,14 @@ } int -bslist_cmd(int argc, char *const argv[]) +_bslist_cmd(mach_port_t bport, unsigned int depth) { kern_return_t result; - mach_port_t bport = bootstrap_port; name_array_t service_names; mach_msg_type_number_t service_cnt, service_active_cnt; bootstrap_status_array_t service_actives; unsigned int i; - if (argc == 2) - bport = str2bsport(argv[1]); - if (bport == MACH_PORT_NULL) { fprintf(stderr, "Invalid bootstrap port\n"); return 1; @@ -2624,12 +2633,67 @@ #define bport_state(x) (((x) == BOOTSTRAP_STATUS_ACTIVE) ? "A" : ((x) == BOOTSTRAP_STATUS_ON_DEMAND) ? "D" : "I") - for (i = 0; i < service_cnt ; i++) - fprintf(stdout, "%-3s%s\n", bport_state((service_actives[i])), service_names[i]); + for (i = 0; i < service_cnt ; i++) { + fprintf(stdout, "%*s%-3s%s\n", depth, "", bport_state((service_actives[i])), service_names[i]); + } return 0; } +int +bslist_cmd(int argc, char *const argv[]) +{ + mach_port_t bport = bootstrap_port; + if( argc == 2 ) { + bport = str2bsport(argv[1]); + } + + if( bport == MACH_PORT_NULL ) { + fprintf(stderr, "Invalid bootstrap port\n"); + return 1; + } + + return _bslist_cmd(bport, 0); +} + +int +_bstree_cmd(mach_port_t bsport, unsigned int depth) +{ + if( bsport == MACH_PORT_NULL ) { + fprintf(stderr, "No root port!\n"); + return 1; + } + + mach_port_array_t child_ports = NULL; + name_array_t child_names = NULL; + unsigned int cnt = 0; + + kern_return_t kr = bootstrap_lookup_children(bsport, &child_ports, &child_names, (mach_msg_type_number_t *)&cnt); + if( kr != BOOTSTRAP_SUCCESS && kr != BOOTSTRAP_NO_CHILDREN ) { + fprintf(stderr, "%s(): bootstrap_lookup_children(): %d\n", __func__, kr); + return 1; + } + + unsigned int i = 0; + _bslist_cmd(bsport, depth); + + for( i = 0; i < cnt; i++ ) { + fprintf(stdout, "%*s%s/\n", depth, "", child_names[i]); + if( child_ports[i] != MACH_PORT_NULL ) { + _bstree_cmd(child_ports[i], depth + 4); + } + } + + return 0; +} + +int +bstree_cmd(int argc __attribute__((unused)), char * const argv[] __attribute__((unused))) +{ + fprintf(stdout, "System/\n"); + return _bstree_cmd(str2bsport("/"), 4); +} + bool is_legacy_mach_job(launch_data_t obj) { Modified: branches/PR-6046664/launchd/src/launchd.c =================================================================== --- branches/PR-6046664/launchd/src/launchd.c 2008-09-30 22:09:48 UTC (rev 23716) +++ branches/PR-6046664/launchd/src/launchd.c 2008-09-30 22:33:12 UTC (rev 23717) @@ -106,11 +106,15 @@ bool shutdown_in_progress; bool fake_shutdown_in_progress; bool network_up; -char g_username[128] = "__UnknownUserToLaunchd_DontPanic_NotImportant__"; +char *g_username = "__UninitializedUser__"; int main(int argc, char *const *argv) { + if( getpid() == 1 ) { + printf("launchd[1] is starting.\n"); + } + const char *stdouterr_path = low_level_debug ? _PATH_CONSOLE : _PATH_DEVNULL; bool sflag = false; int ch; @@ -162,12 +166,9 @@ int64_t now = runtime_get_wall_time(); - struct passwd *pwent = getpwuid(getuid()); - if( pwent ) { - strlcpy(g_username, pwent->pw_name, sizeof(g_username) - 1); - } + g_username = getenv("LOGNAME"); - runtime_syslog(LOG_NOTICE, "Per-user launchd for UID %u (%s) began at: %lld.%06llu", getuid(), g_username, now / USEC_PER_SEC, now % USEC_PER_SEC); + runtime_syslog(LOG_DEBUG, "Per-user launchd for UID %u (%s) began at: %lld.%06llu", getuid(), g_username, now / USEC_PER_SEC, now % USEC_PER_SEC); } monitor_networking_state(); @@ -313,7 +314,7 @@ now = runtime_get_wall_time(); char *term_who = pid1_magic ? "System shutdown" : "Per-user launchd termination"; - runtime_syslog(LOG_NOTICE, "%s began at: %lld.%06llu", term_who, now / USEC_PER_SEC, now % USEC_PER_SEC); + runtime_syslog(LOG_DEBUG, "%s began at: %lld.%06llu", term_who, now / USEC_PER_SEC, now % USEC_PER_SEC); launchd_assert(jobmgr_shutdown(root_jobmgr) != NULL); } @@ -336,6 +337,7 @@ launchd_SessionCreate(void) { #if HAVE_SECURITY + runtime_syslog(LOG_NOTICE, "%s(): Called.", __func__); OSStatus (*sescr)(SessionCreationFlags flags, SessionAttributeBits attributes); void *seclib; Modified: branches/PR-6046664/launchd/src/launchd_core_logic.c =================================================================== --- branches/PR-6046664/launchd/src/launchd_core_logic.c 2008-09-30 22:09:48 UTC (rev 23716) +++ branches/PR-6046664/launchd/src/launchd_core_logic.c 2008-09-30 22:33:12 UTC (rev 23717) @@ -289,9 +289,9 @@ kq_callback kqjobmgr_callback; SLIST_ENTRY(jobmgr_s) sle; SLIST_HEAD(, jobmgr_s) submgrs; + LIST_HEAD(, machservice) ms_hash[MACHSERVICE_HASH_SIZE]; LIST_HEAD(, job_s) jobs; LIST_HEAD(, job_s) active_jobs[ACTIVE_JOB_HASH_SIZE]; - LIST_HEAD(, machservice) ms_hash[MACHSERVICE_HASH_SIZE]; LIST_HEAD(, job_s) global_env_jobs; mach_port_t jm_port; mach_port_t req_port; @@ -308,7 +308,7 @@ }; #define jobmgr_assumes(jm, e) \ - (unlikely(!(e)) ? jobmgr_log_bug(jm, __LINE__), false : true) + (unlikely(!(e)) ? jobmgr_log_bug(jm, __LINE__, #e), false : true) static jobmgr_t jobmgr_new(jobmgr_t jm, mach_port_t requestorport, mach_port_t transfer_port, bool sflag, const char *name); static job_t jobmgr_import2(jobmgr_t jm, launch_data_t pload); @@ -331,7 +331,7 @@ static void jobmgr_logv(jobmgr_t jm, int pri, int err, const char *msg, va_list ap) __attribute__((format(printf, 4, 0))); static void jobmgr_log(jobmgr_t jm, int pri, const char *msg, ...) __attribute__((format(printf, 3, 4))); /* static void jobmgr_log_error(jobmgr_t jm, int pri, const char *msg, ...) __attribute__((format(printf, 3, 4))); */ -static void jobmgr_log_bug(jobmgr_t jm, unsigned int line); +static void jobmgr_log_bug(jobmgr_t jm, unsigned int line, const char *test); #define AUTO_PICK_LEGACY_LABEL (const char *)(~0) @@ -453,7 +453,7 @@ #define job_assumes(j, e) \ - (unlikely(!(e)) ? job_log_bug(j, __LINE__), false : true) + (unlikely(!(e)) ? job_log_bug(j, __LINE__, #e), false : true) static void job_import_keys(launch_data_t obj, const char *key, void *context); static void job_import_bool(job_t j, const char *key, bool value); @@ -480,7 +480,6 @@ static void job_log_pids_with_weird_uids(job_t j); static void job_force_sampletool(job_t j); static void job_setup_exception_port(job_t j, task_t target_task); -static void job_reparent_hack(job_t j, const char *where); INTERNAL_ABI static void job_callback(void *obj, struct kevent *kev); static void job_callback_proc(job_t j, int fflags); static void job_callback_timer(job_t j, void *ident); @@ -495,7 +494,7 @@ static void job_log_stdouterr(job_t j); static void job_logv(job_t j, int pri, int err, const char *msg, va_list ap) __attribute__((format(printf, 4, 0))); static void job_log_error(job_t j, int pri, const char *msg, ...) __attribute__((format(printf, 3, 4))); -static void job_log_bug(job_t j, unsigned int line); +static void job_log_bug(job_t j, unsigned int line, const char *test); static void job_log_stdouterr2(job_t j, const char *msg, ...); static void job_set_exeception_port(job_t j, mach_port_t port); static kern_return_t job_handle_mpm_wait(job_t j, mach_port_t srp, int *waitstatus); @@ -526,7 +525,6 @@ /* miscellaneous file local functions */ static size_t get_kern_max_proc(void); -static void ensure_root_bkgd_setup(void); static int dir_has_files(job_t j, const char *path); static char **mach_cmd2argv(const char *string); static size_t our_strhash(const char *s) __attribute__((pure)); @@ -540,7 +538,6 @@ static mach_port_t the_exception_server; static bool did_first_per_user_launchd_BootCache_hack; #define JOB_BOOTCACHE_HACK_CHECK(j) (unlikely(j->per_user && !did_first_per_user_launchd_BootCache_hack && (j->mach_uid >= 500) && (j->mach_uid != (uid_t)-2))) -static jobmgr_t background_jobmgr; static job_t workaround_5477111; /* process wide globals */ @@ -871,7 +868,7 @@ jobmgr_t jmi; job_t ji; - jobmgr_log(jm, LOG_DEBUG, "Removed job manager"); + jobmgr_log(jm, LOG_NOTICE, "Removed job manager"); if (!jobmgr_assumes(jm, SLIST_EMPTY(&jm->submgrs))) { while ((jmi = SLIST_FIRST(&jm->submgrs))) { @@ -893,10 +890,6 @@ jobmgr_assumes(jm, launchd_mport_close_recv(jm->jm_port) == KERN_SUCCESS); } - if (jm == background_jobmgr) { - background_jobmgr = NULL; - } - if (jm->parentmgr) { runtime_del_weak_ref(); SLIST_REMOVE(&jm->parentmgr->submgrs, jm, jobmgr_s, sle); @@ -1283,8 +1276,7 @@ } if (jp && !jp->anonymous && unlikely(!(kp.kp_proc.p_flag & P_EXEC))) { - job_log(jp, LOG_APPLEONLY, "Called *fork(). Please switch to posix_spawn*(), pthreads or launchd. Child PID %u", - kp.kp_proc.p_pid); + job_log(jp, LOG_APPLEONLY, "Called *fork(). Please switch to posix_spawn*(), pthreads or launchd. Child PID %u", kp.kp_proc.p_pid); } @@ -1358,6 +1350,7 @@ strlcpy(tmp_path, argv[0], sizeof(tmp_path)); bn = basename(tmp_path); /* prog for auto labels is kp.kp_kproc.p_comm */ } + snprintf(auto_label, sizeof(auto_label), "%s.%s", sizeof(void *) == 8 ? "0xdeadbeeffeedface" : "0xbabecafe", bn); label = auto_label; /* This is so we can do gross things later. See NOTE_EXEC for anonymous jobs */ @@ -1625,7 +1618,6 @@ } else if (strcasecmp(key, LAUNCH_JOBKEY_LIMITLOADFROMHOSTS) == 0) { return; } else if (strcasecmp(key, LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE) == 0) { - job_reparent_hack(j, value); return; } break; @@ -2199,7 +2191,6 @@ struct ldcred *ldc = runtime_get_caller_creds(); job_t jr; - jr = job_mig_intran2(root_jobmgr, p, ldc->pid); if (!jobmgr_assumes(root_jobmgr, jr != NULL)) { @@ -3624,7 +3615,7 @@ } void -jobmgr_log_bug(jobmgr_t jm, unsigned int line) +jobmgr_log_bug(jobmgr_t jm, unsigned int line, const char *test) { static const char *file; int saved_errno = errno; @@ -3645,14 +3636,14 @@ /* the only time 'jm' should not be set is if setting up the first bootstrap fails for some reason */ if (likely(jm)) { - jobmgr_log(jm, LOG_NOTICE, "Bug: %s:%u (%s):%u", file, line, buf, saved_errno); + jobmgr_log(jm, LOG_NOTICE, "Bug: %s:%u (%s):%u %s", file, line, buf, saved_errno, test); } else { - runtime_syslog(LOG_NOTICE, "Bug: %s:%u (%s):%u", file, line, buf, saved_errno); + runtime_syslog(LOG_NOTICE, "Bug: %s:%u (%s):%u %s", file, line, buf, saved_errno, test); } } void -job_log_bug(job_t j, unsigned int line) +job_log_bug(job_t j, unsigned int line, const char *test) { static const char *file; int saved_errno = errno; @@ -3673,9 +3664,9 @@ /* I cannot think of any reason why 'j' should ever be NULL, nor have I ever seen the case in the wild */ if (likely(j)) { - job_log(j, LOG_NOTICE, "Bug: %s:%u (%s):%u", file, line, buf, saved_errno); + job_log(j, LOG_NOTICE, "Bug: %s:%u (%s):%u %s", file, line, buf, saved_errno, test); } else { - runtime_syslog(LOG_NOTICE, "Bug: %s:%u (%s):%u", file, line, buf, saved_errno); + runtime_syslog(LOG_NOTICE, "Bug: %s:%u (%s):%u %s", file, line, buf, saved_errno, test); } } @@ -4553,10 +4544,16 @@ } SLIST_INSERT_HEAD(&j->machservices, ms, sle); - LIST_INSERT_HEAD(&j->mgr->ms_hash[hash_ms(ms->name)], ms, name_hash_sle); + + if( pid1_magic ) { + LIST_INSERT_HEAD(&j->mgr->ms_hash[hash_ms(ms->name)], ms, name_hash_sle); + } else { + LIST_INSERT_HEAD(&root_jobmgr->ms_hash[hash_ms(ms->name)], ms, name_hash_sle); + } + LIST_INSERT_HEAD(&port_hash[HASH_PORT(ms->port)], ms, port_hash_sle); - job_log(j, LOG_INFO, "Mach service added: %s", name); + jobmgr_log(j->mgr, LOG_NOTICE, "Mach service %s added.", name); return ms; out_bad2: @@ -4998,7 +4995,7 @@ } } - jobmgr_log(jmr, LOG_DEBUG, "Created job manager%s%s", jm ? " with parent: " : ".", jm ? jm->name : ""); + jobmgr_log(jmr, LOG_NOTICE, "Created job manager%s%s", jm ? " with parent: " : ".", jm ? jm->name : ""); if (bootstrapper) { jobmgr_assumes(jmr, job_dispatch(bootstrapper, true) != NULL); @@ -5020,6 +5017,8 @@ job_t jobmgr_init_session(jobmgr_t jm, const char *session_type, bool sflag) { + jobmgr_log(jm, LOG_NOTICE, "%s(): Bootstrapping %s.", __func__, session_type); + const char *bootstrap_tool[] = { "/bin/launchctl", "bootstrap", "-S", session_type, sflag ? "-s" : NULL, NULL }; char thelabel[1000]; job_t bootstrapper; @@ -5087,37 +5086,60 @@ struct machservice * jobmgr_lookup_service(jobmgr_t jm, const char *name, bool check_parent, pid_t target_pid) -{ +{ struct machservice *ms; job_t target_j; + jobmgr_log(jm, LOG_DEBUG, "%s(): Got lookup request for \"%s\"", __func__, name); + if (target_pid) { - //jobmgr_assumes(jm, !check_parent); + jobmgr_assumes(jm, !check_parent); if (unlikely((target_j = jobmgr_find_by_pid(jm, target_pid, false)) == NULL)) { + jobmgr_log(jm, LOG_DEBUG, "%s(): Couldn't find PID %u in this bootstrap.", __func__, target_pid); return NULL; } + job_log(target_j, LOG_DEBUG, "%s(): Found target job.", __func__); + SLIST_FOREACH(ms, &target_j->machservices, sle) { if (ms->per_pid && strcmp(name, ms->name) == 0) { return ms; } } + job_log(target_j, LOG_DEBUG, "%s(): Couldn't find service \"%s\" in job, giving up.", __func__, name); return NULL; } + + if( pid1_magic ) { + LIST_FOREACH(ms, &jm->ms_hash[hash_ms(name)], name_hash_sle) { + if (!ms->per_pid && strcmp(name, ms->name) == 0) { + return ms; + } + } + + if (jm->parentmgr == NULL || !check_parent) { + jobmgr_log(jm, LOG_DEBUG, "%s(): Couldn't find \"%s\" in this bootstrap, giving up.", __func__, name); + return NULL; + } - LIST_FOREACH(ms, &jm->ms_hash[hash_ms(name)], name_hash_sle) { - if (!ms->per_pid && strcmp(name, ms->name) == 0) { - return ms; + jobmgr_log(jm, LOG_DEBUG, "%s(): Couldn't find \"%s\" in this bootstrap, recursing...", __func__, name); + + return jobmgr_lookup_service(jm->parentmgr, name, true, 0); + } else { + LIST_FOREACH(ms, &root_jobmgr->ms_hash[hash_ms(name)], name_hash_sle) { + if (!ms->per_pid && strcmp(name, ms->name) == 0) { + return ms; + } } - } - - if (jm->parentmgr == NULL || !check_parent) { + + jobmgr_log(jm, LOG_DEBUG, "%s(): Couldn't find \"%s\" in this (flat) bootstrap.", __func__, name); + return NULL; } - - return jobmgr_lookup_service(jm->parentmgr, name, true, 0); + + return NULL; } mach_port_t @@ -5901,9 +5923,7 @@ } kern_return_t -job_mig_swap_complex(job_t j, vproc_gsk_t inkey, vproc_gsk_t outkey, - vm_offset_t inval, mach_msg_type_number_t invalCnt, - vm_offset_t *outval, mach_msg_type_number_t *outvalCnt) +job_mig_swap_complex(job_t j, vproc_gsk_t inkey, vproc_gsk_t outkey, vm_offset_t inval, mach_msg_type_number_t invalCnt, vm_offset_t *outval, mach_msg_type_number_t *outvalCnt) { const char *action; launch_data_t input_obj, output_obj; @@ -6272,23 +6292,8 @@ return 0; } -void -ensure_root_bkgd_setup(void) -{ - if (likely(background_jobmgr) || !pid1_magic) { - return; - } - - if (!jobmgr_assumes(root_jobmgr, (background_jobmgr = jobmgr_new(root_jobmgr, mach_task_self(), MACH_PORT_NULL, false, VPROCMGR_SESSION_BACKGROUND)) != NULL)) { - return; - } - - background_jobmgr->req_port = 0; - jobmgr_assumes(root_jobmgr, launchd_mport_make_send(background_jobmgr->jm_port) == KERN_SUCCESS); -} - kern_return_t -job_mig_lookup_per_user_context(job_t j, uid_t which_user, mach_port_t *up_cont) +job_mig_lookup_per_user_context(job_t j, mach_port_t srp, uid_t which_user, mach_port_t *up_cont) { struct ldcred *ldc = runtime_get_caller_creds(); job_t ji; @@ -6297,27 +6302,40 @@ return BOOTSTRAP_NO_MEMORY; } - job_log(j, LOG_DEBUG, "Looking up per user launchd for UID: %u", which_user); + if( j->per_user ) { + job_log(j, LOG_NOTICE, "Got per-user lookup request from per-user launchd %u.", j->mach_uid); + } if (unlikely(!pid1_magic)) { - job_log(j, LOG_ERR, "Only PID 1 supports per user launchd lookups."); + if( which_user == getuid() ) { + job_log(j, LOG_NOTICE, "Request for local per-user bootstrap (%u). Returning bootstrap port.", which_user); + + launchd_mport_make_send(root_jobmgr->jm_port); + *up_cont = root_jobmgr->jm_port; + return BOOTSTRAP_SUCCESS; + } else if( ldc->euid == 0 ) { + job_log(j, LOG_NOTICE, "Forwarding request for %u's per-user launchd to system launchd.", which_user); + /* Forward the request onto the system launchd. */ + job_assumes(j, vproc_mig_lookup_per_user_context_forward(inherited_bootstrap_port, srp, which_user) == 0); + + /* Have the client wait for the system launchd to get back to it. */ + return MIG_NO_REPLY; + } else { + job_log(j, LOG_ERR, "Only PID 1 supports non-local per user launchd lookups."); + } + return BOOTSTRAP_NOT_PRIVILEGED; } - if (ldc->euid || ldc->uid) { + /* If the request came from a per-user launchd, it was forwarded on behalf of a root-owned client. */ + if( !j->per_user && (ldc->euid || ldc->uid) ) { which_user = ldc->euid ?: ldc->uid; } + job_log(j, LOG_NOTICE, "Looking up per user launchd for UID: %u", which_user); + *up_cont = MACH_PORT_NULL; - if (which_user == 0) { - ensure_root_bkgd_setup(); - - *up_cont = background_jobmgr->jm_port; - - return 0; - } - LIST_FOREACH(ji, &root_jobmgr->jobs, sle) { if (!ji->per_user) { continue; @@ -6366,6 +6384,7 @@ } if (job_assumes(j, ji != NULL)) { + launchd_mport_copy_send(machservice_port(SLIST_FIRST(&ji->machservices))); *up_cont = machservice_port(SLIST_FIRST(&ji->machservices)); } @@ -6384,12 +6403,15 @@ return BOOTSTRAP_NO_MEMORY; } + job_log(j, LOG_NOTICE, "%s(): Checking in service \"%s\"%s.", __func__, servicename, per_pid_service ? " as a per-PID service" : ""); ms = jobmgr_lookup_service(j->mgr, servicename, false, per_pid_service ? ldc->pid : 0); if (ms == NULL) { + job_log(j, LOG_NOTICE, "%s(): Service \"%s\" not found.", __func__, servicename); *serviceportp = MACH_PORT_NULL; if (unlikely((ms = machservice_new(j, servicename, serviceportp, per_pid_service)) == NULL)) { + job_log(j, LOG_NOTICE, "%s(): Creating service \"%s\" failed.", __func__, servicename); return BOOTSTRAP_NO_MEMORY; } @@ -6438,7 +6460,7 @@ job_log(j, LOG_APPLEONLY, "Performance: bootstrap_register() is deprecated. Service: %s", servicename); } - job_log(j, LOG_DEBUG, "%sMach service registration attempt: %s", flags & BOOTSTRAP_PER_PID_SERVICE ? "Per PID " : "", servicename); + job_log(j, LOG_NOTICE, "%sMach service registration attempt: %s", flags & BOOTSTRAP_PER_PID_SERVICE ? "Per PID " : "", servicename); /* 5641783 for the embedded hack */ #if !TARGET_OS_EMBEDDED @@ -6583,54 +6605,52 @@ } kern_return_t -job_mig_info(job_t j, name_array_t *servicenamesp, unsigned int *servicenames_cnt, - bootstrap_status_array_t *serviceactivesp, unsigned int *serviceactives_cnt) +job_mig_info(job_t j, name_array_t *servicenamesp, unsigned int *servicenames_cnt, bootstrap_status_array_t *serviceactivesp, unsigned int *serviceactives_cnt) { - name_array_t service_names = NULL; - bootstrap_status_array_t service_actives = NULL; - unsigned int cnt = 0, cnt2 = 0; - struct machservice *ms; - jobmgr_t jm; - job_t ji; - - if (!launchd_assumes(j != NULL)) { + if( !launchd_assumes(j != NULL) ) { return BOOTSTRAP_NO_MEMORY; } - jm = j->mgr; - - LIST_FOREACH(ji, &jm->jobs, sle) { - SLIST_FOREACH(ms, &ji->machservices, sle) { - if (!ms->per_pid) { + jobmgr_t jm = j->mgr; + struct machservice *msi = NULL; + unsigned int cnt = 0; + + unsigned int i = 0; + for( i = 0; i < MACHSERVICE_HASH_SIZE; i++ ) { + LIST_FOREACH( msi, &jm->ms_hash[i], name_hash_sle ) { + if( !msi->per_pid ) { cnt++; } } } - if (cnt == 0) { + if( cnt == 0 ) { goto out; } + name_array_t service_names = NULL; mig_allocate((vm_address_t *)&service_names, cnt * sizeof(service_names[0])); - if (!job_assumes(j, service_names != NULL)) { + if( !job_assumes(j, service_names != NULL) ) { goto out_bad; } + bootstrap_status_array_t service_actives = NULL; mig_allocate((vm_address_t *)&service_actives, cnt * sizeof(service_actives[0])); - if (!job_assumes(j, service_actives != NULL)) { + if( !job_assumes(j, service_actives != NULL) ) { goto out_bad; } - LIST_FOREACH(ji, &jm->jobs, sle) { - SLIST_FOREACH(ms, &ji->machservices, sle) { - if (!ms->per_pid) { - strlcpy(service_names[cnt2], machservice_name(ms), sizeof(service_names[0])); - service_actives[cnt2] = machservice_status(ms); + unsigned int cnt2 = 0; + for( i = 0; i < MACHSERVICE_HASH_SIZE; i++ ) { + LIST_FOREACH( msi, &jm->ms_hash[i], name_hash_sle ) { + if( !msi->per_pid ) { + strlcpy(service_names[cnt2], machservice_name(msi), sizeof(service_names[0])); + service_actives[cnt2] = machservice_status(msi); cnt2++; } } } - + job_assumes(j, cnt == cnt2); out: @@ -6651,59 +6671,6 @@ return BOOTSTRAP_NO_MEMORY; } -void -job_reparent_hack(job_t j, const char *where) -{ - jobmgr_t jmi, jmi2; - - ensure_root_bkgd_setup(); - - /* NULL is only passed for our custom API for LaunchServices. If that is the case, we do magic. */ - if (where == NULL) { - if (strcasecmp(j->mgr->name, VPROCMGR_SESSION_LOGINWINDOW) == 0) { - where = VPROCMGR_SESSION_LOGINWINDOW; - } else { - where = VPROCMGR_SESSION_AQUA; - } - } - - if (strcasecmp(j->mgr->name, where) == 0) { - return; - } - - SLIST_FOREACH(jmi, &root_jobmgr->submgrs, sle) { - if (unlikely(jmi->shutting_down)) { - continue; - } else if (strcasecmp(jmi->name, where) == 0) { - goto jm_found; - } else if (strcasecmp(jmi->name, VPROCMGR_SESSION_BACKGROUND) == 0 && pid1_magic) { - SLIST_FOREACH(jmi2, &jmi->submgrs, sle) { - if (strcasecmp(jmi2->name, where) == 0) { - jmi = jmi2; - goto jm_found; - } - } - } - } - -jm_found: - if (job_assumes(j, jmi != NULL)) { - struct machservice *msi; - - SLIST_FOREACH(msi, &j->machservices, sle) { - LIST_REMOVE(msi, name_hash_sle); - } - - LIST_REMOVE(j, sle); - LIST_INSERT_HEAD(&jmi->jobs, j, sle); - j->mgr = jmi; - - SLIST_FOREACH(msi, &j->machservices, sle) { - LIST_INSERT_HEAD(&j->mgr->ms_hash[hash_ms(msi->name)], msi, name_hash_sle); - } - } -} - kern_return_t job_mig_move_subset(job_t j, mach_port_t target_subset, name_t session_type) { @@ -6723,50 +6690,9 @@ job_t j2; if (j->mgr->session_initialized) { - if (ldc->uid == 0 && pid1_magic) { - if (strcmp(j->mgr->name, VPROCMGR_SESSION_LOGINWINDOW) == 0) { - job_t ji, jn; - - LIST_FOREACH_SAFE(ji, &j->mgr->jobs, sle, jn) { - if (!ji->anonymous) { - job_remove(ji); - } - } - - ensure_root_bkgd_setup(); - - SLIST_REMOVE(&j->mgr->parentmgr->submgrs, j->mgr, jobmgr_s, sle); - j->mgr->parentmgr = background_jobmgr; - SLIST_INSERT_HEAD(&j->mgr->parentmgr->submgrs, j->mgr, sle); - - /* - * We really should wait for all the jobs to die before proceeding. See 5351245 for more info. - * - * We have hacked around this in job_find() by ignoring jobs that are pending removal. - */ - - } else if (strcmp(j->mgr->name, VPROCMGR_SESSION_AQUA) == 0) { - job_log(j, LOG_DEBUG, "Tried to move the Aqua session."); - return 0; - } else if (strcmp(j->mgr->name, VPROCMGR_SESSION_BACKGROUND) == 0) { - job_log(j, LOG_DEBUG, "Tried to move the background session."); - return 0; - } else { - job_log(j, LOG_ERR, "Tried to initialize an already setup session!"); - kr = BOOTSTRAP_NOT_PRIVILEGED; - goto out; - } - } else { - job_log(j, LOG_ERR, "Tried to initialize an already setup session!"); - kr = BOOTSTRAP_NOT_PRIVILEGED; - goto out; - } - } else if (ldc->uid == 0 && pid1_magic && strcmp(session_type, VPROCMGR_SESSION_STANDARDIO) == 0) { - ensure_root_bkgd_setup(); - - SLIST_REMOVE(&j->mgr->parentmgr->submgrs, j->mgr, jobmgr_s, sle); - j->mgr->parentmgr = background_jobmgr; - SLIST_INSERT_HEAD(&j->mgr->parentmgr->submgrs, j->mgr, sle); + job_log(j, LOG_ERR, "Tried to initialize an already setup session!"); + kr = BOOTSTRAP_NOT_PRIVILEGED; + goto out; } else if (strcmp(session_type, VPROCMGR_SESSION_LOGINWINDOW) == 0) { jobmgr_t jmi; @@ -6794,7 +6720,7 @@ } } - jobmgr_log(j->mgr, LOG_DEBUG, "Renaming to: %s", session_type); + jobmgr_log(j->mgr, LOG_NOTICE, "Renaming to: %s", session_type); strcpy(j->mgr->name_init, session_type); if (job_assumes(j, (j2 = jobmgr_init_session(j->mgr, session_type, false)))) { @@ -6810,7 +6736,7 @@ goto out; } - job_log(j, LOG_DEBUG, "Move subset attempt: 0x%x", target_subset); + job_log(j, LOG_NOTICE, "Move subset attempt: 0x%x", target_subset); kr = _vproc_grab_subset(target_subset, &reqport, &rcvright, &out_obj_array, &l2l_ports, &l2l_port_cnt); @@ -6877,9 +6803,7 @@ } kern_return_t -job_mig_take_subset(job_t j, mach_port_t *reqport, mach_port_t *rcvright, - vm_offset_t *outdata, mach_msg_type_number_t *outdataCnt, - mach_port_array_t *portsp, unsigned int *ports_cnt) +job_mig_take_subset(job_t j, mach_port_t *reqport, mach_port_t *rcvright, vm_offset_t *outdata, mach_msg_type_number_t *outdataCnt, mach_port_array_t *portsp, unsigned int *ports_cnt) { launch_data_t tmp_obj, tmp_dict, outdata_obj_array = NULL; mach_port_array_t ports = NULL; @@ -6889,7 +6813,10 @@ jobmgr_t jm; job_t ji; + jobmgr_log(j->mgr, LOG_NOTICE, "%s(): Called from %s.", __func__, j->label); + if (!launchd_assumes(j != NULL)) { + runtime_syslog(LOG_NOTICE, "%s(): Called with NULL job.", __func__); return BOOTSTRAP_NO_MEMORY; } @@ -6912,7 +6839,7 @@ return BOOTSTRAP_NOT_PRIVILEGED; } - job_log(j, LOG_DEBUG, "Transferring sub-bootstrap to the per session launchd."); + job_log(j, LOG_NOTICE, "Transferring sub-bootstrap to the per session launchd."); outdata_obj_array = launch_data_alloc(LAUNCH_DATA_ARRAY); if (!job_assumes(j, outdata_obj_array)) { @@ -6944,6 +6871,8 @@ continue; } + jobmgr_log(j->mgr, LOG_NOTICE, "%s(%s, ...): Packing up %s for transfer...", __func__, j->label, ji->label); + SLIST_FOREACH(ms, &ji->machservices, sle) { if (job_assumes(j, (tmp_dict = launch_data_alloc(LAUNCH_DATA_DICTIONARY)))) { job_assumes(j, launch_data_array_set_index(outdata_obj_array, tmp_dict, cnt2)); @@ -7013,6 +6942,7 @@ mig_deallocate((vm_address_t)ports, cnt * sizeof(ports[0])); } + return BOOTSTRAP_NO_MEMORY; } @@ -7160,7 +7090,7 @@ uid_t kp_uid = kp.kp_eproc.e_pcred.p_ruid; if( ldc->euid == kp_euid ) { - job_log(j, LOG_WARNING, "Working around rdar://problem/5982485 and allowing job to set policy for PID %u. We should discuss having %s run under a per-user launchd.", target_pid, target_j->label); + job_log(j, LOG_DEBUG, "Working around rdar://problem/5982485 and allowing job to set policy for PID %u.", target_pid); } else { job_log(j, LOG_ERR, "Denied Mach service policy update requested by UID/EUID %u/%u against PID %u with UID/EUID %u/%u due to mismatched credentials.", ldc->uid, ldc->euid, target_pid, kp_uid, kp_euid); @@ -7236,8 +7166,6 @@ } } - job_reparent_hack(jr, NULL); - if (pid1_magic) { jr->mach_uid = ldc->uid; } @@ -7352,6 +7280,102 @@ return true; } +kern_return_t +job_mig_lookup_children(job_t j, mach_port_array_t *child_ports, unsigned int *child_ports_cnt, name_array_t *child_names, unsigned int *child_names_cnt) +{ + kern_return_t kr = BOOTSTRAP_NO_MEMORY; + if( !launchd_assumes(j != NULL) ) { + return BOOTSTRAP_NO_MEMORY; + } + + unsigned int cnt = 0; + + jobmgr_t jmr = j->mgr; + jobmgr_t jmi = NULL; + SLIST_FOREACH( jmi, &jmr->submgrs, sle ) { + cnt++; + } + + job_t ji = NULL; + LIST_FOREACH( ji, &jmr->jobs, sle ) { + if( ji->per_user ) { + cnt++; + } + } + + if( cnt == 0 ) { + return BOOTSTRAP_NO_CHILDREN; + } + + mach_port_array_t _child_ports = NULL; + mig_allocate((vm_address_t *)&_child_ports, cnt * sizeof(_child_ports[0])); + if( !job_assumes(j, _child_ports != NULL) ) { + kr = BOOTSTRAP_NO_MEMORY; + goto out_bad; + } + + name_array_t _child_names = NULL; + mig_allocate((vm_address_t *)&_child_names, cnt * sizeof(_child_names[0])); + if( !job_assumes(j, _child_ports != NULL) ) { + kr = BOOTSTRAP_NO_MEMORY; + goto out_bad; + } + + unsigned int cnt2 = 0; + SLIST_FOREACH( jmi, &jmr->submgrs, sle ) { + if( jobmgr_assumes(jmi, launchd_mport_make_send(jmi->jm_port)) == KERN_SUCCESS ) { + _child_ports[cnt2] = jmi->jm_port; + } else { + _child_ports[cnt2] = MACH_PORT_NULL; + } + + strlcpy(_child_names[cnt2], jmi->name, sizeof(_child_names[0])); + cnt2++; + } + + LIST_FOREACH( ji, &jmr->jobs, sle ) { + if( ji->per_user ) { + if( job_assumes(ji, SLIST_FIRST(&ji->machservices)->per_user_hack == true) ) { + mach_port_t port = machservice_port(SLIST_FIRST(&ji->machservices)); + + if( job_assumes(ji, launchd_mport_copy_send(port)) == KERN_SUCCESS ) { + _child_ports[cnt2] = port; + } else { + _child_ports[cnt2] = MACH_PORT_NULL; + } + } else { + _child_ports[cnt2] = MACH_PORT_NULL; + } + + strlcpy(_child_names[cnt2], ji->label, sizeof(_child_names[0])); + cnt2++; + } + } + + *child_names_cnt = cnt; + *child_ports_cnt = cnt; + + *child_names = _child_names; + *child_ports = _child_ports; + + unsigned int i = 0; + for( i = 0; i < cnt; i++ ) { + job_log(j, LOG_DEBUG, "child_names[%u] = %s", i, (char *)_child_names[i]); + } + + return BOOTSTRAP_SUCCESS; +out_bad: + if( _child_ports ) { + mig_deallocate((vm_address_t)_child_ports, cnt * sizeof(_child_ports[0])); + } + + if( _child_names ) { + mig_deallocate((vm_address_t)_child_names, cnt * sizeof(_child_ports[0])); + } + + return kr; +} + void mspolicy_setup(launch_data_t obj, const char *key, void *context) { Modified: branches/PR-6046664/launchd/src/launchd_runtime.c =================================================================== --- branches/PR-6046664/launchd/src/launchd_runtime.c 2008-09-30 22:09:48 UTC (rev 23716) +++ branches/PR-6046664/launchd/src/launchd_runtime.c 2008-09-30 22:33:12 UTC (rev 23717) @@ -816,6 +816,12 @@ } INTERNAL_ABI kern_return_t +launchd_mport_copy_send(mach_port_t name) +{ + return errno = mach_port_insert_right(mach_task_self(), name, name, MACH_MSG_TYPE_COPY_SEND); +} + +INTERNAL_ABI kern_return_t launchd_mport_close_recv(mach_port_t name) { return errno = mach_port_mod_refs(mach_task_self(), name, MACH_PORT_RIGHT_RECEIVE, -1); Modified: branches/PR-6046664/launchd/src/launchd_runtime.h =================================================================== --- branches/PR-6046664/launchd/src/launchd_runtime.h 2008-09-30 22:09:48 UTC (rev 23716) +++ branches/PR-6046664/launchd/src/launchd_runtime.h 2008-09-30 22:33:12 UTC (rev 23717) @@ -106,7 +106,7 @@ extern bool pid1_magic; extern bool low_level_debug; -extern char g_username[128]; +extern char *g_username; INTERNAL_ABI mach_port_t runtime_get_kernel_port(void); @@ -174,6 +174,7 @@ INTERNAL_ABI kern_return_t launchd_mport_create_recv(mach_port_t *name); INTERNAL_ABI kern_return_t launchd_mport_deallocate(mach_port_t name); INTERNAL_ABI kern_return_t launchd_mport_make_send(mach_port_t name); +INTERNAL_ABI kern_return_t launchd_mport_copy_send(mach_port_t name); INTERNAL_ABI kern_return_t launchd_mport_close_recv(mach_port_t name); #endif Modified: branches/PR-6046664/launchd/src/launchproxy.c =================================================================== --- branches/PR-6046664/launchd/src/launchproxy.c 2008-09-30 22:09:48 UTC (rev 23716) +++ branches/PR-6046664/launchd/src/launchproxy.c 2008-09-30 22:33:12 UTC (rev 23717) @@ -191,7 +191,7 @@ setpgid(0, 0); -#if HAVE_SECURITY +#if 0 if ((tmp = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_SESSIONCREATE)) && launch_data_get_bool(tmp)) { if (SessionCreate) { OSStatus scr = SessionCreate(0, 0); Modified: branches/PR-6046664/launchd/src/libbootstrap.c =================================================================== --- branches/PR-6046664/launchd/src/libbootstrap.c 2008-09-30 22:09:48 UTC (rev 23716) +++ branches/PR-6046664/launchd/src/libbootstrap.c 2008-09-30 22:33:12 UTC (rev 23717) @@ -18,6 +18,7 @@ * @APPLE_APACHE_LICENSE_HEADER_END@ */ +#include <stdlib.h> #include "config.h" #include "libbootstrap_public.h" #include "libbootstrap_private.h" @@ -56,6 +57,7 @@ kern_return_t bootstrap_subset(mach_port_t bp, mach_port_t requestor_port, mach_port_t *subset_port) { + _vproc_log(LOG_NOTICE, "%s(): Called by %s.", __func__, getprogname()); return vproc_mig_subset(bp, requestor_port, subset_port); } @@ -88,6 +90,56 @@ } kern_return_t +bootstrap_lookup_children(mach_port_t bp, mach_port_array_t *children, name_array_t *names, mach_msg_type_number_t *n_children) +{ + mach_msg_type_number_t junk = 0; + return vproc_mig_lookup_children(bp, children, &junk, names, n_children); +} + +kern_return_t +bootstrap_lookup_per_user_context(mach_port_t bp, uid_t uid, char *session_type __attribute__((unused)), mach_port_t *puc) +{ + return vproc_mig_lookup_per_user_context(bp, uid, puc); +} + +kern_return_t bootstrap_lookup_local_per_user_context(mach_port_t bp, mach_port_t *puc) +{ + return vproc_mig_lookup_local_per_user_context(bp, puc); +} + +kern_return_t +bootstrap_root(mach_port_t *rbsp) +{ + mach_port_t last_bsport = MACH_PORT_NULL; + mach_port_t _rbsp = bootstrap_port; + kern_return_t result = KERN_FAILURE; + + do { + last_bsport = _rbsp; + result = bootstrap_parent(last_bsport, &_rbsp); + + if( result == BOOTSTRAP_NOT_PRIVILEGED ) { + syslog(LOG_ERR, "bootstrap_parent(): Permission denied.\n"); + _rbsp = MACH_PORT_NULL; + } else if( result != BOOTSTRAP_SUCCESS ) { + syslog(LOG_ERR, "bootstrap_parent() %d\n", result); + _rbsp = MACH_PORT_NULL; + } + + /* Even though last_bport being equal to _rbsp is the stopping point, we'll + * still get back another send right, and thus our reference count will be + * incremented by one, and we'll be responsible for releasing the additional + * reference. + */ + mach_port_mod_refs(mach_task_self(), last_bsport, MACH_PORT_RIGHT_SEND, -1); + } while( _rbsp != MACH_PORT_NULL && last_bsport != _rbsp ); + + *rbsp = _rbsp; + + return result; +} + +kern_return_t bootstrap_register(mach_port_t bp, name_t service_name, mach_port_t sp) { return bootstrap_register2(bp, service_name, sp, 0); @@ -237,7 +289,6 @@ mach_port_deallocate(mach_task_self(), *sp); kr = BOOTSTRAP_NOT_PRIVILEGED; } - } return kr; @@ -265,12 +316,9 @@ } kern_return_t -bootstrap_info(mach_port_t bp, - name_array_t *service_names, mach_msg_type_number_t *service_namesCnt, - bootstrap_status_array_t *service_active, mach_msg_type_number_t *service_activeCnt) +bootstrap_info(mach_port_t bp, name_array_t *service_names, mach_msg_type_number_t *service_namesCnt, bootstrap_status_array_t *service_active, mach_msg_type_number_t *service_activeCnt) { - return vproc_mig_info(bp, service_names, service_namesCnt, - service_active, service_activeCnt); + return vproc_mig_info(bp, service_names, service_namesCnt, service_active, service_activeCnt); } const char * Modified: branches/PR-6046664/launchd/src/libbootstrap_private.h =================================================================== --- branches/PR-6046664/launchd/src/libbootstrap_private.h 2008-09-30 22:09:48 UTC (rev 23716) +++ branches/PR-6046664/launchd/src/libbootstrap_private.h 2008-09-30 22:33:12 UTC (rev 23717) @@ -42,6 +42,14 @@ kern_return_t bootstrap_set_policy(mach_port_t bp, pid_t target_pid, uint64_t flags, const char *target_service); +kern_return_t bootstrap_lookup_children(mach_port_t bp, mach_port_array_t *children, name_array_t *names, mach_msg_type_number_t *n_children); + +kern_return_t bootstrap_lookup_per_user_context(mach_port_t bp, uid_t uid, char *session_type __attribute__((unused)), mach_port_t *puc); + +kern_return_t bootstrap_lookup_local_per_user_context(mach_port_t bp, mach_port_t *puc); + +kern_return_t bootstrap_root(mach_port_t *rbsp); + #pragma GCC visibility pop __END_DECLS Modified: branches/PR-6046664/launchd/src/libbootstrap_public.h =================================================================== --- branches/PR-6046664/launchd/src/libbootstrap_public.h 2008-09-30 22:09:48 UTC (rev 23716) +++ branches/PR-6046664/launchd/src/libbootstrap_public.h 2008-09-30 22:33:12 UTC (rev 23717) @@ -102,12 +102,13 @@ #define BOOTSTRAP_MAX_LOOKUP_COUNT 20 #define BOOTSTRAP_SUCCESS 0 -#define BOOTSTRAP_NOT_PRIVILEGED 1100 -#define BOOTSTRAP_NAME_IN_USE 1101 -#define BOOTSTRAP_UNKNOWN_SERVICE 1102 -#define BOOTSTRAP_SERVICE_ACTIVE 1103 +#define BOOTSTRAP_NOT_PRIVILEGED 1100 +#define BOOTSTRAP_NAME_IN_USE 1101 +#define BOOTSTRAP_UNKNOWN_SERVICE 1102 +#define BOOTSTRAP_SERVICE_ACTIVE 1103 #define BOOTSTRAP_BAD_COUNT 1104 #define BOOTSTRAP_NO_MEMORY 1105 +#define BOOTSTRAP_NO_CHILDREN 1106 #define BOOTSTRAP_STATUS_INACTIVE 0 #define BOOTSTRAP_STATUS_ACTIVE 1 Modified: branches/PR-6046664/launchd/src/libvproc.c =================================================================== --- branches/PR-6046664/launchd/src/libvproc.c 2008-09-30 22:09:48 UTC (rev 23716) +++ branches/PR-6046664/launchd/src/libvproc.c 2008-09-30 22:33:12 UTC (rev 23717) @@ -260,8 +260,7 @@ } kern_return_t -_vproc_grab_subset(mach_port_t bp, mach_port_t *reqport, mach_port_t *rcvright, launch_data_t *outval, - mach_port_array_t *ports, mach_msg_type_number_t *portCnt) +_vproc_grab_subset(mach_port_t bp, mach_port_t *reqport, mach_port_t *rcvright, launch_data_t *outval, mach_port_array_t *ports, mach_msg_type_number_t *portCnt) { mach_msg_type_number_t outdata_cnt; vm_offset_t outdata = 0; @@ -325,6 +324,10 @@ return (vproc_err_t)_vprocmgr_move_subset_to_user; } + _vproc_log(LOG_NOTICE, "%s(%u, %s): %s, uid = %u", __func__, target_user, session_type, getprogname(), getuid()); + + _vproc_log(LOG_NOTICE, "%s(%u, %s): %s", __func__, target_user, session_type, getprogname()); + if (!is_bkgd && ldpid != 1) { if (lduid == getuid()) { return NULL; @@ -336,25 +339,42 @@ return (vproc_err_t)_vprocmgr_move_subset_to_user; } - if (is_bkgd || target_user) { - mach_port_t puc = 0, rootbs = get_root_bootstrap_port(); +#if 0 + mach_port_t puc = 0, rootbs = get_root_bootstrap_port(); - if (vproc_mig_lookup_per_user_context(rootbs, target_user, &puc) != 0) { - return (vproc_err_t)_vprocmgr_move_subset_to_user; - } + if (vproc_mig_lookup_per_user_context(rootbs, target_user, &puc) != 0) { + return (vproc_err_t)_vprocmgr_move_subset_to_user; + } - if (is_bkgd) { - task_set_bootstrap_port(mach_task_self(), puc); - mach_port_deallocate(mach_task_self(), bootstrap_port); - bootstrap_port = puc; - } else { - kr = vproc_mig_move_subset(puc, bootstrap_port, (char *)session_type); - mach_port_deallocate(mach_task_self(), puc); - } + if( ldpid == 1 ) { + _vproc_log(LOG_NOTICE, "%s(): %s: ldpid = %llu, lduid = %llu, moving subset to per-user bootstrap.", __func__, getprogname(), ldpid, lduid); + kr = vproc_mig_move_subset(puc, bootstrap_port, VPROCMGR_SESSION_BACKGROUND); + mach_port_deallocate(mach_task_self(), puc); } else { - kr = _vprocmgr_init(session_type) ? 1 : 0; + _vproc_log(LOG_NOTICE, "%s(): %s: ldpid = %llu, lduid = %llu, swapping bootstrap_port and puc.", __func__, getprogname(), ldpid, lduid); + task_set_bootstrap_port(mach_task_self(), puc); + mach_port_deallocate(mach_task_self(), bootstrap_port); + bootstrap_port = puc; } +#else + mach_port_t puc = 0, rootbs = get_root_bootstrap_port(); + _vproc_log(LOG_NOTICE, "%s(%u, %s): Looking up per-user context...", __func__, target_user, session_type); + if (vproc_mig_lookup_per_user_context(rootbs, target_user, &puc) != 0) { + return (vproc_err_t)_vprocmgr_move_subset_to_user; + } + + if (is_bkgd) { + _vproc_log(LOG_NOTICE, "%s(%u, %s): Background session, swapping bootstrap_port with puc.", __func__, target_user, session_type); + task_set_bootstrap_port(mach_task_self(), puc); + mach_port_deallocate(mach_task_self(), bootstrap_port); + bootstrap_port = puc; + } else { + _vproc_log(LOG_NOTICE, "%s(%u, %s): Moving subset...", __func__, target_user, session_type); + kr = vproc_mig_move_subset(puc, bootstrap_port, (char *)session_type); + mach_port_deallocate(mach_task_self(), puc); + } +#endif cached_pid = -1; if (kr) { Modified: branches/PR-6046664/launchd/src/protocol_job.defs =================================================================== --- branches/PR-6046664/launchd/src/protocol_job.defs 2008-09-30 22:09:48 UTC (rev 23716) +++ branches/PR-6046664/launchd/src/protocol_job.defs 2008-09-30 22:33:12 UTC (rev 23717) @@ -35,148 +35,157 @@ type mach_port_move_send_array_t = array[] of mach_port_move_send_t ctype: mach_port_array_t; +type mach_port_make_send_array_t = array[] of mach_port_make_send_t + ctype: mach_port_array_t; userprefix vproc_mig_; serverprefix job_mig_; routine create_server( - __bs_port : job_t; - __server_cmd : cmd_t; - __server_uid : uid_t; - __on_demand : boolean_t; - out __server_port : mach_port_make_send_t); + __bs_port : job_t; + __server_cmd : cmd_t; + __server_uid : uid_t; + __on_demand : boolean_t; +out __server_port : mach_port_make_send_t); routine reboot2( - __bs_port : job_t; - __flags : uint64_t); + __bs_port : job_t; + __flags : uint64_t); routine check_in2( - __bs_port : job_t; - __service_name : name_t; - out __service_port : mach_port_move_receive_t; - __flags : uint64_t); + __bs_port : job_t; + __service_name : name_t; +out __service_port : mach_port_move_receive_t; + __flags : uint64_t); routine register2( - __bs_port : job_t; - __service_name : name_t; - __service_port : mach_port_t; - __flags : uint64_t); + __bs_port : job_t; + __service_name : name_t; + __service_port : mach_port_t; + __flags : uint64_t); routine look_up2( - __bs_port : job_t; - sreplyport __rport : mach_port_make_send_once_t; - __service_name : name_t; - out __service_port : mach_port_t; - UserAuditToken __server_cred: audit_token_t; - __target_pid : pid_t; - __flags : uint64_t); + __bs_port : job_t; +sreplyport __rport : mach_port_make_send_once_t; + __service_name : name_t; +out __service_port : mach_port_t; +UserAuditToken __server_cred : audit_token_t; + __target_pid : pid_t; + __flags : uint64_t); routine send_signal( - __bs_port : job_t; - sreplyport __rport : mach_port_make_send_once_t; - __label : name_t; - __signal : integer_t); + __bs_port : job_t; +sreplyport __rport : mach_port_make_send_once_t; + __label : name_t; + __signal : integer_t); routine parent( - __bs_port : job_t; - sreplyport __rport : mach_port_make_send_once_t; - out __parent_port : mach_port_make_send_t); + __bs_port : job_t; +sreplyport __rport : mach_port_make_send_once_t; +out __parent_port : mach_port_make_send_t); routine post_fork_ping( - __bs_port : job_t; - __task_port : task_t); + __bs_port : job_t; + __task_port : task_t); routine info( - __bs_port : job_t; - out __service_names : name_array_t, dealloc; - out __service_active : bootstrap_status_array_t, dealloc); + __bs_port : job_t; +out __service_names : name_array_t, dealloc; +out __service_active : bootstrap_status_array_t, dealloc); routine subset( - __bs_port : job_t; - __requestor_port: mach_port_t; - out __subset_port : mach_port_make_send_t); + __bs_port : job_t; + __requestor_port : mach_port_t; +out __subset_port : mach_port_make_send_t); routine setup_shmem( - __bs_port : job_t; - out __shmem_port : mach_port_move_send_t); + __bs_port : job_t; +out __shmem_port : mach_port_move_send_t); routine take_subset( - __bs_port : job_t; - out __bs_reqport : mach_port_move_send_t; - out __bs_rcvright : mach_port_move_receive_t; - out __outdata : pointer_t, dealloc; - out __service_ports : mach_port_move_send_array_t, dealloc); + __bs_port : job_t; +out __bs_reqport : mach_port_move_send_t; +out __bs_rcvright : mach_port_move_receive_t; +out __outdata : pointer_t, dealloc; +out __service_ports : mach_port_move_send_array_t, dealloc); routine getsocket( - __bs_port : job_t; - out __sockpath : name_t); + __bs_port : job_t; +out __sockpath : name_t); routine spawn( - __bs_port : job_t; - __indata : pointer_t; - out __pid : pid_t; - out __obsvr_port : mach_port_make_send_t); + __bs_port : job_t; + __indata : pointer_t; +out __pid : pid_t; +out __obsvr_port : mach_port_make_send_t); routine wait( - __bs_port : job_t; - sreplyport __rport : mach_port_make_send_once_t; - out __waitval : integer_t); + __bs_port : job_t; +sreplyport __rport : mach_port_make_send_once_t; +out __waitval : integer_t); routine uncork_fork( - __bs_port : job_t); + __bs_port : job_t); routine swap_integer( - __bs_port : job_t; - __inkey : vproc_gsk_t; - __outkey : vproc_gsk_t; - __inval : int64_t; - out __outval : int64_t); + __bs_port : job_t; + __inkey : vproc_gsk_t; + __outkey : vproc_gsk_t; + __inval : int64_t; +out __outval : int64_t); routine set_service_policy( - __bs_port : job_t; - __target_pid : pid_t; - __flags : uint64_t; - __service : name_t); + __bs_port : job_t; + __target_pid : pid_t; + __flags : uint64_t; + __service : name_t); routine log( - __bs_port : job_t; - __pri : integer_t; - __err : integer_t; - __msg : logmsg_t); + __bs_port : job_t; + __pri : integer_t; + __err : integer_t; + __msg : logmsg_t); routine lookup_per_user_context( - __bs_port : job_t; - __wu : uid_t; - out __u_cont : mach_port_t); + __bs_port : job_t; +sreplyport __rport : mach_port_make_send_once_t; + __wu : uid_t; +out __u_cont : mach_port_move_send_t); routine move_subset( - __bs_port : job_t; - __target_port : mach_port_t; - __sessiontype : name_t); + __bs_port : job_t; + __target_port : mach_port_t; + __sessiontype : name_t); routine swap_complex( - __bs_port : job_t; - __inkey : vproc_gsk_t; - __outkey : vproc_gsk_t; - __inval : pointer_t; - out __outval : pointer_t, dealloc); + __bs_port : job_t; + __inkey : vproc_gsk_t; + __outkey : vproc_gsk_t; + __inval : pointer_t; +out __outval : pointer_t, dealloc); routine log_drain( - __bs_port : job_t; - sreplyport __rport : mach_port_make_send_once_t; - out __outval : pointer_t, dealloc); + __bs_port : job_t; +sreplyport __rport : mach_port_make_send_once_t; +out __outval : pointer_t, dealloc); routine log_forward( - __bs_port : job_t; - __inval : pointer_t); + __bs_port : job_t; + __inval : pointer_t); routine embedded_kickstart( - __bs_port : job_t; - __label : name_t; - out __pid : pid_t; - out __name_port : mach_port_t); + __bs_port : job_t; + __label : name_t; +out __pid : pid_t; +out __name_port : mach_port_t); routine embedded_wait( - __bs_port : job_t; - __label : name_t; - out __waitval : integer_t); + __bs_port : job_t; + __label : name_t; +out __waitval : integer_t); + +routine lookup_children( + __bs_port : job_t; +out __child_ports : mach_port_move_send_array_t, dealloc; +out __child_names : name_array_t, dealloc); + Modified: branches/PR-6046664/launchd/src/protocol_job_forward.defs =================================================================== --- branches/PR-6046664/launchd/src/protocol_job_forward.defs 2008-09-30 22:09:48 UTC (rev 23716) +++ branches/PR-6046664/launchd/src/protocol_job_forward.defs 2008-09-30 22:33:12 UTC (rev 23717) @@ -39,15 +39,43 @@ skip; /* register2 */ simpleroutine look_up2_forward( - __bs_port : job_t; - replyport __rport : mach_port_move_send_once_t; - __service_name : name_t; - __target_pid : pid_t; - __flags : uint64_t); + __bs_port : job_t; +replyport __rport : mach_port_move_send_once_t; + __service_name : name_t; + __target_pid : pid_t; + __flags : uint64_t); skip; /* send_signal */ simpleroutine parent_forward( - __bs_port : job_t; - replyport __rport : mach_port_move_send_once_t); + __bs_port : job_t; +replyport __rport : mach_port_move_send_once_t); +skip; /* post_fork_ping */ + +skip; /* info */ + +skip; /* subset */ + +skip; /* setup_shmem */ + +skip; /* take_subset */ + +skip; /* getsocket */ + +skip; /* spawn */ + +skip; /* wait */ + +skip; /* uncork_fork */ + +skip; /* swap_integer */ + +skip; /* set_service_policy */ + +skip; /* log */ + +simpleroutine lookup_per_user_context_forward( + __bs_port : job_t; +replyport __rport : mach_port_move_send_once_t; + __wu : uid_t); Modified: branches/PR-6046664/launchd/src/protocol_job_reply.defs =================================================================== --- branches/PR-6046664/launchd/src/protocol_job_reply.defs 2008-09-30 22:09:48 UTC (rev 23716) +++ branches/PR-6046664/launchd/src/protocol_job_reply.defs 2008-09-30 22:33:12 UTC (rev 23717) @@ -70,7 +70,7 @@ skip; /* log */ -skip; /* lookup_per_user_context */ +skip; /* lookup_per_user_context_reply */ skip; /* move_subset */ @@ -79,4 +79,4 @@ simpleroutine job_mig_log_drain_reply( __r_port : mach_port_move_send_once_t; __result : kern_return_t, RetCode; - __outval : pointer_t); + __outval : pointer_t);
participants (1)
-
source_changes@macosforge.org