]> git.saurik.com Git - apple/launchd.git/blobdiff - launchd/src/launchd_core_logic.c
launchd-258.22.tar.gz
[apple/launchd.git] / launchd / src / launchd_core_logic.c
index ea6f608137057572c8662cfc2569297670bdca44..6565b24b495f5cb48e170b263ddad8c1c4aa8643 100644 (file)
@@ -16,7 +16,7 @@
  * @APPLE_APACHE_LICENSE_HEADER_END@
  */
 
-static const char *const __rcs_file_version__ = "$Revision: 23585 $";
+static const char *const __rcs_file_version__ = "$Revision: 23792 $";
 
 #include "config.h"
 #include "launchd_core_logic.h"
@@ -81,13 +81,13 @@ static const char *const __rcs_file_version__ = "$Revision: 23585 $";
 #include <quarantine.h>
 #endif
 
-#include "liblaunch_public.h"
-#include "liblaunch_private.h"
-#include "liblaunch_internal.h"
-#include "libbootstrap_public.h"
-#include "libbootstrap_private.h"
-#include "libvproc_public.h"
-#include "libvproc_internal.h"
+#include "launch.h"
+#include "launch_priv.h"
+#include "launch_internal.h"
+#include "bootstrap.h"
+#include "bootstrap_priv.h"
+#include "vproc.h"
+#include "vproc_internal.h"
 
 #include "reboot2.h"
 
@@ -96,7 +96,7 @@ static const char *const __rcs_file_version__ = "$Revision: 23585 $";
 #include "launchd_unix_ipc.h"
 #include "protocol_vproc.h"
 #include "protocol_vprocServer.h"
-#include "job_reply.h"
+#include "protocol_job_reply.h"
 
 #define LAUNCHD_MIN_JOB_RUN_TIME 10
 #define LAUNCHD_DEFAULT_EXIT_TIMEOUT 20
@@ -420,6 +420,9 @@ static void job_setup_attributes(job_t j);
 static bool job_setup_machport(job_t j);
 static void job_setup_fd(job_t j, int target_fd, const char *path, int flags);
 static void job_postfork_become_user(job_t j);
+#if !TARGET_OS_EMBEDDED
+static void job_enable_audit_for_user(job_t j, uid_t u, char *name);
+#endif
 static void job_find_and_blame_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);
@@ -1584,7 +1587,8 @@ job_import_integer(job_t j, const char *key, long long value)
 }
 
 void
-job_import_opaque(job_t j, const char *key, launch_data_t value)
+job_import_opaque(job_t j __attribute__((unused)),
+       const char *key, launch_data_t value __attribute__((unused)))
 {
        switch (key[0]) {
        case 'q':
@@ -2259,6 +2263,8 @@ job_reap(job_t j)
        }
        j->last_exit_status = status;
        j->sent_sigkill = false;
+       j->lastlookup = NULL;
+       j->lastlookup_gennum = 0;
        j->p = 0;
 
        /*
@@ -2396,7 +2402,7 @@ job_kill(job_t j)
 }
 
 void
-job_callback_proc(job_t j, int flags, int fflags)
+job_callback_proc(job_t j, int flags __attribute__((unused)), int fflags)
 {
        if ((fflags & NOTE_EXEC) && j->anonymous) {
                int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, j->p };
@@ -2610,6 +2616,11 @@ job_start(job_t j)
 
        if (!j->legacy_mach_job) {
                sipc = (!SLIST_EMPTY(&j->sockets) || !SLIST_EMPTY(&j->machservices));
+#if TARGET_OS_EMBEDDED
+               if (j->username && strcmp(j->username, "mobile") == 0 && strncmp(j->label, "com.apple.", strlen("com.apple.")) != 0) {
+                       sipc = false;
+               }
+#endif
        }
 
        j->checkedin = false;
@@ -2818,7 +2829,9 @@ job_start_child(job_t j)
                job_log_error(j, LOG_ERR, "posix_spawnp(\"%s\", ...)", argv[0]);
        }
 
+#if HAVE_SANDBOX
 out_bad:
+#endif
        _exit(EXIT_FAILURE);
 }
 
@@ -2917,6 +2930,30 @@ out:
        free(kp);
 }
 
+#if !TARGET_OS_EMBEDDED
+void
+job_enable_audit_for_user(job_t j, uid_t u, char *name)
+{
+       auditinfo_t auinfo = {
+               .ai_auid = u,
+               .ai_asid = j->p,
+       };
+       long au_cond;
+
+       if (!job_assumes(j, auditon(A_GETCOND, &au_cond, sizeof(long)) == 0)) {
+               _exit(EXIT_FAILURE);
+       }
+
+       if (au_cond != AUC_NOAUDIT) {
+               if (!job_assumes(j, au_user_mask(name, &auinfo.ai_mask) == 0)) {
+                       _exit(EXIT_FAILURE);
+               } else if (!job_assumes(j, setaudit(&auinfo) == 0)) {
+                       _exit(EXIT_FAILURE);
+               }
+       }
+}
+#endif
+
 void
 job_postfork_become_user(job_t j)
 {
@@ -2994,6 +3031,10 @@ job_postfork_become_user(job_t j)
                desired_gid = gre->gr_gid;
        }
 
+#if !TARGET_OS_EMBEDDED
+       job_enable_audit_for_user(j, desired_uid, loginname);
+#endif
+
        if (!job_assumes(j, setlogin(loginname) != -1)) {
                _exit(EXIT_FAILURE);
        }
@@ -4164,9 +4205,9 @@ job_setup_exception_port(job_t j, task_t target_task)
                return;
        }
 
-#if defined (__ppc__)
+#if defined (__ppc__) || defined (__ppc64__)
        f = PPC_THREAD_STATE64;
-#elif defined(__i386__)
+#elif defined(__i386__) || defined(__x86_64__)
        f = x86_THREAD_STATE;
 #elif defined(__arm__)
        f = ARM_THREAD_STATE;
@@ -5244,6 +5285,10 @@ job_mig_create_server(job_t j, cmd_t server_cmd, uid_t server_uid, boolean_t on_
        struct ldcred ldc;
        job_t js;
 
+#if TARGET_OS_EMBEDDED
+       return BOOTSTRAP_NOT_PRIVILEGED;
+#endif
+
        if (!launchd_assumes(j != NULL)) {
                return BOOTSTRAP_NO_MEMORY;
        }
@@ -5732,6 +5777,10 @@ job_mig_lookup_per_user_context(job_t j, uid_t which_user, mach_port_t *up_cont)
        struct ldcred ldc;
        job_t ji;
 
+#if TARGET_OS_EMBEDDED
+       return BOOTSTRAP_NOT_PRIVILEGED;
+#endif
+
        if (!launchd_assumes(j != NULL)) {
                return BOOTSTRAP_NO_MEMORY;
        }
@@ -5942,7 +5991,7 @@ job_mig_look_up2(job_t j, name_t servicename, mach_port_t *serviceportp, mach_ms
                ms = jobmgr_lookup_service(j->mgr, servicename, true, 0);
        }
 
-       if (ms && machservice_hidden(ms) && !job_active(machservice_job(ms))) {
+       if (ms && machservice_hidden(ms) && !machservice_active(ms)) {
                ms = NULL;
        } else if (ms && ms->per_user_hack) {
                ms = NULL;
@@ -6018,6 +6067,10 @@ job_mig_info(job_t j, name_array_t *servicenamesp, unsigned int *servicenames_cn
        jobmgr_t jm;
        job_t ji;
 
+#if TARGET_OS_EMBEDDED
+       return BOOTSTRAP_NOT_PRIVILEGED;
+#endif
+
        if (!launchd_assumes(j != NULL)) {
                return BOOTSTRAP_NO_MEMORY;
        }
@@ -6140,6 +6193,10 @@ job_mig_move_subset(job_t j, mach_port_t target_subset, name_t session_type)
        struct ldcred ldc;
        jobmgr_t jmr = NULL;
 
+#if TARGET_OS_EMBEDDED
+       return BOOTSTRAP_NOT_PRIVILEGED;
+#endif
+
        if (!launchd_assumes(j != NULL)) {
                return BOOTSTRAP_NO_MEMORY;
        }
@@ -6316,6 +6373,10 @@ job_mig_take_subset(job_t j, mach_port_t *reqport, mach_port_t *rcvright,
        jobmgr_t jm;
        job_t ji;
 
+#if TARGET_OS_EMBEDDED
+       return BOOTSTRAP_NOT_PRIVILEGED;
+#endif
+
        if (!launchd_assumes(j != NULL)) {
                return BOOTSTRAP_NO_MEMORY;
        }
@@ -6606,12 +6667,41 @@ job_mig_uncork_fork(job_t j)
 kern_return_t
 job_mig_set_service_policy(job_t j, pid_t target_pid, uint64_t flags, name_t target_service)
 {
+       struct ldcred ldc;
        job_t target_j;
 
        if (!launchd_assumes(j != NULL)) {
                return BOOTSTRAP_NO_MEMORY;
        }
 
+       runtime_get_caller_creds(&ldc);
+
+#if TARGET_OS_EMBEDDED
+       if( ldc.euid ) {
+               return BOOTSTRAP_NOT_PRIVILEGED;
+       }
+#else
+       if( ldc.euid && (ldc.euid != getuid()) ) {
+               int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, target_pid };
+               struct kinfo_proc kp;
+               size_t len = sizeof(kp);
+
+               job_assumes(j, sysctl(mib, 4, &kp, &len, NULL, 0) != -1);
+               job_assumes(j, len == sizeof(kp));
+
+               uid_t kp_euid = kp.kp_eproc.e_ucred.cr_uid;
+               uid_t kp_uid = kp.kp_eproc.e_pcred.p_ruid;
+
+               if( ldc.euid == kp_euid ) {
+                       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);
+
+                       return BOOTSTRAP_NOT_PRIVILEGED;
+               }
+       }
+#endif
+
        if (!job_assumes(j, (target_j = jobmgr_find_by_pid(j->mgr, target_pid, true)) != NULL)) {
                return BOOTSTRAP_NO_MEMORY;
        }
@@ -6640,6 +6730,10 @@ job_mig_spawn(job_t j, vm_offset_t indata, mach_msg_type_number_t indataCnt, pid
        struct ldcred ldc;
        job_t jr;
 
+#if TARGET_OS_EMBEDDED
+       return BOOTSTRAP_NOT_PRIVILEGED;
+#endif
+
        runtime_get_caller_creds(&ldc);
 
        if (!launchd_assumes(j != NULL)) {