#include <sys/bsdtask_info.h>
#include <sys/persona.h>
+#ifdef CONFIG_32BIT_TELEMETRY
+#include <sys/kasl.h>
+#endif /* CONFIG_32BIT_TELEMETRY */
+
+#if CONFIG_CSR
+#include <sys/csr.h>
+#endif
+
#if CONFIG_MEMORYSTATUS
#include <sys/kern_memorystatus.h>
#endif
#include <libkern/crypto/sha1.h>
+#ifdef CONFIG_32BIT_TELEMETRY
+#define MAX_32BIT_EXEC_SIG_SIZE 160
+#endif /* CONFIG_32BIT_TELEMETRY */
+
/*
* Structure associated with user cacheing.
*/
extern int cs_debug;
+#if DEVELOPMENT || DEBUG
+extern int cs_enforcement_enable;
+#endif
+
#if DEBUG
#define __PROC_INTERNAL_DEBUG 1
#endif
#if CONFIG_COREDUMP
/* Name to give to core files */
+#if defined(XNU_TARGET_OS_BRIDGE)
+__XNU_PRIVATE_EXTERN char corefilename[MAXPATHLEN+1] = {"/private/var/internal/%N.core"};
+#elif CONFIG_EMBEDDED
+__XNU_PRIVATE_EXTERN char corefilename[MAXPATHLEN+1] = {"/private/var/cores/%N.core"};
+#else
__XNU_PRIVATE_EXTERN char corefilename[MAXPATHLEN+1] = {"/cores/core.%P"};
#endif
+#endif
#if PROC_REF_DEBUG
#include <kern/backtrace.h>
proc_ref_locked(proc_t p)
{
proc_t p1 = p;
+ int pid = proc_pid(p);
- /* if process still in creation return failure */
- if ((p == PROC_NULL) || ((p->p_listflag & P_LIST_INCREATE) != 0))
- return (PROC_NULL);
retry:
+ /*
+ * if process still in creation or proc got recycled
+ * during msleep then return failure.
+ */
+ if ((p == PROC_NULL) || (p1 != p) || ((p->p_listflag & P_LIST_INCREATE) != 0))
+ return (PROC_NULL);
+
/*
* Do not return process marked for termination
* or proc_refdrain called without ref wait.
((p->p_listflag & P_LIST_REFWAIT) != 0))) {
if ((p->p_listflag & P_LIST_REFWAIT) != 0 && uthread_needs_to_wait_in_proc_refwait()) {
msleep(&p->p_listflag, proc_list_mlock, 0, "proc_refwait", 0) ;
+ /*
+ * the proc might have been recycled since we dropped
+ * the proc list lock, get the proc again.
+ */
+ p = pfind_locked(pid);
goto retry;
}
p->p_refcount++;
if (vnode_getwithref(tvp) == 0) {
return tvp;
}
- }
+ }
return NULLVP;
}
}
+#ifndef __arm__
int
IS_64BIT_PROCESS(proc_t p)
{
else
return(0);
}
+#endif
/*
* Locate a process by number
child->p_pptr = parent;
child->p_ppid = parent->p_pid;
child->p_puniqueid = parent->p_uniqueid;
+ child->p_xhighbits = 0;
pg = proc_pgrp(parent);
pgrp_add(pg, parent, child);
case CS_OPS_MARKRESTRICT:
case CS_OPS_SET_STATUS:
case CS_OPS_CLEARINSTALLER:
+ case CS_OPS_CLEARPLATFORM:
if ((error = mac_proc_check_set_cs_info(current_proc(), pt, ops)))
goto out;
break;
error = ENOENT;
break;
}
-
+
length = strlen(identity) + 1; /* include NUL */
idlen = htonl(length + sizeof(fakeheader));
memcpy(&fakeheader[4], &idlen, sizeof(idlen));
case CS_OPS_CLEARINSTALLER:
proc_lock(pt);
- pt->p_csflags &= ~(CS_INSTALLER | CS_EXEC_SET_INSTALLER);
+ pt->p_csflags &= ~(CS_INSTALLER | CS_DATAVAULT_CONTROLLER | CS_EXEC_INHERIT_SIP);
proc_unlock(pt);
break;
+ case CS_OPS_CLEARPLATFORM:
+#if DEVELOPMENT || DEBUG
+ if (cs_enforcement_enable) {
+ error = ENOTSUP;
+ break;
+ }
+
+#if CONFIG_CSR
+ if (csr_check(CSR_ALLOW_APPLE_INTERNAL) != 0) {
+ error = ENOTSUP;
+ break;
+ }
+#endif
+
+ proc_lock(pt);
+ pt->p_csflags &= ~(CS_PLATFORM_BINARY|CS_PLATFORM_PATH);
+ csproc_clear_platform_binary(pt);
+ proc_unlock(pt);
+ break;
+#else
+ error = ENOTSUP;
+ break;
+#endif /* !DEVELOPMENT || DEBUG */
+
default:
error = EINVAL;
break;
for (;;) {
proc_list_lock();
- pid_count_available = nprocs;
+ pid_count_available = nprocs + 1; //kernel_task is not counted in nprocs
assert(pid_count_available > 0);
pid_list_size_needed = pid_count_available * sizeof(pid_t);
#endif /* DEVELOPMENT || DEBUG */
#define MB_SIZE (1024 * 1024ULL)
+boolean_t memorystatus_kill_on_VM_thrashing(boolean_t);
+
+extern int32_t max_kill_priority;
+extern int memorystatus_get_proccnt_upto_priority(int32_t max_bucket_index);
int
no_paging_space_action()
}
}
+ /*
+ * We have some processes within our jetsam bands of consideration and hence can be killed.
+ * So we will invoke the memorystatus thread to go ahead and kill something.
+ */
+ if (memorystatus_get_proccnt_upto_priority(max_kill_priority) > 0) {
+
+ last_no_space_action = now;
+ memorystatus_kill_on_VM_thrashing(TRUE /* async */);
+ return (1);
+ }
+
+ /*
+ * No eligible processes to kill. So let's suspend/kill the largest
+ * process depending on its policy control specifications.
+ */
+
if (nps.pcs_max_size > 0) {
if ((p = proc_find(nps.pcs_pid)) != PROC_NULL) {
*/
last_no_space_action = now;
-#if DEVELOPMENT || DEBUG
- if (kill_on_no_paging_space == TRUE) {
- /*
- * We found the largest process that has a process policy i.e. one of
- * PC_KILL, PC_SUSP, PC_THROTTLE.
- * But we are in a mode where we will kill it regardless of its policy.
- */
- printf("low swap: killing largest process with pid %d (%s) and size %llu MB\n", p->p_pid, p->p_comm, (nps.pcs_max_size/MB_SIZE));
- psignal(p, SIGKILL);
-
- proc_rele(p);
-
- return 1;
- }
-#endif /* DEVELOPMENT || DEBUG */
-
proc_dopcontrol(p);
proc_rele(p);
uthread_t uth = (uthread_t)uthread_v;
return (uth != NULL) ? uth->uu_threadlist : NULL;
}
+
+#ifdef CONFIG_32BIT_TELEMETRY
+void
+proc_log_32bit_telemetry(proc_t p)
+{
+ /* Gather info */
+ char signature_buf[MAX_32BIT_EXEC_SIG_SIZE] = { 0 };
+ char * signature_cur_end = &signature_buf[0];
+ char * signature_buf_end = &signature_buf[MAX_32BIT_EXEC_SIG_SIZE - 1];
+ int bytes_printed = 0;
+
+ const char * teamid = NULL;
+ const char * identity = NULL;
+ struct cs_blob * csblob = NULL;
+
+ proc_list_lock();
+
+ /*
+ * Get proc name and parent proc name; if the parent execs, we'll get a
+ * garbled name.
+ */
+ bytes_printed = snprintf(signature_cur_end,
+ signature_buf_end - signature_cur_end,
+ "%s,%s,", p->p_name,
+ (p->p_pptr ? p->p_pptr->p_name : ""));
+
+ if (bytes_printed > 0) {
+ signature_cur_end += bytes_printed;
+ }
+
+ proc_list_unlock();
+
+ /* Get developer info. */
+ vnode_t v = proc_getexecutablevnode(p);
+
+ if (v) {
+ csblob = csvnode_get_blob(v, 0);
+
+ if (csblob) {
+ teamid = csblob_get_teamid(csblob);
+ identity = csblob_get_identity(csblob);
+ }
+ }
+
+ if (teamid == NULL) {
+ teamid = "";
+ }
+
+ if (identity == NULL) {
+ identity = "";
+ }
+
+ bytes_printed = snprintf(signature_cur_end,
+ signature_buf_end - signature_cur_end,
+ "%s,%s", teamid, identity);
+
+ if (bytes_printed > 0) {
+ signature_cur_end += bytes_printed;
+ }
+
+ if (v) {
+ vnode_put(v);
+ }
+
+ /*
+ * We may want to rate limit here, although the SUMMARIZE key should
+ * help us aggregate events in userspace.
+ */
+
+ /* Emit log */
+ kern_asl_msg(LOG_DEBUG, "messagetracer", 3,
+ /* 0 */ "com.apple.message.domain", "com.apple.kernel.32bit_exec",
+ /* 1 */ "com.apple.message.signature", signature_buf,
+ /* 2 */ "com.apple.message.summarize", "YES",
+ NULL);
+}
+#endif /* CONFIG_32BIT_TELEMETRY */