Skip to content

forkSystemServer

拆解 forkSystemServer 的 capability 交集、参数协议、MTE/GWP-ASan flags、native fork 和子进程交接。

基于android-17.0.0_r1
AndroidZygoteSystemServerfork源码阅读

forkSystemServer ​

forkSystemServer() 不是对通用应用 fork 的简单包装。它在 Java 中构造固定的 system uid/gid、supplementary groups、capability 和目标类参数,再根据设备能力补充 MTE、GWP-ASan 与 profile flags,最后调用专用 native fork。父 Zygote 得到子 pid 并返回 null;子进程得到 0,等待 secondary Zygote、关闭继承 socket,再把 parsedArgs 交给 handleSystemServerProcess()。

1. Capability候选集 ​

源码文件:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

java
long capabilities =
        (1L << OsConstants.CAP_IPC_LOCK) |
        (1L << OsConstants.CAP_KILL) |
        (1L << OsConstants.CAP_NET_ADMIN) |
        (1L << OsConstants.CAP_NET_BIND_SERVICE) |
        (1L << OsConstants.CAP_NET_BROADCAST) |
        (1L << OsConstants.CAP_NET_RAW) |
        (1L << OsConstants.CAP_SYS_NICE) |
        (1L << OsConstants.CAP_SYS_PTRACE) |
        (1L << OsConstants.CAP_SYS_TIME) |
        (1L << OsConstants.CAP_SYS_TTY_CONFIG) |
        (1L << OsConstants.CAP_WAKE_ALARM) |
        (1L << OsConstants.CAP_BLOCK_SUSPEND) |
        (1L << OsConstants.CAP_MAC_ADMIN);

这是期望集合,不是无条件最终集合。SystemServer 需要网络管理、进程终止、调度、唤醒和 safesetid policy 等能力;每个 bit 的消费者属于后续具体系统服务。forkSystemServer() 只负责把候选集合传给 specialization。

2. 与当前能力取交集 ​

java
StructCapUserHeader header = new StructCapUserHeader(
        OsConstants._LINUX_CAPABILITY_VERSION_3, 0);
StructCapUserData[] data;
try {
    data = Os.capget(header);
} catch (ErrnoException ex) {
    throw new RuntimeException("Failed to capget()", ex);
}

capabilities &= Integer.toUnsignedLong(data[0].effective)
        | (Integer.toUnsignedLong(data[1].effective) << 32);

Zygote 用 capget() 读取自身 effective set,再与候选集合取交集。容器或裁剪环境缺少的 capability 不会凭 SystemServer 参数重新产生。capget 失败会阻止 fork;这比在子进程中带着未知 capability 状态继续启动更安全。

3. 固定参数协议 ​

java
String[] args = {
    "--setuid=1000",
    "--setgid=1000",
    "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,"
            + "1024,1032,1065,3001,3002,3003,3005,3006,3007,3009,3010,3011,3012",
    "--capabilities=" + capabilities + "," + capabilities,
    "--nice-name=system_server",
    "--runtime-args",
    "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
    "com.android.server.SystemServer",
};

这些参数复用 ZygoteArguments 协议:uid/gid 切到 system,groups 提供设备/网络等 supplementary 权限,permitted/effective capability 使用同一交集结果,目标类固定为 SystemServer。参数先写入内存 ZygoteCommandBuffer 再由统一 parser 解析,避免 SystemServer 特殊路径和普通 Zygote 命令对字段语义产生两套实现。

4. Runtime flags ​

源码文件:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

java
Zygote.applyDebuggerSystemProperty(parsedArgs);
Zygote.applyInvokeWithSystemProperty(parsedArgs);

if (Zygote.nativeSupportsMemoryTagging()) {
    String mode = SystemProperties.get(
            "persist.arm64.memtag.system_server", "");
    if (mode.isEmpty()) {
        mode = SystemProperties.get(
                "persist.arm64.memtag.default", "async");
    }
    if (mode.equals("async")) {
        parsedArgs.mRuntimeFlags |= Zygote.MEMORY_TAG_LEVEL_ASYNC;
    } else if (mode.equals("sync")) {
        parsedArgs.mRuntimeFlags |= Zygote.MEMORY_TAG_LEVEL_SYNC;
    } else if (!mode.equals("off")) {
        parsedArgs.mRuntimeFlags |= Zygote.nativeCurrentTaggingLevel();
    }
} else if (Zygote.nativeSupportsTaggedPointers()) {
    parsedArgs.mRuntimeFlags |= Zygote.MEMORY_TAG_LEVEL_TBI;
}

parsedArgs.mRuntimeFlags |= Zygote.GWP_ASAN_LEVEL_LOTTERY;
if (shouldProfileSystemServer()) {
    parsedArgs.mRuntimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
}

MTE 分支首先看硬件/runtime 支持,再读 SystemServer 专用属性;非法 mode 保留当前 tagging level 并记录错误。没有 MTE 但支持 tagged pointers 时使用 TBI。GWP-ASan lottery 无条件加入 runtime flags,profile 则受实验属性控制。这些 flags 在 native specialization/post-fork 中消费,不是 SystemServer.main() 自己解析。

5. Native fork入口 ​

java
pid = Zygote.forkSystemServer(
        parsedArgs.mUid,
        parsedArgs.mGid,
        parsedArgs.mGids,
        parsedArgs.mRuntimeFlags,
        null,
        parsedArgs.mPermittedCapabilities,
        parsedArgs.mEffectiveCapabilities);

SystemServer 使用专用 Zygote.forkSystemServer(),rlimits 参数传 null。native 层负责真正 fork、uid/gid/groups、capability、SELinux、seccomp 和 post-fork hooks。Java 返回值仍遵循 POSIX 语义:父进程为 child pid,子进程为 0,错误通过异常/abort 路径处理。

6. 子进程同步与交接 ​

java
if (pid == 0) {
    if (hasSecondZygote(abiList)) {
        waitForSecondaryZygote(socketName);
    }
    zygoteServer.closeServerSocket();
    return handleSystemServerProcess(parsedArgs);
}
return null;

双 Zygote 配置下,SystemServer 子进程等待另一 socket 可连接,保证后续 32/64 位应用路由的基础服务已就绪。然后关闭继承的监听 socket,避免 SystemServer 持有 Zygote 控制 fd。返回的 Runnable 才是下一阶段入口;父 Zygote得到 null 并继续 runSelectLoop()。

7. 失败与owner ​

  • capget 失败:Zygote Java 阶段终止,尚未 fork;
  • 参数 parser 失败:包装为 RuntimeException,不进入 native fork;
  • MTE 属性非法:记录错误并保留当前 tagging level,不直接停止;
  • native fork/specialization 失败:由 native Zygote 路径终止或抛错;
  • secondary Zygote 长时间不可连接:SystemServer 子进程阻塞在连接等待,尚未进入 handleSystemServerProcess();
  • socket close 失败:记录清理错误,必须结合子进程是否仍持有监听 fd 判断风险。

8. 导航与后续 ​

bash
# 输入 SystemServer fork 实现,输出 capability、参数、runtime flags 和父子分支。
rg -n "forkSystemServer|capget|--setuid=1000|MEMORY_TAG|GWP_ASAN|PROFILE_SYSTEM_SERVER|waitForSecondaryZygote" \
  frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

# 输入 native Zygote,输出专用 fork 与 specialization 消费者。
rg -n "nativeForkSystemServer|forkSystemServer|SpecializeCommon|postForkSystemServer" \
  frameworks/base/core/java/com/android/internal/os/Zygote.java \
  frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

下一篇将展开 handleSystemServerProcess():umask、进程名、classloader、profile、invoke-with 和 zygoteInit() 交接;不会重复本文的 capability 与 native fork 输入。