私はMSVCを使用して、getenv()
、sprintf
などの標準ライブラリ関数を使用するCコードをコンパイルしています。警告には/W3
が設定されています。私はMSVCから次のように言われています:
'getenv':この関数または変数は安全でない可能性があります。代わりに_dupenv_sの使用を検討してください。非推奨を無効にするには、_CRT_SECURE_NO_WARNINGSを使用します
質問:
getenv()
は、同じ関数への後続の呼び出しが以前に返されたポインターを無効にする可能性があるため、潜在的に安全ではありません。その結果、
_char *a = getenv("A");
char *b = getenv("B");
/* do stuff with both a and b */
_
a
がその時点でまだ使用可能であるという保証がないため、破損する可能性があります。
getenv_s()
--C11以降のC標準ライブラリで使用可能-値を呼び出し元が提供するバッファーにすぐにコピーすることでこれを回避します。呼び出し元はバッファーの存続期間を完全に制御できます。 dupenv_s()
は、割り当てられたバッファーの存続期間を管理する責任を呼び出し元に持たせることにより、これを回避します。
ただし、_getenv_s
_の署名はやや物議を醸すものであり、関数はある時点でC標準から削除されることさえあります...を参照してください。 このレポート 。
getenv
は、文字列バッファの長さを制限しないことにより、従来のC標準ライブラリの多くと同じように苦しんでいます。これは、バッファオーバーランなどのセキュリティバグが頻繁に発生する場所です。
getenv_s
を見ると、返される文字列の長さに明示的な境界が設定されていることがわかります。 セキュリティ開発ライフサイクル のベストプラクティスによるすべてのコーディングに推奨されます。そのため、Visual C++は安全性の低いバージョンに対して非推奨の警告を発します。
[〜#〜] msdn [〜#〜] および このブログ投稿 を参照してください。
マイクロソフトは、C/C++ ISO標準ライブラリにSecureCRTを含めるように努力しました ここ 、その一部は、前述のようにC11 Annex Kで承認されました ここ 。これは、
getenv_s
が参照によりC++ 17標準ライブラリの一部であることも意味します。とは言うものの、Annex Kは、適合性のために公式にはオプションと見なされています。これらの関数の_s
境界チェックバージョンも、C/C++コミュニティでまだいくつかの 討論 の対象となっています。