前言

范围分析库(在semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis中定义)提供了一组谓词,用于确定表达式的恒定上限和下限,以及识别整数溢出。对于性能,库执行自动加宽,因此可能无法提供最严格的边界

边界谓词

upperBoundlowerBound谓词提供表达式的常量边界。参数的转换不包含在边界中。在您的查询需要考虑转换的常见情况下,在转换后的表单上调用它们,例如 upperBound(expr.getFullyConverted())

溢出谓词

exprMightOverflow和相关谓词保持相关表达式是否可能溢出,这由范围分析库确定。谓词的convertedExprMightOverflow系列将考虑转换

示例

这个查询使用upperBound来判断snprintf的结果在循环中使用时是否检查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from FunctionCall call, DataFlow::Node source, DataFlow::Node sink, Expr convSink
where
// the call is an snprintf with a string format argument
call.getTarget().getName() = "snprintf" and
call.getArgument(2).getValue().regexpMatch(".*%s.*") and

// the result of the call influences its size argument in later iterations
TaintTracking::localTaint(source, sink) and
source.asExpr() = call and
sink.asExpr() = call.getArgument(1) and

// there is no fixed bound on the snprintf's size argument
upperBound(convSink) = typeUpperBound(convSink.getType().getUnspecifiedType()) and
convSink = call.getArgument(1).getFullyConverted()

select call, upperBound(call.getArgument(1).getFullyConverted())