如果没有崩溃,我真的应该担心修复null defres吗?

时间:2012-10-02 07:02:35

标签: c

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可能会导致崩溃,但这是否真的是一个很大的安全问题,因为有些人认为这样做了?在这种情况下我该怎么做?

6 个答案:

答案 0 :(得分:5)

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

未定义行为的真相是它服从 Murphy's Law

“任何可能出错的地方都会出错”

答案 1 :(得分: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分支内执行这两个语句?

答案 2 :(得分:4)

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

您可能希望将代码放在一个块中,以便所有这些代码都由NULL检查,而不仅仅是下一行。

答案 3 :(得分:1)

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

修复它们。现在

以下是如何:将dereference语句放在if中 - 否则(正如你所做的那样:检查NULL然后解除引用)会使无意义。

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

^^这是一个很好的做法。

答案 4 :(得分:0)

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

do_lookup(who, me, UNLINK);

始终返回有效指针。

但是如果这个功能改变会发生什么?或者它的参数有所不同?

您必须在解除引用之前检查NULL指针

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

如果您完全确定将来do_lookup或其参数都不会改变(并且您可以在其上安全执行您的程序),并且更改所有类似功能的成本是与你这样做的好处相比过高,那么:

你可能决定让你的代码破碎。

许多程序员过去都是这样做的,未来会有更多人这样做。否则什么可以解释Windows ME的存在?

答案 5 :(得分:0)

如果程序因NULL指针取消引用而崩溃,则可将其归类为拒绝服务(DoS)。

如果此程序与其他程序一起使用(例如,它们调用它),则安全方面现在开始依赖于其他程序在此程序崩溃时所执行的操作。整体效果可能与DoS相同或更糟糕(利用,敏感信息泄露等)。

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

除非你能负担得起潜在黑客行为的后果,否则不要上线(或在线)破解代码。