Revision: 23037 http://trac.macosforge.org/projects/launchd/changeset/23037 Author: zarzycki@apple.com Date: 2007-02-07 10:26:57 -0800 (Wed, 07 Feb 2007) Log Message: ----------- <rdar://problem/4941920> job_export_all() crash via launchd's Unix IPC Modified Paths: -------------- trunk/launchd/src/launchd_core_logic.c trunk/launchd/src/launchd_core_logic.h Modified: trunk/launchd/src/launchd_core_logic.c =================================================================== --- trunk/launchd/src/launchd_core_logic.c 2007-02-07 17:39:53 UTC (rev 23036) +++ trunk/launchd/src/launchd_core_logic.c 2007-02-07 18:26:57 UTC (rev 23037) @@ -976,9 +976,7 @@ return NULL; } - job_dispatch(j, false); - - return j; + return job_dispatch(j, false); } launch_data_t @@ -1641,19 +1639,19 @@ void jobmgr_dispatch_all(jobmgr_t jm) { - jobmgr_t jmi; - job_t ji; + jobmgr_t jmi, jmn; + job_t ji, jn; - SLIST_FOREACH(jmi, &jm->submgrs, sle) { + SLIST_FOREACH_SAFE(jmi, &jm->submgrs, sle, jmn) { jobmgr_dispatch_all(jmi); } - SLIST_FOREACH(ji, &jm->jobs, sle) { + SLIST_FOREACH_SAFE(ji, &jm->jobs, sle, jn) { job_dispatch(ji, false); } } -void +job_t job_dispatch(job_t j, bool kickstart) { /* @@ -1664,15 +1662,18 @@ * * This is a classic example. The act of dispatching a job may delete it. */ - if (job_active(j)) { - return; - } else if (job_useless(j)) { - job_remove(j); - } else if (kickstart || job_keepalive(j)) { - job_start(j); - } else { - job_watch(j); + if (!job_active(j)) { + if (job_useless(j)) { + job_remove(j); + return NULL; + } else if (kickstart || job_keepalive(j)) { + job_start(j); + } else { + job_watch(j); + } } + + return j; } void @@ -3468,6 +3469,7 @@ } } + /* We don't need the _SAFE version because we return after the job_dispatch() */ SLIST_FOREACH(ji, &jm->jobs, sle) { SLIST_FOREACH(ms, &ji->machservices, sle) { if (ms->port != p) { @@ -3613,11 +3615,11 @@ void jobmgr_dispatch_all_semaphores(jobmgr_t jm) { - jobmgr_t jmi; + jobmgr_t jmi, jmn; job_t ji, jn; - SLIST_FOREACH(jmi, &jm->submgrs, sle) { + SLIST_FOREACH_SAFE(jmi, &jm->submgrs, sle, jmn) { jobmgr_dispatch_all_semaphores(jmi); } @@ -3979,10 +3981,12 @@ ms->must_match_uid = true; ms->hide = true; - job_dispatch(ji, false); + ji = job_dispatch(ji, false); } - *up_cont = machservice_port(SLIST_FIRST(&ji->machservices)); + if (job_assumes(j, ji != NULL)) { + *up_cont = machservice_port(SLIST_FIRST(&ji->machservices)); + } return 0; } @@ -4538,8 +4542,12 @@ memcpy(jr->j_binpref, bin_pref, sizeof(jr->j_binpref)); jr->j_binpref_cnt = binpref_cnt; - job_dispatch(jr, true); + jr = job_dispatch(jr, true); + if (!job_assumes(j, jr != NULL)) { + return BOOTSTRAP_NO_MEMORY; + } + if (!job_setup_machport(jr)) { job_remove(jr); return BOOTSTRAP_NO_MEMORY; Modified: trunk/launchd/src/launchd_core_logic.h =================================================================== --- trunk/launchd/src/launchd_core_logic.h 2007-02-07 17:39:53 UTC (rev 23036) +++ trunk/launchd/src/launchd_core_logic.h 2007-02-07 18:26:57 UTC (rev 23037) @@ -43,7 +43,7 @@ launch_data_t job_export_all(void); job_t job_new(jobmgr_t jm, const char *label, const char *prog, const char *const *argv, const char *stdinpath); -void job_dispatch(job_t j, bool kickstart); +job_t job_dispatch(job_t j, bool kickstart); /* returns j on success, NULL on job removal */ bool job_active(job_t j); launch_data_t job_export(job_t j); void job_stop(job_t j);