Просматривает ли это использование strncmp за пределами границ?
Fortify указывает, что это за пределами чтения:
if (strncmp("test string", "less than 32 char", 32) == 0)
{
...
}
В нем говорится, что функция считывает данные из-за пределов less than 32 char
.
Есть ли на самом деле вывод, если strncmp
выходит за пределы 32 символов, а вторая строка меньше 32 символов?
Ответы
Ответ 1
TL; DR - strncmp()
будет продолжать сравнивать строковые элементы, пока не закончится ни строка, ни 32 элемента (символы), в зависимости от того, что меньше.
Строка A (ny) всегда заканчивается на нуль и при столкновении с нулевым терминатором дальнейшее сравнение не выполняется. Ваш код в безопасности.
Цитата C11
, глава §7.24.4.4 (выделение мое)
int strncmp(const char *s1, const char *s2, size_t n);
Функция strncmp
сравнивает не более n
символов (символы, следующие за нулевой символ не сравниваются) из массива, на который указывает s1
, на массив, на который указывает на s2
.
Ответ 2
По соображениям производительности реализации стандартных строковых функций часто обрабатывают данные в естественно выровненных блоках ширины регистров. Это может привести к доступу чтения к концу исходных объектов данных, но выравнивание гарантирует, что код ведет себя точно так же, как наивная реализация в отношении исключений памяти. Каждый широкий доступ содержится в одной странице, и никакие страницы не затрагиваются, что также не затрагивается байт-мудрой реализацией.
Я бы утверждал, что такие реализации покрываются правилом C as-if, то есть они ведут себя так же, как если бы они выполняли абстрактные функциональные спецификации.
Примером такой оптимизированной реализации будет OpenSolaris strcmp()
для SPARC v8. Это код, который я написал пятнадцать лет назад, а также другие строковые функции, оптимизированные по производительности.
Различные инструменты проверки памяти будут жаловаться на такой код, однако, поскольку его использование может привести к доступу за пределы выделенного объекта данных, даже несмотря на то, что доступ к чтению вне границ безвреден по дизайну.
Ответ 3
У вас есть действительно действующий код.
Либо ваш компилятор генерирует плохой код объекта, либо fortify сообщает о ложном срабатывании.
Я сомневаюсь, что это компилятор, создающий плохой код. Это создаст слишком много проблем и будет обнаружено и исправлено в кратчайшие сроки.
Скорее всего, fortify сообщает о ложном срабатывании.