进程specialization
fork 出来的进程仍带着 Zygote 的地址空间、文件描述符和部分权限。specialization 先在仍有特权时完成 mount namespace、app data/storage bind mount、capability 和 seccomp 准备,再切换 groups、gid、uid、SELinux context、heap/debug 策略,最后执行 post-fork hooks 并进入 zygoteInit()。
1. Java入口
源码文件:frameworks/base/core/java/com/android/internal/os/Zygote.java
private static void specializeAppProcess(
int uid, int gid, int[] gids,
int runtimeFlags, int[][] rlimits,
int mountExternal, String seInfo,
String niceName, boolean startChildZygote,
String instructionSet, String appDataDir,
boolean isTopApp, String[] pkgDataInfoList,
String[] allowlistedDataInfoList,
boolean bindMountAppDataDirs,
boolean bindMountAppStorageDirs,
boolean bindMountSyspropOverrides) {
nativeSpecializeAppProcess(...);
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
if (gids != null && gids.length > 0) {
NetworkUtilsInternal.setAllowNetworkingForProcess(
containsInetGid(gids));
}
Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
ZygoteHooks.postForkCommon();
}Java wrapper 在 native 成功后设置网络组语义、恢复 Java 线程优先级和 ART daemon。权限与 namespace 的 owner 是 native SpecializeCommon()。
2. 能力与挂载
源码文件:frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
permitted_capabilities |= bounding_capabilities;
if (uid != 0) {
EnableKeepCapabilities(fail_fn);
}
SetInheritable(permitted_capabilities, fail_fn);
DropCapabilitiesBoundingSet(fail_fn, bounding_capabilities);
MountEmulatedStorage(uid, mount_external,
need_pre_initialize_native_bridge, fail_fn);
ensureInAppMountNamespace(fail_fn);UID 切换会清理 capability,所以 keepcaps/inheritable/bounding 必须提前设置。mount namespace 也必须在父 Zygote 仍具备权限时建立,避免修改全局挂载视图。
3. 数据隔离
if (mount_data_dirs) {
isolateAppData(env, pkg_data_info_list,
allowlisted_data_info_list, uid,
process_name, managed_nice_name, fail_fn);
isolateJitProfile(env, pkg_data_info_list, uid,
process_name, managed_nice_name, fail_fn);
}
if (mount_storage_dirs) {
BindMountStorageDirs(env, pkg_data_info_list,
uid, process_name, managed_nice_name, fail_fn);
}
if (mount_sysprop_overrides) {
BindMountSyspropOverride(fail_fn, env);
MountInitOverride(fail_fn, env);
}app data/JIT/sandbox 通过 tmpfs 和 bind mount 隔离;storage 参数决定 Android/data/obb 等目录;调试构建还可绑定 sysprop override。ProcessList 已对 isolated process 和 FUSE 状态过滤参数,native 只执行请求。
4. SystemServer预取
if (is_system_server
&& !(runtime_flags
& RuntimeFlags::PROFILE_SYSTEM_SERVER)) {
env->CallStaticObjectMethod(gZygoteInitClass,
gGetOrCreateSystemServerClassLoader);
env->CallStaticVoidMethod(gZygoteInitClass,
gPrefetchStandaloneSystemServerJars);
if (env->ExceptionCheck()) {
env->ExceptionClear();
}
}SystemServer 在 SELinux domain 切换前预取 classloader/AOT artifacts;profile 模式跳过以便 JIT。异常被清除,Java 后续仍有 fallback,但可能失去预取性能收益。
5. 身份与Seccomp
SetGids(env, gids, is_child_zygote, fail_fn);
SetRLimits(env, rlimits, fail_fn);
if (setresgid(gid, gid, gid) == -1) {
fail_fn(CREATE_ERROR("setresgid failed"));
}
SetUpSeccompFilter(uid, is_child_zygote);
SetSchedulerPolicy(fail_fn, is_top_app);
if (setresuid(uid, uid, uid) == -1) {
fail_fn(CREATE_ERROR("setresuid failed"));
}groups/rlimit 先设置;seccomp 和调度策略在失去特权前安装;最后切换 gid/uid。顺序错误会导致策略无法安装或进程保留过多权限。
6. Heap与SELinux
mallopt(M_BIONIC_SET_HEAP_TAGGING_LEVEL,
heap_tagging_level);
android_mallopt(M_INITIALIZE_GWP_ASAN,
&gwp_asan_options, sizeof(gwp_asan_options));
SetCapabilities(permitted_capabilities,
effective_capabilities,
permitted_capabilities, fail_fn);
if (selinux_android_setcontext(uid, is_system_server,
se_info_ptr, nice_name_ptr) == -1) {
fail_fn(CREATE_ERROR("selinux context failed"));
}MTE/TBI、heap zero init、GWP-ASan 和 page-size compat 从 runtime flags 映射到 bionic/allocator,再清除已消费 flag。SELinux context 由 uid、isSystemServer、seInfo 和 niceName 决定。
7. Post-fork hooks
if (is_system_server) {
env->CallStaticVoidMethod(gZygoteClass,
gCallPostForkSystemServerHooks,
runtime_flags);
selinux_android_setcon("u:r:system_server:s0");
}
env->CallStaticVoidMethod(gZygoteClass,
gCallPostForkChildHooks, runtime_flags,
is_system_server, is_child_zygote,
managed_instruction_set);
setpriority(PRIO_PROCESS, 0,
PROCESS_PRIORITY_DEFAULT);SystemServer 有专用 post-fork hook 和固定 domain;所有 child 都执行 postForkChild,恢复 ART/随机种子/coverage 等角色状态,最后恢复默认优先级。异常由 fail_fn 终止子进程。
8. 失败与导航
- mount/data failure:查 ProcessList 参数、FUSE 和 inode map;
- capability/seccomp failure:查目标 uid、child zygote 角色和内核策略;
- SELinux failure:查 seInfo、nice name 与 seapp_context;
- classloader prefetch error:查 profile flag 和 AOT 权限;
- post-fork error:查 ART hook 和 role-specific 初始化。
# Java specialization wrapper 和 post-fork。
rg -n "specializeAppProcess|nativeSpecializeAppProcess|postForkCommon|setAllowNetworkingForProcess" \
frameworks/base/core/java/com/android/internal/os/Zygote.java
# Native mount、身份、heap、SELinux、seccomp 与 hook 顺序。
rg -n "SpecializeCommon|MountEmulatedStorage|isolateAppData|BindMountStorageDirs|SetGids|SetRLimits|SetUpSeccompFilter|setresuid|selinux_android_setcontext|gCallPostForkChildHooks" \
frameworks/base/core/jni/com_android_internal_os_Zygote.cpp下一篇将分析 64/32 位进程选择与 ABI 路由,不重复 specialization 的安全和 namespace 顺序。
