[launchd-changes] [23207] trunk/launchd/src
source_changes at macosforge.org
source_changes at macosforge.org
Thu Apr 5 14:14:12 PDT 2007
Revision: 23207
http://trac.macosforge.org/projects/launchd/changeset/23207
Author: zarzycki at apple.com
Date: 2007-04-05 14:14:11 -0700 (Thu, 05 Apr 2007)
Log Message:
-----------
<rdar://problem/4746572> SUBTASK: Changes to launchd's job management in support of Seatbelt
Modified Paths:
--------------
trunk/launchd/src/launchd_core_logic.c
trunk/launchd/src/libbootstrap.c
trunk/launchd/src/libbootstrap_private.h
trunk/launchd/src/liblaunch_public.h
trunk/launchd/src/protocol_job.defs
Modified: trunk/launchd/src/launchd_core_logic.c
===================================================================
--- trunk/launchd/src/launchd_core_logic.c 2007-04-05 18:45:08 UTC (rev 23206)
+++ trunk/launchd/src/launchd_core_logic.c 2007-04-05 21:14:11 UTC (rev 23207)
@@ -100,6 +100,17 @@
mach_port_t inherited_bootstrap_port;
+struct mspolicy {
+ SLIST_ENTRY(mspolicy) sle;
+ unsigned int allow:1, per_pid:1;
+ const char name[0];
+};
+
+static bool mspolicy_new(job_t j, const char *name, bool allow, bool pid_local);
+static void mspolicy_setup(launch_data_t obj, const char *key, void *context);
+static bool mspolicy_check(job_t j, const char *name, bool pid_local);
+static void mspolicy_delete(job_t j, struct mspolicy *msp);
+
struct machservice {
SLIST_ENTRY(machservice) sle;
LIST_ENTRY(machservice) name_hash_sle;
@@ -239,8 +250,8 @@
static void jobmgr_log_stray_children(jobmgr_t jm);
static void jobmgr_remove(jobmgr_t jm);
static void jobmgr_dispatch_all(jobmgr_t jm, bool newmounthack);
-static job_t jobmgr_find_by_pid(jobmgr_t jm, pid_t p);
-static job_t job_mig_intran2(jobmgr_t jm, mach_port_t p);
+static job_t jobmgr_find_by_pid(jobmgr_t jm, pid_t p, bool create_anon);
+static job_t job_mig_intran2(jobmgr_t jm, mach_port_t mport, pid_t upid);
static void job_export_all2(jobmgr_t jm, launch_data_t where);
static void jobmgr_callback(void *obj, struct kevent *kev);
static void jobmgr_setup_env_from_other_jobs(jobmgr_t jm);
@@ -264,6 +275,7 @@
SLIST_HEAD(, envitem) global_env;
SLIST_HEAD(, envitem) env;
SLIST_HEAD(, limititem) limits;
+ SLIST_HEAD(, mspolicy) mspolicies;
SLIST_HEAD(, machservice) machservices;
SLIST_HEAD(, semaphoreitem) semaphores;
#if DO_RUSAGE_SUMMATION
@@ -305,7 +317,7 @@
unsigned int globargv:1, wait4debugger:1, unload_at_exit:1, stall_before_exec:1, only_once:1,
currently_ignored:1, forced_peers_to_demand_mode:1, setnice:1, hopefully_exits_last:1, removal_pending:1,
wait4pipe_eof:1, sent_sigkill:1, debug_before_kill:1, weird_bootstrap:1, start_on_mount:1,
- per_user:1, hopefully_exits_first:1;
+ per_user:1, hopefully_exits_first:1, deny_unknown_mslookups:1;
const char label[0];
};
@@ -617,9 +629,7 @@
while ((ji = LIST_FIRST(&jm->jobs))) {
/* We should only have anonymous jobs left */
- if (job_assumes(ji, ji->anonymous) && ji->p) {
- job_reap(ji);
- }
+ job_assumes(ji, ji->anonymous);
job_remove(ji);
}
@@ -651,13 +661,16 @@
job_remove(job_t j)
{
struct calendarinterval *ci;
+ struct semaphoreitem *si;
struct socketgroup *sg;
+ struct machservice *ms;
struct limititem *li;
+ struct mspolicy *msp;
struct envitem *ei;
- struct machservice *ms;
- struct semaphoreitem *si;
- if (j->p && !j->anonymous) {
+ if (j->p && j->anonymous) {
+ job_reap(j);
+ } else if (j->p) {
job_log(j, LOG_DEBUG, "Removal pended until the job exits.");
if (!j->removal_pending) {
@@ -690,6 +703,9 @@
job_assumes(j, launchd_mport_deallocate(j->wait_reply_port) == KERN_SUCCESS);
}
+ while ((msp = SLIST_FIRST(&j->mspolicies))) {
+ mspolicy_delete(j, msp);
+ }
while ((sg = SLIST_FIRST(&j->sockets))) {
socketgroup_delete(j, sg);
}
@@ -1412,6 +1428,8 @@
case 'M':
if (strcasecmp(key, LAUNCH_JOBKEY_MACHSERVICES) == 0) {
launch_data_dict_iterate(value, machservice_setup, j);
+ } else if (strcasecmp(key, LAUNCH_JOBKEY_MACHSERVICELOOKUPPOLICIES) == 0) {
+ launch_data_dict_iterate(value, mspolicy_setup, j);
}
break;
default:
@@ -1603,7 +1621,7 @@
}
job_t
-jobmgr_find_by_pid(jobmgr_t jm, pid_t p)
+jobmgr_find_by_pid(jobmgr_t jm, pid_t p, bool create_anon)
{
job_t ji = NULL;
@@ -1613,34 +1631,35 @@
}
}
- return ji;
+ if (ji) {
+ return ji;
+ } else if (create_anon) {
+ return job_new_anonymous(jm, p);
+ } else {
+ return NULL;
+ }
}
job_t
-job_mig_intran2(jobmgr_t jm, mach_port_t p)
+job_mig_intran2(jobmgr_t jm, mach_port_t mport, pid_t upid)
{
- struct ldcred ldc;
jobmgr_t jmi;
job_t ji;
- if (jm->jm_port == p) {
- runtime_get_caller_creds(&ldc);
-
- ji = jobmgr_find_by_pid(jm, ldc.pid);
-
- return ji ? ji : job_new_anonymous(jm, ldc.pid);
+ if (jm->jm_port == mport) {
+ return jobmgr_find_by_pid(jm, upid, true);
}
SLIST_FOREACH(jmi, &jm->submgrs, sle) {
job_t jr;
- if ((jr = job_mig_intran2(jmi, p))) {
+ if ((jr = job_mig_intran2(jmi, mport, upid))) {
return jr;
}
}
LIST_FOREACH(ji, &jm->jobs, sle) {
- if (ji->j_port == p) {
+ if (ji->j_port == mport) {
return ji;
}
}
@@ -1651,15 +1670,18 @@
job_t
job_mig_intran(mach_port_t p)
{
- job_t jr = job_mig_intran2(root_jobmgr, p);
+ struct ldcred ldc;
+ job_t jr;
+ runtime_get_caller_creds(&ldc);
+
+ jr = job_mig_intran2(root_jobmgr, p, ldc.pid);
+
if (!jobmgr_assumes(root_jobmgr, jr != NULL)) {
int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, 0 };
struct kinfo_proc kp;
- struct ldcred ldc;
size_t len = sizeof(kp);
- runtime_get_caller_creds(&ldc);
mib[3] = ldc.pid;
if (jobmgr_assumes(root_jobmgr, sysctl(mib, 4, &kp, &len, NULL, 0) != -1)) {
@@ -2000,7 +2022,7 @@
jobmgr_reap_bulk(jmi, kev);
}
- if ((j = jobmgr_find_by_pid(jm, kev->ident))) {
+ if ((j = jobmgr_find_by_pid(jm, kev->ident, false))) {
kev->udata = j;
job_callback(j, kev);
}
@@ -4697,6 +4719,11 @@
return VPROC_ERR_TRY_PER_USER;
}
+ if (!mspolicy_check(j, servicename, flags & BOOTSTRAP_PER_PID_SERVICE)) {
+ job_log(j, LOG_NOTICE, "Policy denied Mach service lookup: %s", servicename);
+ return BOOTSTRAP_NOT_PRIVILEGED;
+ }
+
if (flags & BOOTSTRAP_PER_PID_SERVICE) {
ms = jobmgr_lookup_service(j->mgr, servicename, false, target_pid);
} else {
@@ -4884,7 +4911,7 @@
snprintf(thelabel, sizeof(thelabel), "com.apple.launchctl.%s", session_type);
- job_assumes(j, (j2 = job_mig_intran2(root_jobmgr, target_subset)) != NULL);
+ job_assumes(j, (j2 = job_mig_intran(target_subset)) != NULL);
j = j2;
jobmgr_log(j->mgr, LOG_DEBUG, "Renaming to: %s", session_type);
strcpy(j->mgr->name, session_type);
@@ -4897,7 +4924,7 @@
return 0;
}
- if (getpid() != 1 && job_mig_intran2(root_jobmgr, target_subset)) {
+ if (getpid() != 1 && job_mig_intran(target_subset)) {
job_assumes(j, launchd_mport_deallocate(target_subset) == KERN_SUCCESS);
return 0;
}
@@ -5164,6 +5191,34 @@
}
kern_return_t
+job_mig_set_service_policy(job_t j, pid_t target_pid, uint64_t flags, name_t target_service)
+{
+ job_t target_j;
+
+ if (!launchd_assumes(j != NULL)) {
+ return BOOTSTRAP_NO_MEMORY;
+ }
+
+ if (!job_assumes(j, (target_j = jobmgr_find_by_pid(j->mgr, target_pid, true)) != NULL)) {
+ return BOOTSTRAP_NO_MEMORY;
+ }
+
+ if (SLIST_EMPTY(&j->mspolicies)) {
+ job_log(j, LOG_DEBUG, "Setting policy on job \"%s\" for Mach service: %s", target_j->label, target_service);
+ if (target_service[0]) {
+ job_assumes(j, mspolicy_new(target_j, target_service, flags & BOOTSTRAP_ALLOW_LOOKUP, flags & BOOTSTRAP_PER_PID_SERVICE));
+ } else {
+ target_j->deny_unknown_mslookups = !(flags & BOOTSTRAP_ALLOW_LOOKUP);
+ }
+ } else {
+ job_log(j, LOG_WARNING, "Jobs that have policies assigned to them may not set policies.");
+ return BOOTSTRAP_NOT_PRIVILEGED;
+ }
+
+ return 0;
+}
+
+kern_return_t
job_mig_spawn(job_t j, _internal_string_t charbuf, mach_msg_type_number_t charbuf_cnt,
uint32_t argc, uint32_t envc, uint64_t flags, uint16_t mig_umask,
binpref_t bin_pref, uint32_t binpref_cnt, pid_t *child_pid, mach_port_t *obsvr_port)
@@ -5286,3 +5341,66 @@
{
return our_strhash(msstr) % MACHSERVICE_HASH_SIZE;
}
+
+bool
+mspolicy_new(job_t j, const char *name, bool allow, bool pid_local)
+{
+ struct mspolicy *msp;
+
+ SLIST_FOREACH(msp, &j->mspolicies, sle) {
+ if (msp->per_pid != pid_local) {
+ continue;
+ } else if (strcmp(msp->name, name) == 0) {
+ return false;
+ }
+ }
+
+ if ((msp = calloc(1, sizeof(struct mspolicy) + strlen(name) + 1)) == NULL) {
+ return false;
+ }
+
+ strcpy((char *)msp->name, name);
+ msp->per_pid = pid_local;
+
+ SLIST_INSERT_HEAD(&j->mspolicies, msp, sle);
+
+ return true;
+}
+
+void
+mspolicy_setup(launch_data_t obj, const char *key, void *context)
+{
+ job_t j = context;
+
+ if (launch_data_get_type(obj) != LAUNCH_DATA_BOOL) {
+ job_log(j, LOG_WARNING, "Invalid object type for Mach service policy key: %s", key);
+ return;
+ }
+
+ job_assumes(j, mspolicy_new(j, key, launch_data_get_bool(obj), false));
+}
+
+bool
+mspolicy_check(job_t j, const char *name, bool pid_local)
+{
+ struct mspolicy *mspi;
+
+ SLIST_FOREACH(mspi, &j->mspolicies, sle) {
+ if (mspi->per_pid != pid_local) {
+ continue;
+ } else if (strcmp(mspi->name, name) != 0) {
+ continue;
+ }
+ return mspi->allow;
+ }
+
+ return !j->deny_unknown_mslookups;
+}
+
+void
+mspolicy_delete(job_t j, struct mspolicy *msp)
+{
+ SLIST_REMOVE(&j->mspolicies, msp, mspolicy, sle);
+
+ free(msp);
+}
Modified: trunk/launchd/src/libbootstrap.c
===================================================================
--- trunk/launchd/src/libbootstrap.c 2007-04-05 18:45:08 UTC (rev 23206)
+++ trunk/launchd/src/libbootstrap.c 2007-04-05 21:14:11 UTC (rev 23207)
@@ -69,6 +69,12 @@
}
kern_return_t
+bootstrap_set_policy(mach_port_t bp, pid_t target_pid, uint64_t flags, const char *target_service)
+{
+ return vproc_mig_set_service_policy(bp, target_pid, flags, target_service ? (char *)target_service : "");
+}
+
+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);
Modified: trunk/launchd/src/libbootstrap_private.h
===================================================================
--- trunk/launchd/src/libbootstrap_private.h 2007-04-05 18:45:08 UTC (rev 23206)
+++ trunk/launchd/src/libbootstrap_private.h 2007-04-05 21:14:11 UTC (rev 23207)
@@ -27,7 +27,8 @@
#pragma GCC visibility push(default)
-#define BOOTSTRAP_PER_PID_SERVICE 1
+#define BOOTSTRAP_PER_PID_SERVICE 0x1
+#define BOOTSTRAP_ALLOW_LOOKUP 0x2
kern_return_t bootstrap_register2(mach_port_t bp, name_t service_name, mach_port_t sp, uint64_t flags);
@@ -35,6 +36,8 @@
kern_return_t bootstrap_look_up_per_user(mach_port_t bp, name_t service_name, uid_t target_user, mach_port_t *sp);
+kern_return_t bootstrap_set_policy(mach_port_t bp, pid_t target_pid, uint64_t flags, const char *target_service);
+
#pragma GCC visibility pop
__END_DECLS
Modified: trunk/launchd/src/liblaunch_public.h
===================================================================
--- trunk/launchd/src/liblaunch_public.h 2007-04-05 18:45:08 UTC (rev 23206)
+++ trunk/launchd/src/liblaunch_public.h 2007-04-05 21:14:11 UTC (rev 23207)
@@ -62,6 +62,7 @@
#define LAUNCH_JOBKEY_INITGROUPS "InitGroups"
#define LAUNCH_JOBKEY_SOCKETS "Sockets"
#define LAUNCH_JOBKEY_MACHSERVICES "MachServices"
+#define LAUNCH_JOBKEY_MACHSERVICELOOKUPPOLICIES "MachServiceLookupPolicies"
#define LAUNCH_JOBKEY_INETDCOMPATIBILITY "inetdCompatibility"
#define LAUNCH_JOBKEY_ENABLEGLOBBING "EnableGlobbing"
#define LAUNCH_JOBKEY_PROGRAMARGUMENTS "ProgramArguments"
Modified: trunk/launchd/src/protocol_job.defs
===================================================================
--- trunk/launchd/src/protocol_job.defs 2007-04-05 18:45:08 UTC (rev 23206)
+++ trunk/launchd/src/protocol_job.defs 2007-04-05 21:14:11 UTC (rev 23207)
@@ -130,7 +130,11 @@
__inval : int64_t;
out __outval : int64_t);
-skip;
+routine set_service_policy(
+ __bs_port : job_t;
+ __target_pid : pid_t;
+ __flags : uint64_t;
+ __service : name_t);
simpleroutine log(
__bs_port : job_t;
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/launchd-changes/attachments/20070405/982c26a7/attachment.html
More information about the launchd-changes
mailing list