[launchd-changes] [23717] branches/PR-6046664/launchd/src
source_changes at macosforge.org
source_changes at macosforge.org
Tue Sep 30 15:33:13 PDT 2008
Revision: 23717
http://trac.macosforge.org/projects/launchd/changeset/23717
Author: dsorresso at 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);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/launchd-changes/attachments/20080930/b74c0145/attachment-0001.html
More information about the launchd-changes
mailing list