finish 5.4

This commit is contained in:
firmianay
2018-04-03 17:03:37 +08:00
parent 46deb0748b
commit c6cebca6dd
9 changed files with 122 additions and 0 deletions

View File

@ -204,3 +204,64 @@ p = *q;
## 实例分析
#### 检测指针变量的错误使用
在检测指针变量的错误使用时,我们关心的是变量的状态。
下面看一个例子:
```c
int contrived(int *p, int *w, int x) {
int *q;
if (x) {
kfree(w); // w free
q = p;
}
[...]
if (!x)
return *w;
return *q; // p use after free
}
int contrived_caller(int *w, int x, int *p) {
kfree(p); // p free
[...]
int r = contrived(p, w, x);
[...]
return *w; // w use after free
}
```
可以看到上面的代码可能出现 use-after-free 漏洞。
这里我们采用路径敏感的数据流分析,控制流图如下:
![](../pic/5.4_cfg1.png)
![](../pic/5.4_cfg2.png)
调用图如下:
![](../pic/5.4_cg1.png)
下面是用于检测指针变量错误使用的检测规则:
```
v 被分配空间 ==> v.start
v.start: {kfree(v)} ==> v.free
v.free: {*v} ==> v.useAfterFree
v.free: {kfree(v)} ==> v.doubleFree
```
分析过程从函数 contrived_call 的入口点开始,对于过程内代码的分析,使用深度优先遍历控制流图的方法,并使用基本块摘要进行辅助,而对于过程间的分析,选择在遇到函数调用时直接分析被调用函数内代码的方式,并使用函数摘要。
函数 contrived 中的路径有两条:
- BB0->BB1->BB2->BB3->BB5->BB6在进行到 BB5 时BB5 的前置条件为 p.free, q.free 和 w.free此时语句 `q1 = *q` 将触发 use-after-free 规则并设置 q.useAfterFree 状态。然后返回到函数 contrived_call 的 BB2其前置条件为 p.useAfterFree, w.free此时语句 `w1 = *w` 设置 w.useAfterFree。
- BB0->BB1->BB3->BB4->BB6该路径是安全的。
#### 检测缓冲区溢出
在检测缓冲区溢出时,我们关心的是变量的取值,并在一些预定义的敏感操作所在的程序点上,对变量的取值进行检查。
下面是一些记录变量的取值的规则:
```
char s[n]; // len(s) = n
strcpy(des, src); // len(des) > len(src)
strncpy(des, src, n); // len(des) > min(len(src), n)
s = "foo"; // len(s) = 4
strcat(s, suffix); // len(s) = len(s) + len(suffix) - 1
fgets(s, n, ...); // len(s) > n
```