Какие функции C/С++ чаще всего используются некорректно и могут привести к переполнению буфера?
Мне было предложено поддерживать большую С++-кодовую базу, полную утечек памяти. Пока я ковырялся, я узнал, что у нас много переполнений буфера, которые приводят к утечкам (как это плохо, я никогда не хочу знать).
Я решил сначала удалить переполнение буфера, начиная с опасных функций. Какие функции C/С++ наиболее часто используются неправильно и могут привести к переполнению буфера?
Для компилятора и/или инструментов, используемых для поиска переполнения буфера, я создал другой вопрос, который касается этого
Ответы
Ответ 1
В общем, любая функция, которая не проверяет границы в аргументах. Список будет
- получает()
- зсапЕ()
- зЬгср()
- strcat()
Вы должны использовать ограниченные по размеру версии, такие как stncpy, strncat, fgets и т.д. Затем будьте осторожны, указав ограничение по размеру; принимаем во внимание, что '\ 0' завершает строку.
Кроме того, массивы НЕ привязываются на C или С++. Следующий пример может привести к ошибкам. См. с помощью одной ошибки
int foo[3];
foo[3] = WALKED_OFF_END_OF_ARRAY;
edit: скопированные ответы @MrValdez, @Denton Gentry
Ответ 2
Valgrind - ваш новый лучший друг.
valgrind --tool = memcheck --leak-check = full./a.out
Ответ 3
Боюсь, что вопрос начинается с неправильного конца. Предполагая, что переполнение буфера происходит в других функциях. Наиболее распространенной причиной является оператор ++, по моему опыту, или, альтернативно, отсутствие оператора! =.
Лучшее решение для поиска партии - это /GS в Visual Studio 2005/8. Он не найдет их всех, но это дешевый способ уменьшить объем ручной работы.
Ответ 4
Здесь некоторые функции, которые я обнаружил, опасны:
- gets() - Он не проверяет длину переменной и может перезаписывать память, если вход больше, чем буфер переменных.
- scanf() - Я так рад, что Visual Studio сказал мне, что эта функция устарела. Это было простое решение.
- strcpy() - Если исходное пространство памяти больше места назначения, данные после адресата будут перезаписаны.
Ответ 5
Следующая ссылка должна дать вам полный обзор функций безопасности в С++ (те, которые исправлены с помощью _ _s для исправления таких проблем, как переполнение): http://msdn.microsoft.com/en-us/library/8ef0s5kh(VS.80).aspx
EDIT: Эта ссылка содержит определенные функции, которые были заменены: http://msdn.microsoft.com/en-us/library/wd3wzwts(VS.80).aspx
EDIT: Я бы сказал, что это методы Microsoft, но ссылка по-прежнему полезна для идентификации функций, которые считались красным флагом.
Ответ 6
К сожалению, любой массив может привести к переполнению буфера:
uint32_t foo[3];
foo[3] = WALKED_OFF_END_OF_ARRAY;
В терминах функций sprintf с радостью выйдет из конца буфера. Его можно заменить на snprintf.
Ответ 7
Memcpy() является еще одним опасным.
Любой цикл, обращающийся к массиву, является опасной точкой, потому что нет остановки, выходящей за пределы массива.
Утечки памяти вызваны распределением памяти, а не освобождением. Конструктор и деструкторы должны быть еще одной серьезной точкой обзора, чтобы убедиться, что выделенная память освобождена.
Ответ 8
Какую версию визуальной студии вы используете? В 2008 году, когда все предупреждения включены, все функции, о которых вы упоминаете (и многое другое), предупреждают вас, что они устарели.
Возможно, вы могли бы проверить, что все предупреждения включены, и пусть компилятор сделает вам тяжелую работу?
В качестве примечания, отличный написание защищенного кода отлично справляется с объяснением различных ошибок некоторых старых функций.
Ответ 9
У меня есть та же проблема на базе кода, над которой я работаю. Мой совет: будьте осторожны с любыми функциями C, которые выглядят как str *() и mem *(). Также будьте осторожны с тем, что принимает указатель на буфер, без длины. Поскольку кажется, что у вас есть возможность использовать С++, я бы в самых вопиющих случаях пытался использовать контейнеры С++ для вещей: вектор, строку, карту и т.д. Это значительно облегчает вашу жизнь.
Кроме того, автоматические средства обнаружения проблем замечательны. Если вы можете использовать valgrind, я бы порекомендовал его. Также Rational Purify является чрезвычайно мощным, хотя и не дешевым.
Ответ 10
Дополнительная функция getcha в C является функцией strncpy(). Многие люди не понимают, что они могут возвращать строку, которая не завершается нулем.
Ответ 11
В принципе, все, что принимает указатель и записывает на него, не проверяя длину. Так что вещи, такие как strcpy(), sprintf() и т.д.