CodeQL数据流查询无法检测C程序中赋值到函数参数的路径
CodeQL数据流查询无结果问题排查
你的查询未返回结果的核心原因是数据流追踪的起点和终点不匹配,同时存在一些冗余的类型判断逻辑,以下是具体排查和修正方案:
问题根源拆解
- 数据流追踪范围偏差:你设置的
sink是fc.getArgument(0)(即size*sizeof(char)这个完整表达式),但src是size变量。DataFlow::localFlow默认追踪的是直接赋值/直接作为参数传递的数据流,不会自动识别变量作为表达式操作数的间接引用场景。 - 冗余类型判断:
ab.getLValue().getType().getUnspecifiedType()属于多余调用,直接用ab.getLValue().getType()即可判断变量类型。 - 路径问题配置缺失:
@kind path-problem需要导入DataFlow::PathGraph才能生成路径,你注释掉了该导入,影响路径追踪的完整性。
修正后的查询方案
方案1:直接检查参数表达式中的变量引用(适合简单场景)
这种方式跳过复杂数据流追踪,直接验证MyVuln的参数是否引用了由乘法赋值定义的变量:
/* @kind path-problem */ import cpp import semmle.code.cpp.dataflow.new.DataFlow import DataFlow::PathGraph from Function myvuln, FunctionCall fc, AssignExpr ab, Variable sizeVar where // 匹配目标函数MyVuln myvuln.hasGlobalName("MyVuln") and fc.getTarget() = myvuln // 匹配右值为乘法运算的赋值语句,左值为整型变量 and ab.getRValue() instanceof MulExpr and sizeVar = ab.getLValue().asVariable() and sizeVar.getType() instanceof IntegralType // 检查MyVuln第一个参数的子节点中是否包含size变量的引用 and fc.getArgument(0).getAChild*() = sizeVar.getAnAccess() select fc, sizeVar, "MyVuln调用参数来源于乘法定义的变量: " + sizeVar.getName(), PathGraph::path(sizeVar.getAnAccess(), fc.getArgument(0))
方案2:自定义数据流配置(适合复杂场景)
通过自定义数据流规则,允许追踪到参数表达式的内部操作数,覆盖更复杂的数据流路径:
/* @kind path-problem */ import cpp import semmle.code.cpp.dataflow.new.DataFlow import DataFlow::PathGraph // 自定义数据流配置,允许追踪到参数表达式的子节点 class VulnArgConfig extends DataFlow::Configuration { VulnArgConfig() { this = "VulnArgConfig" } override predicate isSource(DataFlow::Node node) { node.asExpr() = ab.getLValue() } override predicate isSink(DataFlow::Node node) { node.asExpr() = fc.getArgument(0).getAChild*() } } from Function myvuln, FunctionCall fc, AssignExpr ab, DataFlow::PathNode source, DataFlow::PathNode sink where myvuln.hasGlobalName("MyVuln") and fc.getTarget() = myvuln and ab.getRValue() instanceof MulExpr and ab.getLValue().getType() instanceof IntegralType and source.getNode().asExpr() = ab.getLValue() and sink.getNode().asExpr() = fc.getArgument(0).getAChild*() and DataFlow::flowPath(source, sink, VulnArgConfig{}) select sink.getNode(), "MyVuln调用参数来源于乘法定义的变量", source, sink
关键排查要点
- 明确数据流的起点和终点:若变量是作为表达式的一部分传入函数,需将终点设为表达式的子节点而非整个表达式。
- 简化类型判断逻辑:避免不必要的类型包装函数调用,直接针对变量类型判断即可。
- 路径问题需导入
DataFlow::PathGraph:否则无法生成和展示完整的数据流路径。
内容的提问来源于stack exchange,提问作者Sanjay
相关产品推荐
相关产品推荐

