news 2026/9/28 8:44:22

CodeQL C++ 查询库 4.3.1 解读:`RangeAnalysis` 在大型复杂函数体中的无限循环修复

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CodeQL C++ 查询库 4.3.1 解读:`RangeAnalysis` 在大型复杂函数体中的无限循环修复
  • 静态分析
  • SAST
  • 应用安全
  • 漏洞扫描
  • 代码质量

【免费下载链接】codeql

CodeQL: the libraries and queries that power security researchers around the world, as well as code scanning in GitHub Advanced Security

项目地址:https://gitcode.com/gh_mirrors/co/codeql
点击查看免费下载

CodeQL C++ 查询库(cppQL pack)的 4.3.1 版本是一个补丁版本,其发布说明记录了一项重要的缺陷修复:semmle.code.cpp.rangeanalysis.new.RangeAnalysis模块在计算“非常大且复杂”的函数体中的数值范围时不再陷入无限循环。本文以该发布说明为骨架,结合当前仓库中的范围分析模块源码,深入讲解这一修复涉及的模块职责、终止性问题的成因,以及该模块在 CodeQL C++ 安全查询体系中的实际地位,帮助读者理解这一补丁修复的底层原理与其对查询性能、结果完备性的影响。

一、4.3.1 发布说明原文

本次发布的变更记录位于 cpp/ql/lib/change-notes/released/4.3.1.md,全文如下:

4.3.1

Bug Fixes

  • Fixed an infinite loop insemmle.code.cpp.rangeanalysis.new.RangeAnalysiswhen computing ranges in very large and complex function bodies.

这条变更记录属于 CodeQL 仓库标准的“change notes”体系:每个已发布的查询库版本对应cpp/ql/lib/change-notes/released/目录下的一个独立 Markdown 文件(如 0.0.4.md、4.3.0.md、12.1.1.md 等),按“新增功能 / Bug 修复 / 弃用”等分类组织。仓库根目录的 docs/change-notes.md 描述了这套变更记录的编写约定。4.3.1作为4.3.0之后的补丁号,只包含缺陷修复,不引入新功能,因此本次记录仅有一条 Bug Fixes 条目。

虽然记录只有一句话,但它指向了一个贯穿多类安全查询的核心基础设施模块——这正是值得深入展开的技术点。

二、被修复的模块:semmle.code.cpp.rangeanalysis.new.RangeAnalysis

2.1 模块定位:C++ 的相对范围分析

发布说明中被修复的模块位于 cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/RangeAnalysis.qll,其文件头注释给出了精确定义:

Provides an AST-based interface to the relative range analysis, which tracks bounds of the forma <= b + deltafor expressionsaandband an integer offsetdelta.

也就是说,这是一个面向 AST 的“相对范围分析”接口:它并不只推断某个表达式是常数范围内的值,而是追踪形如表达式 a <= 表达式 b + 整数偏移 delta的相对边界。这种形式比单纯的常数范围分析表达能力更强——例如它可以表达“y <= arr.length - 2”这类依赖其他运行时值的边界。

2.2 核心公共谓词

该模块向查询作者暴露了以下关键入口(对应文件 cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/RangeAnalysis.qll):

  • bounded(Expr e, Bound b, float delta, boolean upper, Reason reason):当upper = true时表示e <= b + delta,且该边界可以追溯到一个 guard 条件(由reason表示);
  • convertedBounded(...):与bounded语义相同,但允许e是一个转换(conversion)表达式,即带隐式类型转换后依然成立的范围边界。

配套的类型还包括:

  • Bound抽象类:表示可为表达式推断出的“边界基值”,其子类ZeroBound(整数 0,用于表示所有常数边界)与ValueNumberBound(对应某个全局值编号GVN,即某个程序值的抽象代表)分别对应“相对零的常数边界”与“相对某个程序值的边界”;
  • Reason抽象类:CondReason表示边界来自某个具体条件(guard),NoReason表示边界是直接推导得到、不经过任何边界条件。

2.3 底层语义实现:IR 层的两阶段分析

AST 接口只是薄薄的一层“翻译”,真正的计算发生在语义层。RangeAnalysis.qll将 AST 表达式映射为语义表达式后,委托给 cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysis.qll 与 cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisImpl.qll。

从RangeAnalysisImpl.qll的源码结构可以看到,分析被组织为两个可实例化的阶段(RangeStage):

  • ConstantStage:常数阶段,推断零基(ZeroBound)边界,即e <= 0 + delta形式的常数范围;
  • RelativeStage:相对阶段,推断相对边界,即e <= b + delta且b是某个程序值。

公共谓词semBounded将两阶段的结果取并集(见 RangeAnalysisImpl.qll),并通过FloatDelta支持浮点偏移量。此外还组合了符号分析(SignAnalysis)与模运算分析(ModulusAnalysisInstantiated,来自codeql.rangeanalysis.ModulusAnalysis),用于处理取模、位与、位或等运算的边界传递。

因此,4.3.1 中“在计算范围时出现无限循环”的修复,作用于的正是这一整套跨阶段、跨 IR 指令的递归推导过程。

三、无限循环为什么会发生:终止性问题的理论背景

发布说明没有描述修复的具体手法,但仓库中同族模块的头部注释对这类分析的非终止风险给出了权威解释。参见实验版模块 cpp/ql/lib/experimental/semmle/code/cpp/rangeanalysis/RangeAnalysis.qll,其开篇完整描述了这一分析的基本模型:

  1. 步进关系(step relation):分析把范围推断建模为流问题。以len = arr.length; if (x < len) { ... y = x - 1; ... }为例,目标是推断y <= arr.length - 2,通过跟踪一条推导链完成:arr.length --> len = .. --> x < len --> x-1 --> y = .. --> y。
  2. 带偏移的步进:为处理加减常数与严格比较,步进关系被泛化为I1 --(delta)--> I2,表示“若I1 <= B则I2 <= B + delta”,对应谓词boundFlowStep。
  3. 传递闭包:完整范围分析即步进关系的传递闭包,沿途累加delta,对应谓词boundedInstruction。

关键在于,该注释还明确指出(RangeAnalysis.qll):

As all inferred bounds can be related directly to a path in the source code the only source of non-termination is if successive redundant (and thereby increasingly worse) bounds are calculated along a loop in the source code. We prevent this by weakening the bound to a small finite set of bounds when a path follows a second back-edge.

即:由于所有推断出的边界都能直接关联到源码中的一条路径,非终止的唯一来源是:沿着源码中的循环反复计算“冗余且越来越差”的边界(例如每次迭代都让delta增大/减小一个单位,永不收敛)。防御手段是当路径经过第二条回边(back-edge,即循环反向边)时,把边界弱化到一个小而有限的集合(weakenDelta将偏移弱化到[-1..1]区间,见 RangeAnalysis.qll 的weakenDelta)。之所以推迟到第二条回边才弱化,是因为精确边界有时需要完整遍历一次循环。

结合这一背景可以推断:4.3.1 修复的“在非常大且复杂的函数体中计算范围时出现无限循环”,属于同一类终止性缺陷在该“new”模块上的具体表现——当函数体规模极大、控制流复杂(多重嵌套循环、大量 phi 节点与回边)时,原有的弱化策略可能在某条推导路径上未能及时将边界限制到有限集合,导致推导链不收敛。修复的目标就是保证即使面对极端复杂的函数体,范围分析也必然终止。

3.1 phi 节点与回边:复杂度的重要来源

为什么复杂函数体容易触发这类问题?从实验版模块的注释可以看到,phi 节点(SSA 合并点)需要特殊处理:对x0 = phi(x1, x2),当x1 <= B + d1且x2 <= B + d2时,x0 <= B + max(d1, d2);而当x2来自回边且能证明变量在循环迭代中“非增”时,可以用“循环前成立的上界在循环内依然成立”这一规则。对 n 输入的 phi 节点,规则进一步泛化(RangeAnalysis.qll)。

在语义实现中,对应逻辑分散于boundedPhiOperand、boundedPhiInp、selfBoundedPhiInp、boundedPhiCandValidForEdge等谓词(见 RangeAnalysisImpl.qll)。函数体越大、循环与分支越复杂,phi 节点与回边就越多,边界推导的递归深度与分支组合数呈指数增长,非终止与性能恶化的风险随之显著上升——这正是发布说明强调“very large and complex function bodies”的原因。

四、修复的实际影响:范围分析被哪些查询使用

RangeAnalysis不是孤立模块,它支撑着 C++ 查询库中多条与“越界”“溢出”直接相关的安全查询。以下是仓库中确认的消费方(均为private import或import该模块的文件):

  • cpp/ql/lib/semmle/code/cpp/security/Overflow.qll:溢出检测的核心库,导入SimpleRangeAnalysis与RangeAnalysisUtils;
  • cpp/ql/lib/semmle/code/cpp/security/InvalidPointerDereference/AllocationToInvalidPointer.qll 与 InvalidPointerToDereference.qll:支撑cpp/invalid-pointer-deref查询;
  • cpp/ql/lib/semmle/code/cpp/security/ProductFlowUtils/ProductFlowUtils.qll:乘积类数据流工具;
  • cpp/ql/lib/semmle/code/cpp/commons/Printf.qll:格式化字符串相关检查。

其中,面向查询作者常用的入口是 cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/SimpleRangeAnalysis.qll(提供upperBound/lowerBound等简化接口),以及供上述安全查询使用的 cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/RangeAnalysisUtil.qll。后者头部注释明确写道:

This file contains the range-analysis specific parts of thecpp/invalid-pointer-derefandcpp/overrun-writequery.

其bounded1/bounded2/bounded谓词通过bindingset与inline_late等编译指令强制 join 顺序,以保证在已绑定的指令上高效求值(见 RangeAnalysisUtil.qll)。

因此,4.3.1 的修复不只是“某个内部模块不卡死”这么简单:它保证依赖范围分析的溢出检测(如整数溢出、无效指针解引用、缓冲区越界写等)在遇到极端庞大的函数体时依然能够正常返回结果,而不是让整个查询评估在该函数上挂起——这对 CodeQL 在大型真实代码库上的可用性与结果完备性都至关重要。

五、如何在当前仓库中验证与跟进

  • 查看本次变更记录:直接阅读 cpp/ql/lib/change-notes/released/4.3.1.md,对比相邻版本 4.3.0.md 可观察补丁版本只含 Bug Fixes 的发布节奏;
  • 通读被修复模块:cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/RangeAnalysis.qll 全文约 100 行,是理解“相对范围分析”公共接口的最佳起点;
  • 追踪语义实现:RangeAnalysisImpl.qll 展示了常数阶段与相对阶段如何组合、符号分析与模运算分析如何接入;
  • 学习终止性理论:实验版模块 cpp/ql/lib/experimental/semmle/code/cpp/rangeanalysis/RangeAnalysis.qll 的头部注释是理解步进关系、回边与弱化策略的最佳材料。

对于使用 CodeQL 的开发者而言,本修复随cpp查询库 4.3.1 版本发布,升级到包含该版本或更高版本的 CodeQL 查询包后即可自动受益,无需修改任何查询代码——影响体现在:原本在超大函数体上可能导致范围分析不终止的查询场景,现在能够顺利评估并产出结果。

小结

cpp查询库 4.3.1 用一条简洁的 Bug Fixes 记录,修复了semmle.code.cpp.rangeanalysis.new.RangeAnalysis在非常大且复杂的函数体中计算范围时的无限循环问题。透过这条记录,我们得以审视 CodeQL C++ 中相对范围分析的设计:以a <= b + delta为基本形式、以步进关系与传递闭包为计算模型、以回边弱化策略保证终止性。该模块作为溢出、无效指针解引用、越界写等核心安全查询的公共依赖,其终止性与性能直接决定了这些查询在大型代码库上的可用性——这正是本次补丁修复的深层价值所在。

  • 静态分析
  • SAST
  • 应用安全
  • 漏洞扫描
  • 代码质量

【免费下载链接】codeql

CodeQL: the libraries and queries that power security researchers around the world, as well as code scanning in GitHub Advanced Security

项目地址:https://gitcode.com/gh_mirrors/co/codeql
点击查看免费下载

相关推荐

上一篇:Blender 3MF格式插件:实现3D打印工作流的技术架构与实践指南
下一篇:Jedis RediSearch 快速上手:在 Java 中构建索引、全文检索与聚合分析

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

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

基于SpringBoot与Vue的景区在线购票系统设计与实现

1. 项目概述1.1 核心需求解析这两年随着文旅行业复苏&#xff0c;景区票务系统的线上化率一直在涨&#xff0c;但很多中小景区的购票体验还停留在“线下排队人工核销”的阶段。我之前帮一个客户做景区数字化改造&#xff0c;发现他们最大的痛点不是硬件&#xff0c;而是没有一个…

作者头像 李华
网站建设 2026/9/28 8:43:28

基于YOLOv8的道路标线磨损监测系统:数据训练到部署全流程

简介&#xff1a;一套基于YOLOv8的交通道路标线磨损监测系统&#xff0c;面向目标检测、深度学习的毕设与课程设计场景&#xff0c;也适合计算机相关专业学生快速上手实战。资源包含完整源码、可视化交互界面、标注数据集与部署说明&#xff0c;运行环境简单&#xff0c;下载后…

作者头像 李华
网站建设 2026/9/28 8:42:43

操作系统核心原理与实战:从进程、内存到文件系统的完整认知体系

写这篇东西的起因很简单——我带过不少新人&#xff0c;也带过不少刚转行做开发的朋友&#xff0c;发现大家问得最频繁、卡壳最多的往往是同一个问题&#xff1a;操作系统到底在做什么&#xff1f;这个词咱们每天都在用&#xff0c;电脑上跑着 Windows&#xff0c;服务器上跑着…

作者头像 李华
网站建设 2026/9/28 8:42:43

MATLAB实现RF-RFE-BP回归预测:随机森林特征筛选与神经网络结合

做回归预测的人&#xff0c;多少都被“特征太多”折腾过。手里一份多维数据集&#xff0c;特征几十个上百个&#xff0c;直接扔给BP神经网络&#xff0c;经常出现两种结果&#xff1a;要么训练半天收敛不动&#xff0c;要么训练集拟合得漂亮&#xff0c;测试集一测就拉胯。问题…

作者头像 李华
网站建设 2026/9/28 8:42:19

Univer SDK:国产开源文档协同引擎技术解析

1. Univer 是什么&#xff1a;一个被严重低估的国产办公套件底层引擎最近在几个技术群里看到有人问“Univer 在线怎么接入”“Univer SDK 文档在哪找”&#xff0c;还有人把 Univer 和阿里云认证 SDK、Android SDK、Vivado SDK 混在一起搜&#xff0c;甚至搜出“hip sdk 安装包…

作者头像 李华