Какие функции 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() и т.д.