ClickHouse v26.3.15.4-lts 版本发布说明:输入解析深度限制、ELF/DWARF 边界检查与 Arrow 空字符串列修复
【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse
本篇指南基于当前仓库中的官方发布说明 docs/changelogs/v26.3.15.4-lts.md,系统梳理 ClickHouse 26.3 LTS 分支补丁版本 v26.3.15.4-lts 的三项核心修复。你将了解到:嵌套格式输入深度防护如何消除解析崩溃、ELF/DWARF 解析如何补齐边界检查、以及 Apache Arrow Java 旧版本空列兼容问题的修复细节,并能在源码中定位到对应的实现与印证位置。
版本定位:26.3 LTS 分支的持续维护补丁
v26.3.15.4-lts (3c767441a1e)是 ClickHouse 26.3 长期支持(LTS)分支上的一个小版本补丁,其对比基准为v26.3.14.49-lts (9d65f3bceb7)。从当前仓库的 cmake/autogenerated_versions.txt 可以看到,主线开发版本号体系采用MAJOR.MINOR.PATCH三段式(例如当前主线为26.10.1.1-testing),而 LTS 分支则在此基础上叠加了第四段.15的补丁号与.49的构建号,反映同一条稳定分支上的多次迭代。
本次发布包含 3 项修复,全部归入Bug Fix(用户可感知的官方稳定版问题修复)类别,即修复的都是用户在官方稳定版本中实际可能遇到的功能错误或崩溃问题,而非新功能增强。这类修复通常具备两个特征:影响面明确(仅针对受影响的功能模块)、风险可控(改动经过 LTS 分支的后向移植评审)。
修复一:深层嵌套输入导致的服务端栈溢出崩溃
问题现象
当读取深度嵌套的 schema 或值时,服务端可能出现栈溢出(stack overflow)并崩溃。受影响的格式包括:
- MsgPack(MessagePack 二进制序列化格式)
- BSON(MongoDB 等使用的二进制 JSON 变体)
- ORC(Apache ORC 列式存储格式)
- Parquet(Apache Parquet 列式存储格式)
- JSON(文本 JSON 系列格式)
- DeltaLake(Delta Lake 表格式)
- Iceberg(Apache Iceberg 表格式)
- Paimon(Apache Paimon 表格式)
以上格式的输入解析器中存在递归或嵌套处理逻辑。当输入数据人为构造为极深的嵌套层级时,解析递归深度会超过线程栈容量,导致进程栈溢出直接崩溃。这种输入既可能是恶意的(作为拒绝服务攻击向量),也可能是意外产生的异常数据。
修复方式
修复后,此类深层嵌套输入不再被解析,而是以异常(exception)形式被拒绝,从而将"进程崩溃"降级为"可捕获、可报告的错误"。该修复由 Raúl Marín 提交于 PR #107341,并作为 Issue #108279 的后向移植合并进 26.3 LTS 分支。
源码印证
从当前仓库源码看,ClickHouse 为 BSON、MsgPack 等格式维护了独立的类型定义与格式设置模块,例如:
- src/Formats/BSONTypes.h 定义了 BSON 的类型枚举、文档结束符(
BSON_DOCUMENT_END = 0x00)、对象 ID 大小、32 位长度类型BSONSizeT等底层结构,说明 BSON 解析器直接面对二进制长度前缀与嵌套文档结构; - src/Formats/MsgPackExtensionTypes.h 定义了 MsgPack 扩展类型枚举;
- src/Formats/FormatSettings.h 中可见 MsgPack 的 UUID 表示方式等格式相关配置项。
这些格式在解析嵌套结构时都依赖递归下降式的子对象读取逻辑,深度未加限制时即存在栈耗尽风险。修复方案的核心思路是引入深度上限检测:当嵌套层级超过阈值时立即抛出异常并终止解析,而不是继续无限递归。这与此类格式解析器的通用防护手段一致,即在递归入口处维护深度计数器,并在超过上限时短路返回错误。
修复二:ELF 与 DWARF 解析补齐缺失的边界检查
问题现象
第二项修复针对的是 ELF 与 DWARF 解析器中的缺失边界检查(missing bounds checks),由 Michael Kolupaev 提交于 PR #107579,作为 Issue #108237 的后向移植合入。
ELF(Executable and Linkable Format)是 Linux 下可执行文件与共享库的二进制格式;DWARF 则是用于存储调试信息(如源码行号、变量位置)的标准调试格式。ClickHouse 在崩溃时打印堆栈、将地址反解为函数名与源码位置时,需要解析这些格式。
影响范围与风险
如果解析器在读取 ELF section header、DWARF 调试信息条目(DIE)、缩写表(abbreviations)、属性(attributes)以及行号虚拟机(line number VM)字节码时未做边界校验,那么面对被截断、损坏或恶意构造的 ELF/DWARF 数据,就可能在越界读取时产生未定义行为,甚至被利用造成内存破坏。从源码结构看,这类解析发生在异常处理与堆栈符号化的关键路径上,一旦出错会直接影响崩溃诊断的可靠性。
源码印证
相关实现集中在 src/Common/Elf.h、src/Common/Elf.cpp、src/Common/Dwarf.h 与 src/Common/Dwarf.cpp:
- src/Common/Elf.h 中的
Elf类负责"遍历 ELF 中的 section",并提供iterateSections、findSection等 API;其内部保存了section_headers指针与section_names_size("自section_names起可用的字节数,用于边界检查"),说明边界检查能力本身就是该类设计的一部分,本次修复正是补齐了这一能力在若干解析分支上的覆盖; - src/Common/Elf.h 展示了从
SHT_NOTE(section header)获取 build id、并回退到PT_NOTES(program header)的逻辑,这两类区域都来自文件偏移,是需要严格校验边界的典型场景; - src/Common/Dwarf.h 的类注释明确说明:DWARF 解析器完全不分配堆内存,这是为了能在内存受限场景(如
std::out_of_memory异常处理器)中安全使用——正因如此,它用std::string_view直接指向 ELF 文件 section 内的数据,任何越界都直接落在进程地址空间中,边界检查因此至关重要; - DWARF 解析器支持 DWARF 2/3/4/5 版本,能够解析 DIE、缩写表、属性及行号虚拟机字节码,用于将 PC 地址转换为文件名与行号。
修复后,解析器在访问这些二进制结构时都会校验偏移与长度是否落在可用范围内,非法输入将得到明确的解析失败结果而非越界访问。
修复三:兼容 Apache Arrow Java 旧版本的空 String/Binary 列
问题现象
第三项修复针对读取Arrow/ArrowStream数据时的兼容性问题:当数据由Apache Arrow Java < 19.0.0(包括 Apache Spark 生成的数据)产生,且包含空的String/Binary列时,ClickHouse 读取会抛出INCORRECT_DATA错误。
根因分析
从行为特征可以推断,旧版 Arrow Java 在序列化空字符串/二进制列时,对 buffer 元数据(如变长列的长度 buffer 与数据 buffer 的划分)的处理与新版实现或 Arrow C++ 的约定存在差异。ClickHouse 的 Arrow 读取器依据严格约定校验列元数据与 buffer 布局,当两者不一致时即判定数据非法,抛出INCORRECT_DATA。修复的实质是放宽对空列 buffer 布局的校验,使这类合法但"另类"的空列数据能够被正确识别为空值而不是被当作损坏数据。该修复由 Raúl Marín 提交于 PR #107764,作为 Issue #108157 的后向移植合入。
实战意义
这一修复对使用 Spark 或 Arrow Java 生态将数据写入 Arrow 格式,再由 ClickHouse 消费的场景有直接价值:升级前空字符串列会整表读取失败,升级后无需改写上游数据即可正常读取。对于 Arrow 格式用户,建议在升级 26.3 LTS 分支到本版本后,对存量 Arrow 数据做一次全量读取回归验证。
升级与验证建议
- 升级目标:将 26.3 LTS 分支升级到
v26.3.15.4-lts(或该分支的更新补丁版本),以同时获得上述三项修复。 - 回归重点:
- 构造或收集包含深度嵌套文档的 MsgPack/BSON/JSON 输入,确认现在得到的是可捕获的异常(如
INCORRECT_DATA或深度限制相关错误)而非进程崩溃; - 对由 Spark 或 Arrow Java 旧版生成的 Arrow 文件(含空字符串列)执行
SELECT全量读取,确认不再报INCORRECT_DATA; - 触发一次服务端崩溃(如
kill -SEGV或使用clickhouse-local的 stack trace 功能),确认堆栈符号化(ELF/DWARF 解析路径)正常输出函数名与行号。
- 构造或收集包含深度嵌套文档的 MsgPack/BSON/JSON 输入,确认现在得到的是可捕获的异常(如
- 版本核对:可在升级后通过
SELECT version()确认版本号为26.3.15.4(LTS 补丁系列),并参考 docs/changelogs 目录持续关注该分支的后续补丁发布。
小结
v26.3.15.4-lts是一个典型的 LTS 稳定性补丁版本:三项修复分别覆盖输入解析健壮性(深层嵌套防护)、二进制解析安全性(ELF/DWARF 边界检查)与生态兼容性(Arrow Java 空列兼容),均属于"用户可感知"级别的修复。从源码印证看,这些改动与 src/Common/Elf.h、src/Common/Dwarf.h、src/Formats/BSONTypes.h 等模块的既有设计一脉相承——前者补全了设计文档中承诺的边界检查,后者为解析递归引入了深度护栏。对于在生产环境运行 26.3 LTS 的用户,建议及时跟进该分支补丁以消除上述崩溃与兼容性隐患。
【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考