17

メモリリークでいっぱいの大規模なC++コードベースを維持するように依頼されました。調べてみると、リークにつながるバッファオーバーフローがたくさんあることがわかりました(どうしてこれが悪くなったのか、知りたくありません)。

危険な機能から始めて、最初にバッファオーバーフローを削除することにしました。最も頻繁に誤って使用され、バッファオーバーフローを引き起こす可能性のあるC / C ++関数はどれですか?

バッファオーバーランの検索に使用されるコンパイラやツールについて、これを扱う別の質問を作成しました

4

11 に答える 11

12

一般に、引数の境界をチェックしない関数。リストは

  • 取得()
  • scanf()
  • strcpy()
  • strcat()

stncpy、strncat、fgetsなどのサイズ制限バージョンを使用する必要があります。次に、サイズ制限を指定するときは注意してください。文字列を終了する「\0」を考慮に入れてください。

また、配列はCまたはC++でバインドチェックされません。次の例ではエラーが発生します。1つのエラーで見送ります

int foo[3];
foo[3] = WALKED_OFF_END_OF_ARRAY;

編集:@ MrValdez、@DentonGentryの回答をコピー

于 2008-10-03T14:37:06.293 に答える
5

Valgrind はあなたの新しい親友です。

valgrind --tool=memcheck --leak-check=full ./a.out

于 2008-10-03T15:11:03.030 に答える
3

質問は間違ったところから始まっています。他の関数でバッファ オーバーランが発生することを想定しています。最も一般的な原因は、私の経験では operator++ であるか、あるいは operator!= の欠如です。

これらのバッチを見つけるための最良のソリューションは、Visual Studio 2005/8 の /GS です。すべてを見つけることはできませんが、必要な手作業の量を減らす安価な方法です。

于 2008-10-03T15:08:02.473 に答える
2

危険であることがわかった関数は次のとおりです。

  • get()-変数の長さをチェックせず、入力が変数のバッファよりも大きい場合、メモリを上書きする可能性があります。
  • scanf()-VisualStudioがこの関数は非推奨であると言ってくれてとてもうれしいです。これは簡単な修正でした。
  • strcpy()-ソースのメモリスペースが宛先のメモリスペースよりも大きい場合、宛先の後のデータは上書きされます。
于 2008-10-03T14:34:17.377 に答える
2

次のリンクから、C ++のセキュリティ機能(オーバーフローなどの問題を修正するために「_s」で後修正されたもの)を包括的に確認できます。http://msdn.microsoft.com/en-us/library/8ef0s5kh( VS.80).aspx

編集:このリンクには、置き換えられた特定の機能が含まれています:http: //msdn.microsoft.com/en-us/library/wd3wzwts (VS.80).aspx

編集:これらはMicrosoftの方法であることに言及する必要がありますが、リンクは依然として危険信号と見なされた関数を識別するのに役立ちます。

于 2008-10-03T14:36:07.933 に答える
2

残念ながら、どの配列でもバッファオーバーフローが発生する可能性があります。

uint32_t foo[3];
foo[3] = WALKED_OFF_END_OF_ARRAY;

関数に関しては、sprintfはバッファの終わりを喜んで歩きます。snprintfに置き換えることができます。

于 2008-10-03T14:36:43.487 に答える
2

Memcpy()はもう1つの危険なものです。

配列の終わりを超えて停止することはないため、配列にアクセスするループは危険なポイントです。

メモリリークは、メモリを割り当てて解放しないことによって発生します。コンストラクタとデストラクタは、もう1つの強力なレビューポイントである必要があります。後者は、割り当てられたメモリが解放されていることを確認するためのものです。

于 2008-10-03T14:39:33.950 に答える
2

どのバージョンのVisualStudioを使用していますか?すべての警告が有効になっている2008年には、言及したすべての機能(およびそれ以上)が非推奨であることを警告します。

おそらく、すべての警告がオンになっていることを確認して、コンパイラーにハードワークを任せることができますか?

ちなみに、安全なコードを書くことは、古い関数のいくつかの落とし穴を説明する素晴らしい仕事をします。

于 2008-10-03T14:43:24.723 に答える
2

私が取り組んでいるコードベースでも同じ問題があります。私のアドバイス:str *()やmem *()のように見えるC関数には注意してください。また、長さを指定せずに、バッファへのポインタを取得するものにも注意してください。C ++を使用する機会があるように思われるので、最もひどい場合には、ベクトル、文字列、マップなどにC++コンテナを使用しようとします。これらはあなたの生活をはるかに楽にします。

また、自動化された問題検出ツールは素晴らしいものです。valgrindを使用できる場合は、それをお勧めします。また、Rational Purifyは非常に強力ですが、安価ではありません。

于 2008-10-03T14:43:28.623 に答える
1

C での追加の問題は、"strncpy()" 関数です。多くの人は、null で終了していない文字列を自由に返すことができることに気づいていません。

于 2009-06-08T00:11:36.113 に答える
0

基本的に、長さをチェックせずに、ポインタを受け入れて書き込むものはすべて。つまり、strcpy()、sprintf()などです。

于 2008-10-03T14:38:40.207 に答える