为什么在使用它之后检查指针是否为NULL?

时间:2014-11-17 09:37:01

标签: c security undefined-behavior

我正在阅读这篇文章http://blog.regehr.org/archives/213它包含了Linux内核页面底部的一个示例(略有编辑)

static void __devexit agnx_pci_remove (struct pci_dev *pdev)
{
  struct ieee80211_hw *dev = pci_get_drvdata(pdev);
  struct agnx_priv *priv = dev->priv; 

  if (!dev) return;

  ... do stuff using dev ...
}

文章声称

  

我们现在可以很容易地看到,这两种情况都不需要空指针检查。检查已删除,可能会产生可利用的安全漏洞。

如果他们取消引用空指针会不会出现段错误?他们甚至不会去检查吗?

这个漏洞可以是什么?

编辑: 我读了这篇文章,我明白了!我想明白为什么人们无论如何都要用这种方式编码,也许这是故意的?至少对我来说,仅仅是因为一个人声称它在他的博客上是一个错误,并不意味着它是,所以我想仔细检查它。那有什么不对?

2 个答案:

答案 0 :(得分:2)

  

如果他们取消引用空指针会不会出现段错误?

是的,还有一张纸条:

  

这里的习惯用法是获取指向设备结构的指针,测试它   null,然后使用它。但是有一个问题!在这个功能中,   在空检查之前,指针被取消引用。

答案 1 :(得分:0)

  

这有什么问题?

通过在检查NULL之前取消引用指针,允许编译器思考:“哦,指针被解除引用,因此在程序的这一点上它不能为NULL,否则解除引用将起作用。所以我可以安全地省略整个代码路径。“

写这个人的想法?不知道,无论如何这都是糟糕的风格。带有暴露符号的每个函数应该做的第一件事就是验证它的输入(静态内联的短辅助函数可以免除该规则,但这些函数的调用者必须确保所有参数都有效)。

实际上,这意味着,首先应该在某种树遍历方法中检查传递给函数的结构和值中的所有指针是否为NULL。有些人首先选择广度,我通常先使用深度。重要的是,在解除引用之前检查每个指针是否为NULL。