0

Clang 的 scan-build 报告了我的项目中很多空指针的取消引用,但是,我真的没有看到任何异常行为(在使用它的 6 年中),即:

Dereference of null pointer (loaded from variable chan)

char *tmp;
CList *chan = NULL; 
/* This is weird because chan is set via do_lookup so why could it be NULL? */
chan = do_lookup(who, me, UNLINK);
if (chan)
tmp = do_lookup2(you,me,0);

prot(get_sec_var(chan->zsets));

                 ^^^^

我知道 null derefs 会导致崩溃,但这真的是一个很大的安全问题,因为有些人认为它是?在这种情况下我该怎么办?

4

6 回答 6

5

取消引用指针是未定义的行为。NULL它可以显示任何行为,它可能会崩溃,但你必须修复这些!

未定义行为的真相是它遵守墨菲定律

“任何可能出错的事情都会出错”

于 2012-10-02T07:04:23.307 回答
4

chan在某一时刻检查 NULL是没有意义的:

if (chan)
  tmp = do_lookup2(you,me,0);     /* not evaluated if `chan` is NULL */
  prot(get_sec_var(chan->zsets)); /* will be evaluated in any case */

...但没有在下一行检查它。

您不必在if分支中执行这两个语句吗?

于 2012-10-02T07:06:24.943 回答
4

Clang 警告您,因为您检查是否为chanNULL,然后您在下一行无条件地取消引用它。这不可能是正确的。要么do_lookup不能返回NULL,那么检查是没有用的,应该被删除。或者它可以,那么最后一行可能会导致未定义的行为并且必须修复。Als 是 100% 正确的:NULL 指针取消引用是未定义的行为,并且始终存在潜在风险。

可能您想将代码包含在一个块中,以便所有代码都由检查 NULL 来控制,而不仅仅是下一行。

于 2012-10-02T07:07:37.087 回答
1

您必须尽快解决这些问题。或者可能更早。该标准说 NULL 指针是一个指向“没有有效内存位置”的指针,因此取消引用它是未定义的行为。这意味着它可能会工作,它可能会崩溃,它可能会在你程序的其他部分做一些奇怪的事情,或者可能导致守护进程飞出你的鼻子。

修复它们。现在。

方法如下:将取消引用语句放入if- 否则(如您所做的那样:检查 NULL 然后取消引用)没有任何意义。

if (pointer != NULL) {
    something = pointer->field;
}

^^ 这是一个好习惯。

于 2012-10-02T07:09:24.080 回答
0

如果您从未遇到过此代码的问题,可能是因为:

do_lookup(who, me, UNLINK);

总是返回一个有效的指针。

但是如果这个函数改变了会发生什么呢?还是它的参数不同?

您必须在取消引用它们之前检查 NULL 指针

if (chan)
   prot(get_sec_var(chan->zsets));

如果您绝对确定do_lookup将来它们或其参数都不会更改(并且您可以打赌程序在其上的安全执行),并且与您获得的收益相比,更改所有出现的类似函数的成本过高会这样做,然后:

你可能会决定让你的代码被破坏。

许多程序员过去都这样做过,将来还会有更多的程序员这样做。否则怎么解释 的存在Windows ME

于 2012-10-02T07:27:02.780 回答
0

如果您的程序由于 NULL 指针取消引用而崩溃,这可以归类为拒绝服务 (DoS)。

如果这个程序与其他程序一起使用(例如,他们调用它),安全方面现在开始依赖于其他程序在这个程序崩溃时会做什么。总体影响可能是相同的 DoS 或更糟(利用、敏感信息泄漏等)。

如果您的程序没有因为 NULL 指针取消引用而崩溃,而是继续运行,同时破坏自身以及可能在同一地址空间内的操作系统和/或其他程序,您可能会遇到一系列安全问题。

不要在线(或在线)放置损坏的代码,除非您有能力处理潜在黑客攻击的后果。

于 2012-10-02T08:29:50.503 回答