"getenv": эта функция или переменная могут быть небезопасны." - действительно?

Я использую MSVC для компиляции кода C, который использует функции стандартной библиотеки, такие как getenv(), sprintf и другие, с /W3 набор для предупреждений. Мне сказали MSVC, что:

'getenv': эта функция или переменная может быть небезопасной. Попробуйте вместо этого использовать _dupenv_s. Чтобы отключить устаревание, используйте _CRT_SECURE_NO_WARNINGS

Вопросы:

  • Почему это было бы небезопасно, теоретически - в отличие от его использования на других платформах?
  • На практике это небезопасно для Windows?
  • Предполагая, что я не пишу ориентированный на безопасность код - следует ли отключить это предупреждение или фактически начать создавать псевдонимы для набора стандартных библиотечных функций?

2 ответа

Решение

getenv() потенциально небезопасно, поскольку последующие вызовы этой же функции могут сделать недействительными ранее возвращенные указатели. В результате использование таких как

char *a = getenv("A");
char *b = getenv("B");
/* do stuff with both a and b */

может сломаться, потому что нет гарантии a все еще можно использовать в этой точке.

getenv_s() избегает этого, немедленно копируя значение в предоставленный вызывающим буфер, где вызывающий имеет полный контроль над временем жизни буфера. dupenv_s() избегает этого, делая вызывающего ответственным за управление временем жизни выделенного буфера.

getenv страдает, как большая часть классической стандартной библиотеки C, не ограничивая длину буфера строки. Именно здесь часто возникают ошибки безопасности, такие как переполнение буфера.

Если вы посмотрите на getenv_s вы увидите, что он обеспечивает явную границу длины возвращаемой строки. Это рекомендуется для всего кодирования в соответствии с рекомендациями жизненного цикла разработки безопасности, поэтому Visual C++ выдает предупреждения об устаревании для менее безопасных версий.

Смотрите MSDN и этот пост

Microsoft предприняла попытку заставить стандартную библиотеку ISO C/C++ включить сюда защищенный CRT, некоторые из которых были одобрены для Приложения K C11, как указано здесь. Это также означает, что getenv_s должен быть частью стандартной библиотеки C++17 по ссылке. При этом Приложение K официально считается необязательным для соответствия. _s Проверяющие границы версии этих функций также все еще являются предметом некоторых дискуссий в сообществе C/C++.

Другие вопросы по тегам