2016-08-10 12 views
13

Fortify указывает, что это выходит за границы чтения:Просматривает ли это использование strncmp за пределами границ?

if (strncmp("test string", "less than 32 char", 32) == 0) 
{ 
... 
} 

Это говорит о том, что функция считывает данные из вне границ less than 32 char.

Есть ли находка, если strncmp выходит за пределы 32 символов, а вторая строка меньше 32 символов?

+2

Крепость неправильная. По крайней мере, для правильной, это стандартная соответствующая реализация 'strncmp()'. – alk

+1

Если я не очень сильно ошибаюсь, 'strncmp()' нужно будет сравнить только один символ 'char' от каждой строки в вашем примере. Я второй ложный положительный. – EOF

+0

Просьба указать [mcve] и посмотреть [ask]. Это будет включать параметризацию Fortify. Или спросите HP, почему он генерирует ложные данные с необходимой информацией. – Olaf

ответ

9

TL; DR - strncmp() будет держать не сравнивая элементы снабжать струной, тетивой, пока либо в конце каждой строки или 32 элементов (символов), в зависимости от того меньше.

А (пу) строка всегда оканчивается нулем и при встрече с нуль-терминатор, дальнейшее сравнение не выполняется. Ваш код в безопасности.

Цитирование C11, глава §7.24.4.4 (курсив мой)

int strncmp(const char *s1, const char *s2, size_t n); 

strncmp функция сравнивает не более n символов (символы, которые следуют за нулевой символ не сравниваются) из массива, на который указывает s1, на массив, указанный на , на s2.

6

У вас есть действительно действующий код.

Либо ваш компилятор генерирует плохой объектный код, либо fortify сообщает об ошибке.

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

Скорее всего, fortify сообщает о ложном положительном результате.

+1

Создание кода плохого объекта? Для чего? Вызов функции? к стандартной библиотечной функции? Это анализ исходного кода. Ничего общего с компилятором или объектным кодом. – EJP

12

По соображениям производительности реализации стандартных строковых функций часто обрабатывают данные в естественно выровненных блоках ширины регистров. Это может привести к доступу чтения к концу исходных объектов данных, но выравнивание гарантирует, что код ведет себя точно так же, как наивная реализация в отношении исключений памяти. Каждый широкий доступ содержится в одной странице, и никакие страницы не затрагиваются, что также не затрагивается байт-мудрой реализацией.

Я бы утверждал, что такие реализации охватываются правилом C как-будто, то есть они ведут себя так же, как если бы они следовали абстрактным функциональным спецификациям.

Примером такой оптимизированной реализации будет OpenSolaris's strcmp() for SPARC v8. Это код, который я написал пятнадцать лет назад, а также другие строковые функции, оптимизированные по производительности.

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

+0

Очень жаль, что «современные» авторы компилятора не проявляют большого интереса к тому, чтобы программисты могли использовать такие методы для выполнения задач, не встроенных в стандартную библиотеку. Иногда компилятор может найти эквивалентную или лучшую оптимизацию при предоставлении кода, который просто обрабатывает элементы последовательно, но во многих случаях компиляторы не находят таких оптимизаций. К сожалению, они могут найти «оптимизацию» на основе UB, которая может случайным образом нарушать код пользователя, который использует такие методы. – supercat