You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CodeQL数据流查询无法检测C程序中赋值到函数参数的路径

CodeQL数据流查询无结果问题排查

你的查询未返回结果的核心原因是数据流追踪的起点和终点不匹配,同时存在一些冗余的类型判断逻辑,以下是具体排查和修正方案:

问题根源拆解

  1. 数据流追踪范围偏差:你设置的sink是fc.getArgument(0)(即size*sizeof(char)这个完整表达式),但src是size变量。DataFlow::localFlow默认追踪的是直接赋值/直接作为参数传递的数据流,不会自动识别变量作为表达式操作数的间接引用场景。
  2. 冗余类型判断:ab.getLValue().getType().getUnspecifiedType()属于多余调用,直接用ab.getLValue().getType()即可判断变量类型。
  3. 路径问题配置缺失:@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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 19:19:56