CodeQL C++ 范围分析演进:SimpleRangeAnalysis 对无符号乘法、常量乘法的扩展与自定义规则机制

发布时间:2026/9/25 10:13:00

CodeQL C++ 范围分析演进:SimpleRangeAnalysis 对无符号乘法、常量乘法的扩展与自定义规则机制 静态分析SAST应用安全漏洞扫描代码质量【免费下载链接】codeqlCodeQL: 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 查询库的一次重要变更记录展开SimpleRangeAnalysis范围分析库新增了对无符号数乘法、常量乘法、引用类型函数参数、不等比较收窄范围以及if (x)布尔判零等语言构造的支持并且首次开放了通过SimpleRangeAnalysisExpr抽象类注入自定义范围规则的扩展点。读完本文你将理解这些能力背后的格lattice抽象解释原理、widening 终止性设计并能参考仓库中的现成示例为自己的查询添加范围分析扩展。1. 变更概览五项新语法支持与自定义规则能力该变更记录2020-09-29-range-analysis-rollup.md面向 lgtm 与 codescanning 两个平台其核心内容可以概括为两部分第一部分新支持的语言构造。SimpleRangeAnalysis库在此前不支持五类 C 语言构造本次变更全部补齐无符号数的乘法multiplication of unsigned numbers与常量相乘multiplication by a constant引用类型的函数参数reference-typed function parameters用“变量不等于其值域端点”的比较收窄范围——例如x ! c且c是x的当前下界时可将下界向前推进一格用if (x)或if (!x)这类布尔上下文测试“是否等于零”。变更说明同时指出这些改进主要影响三个查询cpp/constant-comparison、cpp/comparison-with-wider-type和cpp/integer-multiplication-cast-to-long。第二部分可扩展性。库从此可以接受用户自定义规则官方示例存放在变更记录所列的cpp/ql/src/experimental/semmle/code/cpp/rangeanalysis/extensions/目录下。需要说明的是在当前的仓库结构中这些示例已经迁移到了cpp/ql/lib/experimental/semmle/code/cpp/rangeanalysis/extensions/而抽象接口则位于cpp/ql/lib/experimental/semmle/code/cpp/models/interfaces/。2. 原理基础在 QL 中实现范围分析的三个关键设计要理解这次变更的价值先看 SimpleRangeAnalysis.qll 文件头部注释对算法本身的描述。范围分析通常是对“值域格”的抽象解释——每个表达式的抽象值是一对浮点数(lowerBound, upperBound)。直接用格求最小不动点会遇到收敛过慢的问题文件注释中给出的经典反例是int count 0; for (; p; p p-next) { count count 1; }count的值域从(0,0)出发每轮不动点迭代只向上推进一格的边界(0,1)、(0,2)……直到maxInt格的高度几乎无界。库给出的对策有三点全部可以直接在源码中验证固定 widening 边界集。当某个定义“递归地依赖自身”通过defDependsOnDef的传递闭包检测见 SimpleRangeAnalysis.qll 中的defDependsOnDefTransitively与isRecursiveDef就把它的边界舍入到一个固定集合。下界集合是2, 1, 0, -1, -2, -8, -16, -128, -256, -32768, -65536, typeLowerBound, -Inf上界集合是对称的-2, -1, 0, 1, 2, 7, 15, 127, 255, 32767, 65535, typeUpperBound, InfwideningLowerBounds / wideningUpperBounds。注释明确说这与抽象解释中的 widening 技术类似但因为 QL 无法查看上一轮迭代的边界精度略低——例如 widening 可能推出下界-11而这里只能近似为-16。用浮点数表示边界。注释解释了动机浮点不会溢出回绕且可以通过“边界落在类型可表示范围之外”直接检测正/负溢出getTruncatedLowerBounds与getTruncatedUpperBounds分别处理了这种不可表示边界的截断见 SimpleRangeAnalysis.qll。先收集边界集合、后聚合。由于 QL 不允许在递归子表达式上做聚合aggregate递归阶段为每个表达式产生“一组下界”和“一组上界”最小下界与最大上界在递归结束后才计算。这条限制还引出了一个性能护栏BoundsEstimate模块在分析前估计边界数量一旦超过2^29的上限getBoundsLimitSimpleRangeAnalysis.qll就提前启用 widening注释说明该阈值是“经验性地选取到足以避免在特定客户数据库上超时”的值。理解这三点后本次变更的五项新支持就不再是“功能列表”而是格上每一类算术/控制流算子的边界传播规则被逐一补全的过程。3. 新支持语法逐一对照源码3.1 无符号数乘法下界相乘、上界相乘无符号乘法之所以值得单独建模是因为它的边界传播比有符号乘法更简单——两个操作数都非负所以“下界×下界、上界×上界”就是精确答案不存在符号翻转问题。源码中UnsignedMulExpr类要求结果类型是IntegralType且无符号并刻意排除已按常量乘处理的表达式以避免重叠SimpleRangeAnalysis.qllprivate class UnsignedMulExpr extends MulExpr { UnsignedMulExpr() { this.getType().(IntegralType).isUnsigned() and // Avoid overlap. It should be slightly cheaper to analyze // MulByConstantExpr. not this instanceof MulByConstantExpr } }对应地getLowerBoundsImpl对UnsignedMulExpr取xLow * yLowgetUpperBoundsImpl取xHigh * yHighSimpleRangeAnalysis.qll 与 L1352-L1357。x * y形式的UnsignedAssignMulExpr也按同样规则处理。变更前后对比的意义在于此前遇到unsigned乘法时表达式会落入“不可分析”分支下界直接退化为exprMinVal、上界退化为exprMaxVal所有依赖精确边界的下游判断都会失效现在这条路径能给出真实边界。3.2 与常量相乘把符号与量级分离处理“乘以一个常量”被拆成了四个协作的谓词/类核心思想是乘正数与乘负数对上下界的作用是相反的必须分开传播。MulByConstantExprSimpleRangeAnalysis.qll恰好一个操作数是常量的乘法表达式暴露出常量值getConstant()与非常量操作数getOperand()effectivelyMultipliesByPositive/effectivelyMultipliesByNegativeSimpleRangeAnalysis.qll除直接乘法外还覆盖“等效”乘常量的情形——一元x乘 1、一元-x乘 -1、逗号表达式取右操作数、StmtExpr取结果表达式这些是真实 C/C 代码里常见的惯用法AssignMulByConstantExpr及其正/负子类的划分用于处理x * c。边界传播规则体现在getLowerBoundsImpl/getUpperBoundsImpl中乘正数时下界 常量 × 操作数下界上界 常量 × 操作数上界乘负数时上下界交换来源用操作数的上界算下界、下界算上界。这套规则同样是x * c复合赋值语句的基础。3.3 引用类型函数参数变更记录列出的第三项是“引用类型函数参数”的支持。从当前源码结构看范围分析统一经由 SSA 信息工作变量访问e只要能在RangeSsaDefinition中找到对应定义e def.getAUse(v)即 analyzableExpr 中“允许变量访问前提是它有 SSA 信息”这一分支就可以通过getDefLowerBounds/getDefUpperBounds拿到边界。引用类型参数在底层同样有 SSA 定义可以推断该项改进正是让这类定义进入可分析集合的结果——具体到边界传播与按值参数走的是同一套规则。3.4 “不等于端点”收窄范围不等比较的 phi 节点第四项“比较变量不等于其值域端点从而把范围收窄一格”对应源码中的isNEPhi机制。getPhiLowerBounds中有一段精确实现了这个语义SimpleRangeAnalysis.qllexists(VariableAccess access, float neConstant, float lower | isNEPhi(v, phi, access, neConstant) and lower getTruncatedLowerBounds(access) and if lower neConstant then result lower 1 else result lower )含义是如果在某个分支上已知x ! c而该分支入口处x的下界恰好就是c那么在这个分支里x的下界可以推进到c 1。上界方向对称处理。这正是“narrowing the range by one”的出处它对循环不变量、数组下标验证这类场景尤为有用。3.5if (x)/if (!x)的判零语义第五项支持的是布尔上下文中“非零即真”的语义。C/C 中if (x)、!x、逻辑运算、(bool)x都隐式测试x 0。实现位于boolConversionLowerBound/boolConversionUpperBoundSimpleRangeAnalysis.qll下界若expr的值域覆盖 0下界为 0若能证明值域不含 0下界 0 或上界 0下界为 1若类型非算术类型如指针下界保守取 0上界若值域可能为 0上界取 0 与 1 都可能只有能证明“永远非零”下界 0 或上界 0时上界才确定为 1反之能证明“永远为零”时上界为 0。exprIsUsedAsBool谓词SimpleRangeAnalysis.qll先把“会被当作布尔用”的表达式集合圈定下来——逻辑运算的子表达式、一元逻辑操作数、条件表达式条件、bool转换——以避免对无关表达式做无谓的边界计算。这个机制让分析器能理解“进入if (x)分支意味着x ! 0、进入if (!x)分支意味着x 0”并据此在分支内收窄后续表达式。4. 自定义规则扩展机制SimpleRangeAnalysisExpr 与官方示例本次变更的另一半是开放扩展点。抽象接口定义在 SimpleRangeAnalysisExpr.qll/** * An expression for which a range can be deduced. Extend this class to add * functionality to the range analysis library. */ abstract class SimpleRangeAnalysisExpr extends Expr { /** Gets the lower bound of the expression. */ abstract float getLowerBounds(); /** Gets the upper bound of the expression. */ abstract float getUpperBounds(); /** * Holds if the range this expression depends on the definition srcDef * for StackVariable srcVar. ... */ predicate dependsOnDef(RangeSsaDefinition srcDef, StackVariable srcVar) { none() } /** * Holds if this expression depends on the range of its unconverted * subexpression child. ... * For example, when modeling a function call whose return value depends on * all of its arguments, implement this predicate as * child this.getAnArgument(). */ abstract predicate dependsOnChild(Expr child); }实现一个扩展规则需要让自定义类同时继承SimpleRangeAnalysisExpr和具体的Expr子类如FunctionCall、SubExpr用类匹配条件圈定要建模的表达式覆写getLowerBounds()/getUpperBounds()其中对子表达式取边界时必须通过getFullyConvertedLowerBounds/getFullyConvertedUpperBounds递归注释明确要求覆写dependsOnChild(Expr child)声明依赖了哪些未转换子表达式的范围——注释特别强调不声明周期依赖会导致“简单情况能跑、复杂代码上无限循环”。主库 SimpleRangeAnalysis.qll 在上下界计算的最后一支统一调用SimpleRangeAnalysisExpr的getLowerBounds()/getUpperBounds()且内置的边界传播规则明确以not expr instanceof SimpleRangeAnalysisExpr收尾即用户扩展优先于内置规则且不同扩展类之间互不干扰。变更记录中提到的示例目录现路径为 extensions 目录给出了两个可以直接参照的最小实现StrlenLiteralRangeExpr.qll对字面量字符串的strlen调用返回精确常量范围——getLowerBounds与getUpperBounds都等于字符串字面量长度dependsOnChild返回none()因为范围不依赖任何子表达式SubtractSelf.qll匹配x - x要求两侧显式转换后是同一个变量的访问排除myInt - (unsigned char)myInt这类类型不同的情形上下界都返回 0。该目录还有ConstantBitwiseAndExprRange.qll、ConstantShiftExprRange.qll、RangeNode.qll等更多示例覆盖了“子表达式为常量时结果可精确推断”这一最常见的扩展模式。5. 对下游查询的影响与验证路径变更记录说明这些改进“主要影响”三个查询它们在仓库中的位置与当前状态可以逐一核对cpp/comparison-with-wider-type实现在 ComparisonWithWiderType.qlid与name见文件头 L1-L15直接import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysisL20。窄类型与宽类型在循环条件中比较的问题其判定质量直接取决于范围分析能否给出循环变量的精确边界cpp/integer-multiplication-cast-to-long对应 IntMultToLong.ql同样构建在SimpleRangeAnalysis之上。整数乘法结果转换到long是否安全的判断本质上是“乘法上界是否落在 long 可表示范围内”的范围判断——无符号乘法与常量乘法的支持使这类判断从保守退化变为精确cpp/constant-comparison比较双方是否恒为常量或恒定大小关系的判定依赖上下界是否收敛为同一点因此五项新支持全部都会提升它的判定率。除这三个查询外当前仓库中SnprintfOverflow.ql、OverflowStatic.ql、ImproperArrayIndexValidation.ql、InconsistentLoopDirection.ql等也都在SimpleRangeAnalysis之上构建属于同一能力的受益面。库本身的回归测试位于 SimpleRangeAnalysis_tests.cpp可作为理解每类构造预期边界的参考。6. 小结这次变更解决的核心问题回到变更记录本身它解决的其实是两个层面的问题。第一层是精度——无符号乘法、常量乘法、引用参数、NE 收窄、布尔判零这五类构造补全后C 代码中大量原本落入“不可分析→边界退化为类型全范围”的表达式开始产生精确边界直接改善了三个核心查询的查全率与查准率。第二层是可扩展性——SimpleRangeAnalysisExpr把“我知道这个表达式的范围”从库的内置知识变成可注入的领域知识扩展者只需回答三个问题这个表达式是什么、它的上下界是多少、它依赖哪些子表达式的范围。对基于 CodeQL 编写 C 自定义查询的开发者而言这套机制是向范围分析库贡献项目特有算术语义的标准入口。赞分享静态分析SAST应用安全漏洞扫描代码质量【免费下载链接】codeqlCodeQL: 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点击查看免费下载相关推荐Alex.js高级用法自定义规则和扩展检测范围的完整教程Alex.js高级用法自定义规则和扩展检测范围的完整教程 Alex.js是一个强大的敏感语言检测工具能够帮助开发者发现写作中的不敏感、不周到表达。在前100开发工具LintFoundry 符号执行改进无分支饱和乘法与 checked-multiply guard 的形式化证明Foundry 符号执行改进无分支饱和乘法与 checked multiply guard 的形式化证明 本篇文章基于 Foundry 仓库 .changel区块链开发工具一文读懂SAM 3D BodyMeta最新3D人体网格恢复技术如何突破遮挡与复杂视角难题一文读懂SAM 3D BodyMeta最新3D人体网格恢复技术如何突破遮挡与复杂视角难题 SAM 3D Body是Meta推出的革命性3D人体网格恢复技术能上一篇如何通过Thorium浏览器获得3大性能优势终极编译优化与隐私保护指南下一篇告别乱码5分钟掌握GBK到UTF-8编码转换的必备技巧创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/25 10:08:00

VMware虚拟机USB直通实战:笔记本摄像头连接与排错指南

1. 为什么要在虚拟机里折腾摄像头把笔记本摄像头直通给 VMware 虚拟机,这个需求听起来小众,实际踩坑的人非常多。我最早碰到这个场景,是要在虚拟机里跑一个视频采集的测试程序,宿主机是 Windows,虚拟机里装的是 Ubuntu…

2026/9/25 10:08:00

Sunshine+Moonlight自托管串流:从搭建到调优的完整指南

1. 为什么我最终选择了 Sunshine 加 Moonlight 这套自托管串流方案1.1 从被串流软件折腾到自建主机的心路历程最早接触游戏串流,我用的是显卡厂商自带的那套方案。刚开始确实省心,装完驱动、打开开关、客户端扫码就能连上,延迟也还能接受。但…

2026/9/25 10:08:00

Atlas 300V 24G推理加速卡解析:从AI加速原理到YOLO部署实战

“Atlas 300V 24G到底算不算运算加速卡?”这个问题我最近被问了很多次。起因不外乎是两类人:一类是手里正好有这台卡,想拿来跑YOLO做目标检测,却不太确定这东西和常见的NVIDIA GPU有什么区别;另一类是看各种国产化方案…

2026/9/24 20:24:47

GAMP 5 基于风险的计算机化系统验证:软件分类与审计追踪实践

简介:《A Risk-Based Approach to Compliant GxP Computerized Systems》即业内熟知的GAMP 5指南,面向制药企业质量与IT合规人员、验证工程师及计算机化系统管理者,用于解决GxP法规环境下系统合规性难以科学落地的问题。文档以风险管理为主线…

2026/9/23 12:06:55

安全托管MSSP实战:从静态防御到人机协同的攻防运营与应急响应

简介:这份PPT围绕互联网业务安全托管服务展开,面向企业安全负责人、IT运维人员及关注MSSP/MSS选型的读者,重点回应传统安全过度依赖人工、碎片化静态防御难以对抗产业化攻击等痛点。资源共1个pptx文件,包体约30.63MB,以…

2026/9/25 0:02:35

AI元人文:从工具使用到思维重构的深度探索

最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决…

2026/9/25 0:02:35

Python+CNN车牌识别实战:从数据预处理到模型训练与部署

简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据…

2026/9/25 0:02:35

Vim基础操作全攻略:保存退出、模式切换与高频命令实战

1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保…

2026/9/22 16:34:32

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/22 20:01:30

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/22 13:25:41

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑