Каковы опасности исключений с плавающей точкой при неверном вводе?

Я пробежал fuzzying на Dcraw и нашел исключение с плавающей запятой.

Каковы опасности этого? Это читает некоторую длину plen из поврежденного файла и вычисляет foo[i % plen], Если plen == 0 тогда это не определено по стандарту и gcc выдает исключение с плавающей запятой. РЕДАКТИРОВАТЬ: И исключение не перехватывается (это C), и программа завершается.

Должен ли я заботиться? Есть ли сценарий, где это может быть использовано или вызвать другие плохие вещи? Одним из возможных правильных действий кода было бы заметить, что файл поврежден и просто существует. Чем это отличается от броска FPE и затем выхода?

(Я удивлен, что не нашел вопрос по этому вопросу, потому что это кажется мне очень простым.)

1

Решение

Если 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 выдает исключение с плавающей запятой.

Не совсем. Это ваш процессор, если код пытается разделить на ноль. Но, как сказано выше, нет никакой гарантии, что такой код будет сгенерирован вообще.

Я сомневаюсь, что GCC что-то здесь определяет (и не смог найти ничего, указывающего на это в документации).

Должен ли я заботиться? Есть ли сценарий, где это может быть использовано или вызвать другие плохие вещи? Одним из возможных правильных действий кода было бы заметить, что файл поврежден и просто существует. Чем это отличается от броска FPE и затем выхода?

Вы должны заботиться. В случае неудачи ваша программа может продолжить работу с неверным входным файлом, см. Выше.

И сообщение об ошибке «Неверный входной файл». на мой взгляд, гораздо приятнее, чем просто «исключение с плавающей точкой». Первый говорит мне (как конечному пользователю), что не так, а второй говорит мне, что в программном обеспечении есть ошибка (я бы посчитал ее такой).

2

Другие решения

Исключения выдают, чтобы вы могли восстановить систему в четко определенное состояние после непредвиденных событий.

Брошенные исключения не восстанавливают систему до четко определенного состояния. Это ваша ответственность. Любая эксплуатация происходит на основе того, как вы это делаете, а не на основе самого брошенного исключения.

1

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

Восстановление из исключения полностью зависит от контекста, в котором было сгенерировано исключение. Если в результате некоторых вычислений возникло исключение, результат которого необходим для продвижения вперед, лучше остановить систему.

Однако, если ваше исключение выдается для чего-то, что может быть проигнорировано ИЛИ для которого могут быть предоставлены другие параметры по умолчанию, тогда вы, безусловно, можете перейти от этого.

Например: —

Допустим, я читаю .ini, используя параметры программы повышения. Из-за некоторых пропущенных переменных в файле .ini возникло исключение. в этом случае я могу восстановиться после исключения, указав для этой переменной подходящее значение по умолчанию.

0
По вопросам рекламы [email protected]