Value-Flow分析工具Pinpoint

group网址,Pinpoint曾经开源,不过目前已经商业化,因此参考资料只能找到paper,不过其design还是很有参考意义的。相比FastcheckSVF阶段化设计(即先进行全程序指针分析 -> 全程序value-flow分析 -> 全程序bug检测),Pinpoint采用的整体性设计在分析时采用整体性设计原则进行按需分析,因此能减少很多不必要的性能开销。

1.Introduction

下图示例反映了阶段化设计工具(SVF和Fastcheck)的设计原则,首先进行全程序指针分析然后构建全程序的SVFG(图b),然后进行过程间bug检测。图b反映出了部分的SVFG(这里ptr 为2级指针,这里SVFG只展示1级指针变量之间的value-flow关系),包括 a, b, c, d, e 5个变量与 f 的value-flow关系以及每个value-flow对应的路径条件。而随后报出的use-after-free bug report涉及的value-flow包括: c --> free(c), c --> f, f --> print(*f),可以看到 a, b, c, d 都没涉及到。如果在指针分析和VFG构建的时候能忽略这4个变量将节省很多性能开销。

请添加图片描述
下图则反映了Pinpoint的idea,包括: 1.识别side-effect、2.对原始程序进行语义等价转换、3. local points-to Analysis、4.Local SEG构建、5.过程间bug分析。

首先Pinpoint会对原始代码进行一些语义等价转换,以将原始程序的side-effect暴露在parameter和return value(也就是function interface处),side-effect主要指的是在当前函数引用和修改了非局部类型(比如全局变量内存、解引用指向其它函数局部变量的指针、堆内存的访问等)。

示例中, bar 函数的 q 参数带来的side-effect包括:∗q != 0 的load操作、*q = c*q = b 的store操作,这几个操作都访问了非 bar 函数的局部内存。 语义转换后 ∗q 会直接作为函数参数传递并通过返回值 Y 返回。bar 转换后函数签名换了,foo 内相应代码也跟着一起转换。

请添加图片描述
随后,Pinpoint会分别对 fooquxbar 进行Local指针分析而不是像Fastcheck和SVF那样考虑3个函数的调用关系进行全程序指针分析。指针分析后为每个函数单独构建SVFG(这里表示为symbolic expression graph SEG)。比如为了 foo 第12行的 f 构建数据依赖关系,首先需要获取 *ptr 的local point-to set { ( L , θ 1 ) , ( M , ¬ θ 1 ) } \{(L, \theta_1 ), (M, \neg \theta_1 )\} {(L,θ1),(M,¬θ1)}(表示分别在条件 θ 1 \theta_1 θ1 ¬ θ 1 \neg \theta_1 ¬θ1 下指向 LM),这里只会进行函数内分析。

随后在bug检测阶段,use-after-free value-flow包括 ⟨free(c), c, Y , return Y , L, f , print(*f)⟩。整个过程分析的value-flow只包括这个。

2.Holistic Design in Pinpoint

作者将程序抽象为下面形式,似乎不包括局部变量。 r ← c a l l f ( v 1 , v 2 , ⋅ ⋅ ⋅ ) r \leftarrow call f(v_1,v_2, · · · ) rcallf(v1,v2,⋅⋅⋅) r r r 被称为callee的receiver。

请添加图片描述

2.1.Decomposing the Cost of Data Dependence Analysis

主要介绍Local Point-To Analysis和Local Value Flow Analysis的原则。

首先用一个近似path-sensitive的方式对每个function进行local point-to analysis,作者观察到70%的path condition是可以满足的,因此用昂贵的SMT solver来求解会引入太多性能开销。作者观察到90%的不可满足的路径条件形式都比较简单,比如 a ∧ ¬ a a \land \neg a a¬a。因此在这一步,路径条件的构造按下面方式执行。

请添加图片描述
local point-to analysis分析后就是进行local value-flow分析。如果 *q*u 存在别名关系,那么 p = *q*u = wwp 就存在数据依赖关系。但是 qu 可能指向非局部(non-local)内存。作者这里主要讨论由函数调用引起的 qu 可能指向上层caller内存的问题。传统的summary-based方法将访问非本地内存位置的 storeload 语句记录为side-effect或MOD/REF摘要,然后在上层caller的每个当前函数callsite克隆和实例化summary。由于程序中存在大量的 storeload 语句,side-effect summary的大小会迅速膨胀,成为scalability的一个重大障碍。

作者这里参考IFDS/IDE-based方法构建一个connectors来表示每个function的输入-输出side-effect。下图中 XY 就表示 bar 函数的connector,每个input/output connector表示由 store 或者 load 进行的内存区域读/写。在callsite,会构建callsite connector表示实参和返回值的receivers,比如 foo 函数的 KL 表示 bar(ptr, K) 的connector,其中 K 连接 XY 连接 L

请添加图片描述
实际上作者的connector主要包括2部分:

  • 1.Aux formal parameter:一个局部变量,代表通过指针表达式 ∗ ( p , k ∈ N + ) ∗(p, k \in N+) (p,kN+) 引用的非本地内存位置,其中 p p p 是一个形参。

  • 2.Aux return value:性质和Aux formal parameter类似,属于返回值。

connector插入规则如下:

请添加图片描述

2.2.Symbolic Expression Graph

symbolic expression graph (SEG) 是一种新形式的SVFG。它的特性包括:

  • 1.它紧凑且精确地编码了所有条件和无条件的数据依赖关系,以及控制依赖关系。

  • 2.它使得可以方便地查询“有效路径条件”,从而全面支持路径敏感分析。

  • 3.它是为每个函数单独构建的,不仅节省了时间成本,还使高效的组合分析成为可能。

这里 bar 函数的SEG如下图所示,每个图结点可以表示一个语句或者是单目/双目运算符。图有数据依赖和控制依赖(虚线)表示。

请添加图片描述

2.3.Global Value Flow Analysis for Vulnerability Detection

跨函数分析需要解决两个问题:

  • 1.如何在连接来自不同函数的value-flow时实现路径和上下文敏感性。

  • 2.另一个问题是如何重用分析结果以避免重复计算,从而提高效率。

2.3.1.Tackle 1: Demand-Driven Path- and Context-Sensitive Value Flow Analysis

这一步解决的问题包括:

  • 1.给定一个local value flow path π \pi π,对应local路径条件包括 P C ( π ) PC(\pi) PC(π)。这个路径条件不包括caller和callee的,损失了些精度,需要recover。

  • 2.计算任意global value flow path的路径条件。

作者用 P C ( ⋅ ) P R PC(·)_P^R PC()PR 表示 P C ( ⋅ ) PC(·) PC() 中缺失的条件, P P P R R R 分别表示当前对应的形参和返回值。

下图为从 foo 的形参 aoutput(*c, *a) 的value-flow path的路径条件的计算。

请添加图片描述

2.3.2.Tackle 2:Compositional Approach to Bug Detection

分析一个function需要query 两类callee信息:1.return变量 v v v 的数据依赖 D D ( v @ s ) ∅ P DD(v@s)^P_\empty DD(v@s)P。2.某一个value-flow path π \pi π 对应的路径条件 P C ( π ) ∅ P PC(\pi)^P_\empty PC(π)P。对此,Pinpoint分别生成return-value(RV) summary以及value-flow(VF) summary。

作者定义下面几种value-flow summary:

  • VF1 summarizes a value-flow path from a function parameter to a return value;

  • VF2 summarizes a value-flow path from a source to return value;

  • VF3 summarizes a value-flow path from a function parameter to a source;

  • VF4 summarizes a value-flow path from a function parameter to a sink;

VF1 确定在callsite处的实参是否会流回同一调用点处的返回值receiver。因此,当在路径搜索过程中遇到实参时,VF1 决定是否应该从返回值接收者开始继续搜索。VF2 和 VF3 分别确定在callsite之后,返回值receiver和实参是否会被污染。它们有助于决定在分析函数时是否应该从返回值receiver或实参开始路径搜索。VF4 确定在callsite处的实参是否会流向callee中的某个sink点。如果在路径搜索过程中到达实参,并且被调用函数具有VF4 summary,则在callee中可能会存在bug。

在检测bug时遇到函数调用会直接query summary而不是对应的SEG进行分析。

3.Evaluation(部分)

Pinpoint主要与SVF等工具进行比较,主要的比较标准是性能优化以及查找bug的准确率。

3.1.Scalability

下面两张图分别反映了程序变大时Pinpoint和SVF的时间和内存开销对比,红色虚线为Pinpoint。
请添加图片描述

3.2.Bug detection

SVF和Pinpoint生成的report作者通过人工验证(SVF的report比较多作者随机sample后进行人工验证)

请添加图片描述

4.参考文献

Shi Q, Xiao X, Wu R, et al. Pinpoint: Fast and precise sparse value flow analysis for million lines of code[C]//Proceedings of the 39th ACM SIGPLAN Conference on Programming Language Design and Implementation. 2018: 693-706.

  • 15
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值