+/*
+ * Routine: ipc_task_reset
+ * Purpose:
+ * Reset a task's IPC state to protect it when
+ * it enters an elevated security context.
+ * Conditions:
+ * Nothing locked. The task must be suspended.
+ * (Or the current thread must be in the task.)
+ */
+
+void
+ipc_task_reset(
+ task_t task)
+{
+ ipc_port_t old_kport, new_kport;
+ ipc_port_t old_sself;
+#if 0
+ ipc_port_t old_exc_actions[EXC_TYPES_COUNT];
+ int i;
+#endif
+
+ new_kport = ipc_port_alloc_kernel();
+ if (new_kport == IP_NULL)
+ panic("ipc_task_reset");
+
+ itk_lock(task);
+
+ old_kport = task->itk_self;
+
+ if (old_kport == IP_NULL) {
+ /* the task is already terminated (can this happen?) */
+ itk_unlock(task);
+ ipc_port_dealloc_kernel(new_kport);
+ return;
+ }
+
+ task->itk_self = new_kport;
+ old_sself = task->itk_sself;
+ task->itk_sself = ipc_port_make_send(new_kport);
+ ipc_kobject_set(old_kport, IKO_NULL, IKOT_NONE);
+ ipc_kobject_set(new_kport, (ipc_kobject_t) task, IKOT_TASK);
+
+#if 0
+ for (i = FIRST_EXCEPTION; i < EXC_TYPES_COUNT; i++) {
+ old_exc_actions[i] = task->exc_action[i].port;
+ task->exc_actions[i].port = IP_NULL;
+ }/* for */
+#endif
+
+ itk_unlock(task);
+
+ /* release the naked send rights */
+
+ if (IP_VALID(old_sself))
+ ipc_port_release_send(old_sself);
+
+#if 0
+ for (i = FIRST_EXCEPTION; i < EXC_TYPES_COUNT; i++) {
+ if (IP_VALID(old_exc_actions[i])) {
+ ipc_port_release_send(old_exc_actions[i]);
+ }
+ }/* for */
+#endif
+
+ /* destroy the kernel port */
+ ipc_port_dealloc_kernel(old_kport);
+}
+