浮点异常对无效输入有什么危险?

时间:2014-11-14 09:43:00

标签: c++ c gcc floating-point-exceptions

我在fuzzying上运行了一些dcraw,发现了一个浮点异常。

这有什么危险?它从损坏的文件读取一些长度plen并计算foo[i % plen]。如果plen == 0,则标准未定义,gcc会抛出浮点异常。编辑:并没有捕获异常(这是C),程序终止。

我应该关心吗?是否有任何可能被利用或导致其他不良事件的情况?代码的一个可能的正确行为是注意文件已损坏并且只是存在。这与抛出FPE然后退出有什么不同?

(我很惊讶我没有找到这方面的问题,因为这对我来说似乎非常基本。)

3 个答案:

答案 0 :(得分:2)

  

如果plen == 0,则标准未定义...

完全。这意味着,编译器可以自由地假设它没有发生。这段代码,例如

int foo(int m, int n) {
    if(n == 0) return m % n;
    return 0;
}

编译为

foo:                                    # @foo
    xorl    %eax, %eax
    ret

我的机器上的clang -std=c99 -S -O2(Intel x86)。假设永远不会输入if分支,foo无条件地返回0。没有FPE,没有崩溃。 (遗憾的是,我无法找到与gcc类似的小例子。)

  

...并且gcc抛出一个浮点异常。

不完全。如果代码试图除以零,那就是你的CPU。但是,如上所述,根本无法保证生成此类代码。

我怀疑GCC在这里定义了什么(并且在文档中找不到任何表明的东西)。

  我应该在意吗?是否存在可能被利用或导致其他不良事件的情况?代码的一个可能的正确行为是注意文件已损坏并且只是存在。这与抛出FPE然后退出有什么不同?

你应该在乎。运气不好,你的程序可能会输入错误的输入文件,见上文。

错误信息"输入文件无效。"在我看来,这比仅仅是#34;浮动指向异常更好。"。前者告诉我(作为最终用户)出了什么问题,后者只告诉我软件中有一个错误(我会认为是这样)。

答案 1 :(得分:1)

抛出异常,使您能够在意外事件发生后将系统还原到定义良好的状态。

抛出的异常不会将系统恢复到定义良好的状态。这是你的责任。任何利用都是基于你如何做到的,而不是基于抛出的异常本身。

答案 2 :(得分:0)

Regarding "Is there any scenario where this could be exploited or 
cause other bad things? "

从异常中恢复完全取决于抛出异常的上下文。如果某些计算引发了异常,则需要结果向前推进,然后停止系统会更好。

但是,如果您可以忽略某些可以忽略的异常,或者可以提供其他默认选项,那么您肯定会继续这样做。

例如: -

让我们说我正在使用提升程序选项阅读.ini。由于.ini文件中存在一些缺失变量,因此存在一些异常。在这种情况下,我可以通过为该变量提供一些合适的默认值来从异常中恢复。