commit 9f7cc5351f2eccfe7f15c8157b4a834dce785c9d
parent 9df584253d6c16afc69609848fb4ca227d9357d3
Author: Nika Layzell <nika@thelayzells.com>
Date: Tue, 16 Dec 2025 04:53:46 +0000
Bug 1927599 - Part 2: Parent process cannot have child task_t on iOS, r=ipc-reviewers,profiler-reviewers,mstange,jld
Transferring a task_t over XPC during child process startup appears to cause a
connection failure. It seems likely that transferring a task in this way is a
sandbox violation on-device.
This mostly consists of changing ifdefs associated with the task_t object to be
macOS-specific instead. iOS simulator builds will stop working after this
change until the IPC backend is changed.
Differential Revision: https://phabricator.services.mozilla.com/D227102
Diffstat:
7 files changed, 24 insertions(+), 34 deletions(-)
diff --git a/dom/base/ChromeUtils.cpp b/dom/base/ChromeUtils.cpp
@@ -1861,10 +1861,10 @@ already_AddRefed<Promise> ChromeUtils::RequestProcInfo(GlobalObject& aGlobal,
// DOM windows.
/* aUtilityInfo = */ std::move(utilityActors),
/* aChild = */ 0 // Without a ContentProcess, no ChildId.
-#ifdef XP_DARWIN
+#ifdef XP_MACOSX
,
/* aChildTask = */ aGeckoProcess->GetChildTask()
-#endif // XP_DARWIN
+#endif // XP_MACOSX
);
});
@@ -1965,10 +1965,10 @@ already_AddRefed<Promise> ChromeUtils::RequestProcInfo(GlobalObject& aGlobal,
/* aWindowInfo = */ std::move(windows),
/* aUtilityInfo = */ nsTArray<UtilityInfo>(),
/* aChild = */ contentParent->ChildID()
-#ifdef XP_DARWIN
+#ifdef XP_MACOSX
,
/* aChildTask = */ contentParent->Process()->GetChildTask()
-#endif // XP_DARWIN
+#endif // XP_MACOSX
);
}
diff --git a/ipc/glue/GeckoChildProcessHost.cpp b/ipc/glue/GeckoChildProcessHost.cpp
@@ -131,7 +131,7 @@ namespace ipc {
struct LaunchResults {
base::ProcessHandle mHandle = 0;
-#ifdef XP_DARWIN
+#ifdef XP_MACOSX
task_t mChildTask = MACH_PORT_NULL;
#endif
#ifdef XP_IOS
@@ -388,7 +388,7 @@ GeckoChildProcessHost::GeckoChildProcessHost(GeckoProcessType aProcessType,
#endif
mHandleLock("mozilla.ipc.GeckoChildProcessHost.mHandleLock"),
mChildProcessHandle(0),
-#if defined(XP_DARWIN)
+#if defined(XP_MACOSX)
mChildTask(MACH_PORT_NULL),
#endif
#if defined(MOZ_SANDBOX) && defined(XP_MACOSX)
@@ -425,7 +425,7 @@ GeckoChildProcessHost::~GeckoChildProcessHost() {
{
mozilla::AutoWriteLock hLock(mHandleLock);
-#if defined(XP_DARWIN)
+#if defined(XP_MACOSX)
if (mChildTask != MACH_PORT_NULL) {
mach_port_deallocate(mach_task_self(), mChildTask);
}
@@ -462,7 +462,7 @@ base::ProcessId GeckoChildProcessHost::GetChildProcessId() {
return base::GetProcId(mChildProcessHandle);
}
-#ifdef XP_DARWIN
+#ifdef XP_MACOSX
task_t GeckoChildProcessHost::GetChildTask() {
mozilla::AutoReadLock handleLock(mHandleLock);
return mChildTask;
@@ -776,7 +776,7 @@ bool GeckoChildProcessHost::AsyncLaunch(
// "safe" invalid value to use in places like this.
aResults.mHandle = 0;
-#ifdef XP_DARWIN
+#ifdef XP_MACOSX
this->mChildTask = aResults.mChildTask;
#endif
#ifdef XP_IOS
@@ -789,7 +789,7 @@ bool GeckoChildProcessHost::AsyncLaunch(
if (mNodeChannel) {
mNodeChannel->SetOtherPid(
base::GetProcId(this->mChildProcessHandle));
-#ifdef XP_DARWIN
+#ifdef XP_MACOSX
mNodeChannel->SetMachTaskPort(this->mChildTask);
#endif
}
@@ -1511,27 +1511,16 @@ RefPtr<ProcessLaunchPromise> IosProcessLauncher::DoLaunch() {
return;
}
- // FIXME: We have to trust the child to tell us its pid & mach task.
+ // NOTE: We have to trust the child to tell us its pid. The child is
+ // blocked by sandbox from sending its mach task.
// WebKit uses `xpc_connection_get_pid` to get the pid, however this
// is marked as unavailable on iOS.
//
- // Given how the process is started, however, validating this
- // information it sends us this early during startup may be
- // unnecessary.
- self->mResults.mChildTask =
- xpc_dictionary_copy_mach_send(reply, "task");
+ // The process hasn't had a chance to load any untrusted content at
+ // this point, so we should be able to trust it.
pid_t pid =
static_cast<pid_t>(xpc_dictionary_get_int64(reply, "pid"));
- CHROMIUM_LOG(INFO) << "ExtensionKit process started, task: "
- << self->mResults.mChildTask << ", pid: " << pid;
-
- pid_t taskPid;
- kern_return_t kr = pid_for_task(self->mResults.mChildTask, &taskPid);
- if (kr != KERN_SUCCESS || pid != taskPid) {
- CHROMIUM_LOG(ERROR) << "Could not validate child task matches pid";
- promise->Reject(LaunchError("pid_for_task mismatch"), __func__);
- return;
- }
+ CHROMIUM_LOG(INFO) << "ExtensionKit process started, pid: " << pid;
self->mResults.mHandle = pid;
promise->Resolve(std::move(self->mResults), __func__);
diff --git a/ipc/glue/GeckoChildProcessHost.h b/ipc/glue/GeckoChildProcessHost.h
@@ -164,7 +164,7 @@ class GeckoChildProcessHost : public SupportsWeakPtr,
GeckoProcessType GetProcessType() { return mProcessType; }
-#ifdef XP_DARWIN
+#ifdef XP_MACOSX
task_t GetChildTask();
#endif
@@ -266,7 +266,7 @@ class GeckoChildProcessHost : public SupportsWeakPtr,
mozilla::RWLock mHandleLock;
ProcessHandle mChildProcessHandle MOZ_GUARDED_BY(mHandleLock);
-#if defined(XP_DARWIN)
+#if defined(XP_MACOSX)
task_t mChildTask MOZ_GUARDED_BY(mHandleLock);
#endif
#if defined(MOZ_WIDGET_UIKIT)
diff --git a/toolkit/components/processtools/ProcInfo.h b/toolkit/components/processtools/ProcInfo.h
@@ -181,7 +181,7 @@ struct ProcInfoRequest {
ProcInfoRequest(base::ProcessId aPid, ProcType aProcessType,
const nsACString& aOrigin, nsTArray<WindowInfo>&& aWindowInfo,
nsTArray<UtilityInfo>&& aUtilityInfo, uint32_t aChildId = 0
-#ifdef XP_DARWIN
+#ifdef XP_MACOSX
,
mach_port_t aChildTask = 0
#endif // XP_DARWIN
@@ -192,7 +192,7 @@ struct ProcInfoRequest {
windowInfo(std::move(aWindowInfo)),
utilityInfo(std::move(aUtilityInfo)),
childId(aChildId)
-#ifdef XP_DARWIN
+#ifdef XP_MACOSX
,
childTask(aChildTask)
#endif // XP_DARWIN
@@ -205,7 +205,7 @@ struct ProcInfoRequest {
const nsTArray<UtilityInfo> utilityInfo;
// If the process is a child, its child id, otherwise `0`.
const int32_t childId;
-#ifdef XP_DARWIN
+#ifdef XP_MACOSX
const mach_port_t childTask;
#endif // XP_DARWIN
};
diff --git a/toolkit/components/processtools/ProcInfo.mm b/toolkit/components/processtools/ProcInfo.mm
@@ -100,6 +100,7 @@ ProcInfoPromise::ResolveOrRejectValue GetProcInfoSync(
info.windows = std::move(request.windowInfo);
info.utilityActors = std::move(request.utilityInfo);
+#ifdef XP_MACOSX
mach_port_t selectedTask;
// If we did not get a task from a child process, we use mach_task_self()
if (request.childTask == MACH_PORT_NULL) {
@@ -191,6 +192,7 @@ ProcInfoPromise::ResolveOrRejectValue GetProcInfoSync(
thread->name.AssignASCII(threadInfoData.pth_name);
thread->tid = identifierInfo.thread_id;
}
+#endif
if (!gathered.put(request.pid, std::move(info))) {
result.SetReject(NS_ERROR_OUT_OF_MEMORY);
diff --git a/toolkit/xre/IOSBootstrap.mm b/toolkit/xre/IOSBootstrap.mm
@@ -136,10 +136,9 @@ void HandleBootstrapMessage(xpc_object_t aEvent) {
close(fd);
}
- // Immediately send a reply with our pid and mach task port.
+ // Immediately send a reply with our pid
auto reply = mozilla::AdoptDarwinObject(xpc_dictionary_create_reply(aEvent));
xpc_dictionary_set_int64(reply.get(), "pid", getpid());
- xpc_dictionary_set_mach_send(reply.get(), "task", mach_task_self());
xpc_connection_send_message(xpc_dictionary_get_remote_connection(aEvent),
reply.get());
diff --git a/tools/profiler/core/platform.cpp b/tools/profiler/core/platform.cpp
@@ -5350,7 +5350,7 @@ void SamplerThread::SpyOnUnregisteredThreads() {
/* aWindowInfo = */ nsTArray<WindowInfo>{},
/* aUtilityInfo = */ nsTArray<UtilityInfo>{},
/* aChild = */ 0
-#ifdef XP_DARWIN
+#ifdef XP_MACOSX
,
/* aChildTask = */ MACH_PORT_NULL
#endif // XP_DARWIN