[launchd-changes] [22944] trunk/launchd/src
source_changes at macosforge.org
source_changes at macosforge.org
Tue Nov 14 14:49:00 PST 2006
Revision: 22944
http://trac.macosforge.org/projects/launchd/changeset/22944
Author: zarzycki at apple.com
Date: 2006-11-14 14:48:59 -0800 (Tue, 14 Nov 2006)
Log Message:
-----------
<rdar://problem/4836935> rejigger GUI application into the GUI session, regardless of which session they really are spawned in
Modified Paths:
--------------
trunk/launchd/src/launchctl.c
trunk/launchd/src/launchd.c
trunk/launchd/src/launchd.h
trunk/launchd/src/launchd_core_logic.c
trunk/launchd/src/liblaunch.c
trunk/launchd/src/libvproc.c
trunk/launchd/src/libvproc_internal.h
trunk/launchd/src/protocol_job.defs
trunk/launchd/src/protocol_job_reply.defs
Modified: trunk/launchd/src/launchctl.c
===================================================================
--- trunk/launchd/src/launchctl.c 2006-11-13 20:53:23 UTC (rev 22943)
+++ trunk/launchd/src/launchctl.c 2006-11-14 22:48:59 UTC (rev 22944)
@@ -63,6 +63,7 @@
#include <sysexits.h>
#include "libbootstrap_public.h"
+#include "libvproc_public.h"
#include "libvproc_internal.h"
#include "liblaunch_public.h"
#include "liblaunch_private.h"
@@ -534,6 +535,13 @@
goto out_bad;
}
+ if (lus->session_type && !(tmpa = launch_data_dict_lookup(thejob, LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE))) {
+ fprintf(stderr, "%s: Missing key \"%s\", defaulting value to \"Aqua\"\n", getprogname(),
+ LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE);
+ tmpa = launch_data_new_string("Aqua");
+ launch_data_dict_insert(thejob, tmpa, LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE);
+ }
+
if ((tmpa = launch_data_dict_lookup(thejob, LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE))) {
const char *allowed_session;
bool skipjob = true;
Modified: trunk/launchd/src/launchd.c
===================================================================
--- trunk/launchd/src/launchd.c 2006-11-13 20:53:23 UTC (rev 22943)
+++ trunk/launchd/src/launchd.c 2006-11-14 22:48:59 UTC (rev 22944)
@@ -65,6 +65,7 @@
#include <setjmp.h>
#include "libbootstrap_public.h"
+#include "libvproc_public.h"
#include "libvproc_internal.h"
#include "liblaunch_public.h"
#include "liblaunch_private.h"
@@ -122,9 +123,6 @@
};
struct sigaction fsa;
bool sflag = false, dflag = false, Dflag = false;
- mach_msg_type_number_t l2l_name_cnt = 0, l2l_port_cnt = 0;
- name_array_t l2l_names = NULL;
- mach_port_array_t l2l_ports = NULL;
char ldconf[PATH_MAX] = PID1LAUNCHD_CONF;
const char *h = getenv("HOME");
const char *session_type = NULL;
@@ -133,7 +131,6 @@
struct stat sb;
size_t i, checkin_fdcnt = 0;
int *checkin_fds = NULL;
- mach_port_t req_mport = MACH_PORT_NULL;
mach_port_t checkin_mport = MACH_PORT_NULL;
int ch, ker, logopts;
@@ -247,30 +244,8 @@
/* sigh... ignoring SIGCHLD has side effects: we can't call wait*() */
launchd_assert(kevent_mod(SIGCHLD, EVFILT_SIGNAL, EV_ADD, 0, 0, &kqsignal_callback) != -1);
- if (session_type && strcmp(session_type, "Aqua") == 0) {
- mach_port_t newparent;
+ mach_init_init(checkin_mport);
- launchd_assert(bootstrap_parent(bootstrap_port, &newparent) == BOOTSTRAP_SUCCESS);
-
- launchd_assert(_launchd_to_launchd(bootstrap_port, &req_mport, &checkin_mport,
- &l2l_names, &l2l_name_cnt, &l2l_ports, &l2l_port_cnt) == BOOTSTRAP_SUCCESS);
-
- launchd_assert(l2l_name_cnt == l2l_port_cnt);
-
- task_set_bootstrap_port(mach_task_self(), newparent);
- launchd_assumes(mach_port_deallocate(mach_task_self(), bootstrap_port) == KERN_SUCCESS);
- bootstrap_port = newparent;
- }
-
- mach_init_init(req_mport, checkin_mport, l2l_names, l2l_ports, l2l_name_cnt);
-
- if (l2l_names) {
- mig_deallocate((vm_address_t)l2l_names, l2l_name_cnt * sizeof(l2l_names[0]));
- }
- if (l2l_ports) {
- mig_deallocate((vm_address_t)l2l_ports, l2l_port_cnt * sizeof(l2l_ports[0]));
- }
-
if (h) {
snprintf(ldconf, sizeof(ldconf), "%s/%s", h, LAUNCHD_CONF);
}
Modified: trunk/launchd/src/launchd.h
===================================================================
--- trunk/launchd/src/launchd.h 2006-11-13 20:53:23 UTC (rev 22943)
+++ trunk/launchd/src/launchd.h 2006-11-14 22:48:59 UTC (rev 22944)
@@ -59,7 +59,7 @@
void catatonia(void);
void mach_start_shutdown(void);
-void mach_init_init(mach_port_t, mach_port_t, name_array_t, mach_port_array_t, mach_msg_type_number_t);
+void mach_init_init(mach_port_t);
int _fd(int fd);
Modified: trunk/launchd/src/launchd_core_logic.c
===================================================================
--- trunk/launchd/src/launchd_core_logic.c 2006-11-13 20:53:23 UTC (rev 22943)
+++ trunk/launchd/src/launchd_core_logic.c 2006-11-14 22:48:59 UTC (rev 22944)
@@ -74,6 +74,7 @@
#include "liblaunch_public.h"
#include "liblaunch_private.h"
#include "libbootstrap_public.h"
+#include "libvproc_public.h"
#include "libvproc_internal.h"
#include "launchd.h"
@@ -288,6 +289,7 @@
static bool job_setup_machport(job_t j);
static void job_postfork_become_user(job_t j);
static void job_force_sampletool(job_t j);
+static void job_reparent_to_aqua_hack(job_t j);
static void job_callback(void *obj, struct kevent *kev);
static launch_data_t job_export2(job_t j, bool subjobs);
static job_t job_new_spawn(job_t j, const char *label, const char *path, const char *workingdir, const char *const *argv, const char *const *env, mode_t *u_mask, bool w4d, bool fppc);
@@ -815,7 +817,7 @@
{
job_t jr;
- if ((jr = jobmgr_find(j->mgr, label)) != NULL) {
+ if ((jr = jobmgr_find(root_jobmgr, label)) != NULL) {
errno = EEXIST;
return NULL;
}
@@ -826,6 +828,8 @@
return NULL;
}
+ job_reparent_to_aqua_hack(jr);
+
if (getpid() == 1) {
struct ldcred ldc;
@@ -1097,6 +1101,9 @@
} else if (strcasecmp(key, LAUNCH_JOBKEY_LIMITLOADFROMHOSTS) == 0) {
return;
} else if (strcasecmp(key, LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE) == 0) {
+ if (strcmp(value, "Aqua") == 0) {
+ job_reparent_to_aqua_hack(j);
+ }
return;
}
break;
@@ -3705,8 +3712,8 @@
runtime_get_caller_creds(&ldc);
- if (ldc.uid != 0) {
- which_user = ldc.uid;
+ if (ldc.euid || ldc.uid) {
+ which_user = ldc.euid ? ldc.euid : ldc.uid;
}
if (which_user == 0) {
@@ -3940,6 +3947,10 @@
}
}
+ if (cnt == 0) {
+ goto out;
+ }
+
mig_allocate((vm_address_t *)&service_names, cnt * sizeof(service_names[0]));
if (!launchd_assumes(service_names != NULL)) {
goto out_bad;
@@ -3960,6 +3971,7 @@
launchd_assumes(cnt == cnt2);
+out:
*servicenamesp = service_names;
*serviceactivesp = service_actives;
*servicenames_cnt = *serviceactives_cnt = cnt;
@@ -3977,8 +3989,76 @@
return BOOTSTRAP_NO_MEMORY;
}
+
+void
+job_reparent_to_aqua_hack(job_t j)
+{
+ jobmgr_t jmi = NULL;
+
+ SLIST_FOREACH(jmi, &root_jobmgr->submgrs, sle) {
+ if (strcmp(jmi->name, "Aqua") == 0) {
+ break;
+ }
+ }
+
+ if (job_assumes(j, jmi != NULL)) {
+ SLIST_REMOVE(&j->mgr->jobs, j, job_s, sle);
+ SLIST_INSERT_HEAD(&jmi->jobs, j, sle);
+ j->mgr = jmi;
+ }
+}
+
kern_return_t
-job_mig_transfer_subset(job_t j, mach_port_t *reqport, mach_port_t *rcvright,
+job_mig_move_subset_to_user(job_t j, mach_port_t target_subset)
+{
+ mach_msg_type_number_t l2l_i, l2l_name_cnt = 0, l2l_port_cnt = 0;
+ name_array_t l2l_names = NULL;
+ mach_port_array_t l2l_ports = NULL;
+ mach_port_t reqport, rcvright;
+ kern_return_t kr;
+ jobmgr_t jmr;
+
+ kr = _vproc_grab_subset(target_subset, &reqport,
+ &rcvright, &l2l_names, &l2l_name_cnt, &l2l_ports, &l2l_port_cnt);
+
+ if (job_assumes(j, kr == 0)) {
+ job_assumes(j, launchd_mport_deallocate(target_subset) == KERN_SUCCESS);
+ } else {
+ goto out;
+ }
+
+ launchd_assert(l2l_name_cnt == l2l_port_cnt);
+
+ if ((jmr = jobmgr_new(j->mgr, reqport, rcvright)) == NULL) {
+ kr = BOOTSTRAP_NO_MEMORY;
+ goto out;
+ }
+
+ strcpy(jmr->name, "Aqua");
+
+ for (l2l_i = 0; l2l_i < l2l_name_cnt; l2l_i++) {
+ struct machservice *ms;
+
+ if ((ms = machservice_new(jmr->anonj, l2l_names[l2l_i], &l2l_ports[l2l_i]))) {
+ machservice_watch(ms);
+ }
+ }
+
+ kr = 0;
+
+out:
+ if (l2l_names) {
+ mig_deallocate((vm_address_t)l2l_names, l2l_name_cnt * sizeof(l2l_names[0]));
+ }
+ if (l2l_ports) {
+ mig_deallocate((vm_address_t)l2l_ports, l2l_port_cnt * sizeof(l2l_ports[0]));
+ }
+
+ return kr;
+}
+
+kern_return_t
+job_mig_take_subset(job_t j, mach_port_t *reqport, mach_port_t *rcvright,
name_array_t *servicenamesp, unsigned int *servicenames_cnt,
mach_port_array_t *portsp, unsigned int *ports_cnt)
{
@@ -4165,18 +4245,18 @@
const char *path = NULL;
const char *workingdir = NULL;
size_t argv_i = 0, env_i = 0;
+ struct ldcred ldc;
+ runtime_get_caller_creds(&ldc);
+
if (!launchd_assumes(j != NULL)) {
return BOOTSTRAP_NO_MEMORY;
}
-#if 0
- if (ldc.asid != inherited_asid) {
- job_log(j, LOG_ERR, "Security: PID %d (ASID %d) was denied a request to spawn a process in this session (ASID %d)",
- ldc.pid, ldc.asid, inherited_asid);
- return BOOTSTRAP_NOT_PRIVILEGED;
+ if (getpid() == 1 && ldc.euid && ldc.uid) {
+ job_log(j, LOG_DEBUG, "Punting spawn to per-user-context");
+ return VPROC_ERR_TRY_PER_USER;
}
-#endif
argv = alloca((argc + 1) * sizeof(char *));
memset(argv, 0, (argc + 1) * sizeof(char *));
@@ -4270,17 +4350,15 @@
}
void
-mach_init_init(mach_port_t req_port, mach_port_t checkin_port,
- name_array_t l2l_names, mach_port_array_t l2l_ports, mach_msg_type_number_t l2l_cnt)
+mach_init_init(mach_port_t checkin_port)
{
- mach_msg_type_number_t l2l_i;
auditinfo_t inherited_audit;
job_t ji, anon_job = NULL;
getaudit(&inherited_audit);
inherited_asid = inherited_audit.ai_asid;
- launchd_assert((root_jobmgr = jobmgr_new(NULL, req_port ? req_port : mach_task_self(), checkin_port)) != NULL);
+ launchd_assert((root_jobmgr = jobmgr_new(NULL, mach_task_self(), checkin_port)) != NULL);
SLIST_FOREACH(ji, &root_jobmgr->jobs, sle) {
if (ji->anonymous) {
@@ -4302,16 +4380,4 @@
/* cut off the Libc cache, we don't want to deadlock against ourself */
bootstrap_port = MACH_PORT_NULL;
-
- if (l2l_names == NULL) {
- return;
- }
-
- for (l2l_i = 0; l2l_i < l2l_cnt; l2l_i++) {
- struct machservice *ms;
-
- if ((ms = machservice_new(anon_job, l2l_names[l2l_i], &l2l_ports[l2l_i]))) {
- machservice_watch(ms);
- }
- }
}
Modified: trunk/launchd/src/liblaunch.c
===================================================================
--- trunk/launchd/src/liblaunch.c 2006-11-13 20:53:23 UTC (rev 22943)
+++ trunk/launchd/src/liblaunch.c 2006-11-14 22:48:59 UTC (rev 22944)
@@ -39,6 +39,7 @@
#include <pwd.h>
#include "libbootstrap_public.h"
+#include "libvproc_public.h"
#include "libvproc_internal.h"
/* __OSBogusByteSwap__() must not really exist in the symbol namespace
@@ -1188,31 +1189,25 @@
pid_t
create_and_switch_to_per_session_launchd(const char *login, int flags, ...)
{
- static char *const ldargv[] = { "/sbin/launchd", "-S", "Aqua", NULL };
char *largv[] = { "/bin/launchctl", "load", "-S", "Aqua", "-D", "all", "/etc/mach_init_per_user.d", NULL };
mach_port_t bezel_ui_server;
struct passwd *pwe;
struct stat sb;
int wstatus;
- name_t sp;
- pid_t p, ldp;
+ pid_t p;
uid_t u;
gid_t g;
+ if (_vproc_move_subset_to_user()) {
+ return -1;
+ }
+
if ((pwe = getpwnam(login)) == NULL)
return -1;
u = pwe->pw_uid;
g = pwe->pw_gid;
- if ((ldp = fexecv_as_user(login, u, g, ldargv)) == -1) {
- return -1;
- }
-
- while (_vprocmgr_getsocket(sp) != BOOTSTRAP_SUCCESS) {
- usleep(20000);
- }
-
if (flags & LOAD_ONLY_SAFEMODE_LAUNCHAGENTS) {
largv[5] = "system";
}
@@ -1245,5 +1240,5 @@
}
}
- return ldp;
+ return 1;
}
Modified: trunk/launchd/src/libvproc.c
===================================================================
--- trunk/launchd/src/libvproc.c 2006-11-13 20:53:23 UTC (rev 22943)
+++ trunk/launchd/src/libvproc.c 2006-11-14 22:48:59 UTC (rev 22944)
@@ -36,13 +36,28 @@
#include "protocol_vproc.h"
kern_return_t
-_launchd_to_launchd(mach_port_t bp, mach_port_t *reqport, mach_port_t *rcvright,
+_vproc_grab_subset(mach_port_t bp, mach_port_t *reqport, mach_port_t *rcvright,
name_array_t *service_names, mach_msg_type_number_t *service_namesCnt,
mach_port_array_t *ports, mach_msg_type_number_t *portCnt)
{
- return vproc_mig_transfer_subset(bp, reqport, rcvright, service_names, service_namesCnt, ports, portCnt);
+ return vproc_mig_take_subset(bp, reqport, rcvright, service_names, service_namesCnt, ports, portCnt);
}
+vproc_err_t
+_vproc_move_subset_to_user(void)
+{
+ kern_return_t kr = 1;
+ mach_port_t puc;
+
+ if (vproc_mig_lookup_per_user_context(bootstrap_port, 0, &puc) == 0) {
+ kr = vproc_mig_move_subset_to_user(puc, bootstrap_port);
+ mach_port_deallocate(mach_task_self(), puc);
+ }
+
+ return kr == 0 ? NULL : (vproc_err_t)_vproc_move_subset_to_user;
+}
+
+
pid_t
_spawn_via_launchd(const char *label, const char *const *argv, const struct spawn_via_launchd_attr *spawn_attrs, int struct_version)
{
@@ -112,6 +127,15 @@
kr = vproc_mig_spawn(bootstrap_port, buf, buf_len, argc, envc, flags, u_mask, &p, &obsvr_port);
+ if (kr == VPROC_ERR_TRY_PER_USER) {
+ mach_port_t puc;
+
+ if (vproc_mig_lookup_per_user_context(bootstrap_port, 0, &puc) == 0) {
+ kr = vproc_mig_spawn(puc, buf, buf_len, argc, envc, flags, u_mask, &p, &obsvr_port);
+ mach_port_deallocate(mach_task_self(), puc);
+ }
+ }
+
free(buf);
if (kr == BOOTSTRAP_SUCCESS) {
Modified: trunk/launchd/src/libvproc_internal.h
===================================================================
--- trunk/launchd/src/libvproc_internal.h 2006-11-13 20:53:23 UTC (rev 22943)
+++ trunk/launchd/src/libvproc_internal.h 2006-11-14 22:48:59 UTC (rev 22944)
@@ -48,12 +48,14 @@
#define SPAWN_WANTS_FORCE_PPC 0x0010
kern_return_t
-_launchd_to_launchd(mach_port_t bp, mach_port_t *reqport, mach_port_t *rcvright,
+_vproc_grab_subset(mach_port_t bp, mach_port_t *reqport, mach_port_t *rcvright,
name_array_t *service_names, mach_msg_type_number_t *service_namesCnt,
mach_port_array_t *ports, mach_msg_type_number_t *portCnt);
kern_return_t _vprocmgr_getsocket(name_t);
+vproc_err_t _vproc_move_subset_to_user(void);
+
void _vproc_logv(int pri, int err, const char *msg, va_list ap);
kern_return_t
Modified: trunk/launchd/src/protocol_job.defs
===================================================================
--- trunk/launchd/src/protocol_job.defs 2006-11-13 20:53:23 UTC (rev 22943)
+++ trunk/launchd/src/protocol_job.defs 2006-11-14 22:48:59 UTC (rev 22944)
@@ -81,7 +81,7 @@
__service_name : name_t;
out __service_port : mach_port_t);
-routine transfer_subset(
+routine take_subset(
__bs_port : job_t;
out __bs_reqport : mach_port_t;
out __bs_rcvright : mach_port_move_receive_t;
@@ -130,3 +130,7 @@
__bs_port : job_t;
__wu : uid_t;
out __u_cont : mach_port_t);
+
+routine move_subset_to_user(
+ __bs_port : job_t;
+ __target_port : mach_port_t);
Modified: trunk/launchd/src/protocol_job_reply.defs
===================================================================
--- trunk/launchd/src/protocol_job_reply.defs 2006-11-13 20:53:23 UTC (rev 22943)
+++ trunk/launchd/src/protocol_job_reply.defs 2006-11-14 22:48:59 UTC (rev 22944)
@@ -24,6 +24,7 @@
#include <mach/mach_types.defs>
#include "launchd_mig_types.defs"
import "libbootstrap_public.h";
+import "libvproc_public.h";
import "libvproc_internal.h";
skip; /* create_server */
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/launchd-changes/attachments/20061114/ae1cdb05/attachment.html
More information about the launchd-changes
mailing list