news 2026/9/12 11:25:26

SerenityOS 移植 the_silver_searcher:为 pledge 权限列表补充 thread 的补丁全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SerenityOS 移植 the_silver_searcher:为 pledge 权限列表补充 thread 的补丁全解析

SerenityOS 移植 the_silver_searcher:为 pledge 权限列表补充 thread 的补丁全解析

【免费下载链接】serenityThe Serenity Operating System 🐞项目地址: https://gitcode.com/GitHub_Trending/se/serenity

本篇文章围绕 SerenityOS 移植 the_silver_searcher(命令行代码搜索工具 ag)过程中所需的一份关键补丁展开。该补丁的核心是:在程序调用pledge()限制自身系统能力时,把thread权限显式加入权限列表——原因在于 OpenBSD 的stdio通常已隐式授予thread,而 SerenityOS 将thread作为独立权限项。读完本文,你将理解这份补丁的动机、四处分歧点的具体改动,以及 SerenityOS 内核侧pledge系统调用的实现原理与移植构建流程。

补丁文档说了什么

仓库中的 补丁说明文档 内容非常聚焦,它只描述了一个补丁:

  • 补丁文件0001-Add-the-thread-pledge-to-the-pledge-list.patch
  • 补丁标题:Add the thread pledge to the pledge list(向 pledge 权限列表中添加 thread 权限)
  • 补丁动机(文档原文):On OpenBSD, stdio typically grants thread, but on Serenity it is its own option.

这句话是整个补丁的灵魂:在 OpenBSD 的 pledge 语义里,stdio权限会顺带赋予进程创建线程(thread)的能力;而 SerenityOS 对权限的划分更细,stdiothread是两个完全独立的权限位。因此 the_silver_searcher 这份原本面向 OpenBSD 的pledge调用,在 SerenityOS 上运行时会因缺少显式的thread权限而导致线程相关系统调用被拒绝,必须打上这个补丁才能正常发挥多线程并行搜索能力。

补丁的四处分歧点详解

该补丁由作者 Raymond Lucke 提交,共修改了上游源码中的两个文件、四处pledge()调用,统计为 4 行新增、4 行删除(4 insertions(+), 4 deletions(-))。所有改动模式一致:在原有权限字符串中追加thread

1.src/main.c:主函数入口的初始权限

补丁将主函数main()一开始的权限声明从:

pledge("stdio rpath proc exec", NULL)

改为:

pledge("stdio rpath proc exec thread", NULL)

这是进程最早一次声明能力边界,涵盖标准 I/O、文件路径读取(rpath)、进程管理(proc)、执行子进程(exec)以及线程创建(thread)。从补丁上下文可以看到main()中声明了int num_cores;,从源码结构看,ag 会按 CPU 核心数并行调度搜索任务,这正是需要thread权限的直接原因。

2.src/main.c:扫描开始前的权限收紧

在完成初始化、即将进入实际搜索阶段时,ag 再次调用pledge(),将权限从上面的宽集合收紧为:

pledge("stdio rpath thread", NULL)

注意这里去掉了procexec——搜索阶段不再需要派生子进程,这是典型的"最小权限"实践:先以较宽权限完成启动,再在不需要时立即放弃多余权限,降低被攻破后的影响面。

3.src/options.c--skip-vcs-ignores分支

parse_options()中,当用户指定skip_vcs_ignores(跳过.gitignore等版本控制忽略文件,此时需自行递归读取文件系统)时,权限从:

pledge("stdio rpath proc", NULL)

改为:

pledge("stdio rpath proc thread", NULL)

4.src/options.c:选项解析完成后的兜底调用

parse_options()末尾,无论是否跳过 VCS 忽略规则,都会执行最后一次权限设置,同样从"stdio rpath proc"追加为:

pledge("stdio rpath proc thread", NULL)

为什么必须是 thread:SerenityOS 的 pledge 实现

要理解这个补丁,需要看 SerenityOS 内核如何实现pledge。核心实现位于 Kernel/Syscalls/pledge.cpp,系统调用入口为Process::sys$pledge(),它接收两个字符串参数:promises(立即生效的权限)与execpromises(exec 新程序后生效的权限)。

权限字符串的解析逻辑在 pledge.cpp 中:内核按空格拆分字符串,将每一段与ENUMERATE_PLEDGE_PROMISES枚举出的权限名逐一比对,命中则置位对应的权限掩码位;若出现任何无法识别的权限名,整个调用返回EINVAL。因此补丁中追加的thread必须与内核枚举中的名字完全一致,否则会导致pledge失败并触发die("pledge: %s", strerror(errno))

SerenityOS 内核对权限的完整清单定义在 Kernel/Tasks/Process.h 的ENUMERATE_PLEDGE_PROMISES宏中,一共 25 项,其中thread位于列表中部(紧跟在chown之后),stdiorpathprocexec均在列。这从内核源码层面印证了文档的说法:在 SerenityOS 上thread是一个独立权限位,不会由stdio隐式授予。

此外,pledge.cpp 还展示了一个值得注意的细节:权限一旦设置,后续调用只能收缩、不能扩张——若新权限超出已有权限集,除非声明了no_error,否则返回EPERM。这意味着补丁必须把thread写进每一次(包括最初的宽权限调用)pledge 中,否则进程会在中途失去创建线程的能力。这也是为什么这份补丁需要同时修改四处调用点,而不是只改第一处。

移植构建配置:port 是如何被打包的

这份补丁所属的移植位于 Ports/thesilversearcher/,目录结构只有两个文件:package.shpatches/。其中 package.sh 定义了移植的构建方式:

  • portthesilversearcher,版本2.2.0
  • 构建方式useconfigure="true",即采用 autoconf 式的 configure + make 流程;
  • 源码:从上游官方发布渠道下载the_silver_searcher-2.2.0.tar.gz,并以 SHA 值校验完整性;
  • 工作目录:解压后为the_silver_searcher-2.2.0
  • 依赖pcre(正则表达式引擎)与xz(LZMA 压缩解码支持);
  • 编译标志export CFLAGS="-fcommon -D_GNU_SOURCE -lpthread"

值得留意的是-lpthread:它保证链接阶段正确引入 POSIX 线程库,与补丁中显式声明thread权限形成呼应——运行期需要线程能力,构建期同样需要线程库支持,两者缺一不可。

SerenityOS 的 Ports 机制会在构建时自动应用patches/目录下的全部补丁:patch 采用标准git format-patch格式(包含FromDateSubject头部),并带diff --git变更块,构建系统据此将改动打到解压后的源码树上,随后执行 configure 与 make 完成编译安装。

移植工作流参考

若你想在本地复现或验证这个移植,可以遵循 SerenityOS 通用的 Ports 构建流程(详见 Ports/README.md 与 BuildInstructions.md):

  1. 准备 SerenityOS 工具链与构建环境;
  2. 进入Ports/目录,对目标移植执行构建脚本,例如cd Ports/thesilversearcher && ./package.sh
  3. 构建系统会依次完成:下载源码 → 校验 → 应用patches/0001-Add-the-thread-pledge-to-the-pledge-list.patch→ configure → make → 安装;
  4. 在 SerenityOS 系统中执行ag,即可体验多线程并行代码搜索。

若在运行中观察到pledge: ...类报错,可从两个方向排查:一是确认 patches 已正确应用(对比补丁中四处pledge调用是否已带thread);二是确认当前 SerenityOS 内核版本中的Pledge枚举(Kernel/Tasks/Process.h)仍包含thread项。

小结

这份看似只有 4 行改动的补丁,背后串联起 SerenityOS 的安全设计与移植工程的完整链条:上游 OpenBSD 的 pledge 语义与 SerenityOS 的权限粒度差异(stdio是否隐含thread),决定了必须在所有权限声明点显式追加thread;内核侧 pledge.cpp 的"权限只减不增"校验,决定了四处调用必须同步修改;而 package.sh 中的-lpthread则从构建层面保证了线程能力的完整落地。理解这一补丁,也就理解了 SerenityOS 移植第三方软件时处理平台安全 API 差异的典型范式。

【免费下载链接】serenityThe Serenity Operating System 🐞项目地址: https://gitcode.com/GitHub_Trending/se/serenity

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 11:25:03

Django开发流浪动物领养系统:技术实现与公益价值

1. 项目概述:流浪动物领养系统的技术实现与价值去年参与某动物保护组织的IT系统升级时,我亲眼目睹了纸质档案管理的种种不便——领养申请堆积如山、动物信息更新滞后、志愿者排班混乱。这正是我决定用Django开发流浪动物领养系统的初衷。这个毕业设计级别…

作者头像 李华
网站建设 2026/9/12 11:24:07

文本相似度计算算法与应用实践

1. CSP第二题相似度计算概述CSP(Content Security Policy)第二题的相似度计算是一个典型的文本处理与算法设计问题。这类题目通常要求参赛者设计算法来量化两个文本片段之间的相似程度,在信息安全、内容过滤和文本分析等领域有广泛应用。相似…

作者头像 李华
网站建设 2026/9/12 11:22:29

n8n自动化工作流开发:Plivo、PostBin与Postgres节点实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 11:22:08

Prescan与Simulink联合仿真开发LKA和AEB系统

1. 项目概述:PrescanSimulink实现LKA与AEB系统开发在智能驾驶系统开发领域,车道保持辅助(LKA)和自动紧急制动(AEB)是两项关键的ADAS功能。这个项目展示了如何利用Prescan仿真平台与Simulink控制模型的联合仿真环境,实现完整的LKA和AEB系统开发…

作者头像 李华
网站建设 2026/9/12 11:20:28

OpenClaw企业级自动化平台架构与RAG集成实战

1. 项目概述:OpenClaw企业级技术栈解析OpenClaw作为新一代企业级自动化平台,正在重塑传统办公流程。这个看似简单的工具名称背后,实际上整合了文档处理引擎、任务调度系统和智能分析模块三大核心技术组件。在企业级部署场景中,它需…

作者头像 李华